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 }