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 }