Mercurial > hg > truffle
comparison graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotMetaAccessProvider.java @ 21551:5324104ac4f3
moved com.oracle.graal.hotspot.jvmci classes to com.oracle.jvmci.hotspot module (JBS:GRAAL-53)
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Tue, 26 May 2015 17:13:37 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
21550:f48a6cea31eb | 21551:5324104ac4f3 |
---|---|
1 /* | |
2 * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 */ | |
23 package com.oracle.jvmci.hotspot; | |
24 | |
25 import static com.oracle.jvmci.common.UnsafeAccess.*; | |
26 import static com.oracle.jvmci.hotspot.HotSpotResolvedJavaType.*; | |
27 import static com.oracle.jvmci.hotspot.HotSpotResolvedObjectTypeImpl.*; | |
28 | |
29 import java.lang.reflect.*; | |
30 | |
31 import com.oracle.graal.api.code.*; | |
32 import com.oracle.graal.api.meta.*; | |
33 import com.oracle.jvmci.common.*; | |
34 | |
35 /** | |
36 * HotSpot implementation of {@link MetaAccessProvider}. | |
37 */ | |
38 public class HotSpotMetaAccessProvider implements MetaAccessProvider, HotSpotProxified { | |
39 | |
40 protected final HotSpotJVMCIRuntimeProvider runtime; | |
41 | |
42 public HotSpotMetaAccessProvider(HotSpotJVMCIRuntimeProvider runtime) { | |
43 this.runtime = runtime; | |
44 } | |
45 | |
46 public ResolvedJavaType lookupJavaType(Class<?> clazz) { | |
47 if (clazz == null) { | |
48 throw new IllegalArgumentException("Class parameter was null"); | |
49 } | |
50 return runtime.fromClass(clazz); | |
51 } | |
52 | |
53 public HotSpotResolvedObjectType lookupJavaType(JavaConstant constant) { | |
54 if (constant.isNull() || !(constant instanceof HotSpotObjectConstant)) { | |
55 return null; | |
56 } | |
57 return ((HotSpotObjectConstant) constant).getType(); | |
58 } | |
59 | |
60 public Signature parseMethodDescriptor(String signature) { | |
61 return new HotSpotSignature(runtime, signature); | |
62 } | |
63 | |
64 /** | |
65 * {@link Field} object of {@link Method#slot}. | |
66 */ | |
67 @SuppressWarnings("javadoc") private Field reflectionMethodSlot = getReflectionSlotField(Method.class); | |
68 | |
69 /** | |
70 * {@link Field} object of {@link Constructor#slot}. | |
71 */ | |
72 @SuppressWarnings("javadoc") private Field reflectionConstructorSlot = getReflectionSlotField(Constructor.class); | |
73 | |
74 private static Field getReflectionSlotField(Class<?> reflectionClass) { | |
75 try { | |
76 Field field = reflectionClass.getDeclaredField("slot"); | |
77 field.setAccessible(true); | |
78 return field; | |
79 } catch (NoSuchFieldException | SecurityException e) { | |
80 throw new JVMCIError(e); | |
81 } | |
82 } | |
83 | |
84 public ResolvedJavaMethod lookupJavaMethod(Executable reflectionMethod) { | |
85 try { | |
86 Class<?> holder = reflectionMethod.getDeclaringClass(); | |
87 Field slotField = reflectionMethod instanceof Constructor ? reflectionConstructorSlot : reflectionMethodSlot; | |
88 final int slot = slotField.getInt(reflectionMethod); | |
89 final long metaspaceMethod = runtime.getCompilerToVM().getMetaspaceMethod(holder, slot); | |
90 return HotSpotResolvedJavaMethodImpl.fromMetaspace(metaspaceMethod); | |
91 } catch (IllegalArgumentException | IllegalAccessException e) { | |
92 throw new JVMCIError(e); | |
93 } | |
94 } | |
95 | |
96 public ResolvedJavaField lookupJavaField(Field reflectionField) { | |
97 String name = reflectionField.getName(); | |
98 Class<?> fieldHolder = reflectionField.getDeclaringClass(); | |
99 Class<?> fieldType = reflectionField.getType(); | |
100 // java.lang.reflect.Field's modifiers should be enough here since VM internal modifier bits | |
101 // are not used (yet). | |
102 final int modifiers = reflectionField.getModifiers(); | |
103 final long offset = Modifier.isStatic(modifiers) ? unsafe.staticFieldOffset(reflectionField) : unsafe.objectFieldOffset(reflectionField); | |
104 | |
105 HotSpotResolvedObjectType holder = fromObjectClass(fieldHolder); | |
106 JavaType type = fromClass(fieldType); | |
107 | |
108 if (offset != -1) { | |
109 HotSpotResolvedObjectType resolved = holder; | |
110 return resolved.createField(name, type, offset, modifiers); | |
111 } else { | |
112 throw new JVMCIError("unresolved field %s", reflectionField); | |
113 } | |
114 } | |
115 | |
116 private static int intMaskRight(int n) { | |
117 assert n <= 32; | |
118 return n == 32 ? -1 : (1 << n) - 1; | |
119 } | |
120 | |
121 @Override | |
122 public JavaConstant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason, int debugId) { | |
123 HotSpotVMConfig config = runtime.getConfig(); | |
124 int actionValue = convertDeoptAction(action); | |
125 int reasonValue = convertDeoptReason(reason); | |
126 int debugValue = debugId & intMaskRight(config.deoptimizationDebugIdBits); | |
127 JavaConstant c = JavaConstant.forInt(~((debugValue << config.deoptimizationDebugIdShift) | (reasonValue << config.deoptimizationReasonShift) | (actionValue << config.deoptimizationActionShift))); | |
128 assert c.asInt() < 0; | |
129 return c; | |
130 } | |
131 | |
132 public DeoptimizationReason decodeDeoptReason(JavaConstant constant) { | |
133 HotSpotVMConfig config = runtime.getConfig(); | |
134 int reasonValue = ((~constant.asInt()) >> config.deoptimizationReasonShift) & intMaskRight(config.deoptimizationReasonBits); | |
135 DeoptimizationReason reason = convertDeoptReason(reasonValue); | |
136 return reason; | |
137 } | |
138 | |
139 public DeoptimizationAction decodeDeoptAction(JavaConstant constant) { | |
140 HotSpotVMConfig config = runtime.getConfig(); | |
141 int actionValue = ((~constant.asInt()) >> config.deoptimizationActionShift) & intMaskRight(config.deoptimizationActionBits); | |
142 DeoptimizationAction action = convertDeoptAction(actionValue); | |
143 return action; | |
144 } | |
145 | |
146 public int decodeDebugId(JavaConstant constant) { | |
147 HotSpotVMConfig config = runtime.getConfig(); | |
148 return ((~constant.asInt()) >> config.deoptimizationDebugIdShift) & intMaskRight(config.deoptimizationDebugIdBits); | |
149 } | |
150 | |
151 public int convertDeoptAction(DeoptimizationAction action) { | |
152 HotSpotVMConfig config = runtime.getConfig(); | |
153 switch (action) { | |
154 case None: | |
155 return config.deoptActionNone; | |
156 case RecompileIfTooManyDeopts: | |
157 return config.deoptActionMaybeRecompile; | |
158 case InvalidateReprofile: | |
159 return config.deoptActionReinterpret; | |
160 case InvalidateRecompile: | |
161 return config.deoptActionMakeNotEntrant; | |
162 case InvalidateStopCompiling: | |
163 return config.deoptActionMakeNotCompilable; | |
164 default: | |
165 throw new JVMCIError("%s", action); | |
166 } | |
167 } | |
168 | |
169 public DeoptimizationAction convertDeoptAction(int action) { | |
170 HotSpotVMConfig config = runtime.getConfig(); | |
171 if (action == config.deoptActionNone) { | |
172 return DeoptimizationAction.None; | |
173 } | |
174 if (action == config.deoptActionMaybeRecompile) { | |
175 return DeoptimizationAction.RecompileIfTooManyDeopts; | |
176 } | |
177 if (action == config.deoptActionReinterpret) { | |
178 return DeoptimizationAction.InvalidateReprofile; | |
179 } | |
180 if (action == config.deoptActionMakeNotEntrant) { | |
181 return DeoptimizationAction.InvalidateRecompile; | |
182 } | |
183 if (action == config.deoptActionMakeNotCompilable) { | |
184 return DeoptimizationAction.InvalidateStopCompiling; | |
185 } | |
186 throw new JVMCIError("%d", action); | |
187 } | |
188 | |
189 public int convertDeoptReason(DeoptimizationReason reason) { | |
190 HotSpotVMConfig config = runtime.getConfig(); | |
191 switch (reason) { | |
192 case None: | |
193 return config.deoptReasonNone; | |
194 case NullCheckException: | |
195 return config.deoptReasonNullCheck; | |
196 case BoundsCheckException: | |
197 return config.deoptReasonRangeCheck; | |
198 case ClassCastException: | |
199 return config.deoptReasonClassCheck; | |
200 case ArrayStoreException: | |
201 return config.deoptReasonArrayCheck; | |
202 case UnreachedCode: | |
203 return config.deoptReasonUnreached0; | |
204 case TypeCheckedInliningViolated: | |
205 return config.deoptReasonTypeCheckInlining; | |
206 case OptimizedTypeCheckViolated: | |
207 return config.deoptReasonOptimizedTypeCheck; | |
208 case NotCompiledExceptionHandler: | |
209 return config.deoptReasonNotCompiledExceptionHandler; | |
210 case Unresolved: | |
211 return config.deoptReasonUnresolved; | |
212 case JavaSubroutineMismatch: | |
213 return config.deoptReasonJsrMismatch; | |
214 case ArithmeticException: | |
215 return config.deoptReasonDiv0Check; | |
216 case RuntimeConstraint: | |
217 return config.deoptReasonConstraint; | |
218 case LoopLimitCheck: | |
219 return config.deoptReasonLoopLimitCheck; | |
220 case Aliasing: | |
221 return config.deoptReasonAliasing; | |
222 case TransferToInterpreter: | |
223 return config.deoptReasonTransferToInterpreter; | |
224 default: | |
225 throw new JVMCIError("%s", reason); | |
226 } | |
227 } | |
228 | |
229 public DeoptimizationReason convertDeoptReason(int reason) { | |
230 HotSpotVMConfig config = runtime.getConfig(); | |
231 if (reason == config.deoptReasonNone) { | |
232 return DeoptimizationReason.None; | |
233 } | |
234 if (reason == config.deoptReasonNullCheck) { | |
235 return DeoptimizationReason.NullCheckException; | |
236 } | |
237 if (reason == config.deoptReasonRangeCheck) { | |
238 return DeoptimizationReason.BoundsCheckException; | |
239 } | |
240 if (reason == config.deoptReasonClassCheck) { | |
241 return DeoptimizationReason.ClassCastException; | |
242 } | |
243 if (reason == config.deoptReasonArrayCheck) { | |
244 return DeoptimizationReason.ArrayStoreException; | |
245 } | |
246 if (reason == config.deoptReasonUnreached0) { | |
247 return DeoptimizationReason.UnreachedCode; | |
248 } | |
249 if (reason == config.deoptReasonTypeCheckInlining) { | |
250 return DeoptimizationReason.TypeCheckedInliningViolated; | |
251 } | |
252 if (reason == config.deoptReasonOptimizedTypeCheck) { | |
253 return DeoptimizationReason.OptimizedTypeCheckViolated; | |
254 } | |
255 if (reason == config.deoptReasonNotCompiledExceptionHandler) { | |
256 return DeoptimizationReason.NotCompiledExceptionHandler; | |
257 } | |
258 if (reason == config.deoptReasonUnresolved) { | |
259 return DeoptimizationReason.Unresolved; | |
260 } | |
261 if (reason == config.deoptReasonJsrMismatch) { | |
262 return DeoptimizationReason.JavaSubroutineMismatch; | |
263 } | |
264 if (reason == config.deoptReasonDiv0Check) { | |
265 return DeoptimizationReason.ArithmeticException; | |
266 } | |
267 if (reason == config.deoptReasonConstraint) { | |
268 return DeoptimizationReason.RuntimeConstraint; | |
269 } | |
270 if (reason == config.deoptReasonLoopLimitCheck) { | |
271 return DeoptimizationReason.LoopLimitCheck; | |
272 } | |
273 if (reason == config.deoptReasonAliasing) { | |
274 return DeoptimizationReason.Aliasing; | |
275 } | |
276 if (reason == config.deoptReasonTransferToInterpreter) { | |
277 return DeoptimizationReason.TransferToInterpreter; | |
278 } | |
279 throw new JVMCIError("%x", reason); | |
280 } | |
281 | |
282 @Override | |
283 public long getMemorySize(JavaConstant constant) { | |
284 if (constant.getKind() == Kind.Object) { | |
285 HotSpotResolvedObjectType lookupJavaType = lookupJavaType(constant); | |
286 | |
287 if (lookupJavaType == null) { | |
288 return 0; | |
289 } else { | |
290 if (lookupJavaType.isArray()) { | |
291 // TODO(tw): Add compressed pointer support. | |
292 int length = Array.getLength(((HotSpotObjectConstantImpl) constant).object()); | |
293 ResolvedJavaType elementType = lookupJavaType.getComponentType(); | |
294 Kind elementKind = elementType.getKind(); | |
295 final int headerSize = runtime.getArrayBaseOffset(elementKind); | |
296 TargetDescription target = runtime.getHostJVMCIBackend().getTarget(); | |
297 int sizeOfElement = target.getSizeInBytes(elementKind); | |
298 int alignment = target.wordSize; | |
299 int log2ElementSize = CodeUtil.log2(sizeOfElement); | |
300 return computeArrayAllocationSize(length, alignment, headerSize, log2ElementSize); | |
301 } | |
302 return lookupJavaType.instanceSize(); | |
303 } | |
304 } else { | |
305 return constant.getKind().getByteCount(); | |
306 } | |
307 } | |
308 | |
309 /** | |
310 * Computes the size of the memory chunk allocated for an array. This size accounts for the | |
311 * array header size, body size and any padding after the last element to satisfy object | |
312 * alignment requirements. | |
313 * | |
314 * @param length the number of elements in the array | |
315 * @param alignment the object alignment requirement | |
316 * @param headerSize the size of the array header | |
317 * @param log2ElementSize log2 of the size of an element in the array | |
318 */ | |
319 public static int computeArrayAllocationSize(int length, int alignment, int headerSize, int log2ElementSize) { | |
320 int size = (length << log2ElementSize) + headerSize + (alignment - 1); | |
321 int mask = ~(alignment - 1); | |
322 return size & mask; | |
323 } | |
324 } |