001 /* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013 package org.jikesrvm.ia32; 014 015 import org.jikesrvm.VM; 016 import org.jikesrvm.Constants; 017 import org.jikesrvm.classloader.RVMMethod; 018 import org.jikesrvm.classloader.TypeReference; 019 import org.jikesrvm.runtime.Magic; 020 import org.vmmagic.pragma.UnpreemptibleNoWarn; 021 import org.vmmagic.unboxed.Word; 022 import org.vmmagic.unboxed.WordArray; 023 024 /** 025 * Machine dependent portion of Reflective method invoker. 026 */ 027 public abstract class MachineReflection implements RegisterConstants { 028 029 /** 030 * Determine number/type of registers and parameters required to 031 * call specified method. 032 * Unlike the PowerPC code we count all the parameters, not just the 033 * ones that spill. This allow us to make enough space on the stack 034 * following the calling convention. 035 */ 036 public static int countParameters(RVMMethod method) { 037 int GPRs = 0; 038 int FPRs = 0; 039 int parameters = 0; // parameters size in 32-bits quant. 040 041 int gp = NUM_PARAMETER_GPRS; // 0, 1, 2 042 int fp = NUM_PARAMETER_FPRS; // 0-8 043 044 if (!method.isStatic()) { 045 if (gp > 0) { 046 GPRs++; 047 gp--; 048 } 049 parameters++; 050 } 051 052 for (TypeReference t : method.getParameterTypes()) { 053 if (t.isLongType()) { 054 if (gp > 0) { 055 GPRs++; 056 gp--; 057 if (VM.BuildFor32Addr && gp > 0) { 058 GPRs++; 059 gp--; 060 } 061 } 062 parameters += 2; 063 } else if (t.isFloatType()) { 064 if (fp > 0) { 065 FPRs++; 066 fp--; 067 } 068 parameters++; 069 } else if (t.isDoubleType()) { 070 if (fp > 0) { 071 FPRs++; 072 fp--; 073 } 074 parameters += 2; 075 } else { // t is object, int, short, char, byte, or boolean 076 if (gp > 0) { 077 GPRs++; 078 gp--; 079 } 080 parameters++; 081 } 082 } 083 084 // hack to return triple 085 return (parameters << (Constants.REFLECTION_FPRS_BITS + Constants.REFLECTION_GPRS_BITS)) | 086 (FPRs << Constants.REFLECTION_GPRS_BITS) | 087 GPRs; 088 } 089 090 /** 091 * Collect parameters into arrays of registers/spills, as required to 092 * call specified method. 093 */ 094 @UnpreemptibleNoWarn("GC is disabled as Objects are turned into Words."+ 095 "avoid preemption but still allow calls to preemptible unboxing routines") 096 public static void packageParameters(RVMMethod method, Object thisArg, Object[] otherArgs, WordArray GPRs, 097 double[] FPRs, byte[] FPRmeta, WordArray Parameters) { 098 int GPR = 0; 099 int FPR = ArchConstants.SSE2_FULL ? 0 : FPRs.length; 100 int parameter = 0; 101 102 int gp = NUM_PARAMETER_GPRS; // 0, 1, 2 103 int fp = NUM_PARAMETER_FPRS; // 0-8 104 105 if (!method.isStatic()) { 106 Word val = Magic.objectAsAddress(thisArg).toWord(); 107 if (gp > 0) { 108 gp--; 109 GPRs.set(GPR++, val); 110 } 111 Parameters.set(parameter++, val); 112 } 113 114 TypeReference[] types = method.getParameterTypes(); 115 for (int i = 0; i < types.length; i++) { 116 TypeReference t = types[i]; 117 118 if (!t.isPrimitiveType()) { 119 Word val = Magic.objectAsAddress(otherArgs[i]).toWord(); 120 if (gp > 0) { 121 gp--; 122 GPRs.set(GPR++, val); 123 } 124 Parameters.set(parameter++, val); 125 } else if (t.isLongType()) { 126 long l = (Long)otherArgs[i]; 127 if (VM.BuildFor32Addr) { 128 if (gp > 0) { 129 gp--; 130 GPRs.set(GPR++, Word.fromIntZeroExtend((int) (l >>> 32))); 131 if (gp > 0) { 132 gp--; 133 GPRs.set(GPR++, Word.fromIntZeroExtend((int) (l))); 134 } 135 } 136 Parameters.set(parameter++, Word.fromIntZeroExtend((int) (l >>> 32))); 137 Parameters.set(parameter++, Word.fromIntZeroExtend((int) l)); 138 } else { 139 Word val = Word.fromLong(l); 140 if (gp > 0) { 141 gp--; 142 GPRs.set(GPR++, val); 143 } 144 Parameters.set(parameter++, val); 145 Parameters.set(parameter++, val); 146 } 147 } else if (t.isFloatType()) { 148 if (fp > 0) { 149 fp--; 150 if (ArchConstants.SSE2_FULL) { 151 FPRs[FPR] = (Float)otherArgs[i]; 152 FPRmeta[FPR] = 0x0; 153 FPR++; 154 } else { 155 FPRs[--FPR] = (Float)otherArgs[i]; 156 } 157 } 158 float f = (Float)otherArgs[i]; 159 Parameters.set(parameter++, Word.fromIntZeroExtend(Float.floatToIntBits(f))); 160 } else if (t.isDoubleType()) { 161 if (VM.BuildFor32Addr) { 162 if (fp > 0) { 163 fp--; 164 if (ArchConstants.SSE2_FULL) { 165 FPRs[FPR] = (Double)otherArgs[i]; 166 FPRmeta[FPR] = 0x1; 167 FPR++; 168 } else { 169 FPRs[--FPR] = (Double)otherArgs[i]; 170 } 171 } 172 double d = (Double)otherArgs[i]; 173 long l = Double.doubleToLongBits(d); 174 Parameters.set(parameter++, Word.fromIntZeroExtend((int) (l >>> 32))); 175 Parameters.set(parameter++, Word.fromIntZeroExtend((int) l)); 176 } else { 177 if (fp > 0) { 178 fp--; 179 if (ArchConstants.SSE2_FULL) { 180 FPRs[FPR] = (Double)otherArgs[i]; 181 FPRmeta[FPR] = 0x1; 182 FPR++; 183 } else { 184 FPRs[--FPR] = (Double)otherArgs[i]; 185 } 186 } 187 double d = (Double)otherArgs[i]; 188 long l = Double.doubleToLongBits(d); 189 Word val = Word.fromLong(l); 190 Parameters.set(parameter++, val); 191 Parameters.set(parameter++, val); 192 } 193 } else if (t.isBooleanType()) { 194 boolean b = (Boolean)otherArgs[i]; 195 Word val = Word.fromIntZeroExtend(b ? 1 : 0); 196 if (gp > 0) { 197 gp--; 198 GPRs.set(GPR++, val); 199 } 200 Parameters.set(parameter++, val); 201 } else if (t.isCharType()) { 202 char c = (Character)otherArgs[i]; 203 Word val = Word.fromIntZeroExtend(c); 204 if (gp > 0) { 205 gp--; 206 GPRs.set(GPR++, val); 207 } 208 Parameters.set(parameter++, val); 209 } else { 210 if (VM.VerifyAssertions) VM._assert(t.isByteType() || t.isShortType() || t.isIntType()); 211 int x = ((Number)otherArgs[i]).intValue(); 212 Word val = Word.fromIntZeroExtend(x); 213 if (gp > 0) { 214 gp--; 215 GPRs.set(GPR++, val); 216 } 217 Parameters.set(parameter++, val); 218 } 219 } 220 } 221 }