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 }