1 /*
2 * Copyright (c) 2011, 2024, 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
24 package jdk.vm.ci.hotspot;
25
26 import java.lang.reflect.Executable;
27 import java.lang.reflect.Field;
28
29 import jdk.internal.misc.Unsafe;
30 import jdk.vm.ci.code.BytecodeFrame;
31 import jdk.vm.ci.code.InstalledCode;
32 import jdk.vm.ci.code.InvalidInstalledCodeException;
33 import jdk.vm.ci.code.stack.InspectedFrameVisitor;
34 import jdk.vm.ci.common.InitTimer;
35 import static jdk.vm.ci.common.InitTimer.timer;
36 import jdk.vm.ci.common.JVMCIError;
37 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option;
38 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
39 import jdk.vm.ci.meta.Constant;
40 import jdk.vm.ci.meta.ConstantReflectionProvider;
41 import jdk.vm.ci.meta.JavaConstant;
42 import jdk.vm.ci.meta.JavaKind;
43 import jdk.vm.ci.meta.JavaType;
44 import jdk.vm.ci.meta.ResolvedJavaMethod;
45 import jdk.vm.ci.meta.ResolvedJavaType;
46
47 /**
48 * Calls from Java into HotSpot. The behavior of all the methods in this class that take a native
49 * pointer as an argument (e.g., {@link #getSymbol(long)}) is undefined if the argument does not
50 * denote a valid native object.
51 *
52 * Note also that some calls pass a raw VM value to avoid a JNI upcall. For example,
53 * {@link #getBytecode(HotSpotResolvedJavaMethodImpl, long)} needs the raw {@code Method*} value
54 * (stored in {@link HotSpotResolvedJavaMethodImpl#methodHandle}) in the C++ implementation. The
55 * {@link HotSpotResolvedJavaMethodImpl} wrapper is still passed as well as it may be the last
56 * reference keeping the raw value alive.
57 */
58 final class CompilerToVM {
59 /**
60 * Initializes the native part of the JVMCI runtime.
61 */
62 private static native void registerNatives();
63
64 /**
65 * These values mirror the equivalent values from {@code Unsafe} but are appropriate for the JVM
66 * being compiled against.
67 */
68 final int ARRAY_BOOLEAN_BASE_OFFSET;
69 final int ARRAY_BYTE_BASE_OFFSET;
70 final int ARRAY_SHORT_BASE_OFFSET;
71 final int ARRAY_CHAR_BASE_OFFSET;
72 final int ARRAY_INT_BASE_OFFSET;
73 final int ARRAY_LONG_BASE_OFFSET;
74 final int ARRAY_FLOAT_BASE_OFFSET;
75 final int ARRAY_DOUBLE_BASE_OFFSET;
76 final int ARRAY_OBJECT_BASE_OFFSET;
77 final int ARRAY_BOOLEAN_INDEX_SCALE;
78 final int ARRAY_BYTE_INDEX_SCALE;
79 final int ARRAY_SHORT_INDEX_SCALE;
80 final int ARRAY_CHAR_INDEX_SCALE;
81 final int ARRAY_INT_INDEX_SCALE;
82 final int ARRAY_LONG_INDEX_SCALE;
83 final int ARRAY_FLOAT_INDEX_SCALE;
84 final int ARRAY_DOUBLE_INDEX_SCALE;
85 final int ARRAY_OBJECT_INDEX_SCALE;
86
87 @SuppressWarnings("try")
88 CompilerToVM() {
89 try (InitTimer t = timer("CompilerToVM.registerNatives")) {
90 registerNatives();
91 ARRAY_BOOLEAN_BASE_OFFSET = arrayBaseOffset(JavaKind.Boolean.getTypeChar());
92 ARRAY_BYTE_BASE_OFFSET = arrayBaseOffset(JavaKind.Byte.getTypeChar());
93 ARRAY_SHORT_BASE_OFFSET = arrayBaseOffset(JavaKind.Short.getTypeChar());
94 ARRAY_CHAR_BASE_OFFSET = arrayBaseOffset(JavaKind.Char.getTypeChar());
95 ARRAY_INT_BASE_OFFSET = arrayBaseOffset(JavaKind.Int.getTypeChar());
96 ARRAY_LONG_BASE_OFFSET = arrayBaseOffset(JavaKind.Long.getTypeChar());
97 ARRAY_FLOAT_BASE_OFFSET = arrayBaseOffset(JavaKind.Float.getTypeChar());
98 ARRAY_DOUBLE_BASE_OFFSET = arrayBaseOffset(JavaKind.Double.getTypeChar());
99 ARRAY_OBJECT_BASE_OFFSET = arrayBaseOffset(JavaKind.Object.getTypeChar());
100 ARRAY_BOOLEAN_INDEX_SCALE = arrayIndexScale(JavaKind.Boolean.getTypeChar());
101 ARRAY_BYTE_INDEX_SCALE = arrayIndexScale(JavaKind.Byte.getTypeChar());
102 ARRAY_SHORT_INDEX_SCALE = arrayIndexScale(JavaKind.Short.getTypeChar());
103 ARRAY_CHAR_INDEX_SCALE = arrayIndexScale(JavaKind.Char.getTypeChar());
104 ARRAY_INT_INDEX_SCALE = arrayIndexScale(JavaKind.Int.getTypeChar());
105 ARRAY_LONG_INDEX_SCALE = arrayIndexScale(JavaKind.Long.getTypeChar());
106 ARRAY_FLOAT_INDEX_SCALE = arrayIndexScale(JavaKind.Float.getTypeChar());
107 ARRAY_DOUBLE_INDEX_SCALE = arrayIndexScale(JavaKind.Double.getTypeChar());
108 ARRAY_OBJECT_INDEX_SCALE = arrayIndexScale(JavaKind.Object.getTypeChar());
109 }
110 }
111
112 native int arrayBaseOffset(char typeChar);
113
114 native int arrayIndexScale(char typeChar);
115
116 /**
117 * Gets the {@link CompilerToVM} instance associated with the singleton
118 * {@link HotSpotJVMCIRuntime} instance.
119 */
120 public static CompilerToVM compilerToVM() {
121 return runtime().getCompilerToVM();
122 }
123
124 /**
125 * Copies the original bytecode of {@code method} into a new byte array and returns it.
126 *
127 * @return a new byte array containing the original bytecode of {@code method}
128 */
129 byte[] getBytecode(HotSpotResolvedJavaMethodImpl method) {
130 return getBytecode(method, method.getMethodPointer());
131 }
132
133 private native byte[] getBytecode(HotSpotResolvedJavaMethodImpl method, long methodPointer);
134
135 /**
136 * Gets the number of entries in {@code method}'s exception handler table or 0 if it has no
137 * exception handler table.
138 */
139 int getExceptionTableLength(HotSpotResolvedJavaMethodImpl method) {
140 return getExceptionTableLength(method, method.getMethodPointer());
141 }
142
143 private native int getExceptionTableLength(HotSpotResolvedJavaMethodImpl method, long methodPointer);
144
145 /**
146 * Gets the address of the first entry in {@code method}'s exception handler table.
147 *
148 * Each entry is a native object described by these fields:
149 *
150 * <ul>
151 * <li>{@link HotSpotVMConfig#exceptionTableElementSize}</li>
152 * <li>{@link HotSpotVMConfig#exceptionTableElementStartPcOffset}</li>
153 * <li>{@link HotSpotVMConfig#exceptionTableElementEndPcOffset}</li>
154 * <li>{@link HotSpotVMConfig#exceptionTableElementHandlerPcOffset}</li>
155 * <li>{@link HotSpotVMConfig#exceptionTableElementCatchTypeIndexOffset}
156 * </ul>
157 *
158 * @return 0 if {@code method} has no exception handlers (i.e.
159 * {@code getExceptionTableLength(method) == 0})
160 */
161 long getExceptionTableStart(HotSpotResolvedJavaMethodImpl method) {
162 return getExceptionTableStart(method, method.getMethodPointer());
163 }
164
165 private native long getExceptionTableStart(HotSpotResolvedJavaMethodImpl method, long methodPointer);
166
167 /**
168 * Determines whether {@code method} is currently compilable by the JVMCI compiler being used by
169 * the VM. This can return false if JVMCI compilation failed earlier for {@code method}, a
170 * breakpoint is currently set in {@code method} or {@code method} contains other bytecode
171 * features that require special handling by the VM.
172 */
173 boolean isCompilable(HotSpotResolvedJavaMethodImpl method) {
174 return isCompilable(method, method.getMethodPointer());
175 }
176
177 private native boolean isCompilable(HotSpotResolvedJavaMethodImpl method, long methodPointer);
178
179 /**
180 * Determines if {@code method} is targeted by a VM directive (e.g.,
181 * {@code -XX:CompileCommand=dontinline,<pattern>}) or annotation (e.g.,
182 * {@code jdk.internal.vm.annotation.DontInline}) that specifies it should not be inlined.
183 */
184 boolean hasNeverInlineDirective(HotSpotResolvedJavaMethodImpl method) {
185 return hasNeverInlineDirective(method, method.getMethodPointer());
186 }
187
188 private native boolean hasNeverInlineDirective(HotSpotResolvedJavaMethodImpl method, long methodPointer);
189
190 /**
191 * Determines if {@code method} should be inlined at any cost. This could be because:
192 * <ul>
193 * <li>a CompileOracle directive may forces inlining of this methods</li>
194 * <li>an annotation forces inlining of this method</li>
195 * </ul>
196 */
197 boolean shouldInlineMethod(HotSpotResolvedJavaMethodImpl method) {
198 return shouldInlineMethod(method, method.getMethodPointer());
199 }
200
201 private native boolean shouldInlineMethod(HotSpotResolvedJavaMethodImpl method, long methodPointer);
202
203 /**
204 * Used to implement {@link ResolvedJavaType#findUniqueConcreteMethod(ResolvedJavaMethod)}.
205 *
206 * @param actualHolderType the best known type of receiver
207 * @param method the method on which to base the search
208 * @return the method result or 0 is there is no unique concrete method for {@code method}
209 */
210 HotSpotResolvedJavaMethodImpl findUniqueConcreteMethod(HotSpotResolvedObjectTypeImpl actualHolderType, HotSpotResolvedJavaMethodImpl method) {
211 return findUniqueConcreteMethod(actualHolderType, actualHolderType.getKlassPointer(), method, method.getMetaspacePointer());
212 }
213
214 private native HotSpotResolvedJavaMethodImpl findUniqueConcreteMethod(HotSpotResolvedObjectTypeImpl klass, long klassPointer, HotSpotResolvedJavaMethodImpl method, long methodPointer);
215
216 /**
217 * Gets the implementor for the interface class {@code type}.
218 *
219 * @return the implementor if there is a single implementor, {@code null} if there is no
220 * implementor, or {@code type} itself if there is more than one implementor
221 * @throws IllegalArgumentException if type is not an interface type
222 */
223 HotSpotResolvedObjectTypeImpl getImplementor(HotSpotResolvedObjectTypeImpl type) {
224 return getImplementor(type, type.getKlassPointer());
225 }
226
227 private native HotSpotResolvedObjectTypeImpl getImplementor(HotSpotResolvedObjectTypeImpl type, long klassPointer);
228
229 /**
230 * Determines if {@code method} is ignored by security stack walks.
231 */
232 boolean methodIsIgnoredBySecurityStackWalk(HotSpotResolvedJavaMethodImpl method) {
233 return methodIsIgnoredBySecurityStackWalk(method, method.getMetaspacePointer());
234 }
235
236 private native boolean methodIsIgnoredBySecurityStackWalk(HotSpotResolvedJavaMethodImpl method, long methodPointer);
237
238 /**
239 * Converts a name to a type.
240 *
241 * @param name a well formed Java type in {@linkplain JavaType#getName() internal} format
242 * @param accessingClass the class loader of this class is used for resolution. Must not be null.
243 * @param resolve force resolution to a {@link ResolvedJavaType}. If true, this method will
244 * either return a {@link ResolvedJavaType} or throw an exception
245 * @return the type for {@code name} or {@code null} if resolution failed and {@code resolve == false}
246 * @throws NoClassDefFoundError if {@code resolve == true} and the resolution failed
247 */
248 HotSpotResolvedJavaType lookupType(String name, HotSpotResolvedObjectTypeImpl accessingClass, boolean resolve) throws NoClassDefFoundError {
249 return lookupType(name, accessingClass, accessingClass.getKlassPointer(), -1, resolve);
250 }
251
252 /**
253 * Converts a name to a type.
254 *
255 * @param classLoader the class loader to use for resolution. Must not be {@code null},
256 * {@link ClassLoader#getPlatformClassLoader} or {@link ClassLoader#getSystemClassLoader}
257 * @param name a well formed Java type in {@linkplain JavaType#getName() internal} format
258 * @return the type for {@code name}
259 * @throws NoClassDefFoundError if resolution failed
260 */
261 HotSpotResolvedJavaType lookupType(ClassLoader classLoader, String name) throws NoClassDefFoundError {
262 int accessingClassLoader;
263 if (classLoader == null) {
264 accessingClassLoader = 0;
265 } else if (classLoader == ClassLoader.getPlatformClassLoader()) {
266 accessingClassLoader = 1;
267 } else if (classLoader == ClassLoader.getSystemClassLoader()) {
268 accessingClassLoader = 2;
269 } else {
270 throw new IllegalArgumentException("Unsupported class loader for lookup: " + classLoader);
271 }
272 return lookupType(name, null, 0L, accessingClassLoader, true);
273 }
274
275 /**
276 * @param accessingClassLoader ignored if {@code accessingKlassPointer != 0L}. Otherwise, the supported values are:
277 * 0 - boot class loader
278 * 1 - {@linkplain ClassLoader#getPlatformClassLoader() platform class loader}
279 * 2 - {@linkplain ClassLoader#getSystemClassLoader() system class loader}
280 */
281 private native HotSpotResolvedJavaType lookupType(String name, HotSpotResolvedObjectTypeImpl accessingClass, long accessingKlassPointer, int accessingClassLoader, boolean resolve) throws NoClassDefFoundError;
282
283 /**
284 * Converts {@code javaClass} to a HotSpotResolvedJavaType.
285 *
286 * Must not be called if {@link Services#IS_IN_NATIVE_IMAGE} is {@code true}.
287 */
288 native HotSpotResolvedJavaType lookupClass(Class<?> javaClass);
289
290 native HotSpotResolvedJavaType lookupJClass(long jclass);
291
292 /**
293 * Gets the {@code jobject} value wrapped by {@code peerObject}.
294 * Must not be called if {@link Services#IS_IN_NATIVE_IMAGE} is {@code false}.
295 */
296 native long getJObjectValue(HotSpotObjectConstantImpl peerObject);
297
298 /**
299 * Resolves the entry at index {@code cpi} in {@code constantPool} to an interned String object.
300 *
301 * The behavior of this method is undefined if {@code cpi} does not denote an
302 * {@code JVM_CONSTANT_String}.
303 */
304 JavaConstant getUncachedStringInPool(HotSpotConstantPool constantPool, int cpi) {
305 return getUncachedStringInPool(constantPool, constantPool.getConstantPoolPointer(), cpi);
306 }
307
308 private native JavaConstant getUncachedStringInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi);
309
310 /**
311 * Gets the entry at index {@code cpi} in {@code constantPool}, looking in the
312 * constant pool cache first.
313 *
314 * The behavior of this method is undefined if {@code cpi} does not denote one of the following
315 * entry types: {@code JVM_CONSTANT_Dynamic}, {@code JVM_CONSTANT_String},
316 * {@code JVM_CONSTANT_MethodHandle}, {@code JVM_CONSTANT_MethodHandleInError},
317 * {@code JVM_CONSTANT_MethodType} and {@code JVM_CONSTANT_MethodTypeInError}.
318 *
319 * @param resolve specifies if a resolved entry is expected. If {@code false},
320 * {@code null} is returned for an unresolved entry.
321 */
322 JavaConstant lookupConstantInPool(HotSpotConstantPool constantPool, int cpi, boolean resolve) {
323 return lookupConstantInPool(constantPool, constantPool.getConstantPoolPointer(), cpi, resolve);
324 }
325
326 private native JavaConstant lookupConstantInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi, boolean resolve);
327
328 /**
329 * Gets the {@code JVM_CONSTANT_NameAndType} index referenced by the {@code rawIndex}.
330 * The meaning of {@code rawIndex} is dependent on the given {@opcode}.
331 *
332 * The behavior of this method is undefined if the class holding the {@code constantPool}
333 * has not yet been rewritten, or {@code rawIndex} is not a valid index for
334 * this class for the given {@code opcode}
335 */
336 int lookupNameAndTypeRefIndexInPool(HotSpotConstantPool constantPool, int rawIndex, int opcode) {
337 return lookupNameAndTypeRefIndexInPool(constantPool, constantPool.getConstantPoolPointer(), rawIndex, opcode);
338 }
339
340 private native int lookupNameAndTypeRefIndexInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int rawIndex, int opcode);
341
342 /**
343 * Gets the name of the {@code JVM_CONSTANT_NameAndType} entry in {@code constantPool}
344 * referenced by the {@code which}.
345 *
346 * The behavior of this method is undefined if the class holding the {@code constantPool}
347 * has not yet been rewritten, or {@code which} is not a valid index for
348 * this class for the given {@code opcode}
349 *
350 * @param which for INVOKE{VIRTUAL,SPECIAL,STATIC,INTERFACE}, must be {@code cpci}. For all other bytecodes,
351 * must be {@code rawIndex}
352 */
353 String lookupNameInPool(HotSpotConstantPool constantPool, int which, int opcode) {
354 return lookupNameInPool(constantPool, constantPool.getConstantPoolPointer(), which, opcode);
355 }
356
357 private native String lookupNameInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int which, int opcode);
358
359 /**
360 * Gets the signature of the {@code JVM_CONSTANT_NameAndType} entry in {@code constantPool}
361 * referenced by the {@code which}.
362 *
363 * The behavior of this method is undefined if the class holding the {@code constantPool}
364 * has not yet been rewritten, or {@code which} is not a valid index for
365 * this class for the given {@code opcode}
366 *
367 * @param which for INVOKE{VIRTUAL,SPECIAL,STATIC,INTERFACE}, must be {@code cpci}. For all other bytecodes,
368 * must be {@code rawIndex}
369 */
370 String lookupSignatureInPool(HotSpotConstantPool constantPool, int which, int opcode) {
371 return lookupSignatureInPool(constantPool, constantPool.getConstantPoolPointer(), which, opcode);
372 }
373
374 private native String lookupSignatureInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int which, int opcode);
375
376 /**
377 * Gets the {@code JVM_CONSTANT_Class} index from the entry in {@code constantPool}
378 * referenced by the {@code which}. The meaning of {@code which} is dependent
379 * on the given {@opcode}.
380 *
381 * The behavior of this method is undefined if the class holding the {@code constantPool}
382 * has not yet been rewritten, or {@code which} is not a valid index for
383 * this class for the given {@code opcode}
384 *
385 * @param which for INVOKE{VIRTUAL,SPECIAL,STATIC,INTERFACE}, must be {@code cpci}. For all other bytecodes,
386 * must be {@code rawIndex}
387 */
388 int lookupKlassRefIndexInPool(HotSpotConstantPool constantPool, int which, int opcode) {
389 return lookupKlassRefIndexInPool(constantPool, constantPool.getConstantPoolPointer(), which, opcode);
390 }
391
392 private native int lookupKlassRefIndexInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int which, int opcode);
393
394 /**
395 * Looks up a class denoted by the {@code JVM_CONSTANT_Class} entry at index {@code cpi} in
396 * {@code constantPool}. This method does not perform any resolution.
397 *
398 * The behavior of this method is undefined if {@code cpi} does not denote a
399 * {@code JVM_CONSTANT_Class} entry.
400 *
401 * @return the resolved class entry or a String otherwise
402 */
403 Object lookupKlassInPool(HotSpotConstantPool constantPool, int cpi) {
404 return lookupKlassInPool(constantPool, constantPool.getConstantPoolPointer(), cpi);
405 }
406
407 private native Object lookupKlassInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi);
408
409 /**
410 * Looks up a method denoted by the entry at index {@code cpi} in {@code constantPool}. This
411 * method does not perform any resolution.
412 *
413 * The behavior of this method is undefined if {@code cpi} does not denote an entry representing
414 * a method.
415 *
416 * @param opcode the opcode of the instruction for which the lookup is being performed or
417 * {@code -1}. If non-negative, then resolution checks specific to the bytecode it
418 * denotes are performed if the method is already resolved. Should any of these
419 * checks fail, 0 is returned.
420 * @param caller if non-null, do access checks in the context of {@code caller} calling the
421 * looked up method
422 * @return the resolved method entry, 0 otherwise
423 */
424 HotSpotResolvedJavaMethodImpl lookupMethodInPool(HotSpotConstantPool constantPool, int cpi, byte opcode, HotSpotResolvedJavaMethodImpl caller) {
425 long callerMethodPointer = caller == null ? 0L : caller.getMethodPointer();
426 return lookupMethodInPool(constantPool, constantPool.getConstantPoolPointer(), cpi, opcode, caller, callerMethodPointer);
427 }
428
429 private native HotSpotResolvedJavaMethodImpl lookupMethodInPool(HotSpotConstantPool constantPool,
430 long constantPoolPointer,
431 int cpi,
432 byte opcode,
433 HotSpotResolvedJavaMethodImpl caller,
434 long callerMethodPointer);
435
436 /**
437 * Converts the indy index operand of an invokedynamic instruction
438 * to an index directly into {@code constantPool}.
439 *
440 * @param resolve if {@true}, then resolve the entry (which may call a bootstrap method)
441 * @return {@code JVM_CONSTANT_InvokeDynamic} constant pool entry index for the invokedynamic
442 */
443 int decodeIndyIndexToCPIndex(HotSpotConstantPool constantPool, int encoded_indy_index, boolean resolve) {
444 return decodeIndyIndexToCPIndex(constantPool, constantPool.getConstantPoolPointer(), encoded_indy_index, resolve);
445 }
446
447 private native int decodeIndyIndexToCPIndex(HotSpotConstantPool constantPool, long constantPoolPointer, int encoded_indy_index, boolean resolve);
448
449 /**
450 * Converts the {@code rawIndex} operand of a rewritten getfield/putfield/getstatic/putstatic instruction
451 * to an index directly into {@code constantPool}.
452 *
453 * @throws IllegalArgumentException if {@code rawIndex} is out of range.
454 * @return {@code JVM_CONSTANT_FieldRef} constant pool entry index for the instruction
455 */
456 int decodeFieldIndexToCPIndex(HotSpotConstantPool constantPool, int rawIndex) {
457 return decodeFieldIndexToCPIndex(constantPool, constantPool.getConstantPoolPointer(), rawIndex);
458 }
459
460 private native int decodeFieldIndexToCPIndex(HotSpotConstantPool constantPool, long constantPoolPointer, int rawIndex);
461
462 /**
463 * Converts the {@code rawIndex} operand of a rewritten invokestatic/invokespecial/invokeinterface/invokevirtual instruction
464 * to an index directly into {@code constantPool}.
465 *
466 * @throws IllegalArgumentException if {@code rawIndex} is out of range.
467 * @return {@code JVM_CONSTANT_MethodRef} or {@code JVM_CONSTANT_InterfaceMethodRef} constant pool entry index for the instruction
468 */
469 int decodeMethodIndexToCPIndex(HotSpotConstantPool constantPool, int rawIndex) {
470 return decodeMethodIndexToCPIndex(constantPool, constantPool.getConstantPoolPointer(), rawIndex);
471 }
472
473 private native int decodeMethodIndexToCPIndex(HotSpotConstantPool constantPool, long constantPoolPointer, int rawIndex);
474
475 /**
476 * Returns the number of {@code ResolvedIndyEntry}s present within this constant
477 * pool.
478 */
479 int getNumIndyEntries(HotSpotConstantPool constantPool) {
480 return getNumIndyEntries(constantPool, constantPool.getConstantPoolPointer());
481 }
482
483 private native int getNumIndyEntries(HotSpotConstantPool constantPool, long constantPoolPointer);
484
485 /**
486 * Resolves the details for invoking the bootstrap method associated with the
487 * {@code CONSTANT_Dynamic_info} or @{code CONSTANT_InvokeDynamic_info} entry at {@code cpi} in
488 * {@code constant pool}.
489 *
490 * The return value encodes the details in an object array that is described by the pseudo Java
491 * object {@code info} below:
492 *
493 * <pre>
494 * bsm_invocation = [
495 * ResolvedJavaMethod[] method,
496 * String name,
497 * Object type, // JavaConstant: reference to Class (condy) or MethodType (indy)
498 * Object staticArguments, // null: no static arguments
499 * // JavaConstant: single static argument
500 * // JavaConstant[]: multiple static arguments
501 * // int[]: static arguments to be resolved via BootstrapCallInfo
502 * ]
503 * </pre>
504 *
505 * @return bootstrap method invocation details as encoded above
506 */
507 Object[] resolveBootstrapMethod(HotSpotConstantPool constantPool, int cpi) {
508 return resolveBootstrapMethod(constantPool, constantPool.getConstantPoolPointer(), cpi);
509 }
510
511 private native Object[] resolveBootstrapMethod(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi);
512
513 /**
514 * Gets the constant pool index of a static argument of a {@code CONSTANT_Dynamic_info} or
515 * @{code CONSTANT_InvokeDynamic_info} entry. Used when the list of static arguments in the
516 * {@link BootstrapMethodInvocation} is a {@code List<PrimitiveConstant>} of the form
517 * {{@code arg_count}, {@code pool_index}}, meaning the arguments are not already resolved and that
518 * the JDK has to lookup the arguments when they are needed. The {@code cpi} corresponds to
519 * {@code pool_index} and the {@code index} has to be smaller than {@code arg_count}.
520 *
521 * The behavior of this method is undefined if {@code cpi} does not denote an entry representing
522 * a {@code CONSTANT_Dynamic_info} or a @{code CONSTANT_InvokeDynamic_info}, or if the index
523 * is out of bounds.
524 *
525 * @param cpi the index of a {@code CONSTANT_Dynamic_info} or @{code CONSTANT_InvokeDynamic_info} entry
526 * @param index the index of the static argument in the list of static arguments
527 * @return the constant pool index associated with the static argument
528 */
529 int bootstrapArgumentIndexAt(HotSpotConstantPool constantPool, int cpi, int index) {
530 return bootstrapArgumentIndexAt(constantPool, constantPool.getConstantPoolPointer(), cpi, index);
531 }
532
533 private native int bootstrapArgumentIndexAt(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi, int index);
534
535 /**
536 * If {@code cpi} denotes an entry representing a signature polymorphic method ({@jvms 2.9}),
537 * this method ensures that the type referenced by the entry is loaded and initialized. It
538 * {@code cpi} does not denote a signature polymorphic method, this method does nothing.
539 */
540 void resolveInvokeHandleInPool(HotSpotConstantPool constantPool, int cpi) {
541 resolveInvokeHandleInPool(constantPool, constantPool.getConstantPoolPointer(), cpi);
542 }
543
544 private native void resolveInvokeHandleInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi);
545
546 /**
547 * If {@code cpi} denotes an entry representing a resolved dynamic adapter (see
548 * {@link #decodeIndyIndexToCPIndex} and {@link #resolveInvokeHandleInPool}), return the
549 * opcode of the instruction for which the resolution was performed ({@code invokedynamic} or
550 * {@code invokevirtual}), or {@code -1} otherwise.
551 */
552 int isResolvedInvokeHandleInPool(HotSpotConstantPool constantPool, int cpi, int opcode) {
553 return isResolvedInvokeHandleInPool(constantPool, constantPool.getConstantPoolPointer(), cpi, opcode);
554 }
555
556 private native int isResolvedInvokeHandleInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi, int opcode);
557
558 /**
559 * Gets the list of type names (in the format of {@link JavaType#getName()}) denoting the
560 * classes that define signature polymorphic methods.
561 */
562 native String[] getSignaturePolymorphicHolders();
563
564 /**
565 * Gets the resolved type denoted by the entry at index {@code cpi} in {@code constantPool}.
566 *
567 * The behavior of this method is undefined if {@code cpi} does not denote an entry representing
568 * a class.
569 *
570 * @throws LinkageError if resolution failed
571 */
572 HotSpotResolvedObjectTypeImpl resolveTypeInPool(HotSpotConstantPool constantPool, int cpi) throws LinkageError {
573 return resolveTypeInPool(constantPool, constantPool.getConstantPoolPointer(), cpi);
574 }
575
576 private native HotSpotResolvedObjectTypeImpl resolveTypeInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi) throws LinkageError;
577
578 /**
579 * Looks up and attempts to resolve the {@code JVM_CONSTANT_Field} entry denoted by
580 * {@code rawIndex}. For some opcodes, checks are performed that require the
581 * {@code method} that contains {@code opcode} to be specified. The values returned in
582 * {@code info} are:
583 *
584 * <pre>
585 * [ aflags, // fieldDescriptor::access_flags()
586 * offset, // fieldDescriptor::offset()
587 * index, // fieldDescriptor::index()
588 * fflags // fieldDescriptor::field_flags()
589 * ]
590 * </pre>
591 *
592 * The behavior of this method is undefined if {@code rawIndex} is invalid.
593 *
594 * @param info an array in which the details of the field are returned
595 * @return the type defining the field if resolution is successful, null if the type cannot be resolved
596 * @throws LinkageError if there were other problems resolving the field
597 */
598 HotSpotResolvedObjectTypeImpl resolveFieldInPool(HotSpotConstantPool constantPool, int rawIndex, HotSpotResolvedJavaMethodImpl method, byte opcode, int[] info) {
599 long methodPointer = method != null ? method.getMethodPointer() : 0L;
600 return resolveFieldInPool(constantPool, constantPool.getConstantPoolPointer(), rawIndex, method, methodPointer, opcode, info);
601 }
602
603 private native HotSpotResolvedObjectTypeImpl resolveFieldInPool(HotSpotConstantPool constantPool, long constantPoolPointer,
604 int rawIndex, HotSpotResolvedJavaMethodImpl method, long methodPointer, byte opcode, int[] info);
605
606 /**
607 * Gets the appendix object (if any) associated with the entry identified by {@code which}.
608 *
609 * @param which if negative, is treated as an encoded indy index for INVOKEDYNAMIC;
610 * Otherwise, it's treated as a constant pool cache index
611 * for INVOKE{VIRTUAL,SPECIAL,STATIC,INTERFACE}.
612 */
613 HotSpotObjectConstantImpl lookupAppendixInPool(HotSpotConstantPool constantPool, int which, int opcode) {
614 return lookupAppendixInPool(constantPool, constantPool.getConstantPoolPointer(), which, opcode);
615 }
616
617 private native HotSpotObjectConstantImpl lookupAppendixInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int which, int opcode);
618
619 /**
620 * Installs the result of a compilation into the code cache.
621 *
622 * @param compiledCode the result of a compilation
623 * @param code the details of the installed CodeBlob are written to this object
624 *
625 * @return the outcome of the installation which will be one of
626 * {@link HotSpotVMConfig#codeInstallResultOk},
627 * {@link HotSpotVMConfig#codeInstallResultCacheFull},
628 * {@link HotSpotVMConfig#codeInstallResultCodeTooLarge} or
629 * {@link HotSpotVMConfig#codeInstallResultDependenciesFailed}.
630 * @throws JVMCIError if there is something wrong with the compiled code or the associated
631 * metadata.
632 */
633 int installCode(HotSpotCompiledCode compiledCode, InstalledCode code, long failedSpeculationsAddress, byte[] speculations) {
634 int codeInstallFlags = getInstallCodeFlags();
635 boolean withComments = (codeInstallFlags & 0x0001) != 0;
636 boolean withMethods = (codeInstallFlags & 0x0002) != 0;
637 boolean withTypeInfo;
638 if ((codeInstallFlags & 0x0004) != 0 && HotSpotJVMCIRuntime.Option.CodeSerializationTypeInfo.isDefault) {
639 withTypeInfo = true;
640 } else {
641 withTypeInfo = HotSpotJVMCIRuntime.Option.CodeSerializationTypeInfo.getBoolean();
642 }
643 try (HotSpotCompiledCodeStream stream = new HotSpotCompiledCodeStream(compiledCode, withTypeInfo, withComments, withMethods)) {
644 return installCode0(stream.headChunk, stream.timeNS, withTypeInfo, compiledCode, stream.objectPool, code, failedSpeculationsAddress, speculations);
645 }
646 }
647
648 native int installCode0(long compiledCodeBuffer,
649 long serializationNS,
650 boolean withTypeInfo,
651 HotSpotCompiledCode compiledCode,
652 Object[] objectPool,
653 InstalledCode code,
654 long failedSpeculationsAddress,
655 byte[] speculations);
656
657 /**
658 * Gets flags specifying optional parts of code info. Only if a flag is set, will the
659 * corresponding code info being included in the {@linkplain HotSpotCompiledCodeStream
660 * serialized code stream}.
661 *
662 * <ul>
663 * <li>0x0001: code comments ({@link HotSpotCompiledCode#comments})</li>
664 * <li>0x0002: methods ({@link HotSpotCompiledCode#methods})</li>
665 * <li>0x0004: enable {@link Option#CodeSerializationTypeInfo} if it not explicitly specified
666 * (i.e., {@link Option#isDefault} is {@code true})</li>
667 * </ul>
668 */
669 private native int getInstallCodeFlags();
670
671 /**
672 * Resets all compilation statistics.
673 */
674 native void resetCompilationStatistics();
675
676 /**
677 * Reads the database of VM info. The return value encodes the info in a nested object array
678 * that is described by the pseudo Java object {@code info} below:
679 *
680 * <pre>
681 * info = [
682 * VMField[] vmFields,
683 * [String name, Long size, ...] vmTypeSizes,
684 * [String name, Long value, ...] vmConstants,
685 * [String name, Long value, ...] vmAddresses,
686 * VMFlag[] vmFlags
687 * VMIntrinsicMethod[] vmIntrinsics
688 * ]
689 * </pre>
690 *
691 * @return VM info as encoded above
692 */
693 native Object[] readConfiguration();
694
695 /**
696 * Resolves the implementation of {@code method} for virtual dispatches on objects of dynamic
697 * type {@code exactReceiver}. This resolution process only searches "up" the class hierarchy of
698 * {@code exactReceiver}.
699 *
700 * @param exactReceiver the exact receiver type
701 * @param caller the caller or context type used to perform access checks
702 * @return the link-time resolved method (might be abstract) or {@code null} if it is either a
703 * signature polymorphic method or can not be linked.
704 */
705 HotSpotResolvedJavaMethodImpl resolveMethod(HotSpotResolvedObjectTypeImpl exactReceiver, HotSpotResolvedJavaMethodImpl method, HotSpotResolvedObjectTypeImpl caller) {
706 return resolveMethod(exactReceiver, exactReceiver.getKlassPointer(), method, method.getMethodPointer(), caller, caller.getKlassPointer());
707 }
708
709 private native HotSpotResolvedJavaMethodImpl resolveMethod(HotSpotResolvedObjectTypeImpl exactReceiver, long exactReceiverKlass,
710 HotSpotResolvedJavaMethodImpl method, long methodPointer,
711 HotSpotResolvedObjectTypeImpl caller, long callerKlass);
712
713 /**
714 * Gets the static initializer of {@code type}.
715 *
716 * @return {@code null} if {@code type} has no static initializer
717 */
718 HotSpotResolvedJavaMethodImpl getClassInitializer(HotSpotResolvedObjectTypeImpl type) {
719 return getClassInitializer(type, type.getKlassPointer());
720 }
721
722 private native HotSpotResolvedJavaMethodImpl getClassInitializer(HotSpotResolvedObjectTypeImpl type, long klassPointer);
723
724 /**
725 * Determines if {@code type} or any of its currently loaded subclasses overrides
726 * {@code Object.finalize()}.
727 */
728 boolean hasFinalizableSubclass(HotSpotResolvedObjectTypeImpl type) {
729 return hasFinalizableSubclass(type, type.getKlassPointer());
730 }
731
732 private native boolean hasFinalizableSubclass(HotSpotResolvedObjectTypeImpl type, long klassPointer);
733
734 /**
735 * Gets the method corresponding to {@code executable}.
736 */
737 native HotSpotResolvedJavaMethodImpl asResolvedJavaMethod(Executable executable);
738
739 /**
740 * Gets the maximum absolute offset of a PC relative call to {@code address} from any position
741 * in the code cache.
742 *
743 * @param address an address that may be called from any code in the code cache
744 * @return -1 if {@code address == 0}
745 */
746 native long getMaxCallTargetOffset(long address);
747
748 /**
749 * Gets a textual disassembly of {@code codeBlob}.
750 *
751 * @return a non-zero length string containing a disassembly of {@code codeBlob} or null if
752 * {@code codeBlob} could not be disassembled for some reason
753 */
754 // The HotSpot disassembler seems not to be thread safe so it's better to synchronize its usage
755 synchronized native String disassembleCodeBlob(InstalledCode installedCode);
756
757 /**
758 * Gets a stack trace element for {@code method} at bytecode index {@code bci}.
759 */
760 StackTraceElement getStackTraceElement(HotSpotResolvedJavaMethodImpl method, int bci) {
761 return getStackTraceElement(method, method.getMethodPointer(), bci);
762 }
763
764 private native StackTraceElement getStackTraceElement(HotSpotResolvedJavaMethodImpl method, long methodPointer, int bci);
765
766 /**
767 * Executes some {@code installedCode} with arguments {@code args}.
768 *
769 * @return the result of executing {@code nmethodMirror}
770 * @throws InvalidInstalledCodeException if {@code nmethodMirror} has been invalidated
771 */
772 native Object executeHotSpotNmethod(Object[] args, HotSpotNmethod nmethodMirror) throws InvalidInstalledCodeException;
773
774 /**
775 * Gets the line number table for {@code method}. The line number table is encoded as (bci,
776 * source line number) pairs.
777 *
778 * @return the line number table for {@code method} or null if it doesn't have one
779 */
780 long[] getLineNumberTable(HotSpotResolvedJavaMethodImpl method) {
781 return getLineNumberTable(method, method.getMethodPointer());
782 }
783
784 private native long[] getLineNumberTable(HotSpotResolvedJavaMethodImpl method, long methodPointer);
785
786 /**
787 * Gets the number of entries in the local variable table for {@code method}.
788 *
789 * @return the number of entries in the local variable table for {@code method}
790 */
791 int getLocalVariableTableLength(HotSpotResolvedJavaMethodImpl method) {
792 return getLocalVariableTableLength(method, method.getMethodPointer());
793 }
794
795 private native int getLocalVariableTableLength(HotSpotResolvedJavaMethodImpl method, long methodPointer);
796
797 /**
798 * Gets the address of the first entry in the local variable table for {@code method}.
799 *
800 * Each entry is a native object described by these fields:
801 *
802 * <ul>
803 * <li>{@link HotSpotVMConfig#localVariableTableElementSize}</li>
804 * <li>{@link HotSpotVMConfig#localVariableTableElementLengthOffset}</li>
805 * <li>{@link HotSpotVMConfig#localVariableTableElementNameCpIndexOffset}</li>
806 * <li>{@link HotSpotVMConfig#localVariableTableElementDescriptorCpIndexOffset}</li>
807 * <li>{@link HotSpotVMConfig#localVariableTableElementSlotOffset}
808 * <li>{@link HotSpotVMConfig#localVariableTableElementStartBciOffset}
809 * </ul>
810 *
811 * @return 0 if {@code method} does not have a local variable table
812 */
813 long getLocalVariableTableStart(HotSpotResolvedJavaMethodImpl method) {
814 return getLocalVariableTableStart(method, method.getMetaspacePointer());
815 }
816
817 private native long getLocalVariableTableStart(HotSpotResolvedJavaMethodImpl method, long methodPointer);
818
819 /**
820 * Sets flags on {@code method} indicating that it should never be inlined or compiled by the
821 * VM.
822 */
823 void setNotInlinableOrCompilable(HotSpotResolvedJavaMethodImpl method) {
824 setNotInlinableOrCompilable(method, method.getMethodPointer());
825 }
826
827 private native void setNotInlinableOrCompilable(HotSpotResolvedJavaMethodImpl method, long methodPointer);
828
829 /**
830 * Invalidates the profiling information for {@code method} and (re)initializes it such that
831 * profiling restarts upon its next invocation.
832 */
833 void reprofile(HotSpotResolvedJavaMethodImpl method) {
834 reprofile(method, method.getMethodPointer());
835 }
836
837 private native void reprofile(HotSpotResolvedJavaMethodImpl method, long methodPointer);
838
839 /**
840 * Updates {@code nmethodMirror} such that {@link InvalidInstalledCodeException} will be raised
841 * the next time {@code nmethodMirror} is {@linkplain #executeHotSpotNmethod executed}. The
842 * {@code nmethod} associated with {@code nmethodMirror} is also made non-entrant and if
843 * {@code deoptimize == true} any current activations of the {@code nmethod} are deoptimized.
844 */
845 native void invalidateHotSpotNmethod(HotSpotNmethod nmethodMirror, boolean deoptimize);
846
847 /**
848 * Collects the current values of all JVMCI benchmark counters, summed up over all threads.
849 */
850 native long[] collectCounters();
851
852 /**
853 * Get the current number of counters allocated for use by JVMCI. Should be the same value as
854 * the flag {@code JVMCICounterSize}.
855 */
856 native int getCountersSize();
857
858 /**
859 * Attempt to change the size of the counters allocated for JVMCI. This requires a safepoint to
860 * safely reallocate the storage but it's advisable to increase the size in reasonable chunks.
861 */
862 native boolean setCountersSize(int newSize);
863
864 /**
865 * Determines if {@code methodData} is mature.
866 *
867 * @param methodData a {@code MethodData*} value
868 */
869 native boolean isMature(long methodData);
870
871 /**
872 * Generate a unique id to identify the result of the compile.
873 */
874 int allocateCompileId(HotSpotResolvedJavaMethodImpl method, int entryBCI) {
875 return allocateCompileId(method, method.getMethodPointer(), entryBCI);
876 }
877
878 private native int allocateCompileId(HotSpotResolvedJavaMethodImpl method, long methodPointer, int entryBCI);
879
880 /**
881 * Determines if {@code method} has OSR compiled code identified by {@code entryBCI} for
882 * compilation level {@code level}.
883 */
884 boolean hasCompiledCodeForOSR(HotSpotResolvedJavaMethodImpl method, int entryBCI, int level) {
885 return hasCompiledCodeForOSR(method, method.getMethodPointer(), entryBCI, level);
886 }
887
888 private native boolean hasCompiledCodeForOSR(HotSpotResolvedJavaMethodImpl method, long methodPoiner, int entryBCI, int level);
889
890 /**
891 * Gets the value of {@code symbol} as a String.
892 *
893 * @param symbol a {@code Symbol*} value
894 */
895 native String getSymbol(long symbol);
896
897 /**
898 * Gets the name for a {@code klass} as it would appear in a signature.
899 *
900 * @param klass a {@code Klass*} value
901 */
902 native String getSignatureName(long klass);
903
904 /**
905 * @see jdk.vm.ci.code.stack.StackIntrospection#iterateFrames
906 */
907 native <T> T iterateFrames(ResolvedJavaMethod[] initialMethods, ResolvedJavaMethod[] matchingMethods, int initialSkip, InspectedFrameVisitor<T> visitor);
908
909 /**
910 * Materializes all virtual objects within {@code stackFrame} and updates its locals.
911 *
912 * @param invalidate if {@code true}, the compiled method for the stack frame will be
913 * invalidated
914 */
915 native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate);
916
917 /**
918 * Gets the v-table index for interface method {@code method} in the receiver {@code type} or
919 * {@link HotSpotVMConfig#invalidVtableIndex} if {@code method} is not in {@code type}'s
920 * v-table.
921 *
922 * @throws InternalError if {@code type} is an interface, {@code method} is not defined by an
923 * interface, {@code type} does not implement the interface defining {@code method}
924 * or class represented by {@code type} is not initialized
925 */
926 int getVtableIndexForInterfaceMethod(HotSpotResolvedObjectTypeImpl type, HotSpotResolvedJavaMethodImpl method) {
927 return getVtableIndexForInterfaceMethod(type, type.getKlassPointer(), method, method.getMethodPointer());
928 }
929
930 private native int getVtableIndexForInterfaceMethod(HotSpotResolvedObjectTypeImpl type, long klassPointer, HotSpotResolvedJavaMethodImpl method, long methodPointer);
931
932 /**
933 * Determines if debug info should also be emitted at non-safepoint locations.
934 */
935 native boolean shouldDebugNonSafepoints();
936
937 /**
938 * Writes {@code length} bytes from {@code buffer} to HotSpot's log stream.
939 *
940 * @param buffer if {@code length <= 8}, then the bytes are encoded in this value in native
941 * endianness order otherwise this is the address of a native memory buffer holding
942 * the bytes
943 * @param flush specifies if the log stream should be flushed after writing
944 */
945 native void writeDebugOutput(long buffer, int length, boolean flush);
946
947 /**
948 * Flush HotSpot's log stream.
949 */
950 native void flushDebugOutput();
951
952 /**
953 * Read a HotSpot {@code Method*} value from the memory location described by {@code base} plus
954 * {@code displacement} and return the {@link HotSpotResolvedJavaMethodImpl} wrapping it. This
955 * method does no checking that the memory location actually contains a valid pointer and may
956 * crash the VM if an invalid location is provided. If {@code base == null} is null then
957 * {@code displacement} is used by itself. If {@code base} is a
958 * {@link HotSpotResolvedJavaMethodImpl}, {@link HotSpotConstantPool} or
959 * {@link HotSpotResolvedObjectTypeImpl} then the metaspace pointer is fetched from that object
960 * and added to {@code displacement}. Any other non-null object type causes an
961 * {@link IllegalArgumentException} to be thrown.
962 *
963 * @param base an object to read from or null
964 * @param displacement
965 * @return null or the resolved method for this location
966 */
967 native HotSpotResolvedJavaMethodImpl getResolvedJavaMethod(HotSpotObjectConstantImpl base, long displacement);
968
969 /**
970 * Gets the {@code ConstantPool*} associated with {@code object} and returns a
971 * {@link HotSpotConstantPool} wrapping it.
972 *
973 * @param object a {@link HotSpotResolvedJavaMethodImpl} or
974 * {@link HotSpotResolvedObjectTypeImpl} object
975 * @return a {@link HotSpotConstantPool} wrapping the {@code ConstantPool*} associated with
976 * {@code object}
977 * @throws NullPointerException if {@code object == null}
978 * @throws IllegalArgumentException if {@code object} is neither a
979 * {@link HotSpotResolvedJavaMethodImpl} nor a {@link HotSpotResolvedObjectTypeImpl}
980 */
981 HotSpotConstantPool getConstantPool(MetaspaceObject object) {
982 return getConstantPool(object, object.getMetaspacePointer(), object instanceof HotSpotResolvedJavaType);
983 }
984
985 native HotSpotConstantPool getConstantPool(Object object, long klassOrMethod, boolean isKlass);
986
987 /**
988 * Read a {@code Klass*} value from the memory location described by {@code base} plus
989 * {@code displacement} and return the {@link HotSpotResolvedObjectTypeImpl} wrapping it. This method
990 * only performs the read if the memory location is known to contain a valid Klass*. If
991 * {@code base} is a {@link HotSpotConstantPool}, {@link HotSpotMethodData}, {@link HotSpotObjectConstantImpl},
992 * or {@link HotSpotResolvedObjectTypeImpl} then the field
993 * corresopnding to {@code displacement} is fetched using the appropriate HotSpot accessor. Any
994 * other object type or an unexpected displacement causes an {@link IllegalArgumentException} to
995 * be thrown. The set of fields which can be read in this fashion corresponds to the {@link VMField}
996 * with type {@code Klass*} that are described in the {@link HotSpotVMConfigStore#getFields()}.
997 * Additionally several injected fields in {@link Class} are also handled.
998 *
999 * @param base an object to read from
1000 * @param displacement
1001 * @param compressed true if the location contains a compressed Klass*
1002 * @return null or the resolved method for this location
1003 * @throws NullPointerException if {@code base == null}
1004 */
1005 private native HotSpotResolvedObjectTypeImpl getResolvedJavaType0(Object base, long displacement, boolean compressed);
1006
1007 HotSpotResolvedObjectTypeImpl getResolvedJavaType(HotSpotConstantPool base, long displacement) {
1008 return getResolvedJavaType0(base, displacement, false);
1009 }
1010
1011 HotSpotResolvedObjectTypeImpl getResolvedJavaType(HotSpotMethodData base, long displacement) {
1012 return getResolvedJavaType0(base, displacement, false);
1013 }
1014
1015 HotSpotResolvedObjectTypeImpl getResolvedJavaType(HotSpotResolvedObjectTypeImpl base, long displacement, boolean compressed) {
1016 return getResolvedJavaType0(base, displacement, compressed);
1017 }
1018
1019 HotSpotResolvedObjectTypeImpl getResolvedJavaType(HotSpotObjectConstantImpl base, long displacement, boolean compressed) {
1020 return getResolvedJavaType0(base, displacement, compressed);
1021 }
1022
1023 /**
1024 * Reads a {@code Klass*} from {@code address} (i.e., {@code address} is a {@code Klass**}
1025 * value) and wraps it in a {@link HotSpotResolvedObjectTypeImpl}. This VM call must be used for
1026 * any {@code Klass*} value not known to be already wrapped in a
1027 * {@link HotSpotResolvedObjectTypeImpl}. The VM call is necessary so that the {@code Klass*} is
1028 * wrapped in a {@code JVMCIKlassHandle} to protect it from the concurrent scanning done by G1.
1029 */
1030 HotSpotResolvedObjectTypeImpl getResolvedJavaType(long address) {
1031 return getResolvedJavaType0(null, address, false);
1032 }
1033
1034 /**
1035 * Return the size of the HotSpot ProfileData* pointed at by {@code position}. If
1036 * {@code position} is outside the space of the MethodData then an
1037 * {@link IllegalArgumentException} is thrown. A {@code position} inside the MethodData but that
1038 * isn't pointing at a valid ProfileData will crash the VM.
1039 *
1040 * @param metaspaceMethodData
1041 * @param position
1042 * @return the size of the ProfileData item pointed at by {@code position}
1043 * @throws IllegalArgumentException if an out of range position is given
1044 */
1045 native int methodDataProfileDataSize(long metaspaceMethodData, int position);
1046
1047
1048 native int methodDataExceptionSeen(long metaspaceMethodData, int bci);
1049
1050 /**
1051 * Return the amount of native stack required for the interpreter frames represented by
1052 * {@code frame}. This is used when emitting the stack banging code to ensure that there is
1053 * enough space for the frames during deoptimization.
1054 *
1055 * @param frame
1056 * @return the number of bytes required for deoptimization of this frame state
1057 */
1058 native int interpreterFrameSize(BytecodeFrame frame);
1059
1060 /**
1061 * Invokes non-public method {@code java.lang.invoke.LambdaForm.compileToBytecode()} on
1062 * {@code lambdaForm} (which must be a {@code java.lang.invoke.LambdaForm} instance).
1063 */
1064 native void compileToBytecode(HotSpotObjectConstantImpl lambdaForm);
1065
1066 /**
1067 * Gets the value of the VM flag named {@code name}.
1068 *
1069 * @param name name of a VM option
1070 * @return {@code this} if the named VM option doesn't exist, a {@link String} or {@code null}
1071 * if its type is {@code ccstr} or {@code ccstrlist}, a {@link Double} if its type is
1072 * {@code double}, a {@link Boolean} if its type is {@code bool} otherwise a
1073 * {@link Long}
1074 */
1075 native Object getFlagValue(String name);
1076
1077 /**
1078 * @see ResolvedJavaType#getInterfaces()
1079 */
1080 HotSpotResolvedObjectTypeImpl[] getInterfaces(HotSpotResolvedObjectTypeImpl klass) {
1081 return getInterfaces(klass, klass.getKlassPointer());
1082 }
1083
1084 native HotSpotResolvedObjectTypeImpl[] getInterfaces(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1085
1086 /**
1087 * @see ResolvedJavaType#getComponentType()
1088 */
1089 HotSpotResolvedJavaType getComponentType(HotSpotResolvedObjectTypeImpl klass) {
1090 return getComponentType(klass, klass.getKlassPointer());
1091 }
1092
1093 native HotSpotResolvedJavaType getComponentType(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1094
1095 /**
1096 * Get the array class for the primitive type represented by the {@link JavaKind#getTypeChar()}
1097 * value in {@code typeChar} or the non-primitive type represented by {@code nonPrimitiveKlass}.
1098 * This can't be done symbolically since hidden classes can't be looked up by name.
1099 *
1100 * Exactly one of {@code primitiveTypeChar} or {@code nonPrimitiveKlass} must be non-zero.
1101 *
1102 * @param primitiveTypeChar a {@link JavaKind#getTypeChar()} value for a primitive type
1103 * @param nonPrimitiveKlass a non-primitive type
1104 */
1105 HotSpotResolvedObjectTypeImpl getArrayType(char primitiveTypeChar, HotSpotResolvedObjectTypeImpl nonPrimitiveKlass) {
1106 long nonPrimitiveKlassPointer = nonPrimitiveKlass != null ? nonPrimitiveKlass.getKlassPointer() : 0L;
1107 return getArrayType(primitiveTypeChar, nonPrimitiveKlass, nonPrimitiveKlassPointer);
1108 }
1109
1110 native HotSpotResolvedObjectTypeImpl getArrayType(char typeChar, HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1111
1112 /**
1113 * Forces initialization of {@code klass}.
1114 */
1115 void ensureInitialized(HotSpotResolvedObjectTypeImpl klass) {
1116 ensureInitialized(klass, klass.getKlassPointer());
1117 }
1118
1119 native void ensureInitialized(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1120
1121 /**
1122 * Forces linking of {@code klass}.
1123 */
1124 void ensureLinked(HotSpotResolvedObjectTypeImpl klass) {
1125 ensureLinked(klass, klass.getKlassPointer());
1126 }
1127
1128 native void ensureLinked(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1129
1130 /**
1131 * Checks if {@code object} is a String and is an interned string value.
1132 */
1133 native boolean isInternedString(HotSpotObjectConstantImpl object);
1134
1135 /**
1136 * Gets the {@linkplain System#identityHashCode(Object) identity} has code for the object
1137 * represented by this constant.
1138 */
1139 native int getIdentityHashCode(HotSpotObjectConstantImpl object);
1140
1141 /**
1142 * Converts a constant object representing a boxed primitive into a boxed primitive.
1143 */
1144 native Object unboxPrimitive(HotSpotObjectConstantImpl object);
1145
1146 /**
1147 * Converts a boxed primitive into a JavaConstant representing the same value.
1148 */
1149 native HotSpotObjectConstantImpl boxPrimitive(Object source);
1150
1151 /**
1152 * Gets the {@link ResolvedJavaMethod}s for all the constructors of {@code klass}.
1153 */
1154 ResolvedJavaMethod[] getDeclaredConstructors(HotSpotResolvedObjectTypeImpl klass) {
1155 return getDeclaredConstructors(klass, klass.getKlassPointer());
1156 }
1157
1158 native ResolvedJavaMethod[] getDeclaredConstructors(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1159
1160 /**
1161 * Gets the {@link ResolvedJavaMethod}s for all non-overpass and non-initializer
1162 * methods of {@code klass}.
1163 */
1164 ResolvedJavaMethod[] getDeclaredMethods(HotSpotResolvedObjectTypeImpl klass) {
1165 return getDeclaredMethods(klass, klass.getKlassPointer());
1166 }
1167
1168 native ResolvedJavaMethod[] getDeclaredMethods(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1169
1170 /**
1171 * Gets the {@link ResolvedJavaMethod}s for all methods of {@code klass}.
1172 */
1173 ResolvedJavaMethod[] getAllMethods(HotSpotResolvedObjectTypeImpl klass) {
1174 return getAllMethods(klass, klass.getKlassPointer());
1175 }
1176
1177 native ResolvedJavaMethod[] getAllMethods(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1178
1179 HotSpotResolvedObjectTypeImpl.FieldInfo[] getDeclaredFieldsInfo(HotSpotResolvedObjectTypeImpl klass) {
1180 return getDeclaredFieldsInfo(klass, klass.getKlassPointer());
1181 }
1182
1183 native HotSpotResolvedObjectTypeImpl.FieldInfo[] getDeclaredFieldsInfo(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1184
1185 /**
1186 * Reads the current value of a static field of {@code declaringKlass}. Extra sanity checking is
1187 * performed on the offset and kind of the read being performed.
1188 *
1189 * @param declaringKlass the type in which the static field is declared
1190 * @param offset the offset of the field in the {@link Class} mirror of {@code declaringKlass}
1191 * @throws IllegalArgumentException if any of the sanity checks fail
1192 */
1193 JavaConstant readStaticFieldValue(HotSpotResolvedObjectTypeImpl declaringKlass, long offset, char typeChar) {
1194 return readStaticFieldValue(declaringKlass, declaringKlass.getKlassPointer(), offset, typeChar);
1195 }
1196
1197 native JavaConstant readStaticFieldValue(HotSpotResolvedObjectTypeImpl declaringKlass, long declaringKlassPointer, long offset, char typeChar);
1198
1199 /**
1200 * Reads the current value of an instance field. If {@code expectedType} is non-null, then
1201 * {@code object} is expected to be a subtype of {@code expectedType}. Extra sanity checking is
1202 * performed on the offset and kind of the read being performed.
1203 *
1204 * @param object the object from which the field is to be read. If {@code object} is of type
1205 * {@link Class} and {@code offset} is >= the offset of the static field storage in a
1206 * {@link Class} instance, then this operation is a static field read.
1207 * @param expectedType the expected type of {@code object}
1208 * @throws IllegalArgumentException if any of the sanity checks fail
1209 */
1210 JavaConstant readFieldValue(HotSpotObjectConstantImpl object, HotSpotResolvedObjectTypeImpl expectedType, long offset, char typeChar) {
1211 long expectedTypePointer = expectedType != null ? expectedType.getKlassPointer() : 0L;
1212 return readFieldValue(object, expectedType, expectedTypePointer, offset, typeChar);
1213 }
1214
1215 native JavaConstant readFieldValue(HotSpotObjectConstantImpl object, HotSpotResolvedObjectTypeImpl expectedType, long expectedTypePointer, long offset, char typeChar);
1216
1217 /**
1218 * @see ResolvedJavaType#isInstance(JavaConstant)
1219 */
1220 boolean isInstance(HotSpotResolvedObjectTypeImpl klass, HotSpotObjectConstantImpl object) {
1221 return isInstance(klass, klass.getKlassPointer(), object);
1222 }
1223
1224 native boolean isInstance(HotSpotResolvedObjectTypeImpl klass, long klassPointer, HotSpotObjectConstantImpl object);
1225
1226 /**
1227 * @see ResolvedJavaType#isAssignableFrom(ResolvedJavaType)
1228 */
1229 boolean isAssignableFrom(HotSpotResolvedObjectTypeImpl klass, HotSpotResolvedObjectTypeImpl subklass) {
1230 return isAssignableFrom(klass, klass.getKlassPointer(), subklass, subklass.getKlassPointer());
1231 }
1232
1233 native boolean isAssignableFrom(HotSpotResolvedObjectTypeImpl klass, long klassPointer, HotSpotResolvedObjectTypeImpl subklass, long subklassPointer);
1234
1235 /**
1236 * @see ConstantReflectionProvider#asJavaType(Constant)
1237 */
1238 native HotSpotResolvedJavaType asJavaType(HotSpotObjectConstantImpl object);
1239
1240 /**
1241 * Converts a String constant into a String.
1242 */
1243 native String asString(HotSpotObjectConstantImpl object);
1244
1245 /**
1246 * Compares the contents of {@code xHandle} and {@code yHandle} for pointer equality.
1247 */
1248 native boolean equals(HotSpotObjectConstantImpl x, long xHandle, HotSpotObjectConstantImpl y, long yHandle);
1249
1250 /**
1251 * Gets a {@link JavaConstant} wrapping the {@link java.lang.Class} mirror for {@code klass}.
1252 */
1253 HotSpotObjectConstantImpl getJavaMirror(HotSpotResolvedObjectTypeImpl klass) {
1254 return getJavaMirror(klass, klass.getKlassPointer());
1255 }
1256
1257 native HotSpotObjectConstantImpl getJavaMirror(HotSpotResolvedObjectTypeImpl type, long klassPointer);
1258
1259 /**
1260 * Returns the length of the array if {@code object} represents an array or -1 otherwise.
1261 */
1262 native int getArrayLength(HotSpotObjectConstantImpl object);
1263
1264 /**
1265 * Reads the element at {@code index} if {@code object} is an array. Elements of an object array
1266 * are returned as {@link JavaConstant}s and primitives are returned as boxed values. The value
1267 * {@code null} is returned if the {@code index} is out of range or object is not an array.
1268 */
1269 native Object readArrayElement(HotSpotObjectConstantImpl object, int index);
1270
1271 /**
1272 * @see HotSpotJVMCIRuntime#registerNativeMethods
1273 */
1274 native long[] registerNativeMethods(Class<?> clazz);
1275
1276 /**
1277 * @see HotSpotJVMCIRuntime#translate(Object)
1278 */
1279 native long translate(Object obj, boolean callPostTranslation);
1280
1281 /**
1282 * @see HotSpotJVMCIRuntime#unhand(Class, long)
1283 */
1284 native Object unhand(long handle);
1285
1286 /**
1287 * Updates {@code address} and {@code entryPoint} fields of {@code nmethodMirror} based on the
1288 * current state of the {@code nmethod} identified by {@code address} and
1289 * {@code nmethodMirror.compileId} in the code cache.
1290 */
1291 native void updateHotSpotNmethod(HotSpotNmethod nmethodMirror);
1292
1293 /**
1294 * @see InstalledCode#getCode()
1295 */
1296 native byte[] getCode(HotSpotInstalledCode code);
1297
1298 /**
1299 * Gets a {@link Executable} corresponding to {@code method}.
1300 */
1301 Executable asReflectionExecutable(HotSpotResolvedJavaMethodImpl method) {
1302 return asReflectionExecutable(method, method.getMethodPointer());
1303 }
1304
1305 native Executable asReflectionExecutable(HotSpotResolvedJavaMethodImpl method, long methodPointer);
1306
1307 /**
1308 * Gets a {@link Field} denoted by {@code holder} and {@code index}.
1309 *
1310 * @param holder the class in which the requested field is declared
1311 * @param fieldIndex the {@code fieldDescriptor::index()} denoting the field
1312 */
1313 Field asReflectionField(HotSpotResolvedObjectTypeImpl holder, int fieldIndex) {
1314 return asReflectionField(holder, holder.getKlassPointer(), fieldIndex);
1315 }
1316
1317 native Field asReflectionField(HotSpotResolvedObjectTypeImpl holder, long holderPointer, int fieldIndex);
1318
1319 /**
1320 * @see HotSpotJVMCIRuntime#getIntrinsificationTrustPredicate(Class...)
1321 */
1322 boolean isTrustedForIntrinsics(HotSpotResolvedObjectTypeImpl klass) {
1323 return isTrustedForIntrinsics(klass, klass.getKlassPointer());
1324 }
1325
1326 native boolean isTrustedForIntrinsics(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1327
1328 /**
1329 * Clears the oop handle in {@code handle}.
1330 */
1331 native void clearOopHandle(long handle);
1332
1333 /**
1334 * Releases all oop handles whose referent is null.
1335 */
1336 native void releaseClearedOopHandles();
1337
1338 /**
1339 * Gets the failed speculations pointed to by {@code *failedSpeculationsAddress}.
1340 *
1341 * @param currentFailures the known failures at {@code failedSpeculationsAddress}
1342 * @return the list of failed speculations with each entry being a single speculation in the
1343 * format emitted by {@link HotSpotSpeculationEncoding#toByteArray()}
1344 */
1345 native byte[][] getFailedSpeculations(long failedSpeculationsAddress, byte[][] currentFailures);
1346
1347 /**
1348 * Gets the address of the {@code MethodData::_failed_speculations} field in the
1349 * {@code MethodData} associated with {@code method}. This will create and install the
1350 * {@code MethodData} if it didn't already exist.
1351 */
1352 long getFailedSpeculationsAddress(HotSpotResolvedJavaMethodImpl method) {
1353 return getFailedSpeculationsAddress(method, method.getMethodPointer());
1354 }
1355
1356 native long getFailedSpeculationsAddress(HotSpotResolvedJavaMethodImpl method, long methodPointer);
1357
1358 /**
1359 * Frees the failed speculations pointed to by {@code *failedSpeculationsAddress}.
1360 */
1361 native void releaseFailedSpeculations(long failedSpeculationsAddress);
1362
1363 /**
1364 * Adds a speculation to the failed speculations pointed to by
1365 * {@code *failedSpeculationsAddress}.
1366 *
1367 * @return {@code false} if the speculation could not be appended to the list
1368 */
1369 native boolean addFailedSpeculation(long failedSpeculationsAddress, byte[] speculation);
1370
1371 /**
1372 * @see HotSpotJVMCIRuntime#isCurrentThreadAttached()
1373 */
1374 native boolean isCurrentThreadAttached();
1375
1376 /**
1377 * @see HotSpotJVMCIRuntime#getCurrentJavaThread()
1378 */
1379 native long getCurrentJavaThread();
1380
1381 /**
1382 * @param name name of current thread if in a native image otherwise {@code null}
1383 * @see HotSpotJVMCIRuntime#attachCurrentThread
1384 */
1385 native boolean attachCurrentThread(byte[] name, boolean asDaemon, long[] javaVMInfo);
1386
1387 /**
1388 * @see HotSpotJVMCIRuntime#detachCurrentThread
1389 */
1390 native boolean detachCurrentThread(boolean release);
1391
1392 /**
1393 * @see HotSpotJVMCIRuntime#exitHotSpot(int)
1394 */
1395 native void callSystemExit(int status);
1396
1397 /**
1398 * @see JFR.Ticks#now
1399 */
1400 native long ticksNow();
1401
1402 /**
1403 * @see HotSpotJVMCIRuntime#setThreadLocalObject(int, Object)
1404 */
1405 native void setThreadLocalObject(int id, Object value);
1406
1407 /**
1408 * @see HotSpotJVMCIRuntime#getThreadLocalObject(int)
1409 */
1410 native Object getThreadLocalObject(int id);
1411
1412 /**
1413 * @see HotSpotJVMCIRuntime#setThreadLocalLong(int, long)
1414 */
1415 native void setThreadLocalLong(int id, long value);
1416
1417 /**
1418 * @see HotSpotJVMCIRuntime#getThreadLocalLong(int)
1419 */
1420 native long getThreadLocalLong(int id);
1421
1422 /**
1423 * Adds phases in HotSpot JFR.
1424 *
1425 * @see JFR.CompilerPhaseEvent#write
1426 */
1427 native int registerCompilerPhase(String phaseName);
1428
1429 /**
1430 * @see JFR.CompilerPhaseEvent#write
1431 */
1432 native void notifyCompilerPhaseEvent(long startTime, int phase, int compileId, int level);
1433
1434 /**
1435 * @see JFR.CompilerInliningEvent#write
1436 */
1437 void notifyCompilerInliningEvent(int compileId, HotSpotResolvedJavaMethodImpl caller, HotSpotResolvedJavaMethodImpl callee, boolean succeeded, String message, int bci) {
1438 notifyCompilerInliningEvent(compileId, caller, caller.getMethodPointer(), callee, callee.getMethodPointer(), succeeded, message, bci);
1439 }
1440
1441 native void notifyCompilerInliningEvent(int compileId, HotSpotResolvedJavaMethodImpl caller, long callerPointer,
1442 HotSpotResolvedJavaMethodImpl callee, long calleePointer, boolean succeeded, String message, int bci);
1443
1444 /**
1445 * Gets the serialized annotation info for {@code type} by calling
1446 * {@code VMSupport.encodeAnnotations} in the HotSpot heap.
1447 */
1448 byte[] getEncodedClassAnnotationData(HotSpotResolvedObjectTypeImpl type, ResolvedJavaType[] filter) {
1449 try (KlassPointers a = new KlassPointers(filter)) {
1450 return getEncodedClassAnnotationData(type, type.getKlassPointer(),
1451 a.types, a.types.length, a.buffer());
1452 }
1453 }
1454
1455 native byte[] getEncodedClassAnnotationData(HotSpotResolvedObjectTypeImpl type, long klassPointer,
1456 Object filter, int filterLength, long filterKlassPointers);
1457
1458 /**
1459 * Gets the serialized annotation info for {@code method} by calling
1460 * {@code VMSupport.encodeAnnotations} in the HotSpot heap.
1461 */
1462 byte[] getEncodedExecutableAnnotationData(HotSpotResolvedJavaMethodImpl method, ResolvedJavaType[] filter) {
1463 try (KlassPointers a = new KlassPointers(filter)) {
1464 return getEncodedExecutableAnnotationData(method, method.getMethodPointer(),
1465 a.types, a.types.length, a.buffer());
1466 }
1467 }
1468
1469 native byte[] getEncodedExecutableAnnotationData(HotSpotResolvedJavaMethodImpl method, long methodPointer,
1470 Object filter, int filterLength, long filterKlassPointers);
1471
1472 /**
1473 * Gets the serialized annotation info for the field denoted by {@code holder} and
1474 * {@code fieldIndex} by calling {@code VMSupport.encodeAnnotations} in the HotSpot heap.
1475 */
1476 byte[] getEncodedFieldAnnotationData(HotSpotResolvedObjectTypeImpl holder, int fieldIndex, ResolvedJavaType[] filter) {
1477 try (KlassPointers a = new KlassPointers(filter)) {
1478 return getEncodedFieldAnnotationData(holder, holder.getKlassPointer(), fieldIndex,
1479 a.types, a.types.length, a.buffer());
1480 }
1481 }
1482
1483 native byte[] getEncodedFieldAnnotationData(HotSpotResolvedObjectTypeImpl holder, long klassPointer, int fieldIndex,
1484 Object filterTypes, int filterLength, long filterKlassPointers);
1485
1486 /**
1487 * Helper for passing {@Klass*} values to native code.
1488 */
1489 static final class KlassPointers implements AutoCloseable {
1490 final ResolvedJavaType[] types;
1491 long pointersArray;
1492 final Unsafe unsafe = UnsafeAccess.UNSAFE;
1493
1494 KlassPointers(ResolvedJavaType[] types) {
1495 this.types = types;
1496 }
1497
1498 /**
1499 * Gets the buffer in which to pass the {@Klass*} values to JNI.
1500 *
1501 * @return a {@Klass*} value if {@code types.length == 1} otherwise the address of a native
1502 * buffer holding an array of {@Klass*} values
1503 */
1504 long buffer() {
1505 int length = types.length;
1506 if (length == 1) {
1507 return ((HotSpotResolvedObjectTypeImpl) types[0]).getKlassPointer();
1508 } else {
1509 pointersArray = unsafe.allocateMemory(length * Long.BYTES);
1510 long pos = pointersArray;
1511 for (int i = 0; i < types.length; i++) {
1512 HotSpotResolvedObjectTypeImpl hsType = (HotSpotResolvedObjectTypeImpl) types[i];
1513 unsafe.putLong(pos, hsType.getKlassPointer());
1514 pos += Long.BYTES;
1515 }
1516 }
1517 return pointersArray;
1518 }
1519
1520 @Override
1521 public void close() {
1522 if (types.length != 1 && pointersArray != 0) {
1523 unsafe.freeMemory(pointersArray);
1524 pointersArray = 0;
1525 }
1526 }
1527 }
1528
1529 /**
1530 * @see HotSpotResolvedJavaMethod#getOopMapAt
1531 */
1532 void getOopMapAt(HotSpotResolvedJavaMethodImpl method, int bci, long[] oopMap) {
1533 getOopMapAt(method, method.getMethodPointer(), bci, oopMap);
1534 }
1535
1536 native void getOopMapAt(HotSpotResolvedJavaMethodImpl method, long methodPointer, int bci, long[] oopMap);
1537
1538 /**
1539 * If the current thread is a CompilerThread associated with a JVMCI compiler where
1540 * newState != CompilerThread::_can_call_java, then _can_call_java is set to newState.
1541 *
1542 * @returns false if no change was made, otherwise true
1543 */
1544 native boolean updateCompilerThreadCanCallJava(boolean newState);
1545
1546 /**
1547 * Returns the current {@code CompileBroker} compilation activity mode which is one of:
1548 * {@code stop_compilation = 0}, {@code run_compilation = 1} or {@code shutdown_compilation = 2}
1549 */
1550 native int getCompilationActivityMode();
1551
1552 /**
1553 * Returns whether the current thread is a CompilerThread.
1554 */
1555 native boolean isCompilerThread();
1556 }