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 native String getInvalidationReasonDescription(int invalidationReason);
658
659 /**
660 * Gets flags specifying optional parts of code info. Only if a flag is set, will the
661 * corresponding code info being included in the {@linkplain HotSpotCompiledCodeStream
662 * serialized code stream}.
663 *
664 * <ul>
665 * <li>0x0001: code comments ({@link HotSpotCompiledCode#comments})</li>
666 * <li>0x0002: methods ({@link HotSpotCompiledCode#methods})</li>
667 * <li>0x0004: enable {@link Option#CodeSerializationTypeInfo} if it not explicitly specified
668 * (i.e., {@link Option#isDefault} is {@code true})</li>
669 * </ul>
670 */
671 private native int getInstallCodeFlags();
672
673 /**
674 * Resets all compilation statistics.
675 */
676 native void resetCompilationStatistics();
677
678 /**
679 * Reads the database of VM info. The return value encodes the info in a nested object array
680 * that is described by the pseudo Java object {@code info} below:
681 *
682 * <pre>
683 * info = [
684 * VMField[] vmFields,
685 * [String name, Long size, ...] vmTypeSizes,
686 * [String name, Long value, ...] vmConstants,
687 * [String name, Long value, ...] vmAddresses,
688 * VMFlag[] vmFlags
689 * VMIntrinsicMethod[] vmIntrinsics
690 * ]
691 * </pre>
692 *
693 * @return VM info as encoded above
694 */
695 native Object[] readConfiguration();
696
697 /**
698 * Resolves the implementation of {@code method} for virtual dispatches on objects of dynamic
699 * type {@code exactReceiver}. This resolution process only searches "up" the class hierarchy of
700 * {@code exactReceiver}.
701 *
702 * @param exactReceiver the exact receiver type
703 * @param caller the caller or context type used to perform access checks
704 * @return the link-time resolved method (might be abstract) or {@code null} if it is either a
705 * signature polymorphic method or can not be linked.
706 */
707 HotSpotResolvedJavaMethodImpl resolveMethod(HotSpotResolvedObjectTypeImpl exactReceiver, HotSpotResolvedJavaMethodImpl method, HotSpotResolvedObjectTypeImpl caller) {
708 return resolveMethod(exactReceiver, exactReceiver.getKlassPointer(), method, method.getMethodPointer(), caller, caller.getKlassPointer());
709 }
710
711 private native HotSpotResolvedJavaMethodImpl resolveMethod(HotSpotResolvedObjectTypeImpl exactReceiver, long exactReceiverKlass,
712 HotSpotResolvedJavaMethodImpl method, long methodPointer,
713 HotSpotResolvedObjectTypeImpl caller, long callerKlass);
714
715 /**
716 * Gets the static initializer of {@code type}.
717 *
718 * @return {@code null} if {@code type} has no static initializer
719 */
720 HotSpotResolvedJavaMethodImpl getClassInitializer(HotSpotResolvedObjectTypeImpl type) {
721 return getClassInitializer(type, type.getKlassPointer());
722 }
723
724 private native HotSpotResolvedJavaMethodImpl getClassInitializer(HotSpotResolvedObjectTypeImpl type, long klassPointer);
725
726 /**
727 * Determines if {@code type} or any of its currently loaded subclasses overrides
728 * {@code Object.finalize()}.
729 */
730 boolean hasFinalizableSubclass(HotSpotResolvedObjectTypeImpl type) {
731 return hasFinalizableSubclass(type, type.getKlassPointer());
732 }
733
734 private native boolean hasFinalizableSubclass(HotSpotResolvedObjectTypeImpl type, long klassPointer);
735
736 /**
737 * Gets the method corresponding to {@code executable}.
738 */
739 native HotSpotResolvedJavaMethodImpl asResolvedJavaMethod(Executable executable);
740
741 /**
742 * Gets the maximum absolute offset of a PC relative call to {@code address} from any position
743 * in the code cache.
744 *
745 * @param address an address that may be called from any code in the code cache
746 * @return -1 if {@code address == 0}
747 */
748 native long getMaxCallTargetOffset(long address);
749
750 /**
751 * Gets a textual disassembly of {@code codeBlob}.
752 *
753 * @return a non-zero length string containing a disassembly of {@code codeBlob} or null if
754 * {@code codeBlob} could not be disassembled for some reason
755 */
756 // The HotSpot disassembler seems not to be thread safe so it's better to synchronize its usage
757 synchronized native String disassembleCodeBlob(InstalledCode installedCode);
758
759 /**
760 * Gets a stack trace element for {@code method} at bytecode index {@code bci}.
761 */
762 StackTraceElement getStackTraceElement(HotSpotResolvedJavaMethodImpl method, int bci) {
763 return getStackTraceElement(method, method.getMethodPointer(), bci);
764 }
765
766 private native StackTraceElement getStackTraceElement(HotSpotResolvedJavaMethodImpl method, long methodPointer, int bci);
767
768 /**
769 * Executes some {@code installedCode} with arguments {@code args}.
770 *
771 * @return the result of executing {@code nmethodMirror}
772 * @throws InvalidInstalledCodeException if {@code nmethodMirror} has been invalidated
773 */
774 native Object executeHotSpotNmethod(Object[] args, HotSpotNmethod nmethodMirror) throws InvalidInstalledCodeException;
775
776 /**
777 * Gets the line number table for {@code method}. The line number table is encoded as (bci,
778 * source line number) pairs.
779 *
780 * @return the line number table for {@code method} or null if it doesn't have one
781 */
782 long[] getLineNumberTable(HotSpotResolvedJavaMethodImpl method) {
783 return getLineNumberTable(method, method.getMethodPointer());
784 }
785
786 private native long[] getLineNumberTable(HotSpotResolvedJavaMethodImpl method, long methodPointer);
787
788 /**
789 * Gets the number of entries in the local variable table for {@code method}.
790 *
791 * @return the number of entries in the local variable table for {@code method}
792 */
793 int getLocalVariableTableLength(HotSpotResolvedJavaMethodImpl method) {
794 return getLocalVariableTableLength(method, method.getMethodPointer());
795 }
796
797 private native int getLocalVariableTableLength(HotSpotResolvedJavaMethodImpl method, long methodPointer);
798
799 /**
800 * Gets the address of the first entry in the local variable table for {@code method}.
801 *
802 * Each entry is a native object described by these fields:
803 *
804 * <ul>
805 * <li>{@link HotSpotVMConfig#localVariableTableElementSize}</li>
806 * <li>{@link HotSpotVMConfig#localVariableTableElementLengthOffset}</li>
807 * <li>{@link HotSpotVMConfig#localVariableTableElementNameCpIndexOffset}</li>
808 * <li>{@link HotSpotVMConfig#localVariableTableElementDescriptorCpIndexOffset}</li>
809 * <li>{@link HotSpotVMConfig#localVariableTableElementSlotOffset}
810 * <li>{@link HotSpotVMConfig#localVariableTableElementStartBciOffset}
811 * </ul>
812 *
813 * @return 0 if {@code method} does not have a local variable table
814 */
815 long getLocalVariableTableStart(HotSpotResolvedJavaMethodImpl method) {
816 return getLocalVariableTableStart(method, method.getMetaspacePointer());
817 }
818
819 private native long getLocalVariableTableStart(HotSpotResolvedJavaMethodImpl method, long methodPointer);
820
821 /**
822 * Sets flags on {@code method} indicating that it should never be inlined or compiled by the
823 * VM.
824 */
825 void setNotInlinableOrCompilable(HotSpotResolvedJavaMethodImpl method) {
826 setNotInlinableOrCompilable(method, method.getMethodPointer());
827 }
828
829 private native void setNotInlinableOrCompilable(HotSpotResolvedJavaMethodImpl method, long methodPointer);
830
831 /**
832 * Invalidates the profiling information for {@code method} and (re)initializes it such that
833 * profiling restarts upon its next invocation.
834 */
835 void reprofile(HotSpotResolvedJavaMethodImpl method) {
836 reprofile(method, method.getMethodPointer());
837 }
838
839 private native void reprofile(HotSpotResolvedJavaMethodImpl method, long methodPointer);
840
841 /**
842 * Updates {@code nmethodMirror} such that {@link InvalidInstalledCodeException} will be raised
843 * the next time {@code nmethodMirror} is {@linkplain #executeHotSpotNmethod executed}. The
844 * {@code nmethod} associated with {@code nmethodMirror} is also made non-entrant and if
845 * {@code deoptimize == true} any current activations of the {@code nmethod} are deoptimized.
846 */
847 native void invalidateHotSpotNmethod(HotSpotNmethod nmethodMirror, boolean deoptimize, int invalidationReason);
848
849 /**
850 * Collects the current values of all JVMCI benchmark counters, summed up over all threads.
851 */
852 native long[] collectCounters();
853
854 /**
855 * Get the current number of counters allocated for use by JVMCI. Should be the same value as
856 * the flag {@code JVMCICounterSize}.
857 */
858 native int getCountersSize();
859
860 /**
861 * Attempt to change the size of the counters allocated for JVMCI. This requires a safepoint to
862 * safely reallocate the storage but it's advisable to increase the size in reasonable chunks.
863 */
864 native boolean setCountersSize(int newSize);
865
866 /**
867 * Determines if {@code methodData} is mature.
868 *
869 * @param methodData a {@code MethodData*} value
870 */
871 native boolean isMature(long methodData);
872
873 /**
874 * Generate a unique id to identify the result of the compile.
875 */
876 int allocateCompileId(HotSpotResolvedJavaMethodImpl method, int entryBCI) {
877 return allocateCompileId(method, method.getMethodPointer(), entryBCI);
878 }
879
880 private native int allocateCompileId(HotSpotResolvedJavaMethodImpl method, long methodPointer, int entryBCI);
881
882 /**
883 * Determines if {@code method} has OSR compiled code identified by {@code entryBCI} for
884 * compilation level {@code level}.
885 */
886 boolean hasCompiledCodeForOSR(HotSpotResolvedJavaMethodImpl method, int entryBCI, int level) {
887 return hasCompiledCodeForOSR(method, method.getMethodPointer(), entryBCI, level);
888 }
889
890 private native boolean hasCompiledCodeForOSR(HotSpotResolvedJavaMethodImpl method, long methodPoiner, int entryBCI, int level);
891
892 /**
893 * Gets the value of {@code symbol} as a String.
894 *
895 * @param symbol a {@code Symbol*} value
896 */
897 native String getSymbol(long symbol);
898
899 /**
900 * Gets the name for a {@code klass} as it would appear in a signature.
901 *
902 * @param klass a {@code Klass*} value
903 */
904 native String getSignatureName(long klass);
905
906 /**
907 * @see jdk.vm.ci.code.stack.StackIntrospection#iterateFrames
908 */
909 native <T> T iterateFrames(ResolvedJavaMethod[] initialMethods, ResolvedJavaMethod[] matchingMethods, int initialSkip, InspectedFrameVisitor<T> visitor);
910
911 /**
912 * Materializes all virtual objects within {@code stackFrame} and updates its locals.
913 *
914 * @param invalidate if {@code true}, the compiled method for the stack frame will be
915 * invalidated
916 */
917 native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate);
918
919 /**
920 * Gets the v-table index for interface method {@code method} in the receiver {@code type} or
921 * {@link HotSpotVMConfig#invalidVtableIndex} if {@code method} is not in {@code type}'s
922 * v-table.
923 *
924 * @throws InternalError if {@code type} is an interface, {@code method} is not defined by an
925 * interface, {@code type} does not implement the interface defining {@code method}
926 * or class represented by {@code type} is not initialized
927 */
928 int getVtableIndexForInterfaceMethod(HotSpotResolvedObjectTypeImpl type, HotSpotResolvedJavaMethodImpl method) {
929 return getVtableIndexForInterfaceMethod(type, type.getKlassPointer(), method, method.getMethodPointer());
930 }
931
932 private native int getVtableIndexForInterfaceMethod(HotSpotResolvedObjectTypeImpl type, long klassPointer, HotSpotResolvedJavaMethodImpl method, long methodPointer);
933
934 /**
935 * Determines if debug info should also be emitted at non-safepoint locations.
936 */
937 native boolean shouldDebugNonSafepoints();
938
939 /**
940 * Writes {@code length} bytes from {@code buffer} to HotSpot's log stream.
941 *
942 * @param buffer if {@code length <= 8}, then the bytes are encoded in this value in native
943 * endianness order otherwise this is the address of a native memory buffer holding
944 * the bytes
945 * @param flush specifies if the log stream should be flushed after writing
946 */
947 native void writeDebugOutput(long buffer, int length, boolean flush);
948
949 /**
950 * Flush HotSpot's log stream.
951 */
952 native void flushDebugOutput();
953
954 /**
955 * Read a HotSpot {@code Method*} value from the memory location described by {@code base} plus
956 * {@code displacement} and return the {@link HotSpotResolvedJavaMethodImpl} wrapping it. This
957 * method does no checking that the memory location actually contains a valid pointer and may
958 * crash the VM if an invalid location is provided. If {@code base == null} is null then
959 * {@code displacement} is used by itself. If {@code base} is a
960 * {@link HotSpotResolvedJavaMethodImpl}, {@link HotSpotConstantPool} or
961 * {@link HotSpotResolvedObjectTypeImpl} then the metaspace pointer is fetched from that object
962 * and added to {@code displacement}. Any other non-null object type causes an
963 * {@link IllegalArgumentException} to be thrown.
964 *
965 * @param base an object to read from or null
966 * @param displacement
967 * @return null or the resolved method for this location
968 */
969 native HotSpotResolvedJavaMethodImpl getResolvedJavaMethod(HotSpotObjectConstantImpl base, long displacement);
970
971 /**
972 * Gets the {@code ConstantPool*} associated with {@code object} and returns a
973 * {@link HotSpotConstantPool} wrapping it.
974 *
975 * @param object a {@link HotSpotResolvedJavaMethodImpl} or
976 * {@link HotSpotResolvedObjectTypeImpl} object
977 * @return a {@link HotSpotConstantPool} wrapping the {@code ConstantPool*} associated with
978 * {@code object}
979 * @throws NullPointerException if {@code object == null}
980 * @throws IllegalArgumentException if {@code object} is neither a
981 * {@link HotSpotResolvedJavaMethodImpl} nor a {@link HotSpotResolvedObjectTypeImpl}
982 */
983 HotSpotConstantPool getConstantPool(MetaspaceObject object) {
984 return getConstantPool(object, object.getMetaspacePointer(), object instanceof HotSpotResolvedJavaType);
985 }
986
987 native HotSpotConstantPool getConstantPool(Object object, long klassOrMethod, boolean isKlass);
988
989 /**
990 * Read a {@code Klass*} value from the memory location described by {@code base} plus
991 * {@code displacement} and return the {@link HotSpotResolvedObjectTypeImpl} wrapping it. This method
992 * only performs the read if the memory location is known to contain a valid Klass*. If
993 * {@code base} is a {@link HotSpotConstantPool}, {@link HotSpotMethodData}, {@link HotSpotObjectConstantImpl},
994 * or {@link HotSpotResolvedObjectTypeImpl} then the field
995 * corresopnding to {@code displacement} is fetched using the appropriate HotSpot accessor. Any
996 * other object type or an unexpected displacement causes an {@link IllegalArgumentException} to
997 * be thrown. The set of fields which can be read in this fashion corresponds to the {@link VMField}
998 * with type {@code Klass*} that are described in the {@link HotSpotVMConfigStore#getFields()}.
999 * Additionally several injected fields in {@link Class} are also handled.
1000 *
1001 * @param base an object to read from
1002 * @param displacement
1003 * @param compressed true if the location contains a compressed Klass*
1004 * @return null or the resolved method for this location
1005 * @throws NullPointerException if {@code base == null}
1006 */
1007 private native HotSpotResolvedObjectTypeImpl getResolvedJavaType0(Object base, long displacement, boolean compressed);
1008
1009 HotSpotResolvedObjectTypeImpl getResolvedJavaType(HotSpotConstantPool base, long displacement) {
1010 return getResolvedJavaType0(base, displacement, false);
1011 }
1012
1013 HotSpotResolvedObjectTypeImpl getResolvedJavaType(HotSpotMethodData base, long displacement) {
1014 return getResolvedJavaType0(base, displacement, false);
1015 }
1016
1017 HotSpotResolvedObjectTypeImpl getResolvedJavaType(HotSpotResolvedObjectTypeImpl base, long displacement, boolean compressed) {
1018 return getResolvedJavaType0(base, displacement, compressed);
1019 }
1020
1021 HotSpotResolvedObjectTypeImpl getResolvedJavaType(HotSpotObjectConstantImpl base, long displacement, boolean compressed) {
1022 return getResolvedJavaType0(base, displacement, compressed);
1023 }
1024
1025 /**
1026 * Reads a {@code Klass*} from {@code address} (i.e., {@code address} is a {@code Klass**}
1027 * value) and wraps it in a {@link HotSpotResolvedObjectTypeImpl}. This VM call must be used for
1028 * any {@code Klass*} value not known to be already wrapped in a
1029 * {@link HotSpotResolvedObjectTypeImpl}. The VM call is necessary so that the {@code Klass*} is
1030 * wrapped in a {@code JVMCIKlassHandle} to protect it from the concurrent scanning done by G1.
1031 */
1032 HotSpotResolvedObjectTypeImpl getResolvedJavaType(long address) {
1033 return getResolvedJavaType0(null, address, false);
1034 }
1035
1036 /**
1037 * Return the size of the HotSpot ProfileData* pointed at by {@code position}. If
1038 * {@code position} is outside the space of the MethodData then an
1039 * {@link IllegalArgumentException} is thrown. A {@code position} inside the MethodData but that
1040 * isn't pointing at a valid ProfileData will crash the VM.
1041 *
1042 * @param metaspaceMethodData
1043 * @param position
1044 * @return the size of the ProfileData item pointed at by {@code position}
1045 * @throws IllegalArgumentException if an out of range position is given
1046 */
1047 native int methodDataProfileDataSize(long metaspaceMethodData, int position);
1048
1049
1050 native int methodDataExceptionSeen(long metaspaceMethodData, int bci);
1051
1052 /**
1053 * Return the amount of native stack required for the interpreter frames represented by
1054 * {@code frame}. This is used when emitting the stack banging code to ensure that there is
1055 * enough space for the frames during deoptimization.
1056 *
1057 * @param frame
1058 * @return the number of bytes required for deoptimization of this frame state
1059 */
1060 native int interpreterFrameSize(BytecodeFrame frame);
1061
1062 /**
1063 * Invokes non-public method {@code java.lang.invoke.LambdaForm.compileToBytecode()} on
1064 * {@code lambdaForm} (which must be a {@code java.lang.invoke.LambdaForm} instance).
1065 */
1066 native void compileToBytecode(HotSpotObjectConstantImpl lambdaForm);
1067
1068 /**
1069 * Gets the value of the VM flag named {@code name}.
1070 *
1071 * @param name name of a VM option
1072 * @return {@code this} if the named VM option doesn't exist, a {@link String} or {@code null}
1073 * if its type is {@code ccstr} or {@code ccstrlist}, a {@link Double} if its type is
1074 * {@code double}, a {@link Boolean} if its type is {@code bool} otherwise a
1075 * {@link Long}
1076 */
1077 native Object getFlagValue(String name);
1078
1079 /**
1080 * @see ResolvedJavaType#getInterfaces()
1081 */
1082 HotSpotResolvedObjectTypeImpl[] getInterfaces(HotSpotResolvedObjectTypeImpl klass) {
1083 return getInterfaces(klass, klass.getKlassPointer());
1084 }
1085
1086 native HotSpotResolvedObjectTypeImpl[] getInterfaces(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1087
1088 /**
1089 * @see ResolvedJavaType#getComponentType()
1090 */
1091 HotSpotResolvedJavaType getComponentType(HotSpotResolvedObjectTypeImpl klass) {
1092 return getComponentType(klass, klass.getKlassPointer());
1093 }
1094
1095 native HotSpotResolvedJavaType getComponentType(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1096
1097 /**
1098 * Get the array class for the primitive type represented by the {@link JavaKind#getTypeChar()}
1099 * value in {@code typeChar} or the non-primitive type represented by {@code nonPrimitiveKlass}.
1100 * This can't be done symbolically since hidden classes can't be looked up by name.
1101 *
1102 * Exactly one of {@code primitiveTypeChar} or {@code nonPrimitiveKlass} must be non-zero.
1103 *
1104 * @param primitiveTypeChar a {@link JavaKind#getTypeChar()} value for a primitive type
1105 * @param nonPrimitiveKlass a non-primitive type
1106 */
1107 HotSpotResolvedObjectTypeImpl getArrayType(char primitiveTypeChar, HotSpotResolvedObjectTypeImpl nonPrimitiveKlass) {
1108 long nonPrimitiveKlassPointer = nonPrimitiveKlass != null ? nonPrimitiveKlass.getKlassPointer() : 0L;
1109 return getArrayType(primitiveTypeChar, nonPrimitiveKlass, nonPrimitiveKlassPointer);
1110 }
1111
1112 native HotSpotResolvedObjectTypeImpl getArrayType(char typeChar, HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1113
1114 /**
1115 * Forces initialization of {@code klass}.
1116 */
1117 void ensureInitialized(HotSpotResolvedObjectTypeImpl klass) {
1118 ensureInitialized(klass, klass.getKlassPointer());
1119 }
1120
1121 native void ensureInitialized(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1122
1123 /**
1124 * Forces linking of {@code klass}.
1125 */
1126 void ensureLinked(HotSpotResolvedObjectTypeImpl klass) {
1127 ensureLinked(klass, klass.getKlassPointer());
1128 }
1129
1130 native void ensureLinked(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1131
1132 /**
1133 * Checks if {@code object} is a String and is an interned string value.
1134 */
1135 native boolean isInternedString(HotSpotObjectConstantImpl object);
1136
1137 /**
1138 * Gets the {@linkplain System#identityHashCode(Object) identity} has code for the object
1139 * represented by this constant.
1140 */
1141 native int getIdentityHashCode(HotSpotObjectConstantImpl object);
1142
1143 /**
1144 * Converts a constant object representing a boxed primitive into a boxed primitive.
1145 */
1146 native Object unboxPrimitive(HotSpotObjectConstantImpl object);
1147
1148 /**
1149 * Converts a boxed primitive into a JavaConstant representing the same value.
1150 */
1151 native HotSpotObjectConstantImpl boxPrimitive(Object source);
1152
1153 /**
1154 * Gets the {@link ResolvedJavaMethod}s for all the constructors of {@code klass}.
1155 */
1156 ResolvedJavaMethod[] getDeclaredConstructors(HotSpotResolvedObjectTypeImpl klass) {
1157 return getDeclaredConstructors(klass, klass.getKlassPointer());
1158 }
1159
1160 native ResolvedJavaMethod[] getDeclaredConstructors(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1161
1162 /**
1163 * Gets the {@link ResolvedJavaMethod}s for all non-overpass and non-initializer
1164 * methods of {@code klass}.
1165 */
1166 ResolvedJavaMethod[] getDeclaredMethods(HotSpotResolvedObjectTypeImpl klass) {
1167 return getDeclaredMethods(klass, klass.getKlassPointer());
1168 }
1169
1170 native ResolvedJavaMethod[] getDeclaredMethods(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1171
1172 /**
1173 * Gets the {@link ResolvedJavaMethod}s for all methods of {@code klass}.
1174 */
1175 ResolvedJavaMethod[] getAllMethods(HotSpotResolvedObjectTypeImpl klass) {
1176 return getAllMethods(klass, klass.getKlassPointer());
1177 }
1178
1179 native ResolvedJavaMethod[] getAllMethods(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1180
1181 HotSpotResolvedObjectTypeImpl.FieldInfo[] getDeclaredFieldsInfo(HotSpotResolvedObjectTypeImpl klass) {
1182 return getDeclaredFieldsInfo(klass, klass.getKlassPointer());
1183 }
1184
1185 native HotSpotResolvedObjectTypeImpl.FieldInfo[] getDeclaredFieldsInfo(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1186
1187 /**
1188 * Reads the current value of a static field of {@code declaringKlass}. Extra sanity checking is
1189 * performed on the offset and kind of the read being performed.
1190 *
1191 * @param declaringKlass the type in which the static field is declared
1192 * @param offset the offset of the field in the {@link Class} mirror of {@code declaringKlass}
1193 * @throws IllegalArgumentException if any of the sanity checks fail
1194 */
1195 JavaConstant readStaticFieldValue(HotSpotResolvedObjectTypeImpl declaringKlass, long offset, char typeChar) {
1196 return readStaticFieldValue(declaringKlass, declaringKlass.getKlassPointer(), offset, typeChar);
1197 }
1198
1199 native JavaConstant readStaticFieldValue(HotSpotResolvedObjectTypeImpl declaringKlass, long declaringKlassPointer, long offset, char typeChar);
1200
1201 /**
1202 * Reads the current value of an instance field. If {@code expectedType} is non-null, then
1203 * {@code object} is expected to be a subtype of {@code expectedType}. Extra sanity checking is
1204 * performed on the offset and kind of the read being performed.
1205 *
1206 * @param object the object from which the field is to be read. If {@code object} is of type
1207 * {@link Class} and {@code offset} is >= the offset of the static field storage in a
1208 * {@link Class} instance, then this operation is a static field read.
1209 * @param expectedType the expected type of {@code object}
1210 * @throws IllegalArgumentException if any of the sanity checks fail
1211 */
1212 JavaConstant readFieldValue(HotSpotObjectConstantImpl object, HotSpotResolvedObjectTypeImpl expectedType, long offset, char typeChar) {
1213 long expectedTypePointer = expectedType != null ? expectedType.getKlassPointer() : 0L;
1214 return readFieldValue(object, expectedType, expectedTypePointer, offset, typeChar);
1215 }
1216
1217 native JavaConstant readFieldValue(HotSpotObjectConstantImpl object, HotSpotResolvedObjectTypeImpl expectedType, long expectedTypePointer, long offset, char typeChar);
1218
1219 /**
1220 * @see ResolvedJavaType#isInstance(JavaConstant)
1221 */
1222 boolean isInstance(HotSpotResolvedObjectTypeImpl klass, HotSpotObjectConstantImpl object) {
1223 return isInstance(klass, klass.getKlassPointer(), object);
1224 }
1225
1226 native boolean isInstance(HotSpotResolvedObjectTypeImpl klass, long klassPointer, HotSpotObjectConstantImpl object);
1227
1228 /**
1229 * @see ResolvedJavaType#isAssignableFrom(ResolvedJavaType)
1230 */
1231 boolean isAssignableFrom(HotSpotResolvedObjectTypeImpl klass, HotSpotResolvedObjectTypeImpl subklass) {
1232 return isAssignableFrom(klass, klass.getKlassPointer(), subklass, subklass.getKlassPointer());
1233 }
1234
1235 native boolean isAssignableFrom(HotSpotResolvedObjectTypeImpl klass, long klassPointer, HotSpotResolvedObjectTypeImpl subklass, long subklassPointer);
1236
1237 /**
1238 * @see ConstantReflectionProvider#asJavaType(Constant)
1239 */
1240 native HotSpotResolvedJavaType asJavaType(HotSpotObjectConstantImpl object);
1241
1242 /**
1243 * Converts a String constant into a String.
1244 */
1245 native String asString(HotSpotObjectConstantImpl object);
1246
1247 /**
1248 * Compares the contents of {@code xHandle} and {@code yHandle} for pointer equality.
1249 */
1250 native boolean equals(HotSpotObjectConstantImpl x, long xHandle, HotSpotObjectConstantImpl y, long yHandle);
1251
1252 /**
1253 * Gets a {@link JavaConstant} wrapping the {@link java.lang.Class} mirror for {@code klass}.
1254 */
1255 HotSpotObjectConstantImpl getJavaMirror(HotSpotResolvedObjectTypeImpl klass) {
1256 return getJavaMirror(klass, klass.getKlassPointer());
1257 }
1258
1259 native HotSpotObjectConstantImpl getJavaMirror(HotSpotResolvedObjectTypeImpl type, long klassPointer);
1260
1261 /**
1262 * Returns the length of the array if {@code object} represents an array or -1 otherwise.
1263 */
1264 native int getArrayLength(HotSpotObjectConstantImpl object);
1265
1266 /**
1267 * Reads the element at {@code index} if {@code object} is an array. Elements of an object array
1268 * are returned as {@link JavaConstant}s and primitives are returned as boxed values. The value
1269 * {@code null} is returned if the {@code index} is out of range or object is not an array.
1270 */
1271 native Object readArrayElement(HotSpotObjectConstantImpl object, int index);
1272
1273 /**
1274 * @see HotSpotJVMCIRuntime#registerNativeMethods
1275 */
1276 native long[] registerNativeMethods(Class<?> clazz);
1277
1278 /**
1279 * @see HotSpotJVMCIRuntime#translate(Object)
1280 */
1281 native long translate(Object obj, boolean callPostTranslation);
1282
1283 /**
1284 * @see HotSpotJVMCIRuntime#unhand(Class, long)
1285 */
1286 native Object unhand(long handle);
1287
1288 /**
1289 * Updates {@code address} and {@code entryPoint} fields of {@code nmethodMirror} based on the
1290 * current state of the {@code nmethod} identified by {@code address} and
1291 * {@code nmethodMirror.compileId} in the code cache.
1292 */
1293 native void updateHotSpotNmethod(HotSpotNmethod nmethodMirror);
1294
1295 /**
1296 * @see InstalledCode#getCode()
1297 */
1298 native byte[] getCode(HotSpotInstalledCode code);
1299
1300 /**
1301 * Gets a {@link Executable} corresponding to {@code method}.
1302 */
1303 Executable asReflectionExecutable(HotSpotResolvedJavaMethodImpl method) {
1304 return asReflectionExecutable(method, method.getMethodPointer());
1305 }
1306
1307 native Executable asReflectionExecutable(HotSpotResolvedJavaMethodImpl method, long methodPointer);
1308
1309 /**
1310 * Gets a {@link Field} denoted by {@code holder} and {@code index}.
1311 *
1312 * @param holder the class in which the requested field is declared
1313 * @param fieldIndex the {@code fieldDescriptor::index()} denoting the field
1314 */
1315 Field asReflectionField(HotSpotResolvedObjectTypeImpl holder, int fieldIndex) {
1316 return asReflectionField(holder, holder.getKlassPointer(), fieldIndex);
1317 }
1318
1319 native Field asReflectionField(HotSpotResolvedObjectTypeImpl holder, long holderPointer, int fieldIndex);
1320
1321 /**
1322 * @see HotSpotJVMCIRuntime#getIntrinsificationTrustPredicate(Class...)
1323 */
1324 boolean isTrustedForIntrinsics(HotSpotResolvedObjectTypeImpl klass) {
1325 return isTrustedForIntrinsics(klass, klass.getKlassPointer());
1326 }
1327
1328 native boolean isTrustedForIntrinsics(HotSpotResolvedObjectTypeImpl klass, long klassPointer);
1329
1330 /**
1331 * Clears the oop handle in {@code handle}.
1332 */
1333 native void clearOopHandle(long handle);
1334
1335 /**
1336 * Releases all oop handles whose referent is null.
1337 */
1338 native void releaseClearedOopHandles();
1339
1340 /**
1341 * Gets the failed speculations pointed to by {@code *failedSpeculationsAddress}.
1342 *
1343 * @param currentFailures the known failures at {@code failedSpeculationsAddress}
1344 * @return the list of failed speculations with each entry being a single speculation in the
1345 * format emitted by {@link HotSpotSpeculationEncoding#toByteArray()}
1346 */
1347 native byte[][] getFailedSpeculations(long failedSpeculationsAddress, byte[][] currentFailures);
1348
1349 /**
1350 * Gets the address of the {@code MethodData::_failed_speculations} field in the
1351 * {@code MethodData} associated with {@code method}. This will create and install the
1352 * {@code MethodData} if it didn't already exist.
1353 */
1354 long getFailedSpeculationsAddress(HotSpotResolvedJavaMethodImpl method) {
1355 return getFailedSpeculationsAddress(method, method.getMethodPointer());
1356 }
1357
1358 native long getFailedSpeculationsAddress(HotSpotResolvedJavaMethodImpl method, long methodPointer);
1359
1360 /**
1361 * Frees the failed speculations pointed to by {@code *failedSpeculationsAddress}.
1362 */
1363 native void releaseFailedSpeculations(long failedSpeculationsAddress);
1364
1365 /**
1366 * Adds a speculation to the failed speculations pointed to by
1367 * {@code *failedSpeculationsAddress}.
1368 *
1369 * @return {@code false} if the speculation could not be appended to the list
1370 */
1371 native boolean addFailedSpeculation(long failedSpeculationsAddress, byte[] speculation);
1372
1373 /**
1374 * @see HotSpotJVMCIRuntime#isCurrentThreadAttached()
1375 */
1376 native boolean isCurrentThreadAttached();
1377
1378 /**
1379 * @see HotSpotJVMCIRuntime#getCurrentJavaThread()
1380 */
1381 native long getCurrentJavaThread();
1382
1383 /**
1384 * @param name name of current thread if in a native image otherwise {@code null}
1385 * @see HotSpotJVMCIRuntime#attachCurrentThread
1386 */
1387 native boolean attachCurrentThread(byte[] name, boolean asDaemon, long[] javaVMInfo);
1388
1389 /**
1390 * @see HotSpotJVMCIRuntime#detachCurrentThread
1391 */
1392 native boolean detachCurrentThread(boolean release);
1393
1394 /**
1395 * @see HotSpotJVMCIRuntime#exitHotSpot(int)
1396 */
1397 native void callSystemExit(int status);
1398
1399 /**
1400 * @see JFR.Ticks#now
1401 */
1402 native long ticksNow();
1403
1404 /**
1405 * @see HotSpotJVMCIRuntime#setThreadLocalObject(int, Object)
1406 */
1407 native void setThreadLocalObject(int id, Object value);
1408
1409 /**
1410 * @see HotSpotJVMCIRuntime#getThreadLocalObject(int)
1411 */
1412 native Object getThreadLocalObject(int id);
1413
1414 /**
1415 * @see HotSpotJVMCIRuntime#setThreadLocalLong(int, long)
1416 */
1417 native void setThreadLocalLong(int id, long value);
1418
1419 /**
1420 * @see HotSpotJVMCIRuntime#getThreadLocalLong(int)
1421 */
1422 native long getThreadLocalLong(int id);
1423
1424 /**
1425 * Adds phases in HotSpot JFR.
1426 *
1427 * @see JFR.CompilerPhaseEvent#write
1428 */
1429 native int registerCompilerPhase(String phaseName);
1430
1431 /**
1432 * @see JFR.CompilerPhaseEvent#write
1433 */
1434 native void notifyCompilerPhaseEvent(long startTime, int phase, int compileId, int level);
1435
1436 /**
1437 * @see JFR.CompilerInliningEvent#write
1438 */
1439 void notifyCompilerInliningEvent(int compileId, HotSpotResolvedJavaMethodImpl caller, HotSpotResolvedJavaMethodImpl callee, boolean succeeded, String message, int bci) {
1440 notifyCompilerInliningEvent(compileId, caller, caller.getMethodPointer(), callee, callee.getMethodPointer(), succeeded, message, bci);
1441 }
1442
1443 native void notifyCompilerInliningEvent(int compileId, HotSpotResolvedJavaMethodImpl caller, long callerPointer,
1444 HotSpotResolvedJavaMethodImpl callee, long calleePointer, boolean succeeded, String message, int bci);
1445
1446 /**
1447 * Gets the serialized annotation info for {@code type} by calling
1448 * {@code VMSupport.encodeAnnotations} in the HotSpot heap.
1449 */
1450 byte[] getEncodedClassAnnotationData(HotSpotResolvedObjectTypeImpl type, ResolvedJavaType[] filter) {
1451 try (KlassPointers a = new KlassPointers(filter)) {
1452 return getEncodedClassAnnotationData(type, type.getKlassPointer(),
1453 a.types, a.types.length, a.buffer());
1454 }
1455 }
1456
1457 native byte[] getEncodedClassAnnotationData(HotSpotResolvedObjectTypeImpl type, long klassPointer,
1458 Object filter, int filterLength, long filterKlassPointers);
1459
1460 /**
1461 * Gets the serialized annotation info for {@code method} by calling
1462 * {@code VMSupport.encodeAnnotations} in the HotSpot heap.
1463 */
1464 byte[] getEncodedExecutableAnnotationData(HotSpotResolvedJavaMethodImpl method, ResolvedJavaType[] filter) {
1465 try (KlassPointers a = new KlassPointers(filter)) {
1466 return getEncodedExecutableAnnotationData(method, method.getMethodPointer(),
1467 a.types, a.types.length, a.buffer());
1468 }
1469 }
1470
1471 native byte[] getEncodedExecutableAnnotationData(HotSpotResolvedJavaMethodImpl method, long methodPointer,
1472 Object filter, int filterLength, long filterKlassPointers);
1473
1474 /**
1475 * Gets the serialized annotation info for the field denoted by {@code holder} and
1476 * {@code fieldIndex} by calling {@code VMSupport.encodeAnnotations} in the HotSpot heap.
1477 */
1478 byte[] getEncodedFieldAnnotationData(HotSpotResolvedObjectTypeImpl holder, int fieldIndex, ResolvedJavaType[] filter) {
1479 try (KlassPointers a = new KlassPointers(filter)) {
1480 return getEncodedFieldAnnotationData(holder, holder.getKlassPointer(), fieldIndex,
1481 a.types, a.types.length, a.buffer());
1482 }
1483 }
1484
1485 native byte[] getEncodedFieldAnnotationData(HotSpotResolvedObjectTypeImpl holder, long klassPointer, int fieldIndex,
1486 Object filterTypes, int filterLength, long filterKlassPointers);
1487
1488 /**
1489 * Helper for passing {@Klass*} values to native code.
1490 */
1491 static final class KlassPointers implements AutoCloseable {
1492 final ResolvedJavaType[] types;
1493 long pointersArray;
1494 final Unsafe unsafe = UnsafeAccess.UNSAFE;
1495
1496 KlassPointers(ResolvedJavaType[] types) {
1497 this.types = types;
1498 }
1499
1500 /**
1501 * Gets the buffer in which to pass the {@Klass*} values to JNI.
1502 *
1503 * @return a {@Klass*} value if {@code types.length == 1} otherwise the address of a native
1504 * buffer holding an array of {@Klass*} values
1505 */
1506 long buffer() {
1507 int length = types.length;
1508 if (length == 1) {
1509 return ((HotSpotResolvedObjectTypeImpl) types[0]).getKlassPointer();
1510 } else {
1511 pointersArray = unsafe.allocateMemory(length * Long.BYTES);
1512 long pos = pointersArray;
1513 for (int i = 0; i < types.length; i++) {
1514 HotSpotResolvedObjectTypeImpl hsType = (HotSpotResolvedObjectTypeImpl) types[i];
1515 unsafe.putLong(pos, hsType.getKlassPointer());
1516 pos += Long.BYTES;
1517 }
1518 }
1519 return pointersArray;
1520 }
1521
1522 @Override
1523 public void close() {
1524 if (types.length != 1 && pointersArray != 0) {
1525 unsafe.freeMemory(pointersArray);
1526 pointersArray = 0;
1527 }
1528 }
1529 }
1530
1531 /**
1532 * @see HotSpotResolvedJavaMethod#getOopMapAt
1533 */
1534 void getOopMapAt(HotSpotResolvedJavaMethodImpl method, int bci, long[] oopMap) {
1535 getOopMapAt(method, method.getMethodPointer(), bci, oopMap);
1536 }
1537
1538 native void getOopMapAt(HotSpotResolvedJavaMethodImpl method, long methodPointer, int bci, long[] oopMap);
1539
1540 /**
1541 * If the current thread is a CompilerThread associated with a JVMCI compiler where
1542 * newState != CompilerThread::_can_call_java, then _can_call_java is set to newState.
1543 *
1544 * @returns false if no change was made, otherwise true
1545 */
1546 native boolean updateCompilerThreadCanCallJava(boolean newState);
1547
1548 /**
1549 * Returns the current {@code CompileBroker} compilation activity mode which is one of:
1550 * {@code stop_compilation = 0}, {@code run_compilation = 1} or {@code shutdown_compilation = 2}
1551 */
1552 native int getCompilationActivityMode();
1553
1554 /**
1555 * Returns whether the current thread is a CompilerThread.
1556 */
1557 native boolean isCompilerThread();
1558 }