# HG changeset patch # User dnsimon # Date 1542834137 -3600 # Node ID 74cf02d5f6e20e820c82236a9d457674bd2e86ce # Parent 43efb4ca6d6c76dac00a57f2b812d6e54a5c67e5 8213907: [JVMCI] avoid Class.getDeclared* methods when converting JVMCI objects to reflection objects Reviewed-by: kvn, never diff -r 43efb4ca6d6c -r 74cf02d5f6e2 src/hotspot/share/jvmci/jvmciCompilerToVM.cpp --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Wed Nov 21 12:36:16 2018 -0800 +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Wed Nov 21 22:02:17 2018 +0100 @@ -1498,6 +1498,38 @@ } C2V_END +C2V_VMENTRY(jobject, asReflectionExecutable, (JNIEnv* env, jobject, jobject jvmci_method)) + methodHandle m = CompilerToVM::asMethod(jvmci_method); + oop executable; + if (m->is_initializer()) { + if (m->is_static_initializer()) { + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), + "Cannot create java.lang.reflect.Method for class initializer"); + } + executable = Reflection::new_constructor(m, CHECK_NULL); + } else { + executable = Reflection::new_method(m, false, CHECK_NULL); + } + return JNIHandles::make_local(thread, executable); +} + +C2V_VMENTRY(jobject, asReflectionField, (JNIEnv* env, jobject, jobject jvmci_type, jint index)) + Klass* klass = CompilerToVM::asKlass(jvmci_type); + if (!klass->is_instance_klass()) { + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), + err_msg("Expected non-primitive type, got %s", klass->external_name())); + } + InstanceKlass* iklass = InstanceKlass::cast(klass); + Array* fields = iklass->fields(); + if (index < 0 || index > fields->length()) { + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), + err_msg("Field index %d out of bounds for %s", index, klass->external_name())); + } + fieldDescriptor fd(iklass, index); + oop reflected = Reflection::new_field(&fd, CHECK_NULL); + return JNIHandles::make_local(env, reflected); +} + #define CC (char*) /*cast a literal from (const char*)*/ #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f)) @@ -1519,6 +1551,8 @@ #define HS_METADATA "Ljdk/vm/ci/hotspot/HotSpotMetaData;" #define HS_STACK_FRAME_REF "Ljdk/vm/ci/hotspot/HotSpotStackFrameReference;" #define HS_SPECULATION_LOG "Ljdk/vm/ci/hotspot/HotSpotSpeculationLog;" +#define REFLECTION_EXECUTABLE "Ljava/lang/reflect/Executable;" +#define REFLECTION_FIELD "Ljava/lang/reflect/Field;" #define METASPACE_METHOD_DATA "J" JNINativeMethod CompilerToVM::methods[] = { @@ -1586,6 +1620,8 @@ {CC "interpreterFrameSize", CC "(" BYTECODE_FRAME ")I", FN_PTR(interpreterFrameSize)}, {CC "compileToBytecode", CC "(" OBJECT ")V", FN_PTR(compileToBytecode)}, {CC "getFlagValue", CC "(" STRING ")" OBJECT, FN_PTR(getFlagValue)}, + {CC "asReflectionExecutable", CC "(" HS_RESOLVED_METHOD ")" REFLECTION_EXECUTABLE, FN_PTR(asReflectionExecutable)}, + {CC "asReflectionField", CC "(" HS_RESOLVED_KLASS "I)" REFLECTION_FIELD, FN_PTR(asReflectionField)}, }; int CompilerToVM::methods_count() { diff -r 43efb4ca6d6c -r 74cf02d5f6e2 src/hotspot/share/jvmci/jvmciCompilerToVM.hpp --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp Wed Nov 21 12:36:16 2018 -0800 +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp Wed Nov 21 22:02:17 2018 +0100 @@ -91,6 +91,7 @@ static HeapWord** _heap_end_addr; static HeapWord* volatile* _heap_top_addr; static int _max_oop_map_stack_offset; + static int _fields_annotations_base_offset; static jbyte* cardtable_start_address; static int cardtable_shift; @@ -101,7 +102,6 @@ static int sizeof_ExceptionTableElement; static int sizeof_LocalVariableTableElement; static int sizeof_ConstantPool; - static int sizeof_SymbolPointer; static int sizeof_narrowKlass; static int sizeof_arrayOopDesc; static int sizeof_BasicLock; diff -r 43efb4ca6d6c -r 74cf02d5f6e2 src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp --- a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp Wed Nov 21 12:36:16 2018 -0800 +++ b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp Wed Nov 21 22:02:17 2018 +0100 @@ -61,6 +61,7 @@ HeapWord** CompilerToVM::Data::_heap_end_addr; HeapWord* volatile* CompilerToVM::Data::_heap_top_addr; int CompilerToVM::Data::_max_oop_map_stack_offset; +int CompilerToVM::Data::_fields_annotations_base_offset; jbyte* CompilerToVM::Data::cardtable_start_address; int CompilerToVM::Data::cardtable_shift; @@ -71,7 +72,6 @@ int CompilerToVM::Data::sizeof_ExceptionTableElement = sizeof(ExceptionTableElement); int CompilerToVM::Data::sizeof_LocalVariableTableElement = sizeof(LocalVariableTableElement); int CompilerToVM::Data::sizeof_ConstantPool = sizeof(ConstantPool); -int CompilerToVM::Data::sizeof_SymbolPointer = sizeof(Symbol*); int CompilerToVM::Data::sizeof_narrowKlass = sizeof(narrowKlass); int CompilerToVM::Data::sizeof_arrayOopDesc = sizeof(arrayOopDesc); int CompilerToVM::Data::sizeof_BasicLock = sizeof(BasicLock); @@ -122,6 +122,8 @@ symbol_init = (address) vmSymbols::object_initializer_name(); symbol_clinit = (address) vmSymbols::class_initializer_name(); + _fields_annotations_base_offset = Array::base_offset_in_bytes(); + BarrierSet* bs = BarrierSet::barrier_set(); if (bs->is_a(BarrierSet::CardTableBarrierSet)) { jbyte* base = ci_card_table_address(); diff -r 43efb4ca6d6c -r 74cf02d5f6e2 src/hotspot/share/jvmci/vmStructs_jvmci.cpp --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp Wed Nov 21 12:36:16 2018 -0800 +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp Wed Nov 21 22:02:17 2018 +0100 @@ -76,6 +76,7 @@ static_field(CompilerToVM::Data, _heap_top_addr, HeapWord* volatile*) \ \ static_field(CompilerToVM::Data, _max_oop_map_stack_offset, int) \ + static_field(CompilerToVM::Data, _fields_annotations_base_offset, int) \ \ static_field(CompilerToVM::Data, cardtable_start_address, jbyte*) \ static_field(CompilerToVM::Data, cardtable_shift, int) \ @@ -86,7 +87,6 @@ static_field(CompilerToVM::Data, sizeof_ExceptionTableElement, int) \ static_field(CompilerToVM::Data, sizeof_LocalVariableTableElement, int) \ static_field(CompilerToVM::Data, sizeof_ConstantPool, int) \ - static_field(CompilerToVM::Data, sizeof_SymbolPointer, int) \ static_field(CompilerToVM::Data, sizeof_narrowKlass, int) \ static_field(CompilerToVM::Data, sizeof_arrayOopDesc, int) \ static_field(CompilerToVM::Data, sizeof_BasicLock, int) \ @@ -104,6 +104,8 @@ \ static_field(Abstract_VM_Version, _features, uint64_t) \ \ + nonstatic_field(Annotations, _fields_annotations, Array*) \ + \ nonstatic_field(Array, _length, int) \ unchecked_nonstatic_field(Array, _data, sizeof(u1)) \ unchecked_nonstatic_field(Array, _data, sizeof(u2)) \ @@ -164,6 +166,7 @@ nonstatic_field(InstanceKlass, _source_file_name_index, u2) \ nonstatic_field(InstanceKlass, _init_state, u1) \ nonstatic_field(InstanceKlass, _misc_flags, u2) \ + nonstatic_field(InstanceKlass, _annotations, Annotations*) \ \ volatile_nonstatic_field(JavaFrameAnchor, _last_Java_sp, intptr_t*) \ volatile_nonstatic_field(JavaFrameAnchor, _last_Java_pc, address) \ @@ -462,6 +465,8 @@ declare_constant(ConstMethod::_has_linenumber_table) \ declare_constant(ConstMethod::_has_localvariable_table) \ declare_constant(ConstMethod::_has_exception_table) \ + declare_constant(ConstMethod::_has_method_annotations) \ + declare_constant(ConstMethod::_has_parameter_annotations) \ \ declare_constant(CounterData::count_off) \ \ diff -r 43efb4ca6d6c -r 74cf02d5f6e2 src/hotspot/share/oops/annotations.hpp --- a/src/hotspot/share/oops/annotations.hpp Wed Nov 21 12:36:16 2018 -0800 +++ b/src/hotspot/share/oops/annotations.hpp Wed Nov 21 22:02:17 2018 +0100 @@ -42,6 +42,8 @@ // a type_annotation instance. class Annotations: public MetaspaceObj { + friend class JVMCIVMStructs; + // If you add a new field that points to any metaspace object, you // must add this field to Annotations::metaspace_pointers_do(). diff -r 43efb4ca6d6c -r 74cf02d5f6e2 src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Wed Nov 21 12:36:16 2018 -0800 +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Wed Nov 21 22:02:17 2018 +0100 @@ -27,6 +27,7 @@ import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; import java.lang.reflect.Executable; +import java.lang.reflect.Field; import jdk.vm.ci.code.BytecodeFrame; import jdk.vm.ci.code.InstalledCode; @@ -657,4 +658,17 @@ * Gets the host class for {@code type}. */ native HotSpotResolvedObjectTypeImpl getHostClass(HotSpotResolvedObjectTypeImpl type); + + /** + * Gets a {@link Executable} corresponding to {@code method}. + */ + native Executable asReflectionExecutable(HotSpotResolvedJavaMethodImpl method); + + /** + * Gets a {@link Field} denoted by {@code holder} and {@code index}. + * + * @param holder the class in which the requested field is declared + * @param fieldIndex the {@code fieldDescriptor::index()} denoting the field + */ + native Field asReflectionField(HotSpotResolvedObjectTypeImpl holder, int fieldIndex); } diff -r 43efb4ca6d6c -r 74cf02d5f6e2 src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java Wed Nov 21 12:36:16 2018 -0800 +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java Wed Nov 21 22:02:17 2018 +0100 @@ -22,11 +22,15 @@ */ package jdk.vm.ci.hotspot; +import static jdk.internal.misc.Unsafe.ADDRESS_SIZE; +import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; import static jdk.vm.ci.hotspot.HotSpotModifiers.jvmFieldModifiers; import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; +import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; import java.lang.annotation.Annotation; import java.lang.reflect.Field; +import java.util.HashMap; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaType; @@ -156,41 +160,65 @@ return (config().jvmAccFieldStable & modifiers) != 0; } + private boolean hasAnnotations() { + if (!isInternal()) { + HotSpotVMConfig config = config(); + final long metaspaceAnnotations = UNSAFE.getAddress(holder.getMetaspaceKlass() + config.instanceKlassAnnotationsOffset); + if (metaspaceAnnotations != 0) { + long fieldsAnnotations = UNSAFE.getAddress(metaspaceAnnotations + config.annotationsFieldAnnotationsOffset); + if (fieldsAnnotations != 0) { + long fieldAnnotations = UNSAFE.getAddress(fieldsAnnotations + config.fieldsAnnotationsBaseOffset + (ADDRESS_SIZE * index)); + return fieldAnnotations != 0; + } + } + } + return false; + } + @Override public Annotation[] getAnnotations() { - Field javaField = toJava(); - if (javaField != null) { - return javaField.getAnnotations(); + if (!hasAnnotations()) { + return new Annotation[0]; } - return new Annotation[0]; + return toJava().getAnnotations(); } @Override public Annotation[] getDeclaredAnnotations() { - Field javaField = toJava(); - if (javaField != null) { - return javaField.getDeclaredAnnotations(); + if (!hasAnnotations()) { + return new Annotation[0]; } - return new Annotation[0]; + return toJava().getDeclaredAnnotations(); } @Override public T getAnnotation(Class annotationClass) { - Field javaField = toJava(); - if (javaField != null) { - return javaField.getAnnotation(annotationClass); + if (!hasAnnotations()) { + return null; } - return null; + return toJava().getAnnotation(annotationClass); } + /** + * Gets a {@link Field} object corresponding to this object. This method always returns the same + * {@link Field} object for a given {@link HotSpotResolvedJavaFieldImpl}. This ensures + * {@link #getDeclaredAnnotations()}, {@link #getAnnotations()} and + * {@link #getAnnotation(Class)} are stable with respect to the identity of the + * {@link Annotation} objects they return. + */ private Field toJava() { - if (isInternal()) { - return null; - } - try { - return holder.mirror().getDeclaredField(getName()); - } catch (NoSuchFieldException e) { - return null; + synchronized (holder) { + HashMap cache = holder.reflectionFieldCache; + if (cache == null) { + cache = new HashMap<>(); + holder.reflectionFieldCache = cache; + } + Field reflect = cache.get(this); + if (reflect == null) { + reflect = compilerToVM().asReflectionField(holder, index); + cache.put(this, reflect); + } + return reflect; } } } diff -r 43efb4ca6d6c -r 74cf02d5f6e2 src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java Wed Nov 21 12:36:16 2018 -0800 +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java Wed Nov 21 22:02:17 2018 +0100 @@ -33,10 +33,8 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Executable; -import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Type; -import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -54,7 +52,6 @@ import jdk.vm.ci.meta.ProfilingInfo; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.meta.Signature; import jdk.vm.ci.meta.SpeculationLog; import jdk.vm.ci.meta.TriState; @@ -75,11 +72,9 @@ private byte[] code; /** - * Cache for {@link #toJava()}. Set to {@link #signature} when resolving reflection object fails - * due to reflection filtering (see {@code Reflection.fieldFilterMap} and - * {@code Reflection.methodFilterMap}). + * Cache for {@link #toJava()}. */ - private Object toJavaCache; + private volatile Executable toJavaCache; /** * Only 30% of {@link HotSpotResolvedJavaMethodImpl}s have their name accessed so compute it @@ -492,12 +487,10 @@ @Override public Parameter[] getParameters() { - Executable javaMethod = toJava(); - if (javaMethod == null) { - return null; + if (signature.getParameterCount(false) == 0) { + return new ResolvedJavaMethod.Parameter[0]; } - - java.lang.reflect.Parameter[] javaParameters = javaMethod.getParameters(); + java.lang.reflect.Parameter[] javaParameters = toJava().getParameters(); Parameter[] res = new Parameter[javaParameters.length]; for (int i = 0; i < res.length; i++) { java.lang.reflect.Parameter src = javaParameters[i]; @@ -509,32 +502,34 @@ @Override public Annotation[][] getParameterAnnotations() { - Executable javaMethod = toJava(); - return javaMethod == null ? new Annotation[signature.getParameterCount(false)][0] : javaMethod.getParameterAnnotations(); + if ((getConstMethodFlags() & config().constMethodHasParameterAnnotations) == 0) { + return new Annotation[signature.getParameterCount(false)][0]; + } + return toJava().getParameterAnnotations(); } @Override public Annotation[] getAnnotations() { - Executable javaMethod = toJava(); - if (javaMethod != null) { - return javaMethod.getAnnotations(); + if ((getConstMethodFlags() & config().constMethodHasMethodAnnotations) == 0) { + return new Annotation[0]; } - return new Annotation[0]; + return toJava().getAnnotations(); } @Override public Annotation[] getDeclaredAnnotations() { - Executable javaMethod = toJava(); - if (javaMethod != null) { - return javaMethod.getDeclaredAnnotations(); + if ((getConstMethodFlags() & config().constMethodHasMethodAnnotations) == 0) { + return new Annotation[0]; } - return new Annotation[0]; + return toJava().getDeclaredAnnotations(); } @Override public T getAnnotation(Class annotationClass) { - Executable javaMethod = toJava(); - return javaMethod == null ? null : javaMethod.getAnnotation(annotationClass); + if ((getConstMethodFlags() & config().constMethodHasMethodAnnotations) == 0) { + return null; + } + return toJava().getAnnotation(annotationClass); } @Override @@ -561,60 +556,22 @@ @Override public Type[] getGenericParameterTypes() { - Executable javaMethod = toJava(); - return javaMethod == null ? null : javaMethod.getGenericParameterTypes(); - } - - public Class[] signatureToTypes() { - Signature sig = getSignature(); - int count = sig.getParameterCount(false); - Class[] result = new Class[count]; - for (int i = 0; i < result.length; ++i) { - JavaType parameterType = sig.getParameterType(i, holder); - HotSpotResolvedJavaType resolvedParameterType = (HotSpotResolvedJavaType) parameterType.resolve(holder); - result[i] = resolvedParameterType.mirror(); + if (isClassInitializer()) { + return new Type[0]; } - return result; - } - - private static Method searchMethods(Method[] methods, String name, Class returnType, Class[] parameterTypes) { - for (Method m : methods) { - if (m.getName().equals(name) && returnType.equals(m.getReturnType()) && Arrays.equals(m.getParameterTypes(), parameterTypes)) { - return m; - } - } - return null; + return toJava().getGenericParameterTypes(); } private Executable toJava() { - if (toJavaCache != null) { - if (toJavaCache == signature) { - return null; - } - return (Executable) toJavaCache; - } - Class[] parameterTypes = signatureToTypes(); - Class returnType = ((HotSpotResolvedJavaType) getSignature().getReturnType(holder).resolve(holder)).mirror(); - - Executable result; - if (isConstructor()) { - try { - result = holder.mirror().getDeclaredConstructor(parameterTypes); - } catch (NoSuchMethodException e) { - toJavaCache = signature; - return null; - } - } else { - // Do not use Method.getDeclaredMethod() as it can return a bridge method - // when this.isBridge() is false and vice versa. - result = searchMethods(holder.mirror().getDeclaredMethods(), getName(), returnType, parameterTypes); - if (result == null) { - toJavaCache = signature; - return null; + if (toJavaCache == null) { + assert !isClassInitializer() : this; + synchronized (this) { + if (toJavaCache == null) { + toJavaCache = compilerToVM().asReflectionExecutable(this); + } } } - toJavaCache = result; - return result; + return toJavaCache; } @Override diff -r 43efb4ca6d6c -r 74cf02d5f6e2 src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Wed Nov 21 12:36:16 2018 -0800 +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Wed Nov 21 22:02:17 2018 +0100 @@ -33,6 +33,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Array; import java.lang.reflect.Constructor; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.nio.ByteOrder; @@ -75,6 +76,11 @@ private HotSpotResolvedObjectType arrayOfType; /** + * Managed exclusively by {@link HotSpotResolvedJavaFieldImpl#toJava}. + */ + HashMap reflectionFieldCache; + + /** * Gets the JVMCI mirror for a {@link Class} object. * * @return the {@link HotSpotResolvedJavaType} corresponding to {@code javaClass} diff -r 43efb4ca6d6c -r 74cf02d5f6e2 src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java Wed Nov 21 12:36:16 2018 -0800 +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java Wed Nov 21 22:02:17 2018 +0100 @@ -94,6 +94,7 @@ final int instanceKlassInitStateOffset = getFieldOffset("InstanceKlass::_init_state", Integer.class, "u1"); final int instanceKlassConstantsOffset = getFieldOffset("InstanceKlass::_constants", Integer.class, "ConstantPool*"); final int instanceKlassFieldsOffset = getFieldOffset("InstanceKlass::_fields", Integer.class, "Array*"); + final int instanceKlassAnnotationsOffset = getFieldOffset("InstanceKlass::_annotations", Integer.class, "Annotations*"); final int instanceKlassMiscFlagsOffset = getFieldOffset("InstanceKlass::_misc_flags", Integer.class, "u2"); final int klassVtableStartOffset = getFieldValue("CompilerToVM::Data::Klass_vtable_start_offset", Integer.class, "int"); final int klassVtableLengthOffset = getFieldValue("CompilerToVM::Data::Klass_vtable_length_offset", Integer.class, "int"); @@ -102,6 +103,9 @@ final int instanceKlassStateFullyInitialized = getConstant("InstanceKlass::fully_initialized", Integer.class); final int instanceKlassMiscIsUnsafeAnonymous = getConstant("InstanceKlass::_misc_is_unsafe_anonymous", Integer.class); + final int annotationsFieldAnnotationsOffset = getFieldOffset("Annotations::_fields_annotations", Integer.class, "Array*"); + final int fieldsAnnotationsBaseOffset = getFieldValue("CompilerToVM::Data::_fields_annotations_base_offset", Integer.class, "int"); + final int arrayU1LengthOffset = getFieldOffset("Array::_length", Integer.class, "int"); final int arrayU1DataOffset = getFieldOffset("Array::_data", Integer.class); final int arrayU2DataOffset = getFieldOffset("Array::_data", Integer.class); @@ -195,6 +199,8 @@ final int constMethodHasLineNumberTable = getConstant("ConstMethod::_has_linenumber_table", Integer.class); final int constMethodHasLocalVariableTable = getConstant("ConstMethod::_has_localvariable_table", Integer.class); + final int constMethodHasMethodAnnotations = getConstant("ConstMethod::_has_method_annotations", Integer.class); + final int constMethodHasParameterAnnotations = getConstant("ConstMethod::_has_parameter_annotations", Integer.class); final int constMethodHasExceptionTable = getConstant("ConstMethod::_has_exception_table", Integer.class); final int exceptionTableElementSize = getFieldValue("CompilerToVM::Data::sizeof_ExceptionTableElement", Integer.class, "int"); @@ -244,8 +250,6 @@ final int heapWordSize = getConstant("HeapWordSize", Integer.class); - final int symbolPointerSize = getFieldValue("CompilerToVM::Data::sizeof_SymbolPointer", Integer.class, "int"); - final long vmSymbolsSymbols = getFieldAddress("vmSymbols::_symbols[0]", "Symbol*"); final int vmSymbolsFirstSID = getConstant("vmSymbols::FIRST_SID", Integer.class); final int vmSymbolsSIDLimit = getConstant("vmSymbols::SID_LIMIT", Integer.class); @@ -263,8 +267,7 @@ String symbolAt(int index) { HotSpotJVMCIRuntime runtime = runtime(); assert vmSymbolsFirstSID <= index && index < vmSymbolsSIDLimit : "index " + index + " is out of bounds"; - assert symbolPointerSize == Unsafe.ADDRESS_SIZE : "the following address read is broken"; - int offset = index * symbolPointerSize; + int offset = index * Unsafe.ADDRESS_SIZE; return runtime.getCompilerToVM().getSymbol(UNSAFE.getAddress(vmSymbolsSymbols + offset)); } diff -r 43efb4ca6d6c -r 74cf02d5f6e2 test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java Wed Nov 21 12:36:16 2018 -0800 +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java Wed Nov 21 22:02:17 2018 +0100 @@ -142,16 +142,15 @@ } } } + + private static final String NON_EXISTENT_CLASS_NAME = "XXXXXXXXXXX"; + static class TestClassLoader extends ClassLoader { @Override - protected Class findClass(final String name) { + protected Class findClass(final String name) throws ClassNotFoundException { if (!name.equals(TypeWithUnresolvedFieldType.class.getName())) { - try { - return super.findClass(name); - } catch (ClassNotFoundException e) { - throw new AssertionError("unexpected: " + e); - } + return super.findClass(name); } // copy classfile to byte array byte[] classData = null; @@ -176,7 +175,7 @@ int index = -1; while ((index = indexOf(classData, index + 1, "PrintStream")) != -1) { - replace(classData, index, "XXXXXXXXXXX"); + replace(classData, index, NON_EXISTENT_CLASS_NAME); } Class c = defineClass(null, classData, 0, classData.length); @@ -211,13 +210,14 @@ * type of the field is not resolvable. */ @Test - public void testGetType() { + public void testGetType() throws ClassNotFoundException { Class c = new TestClassLoader().findClass(TypeWithUnresolvedFieldType.class.getName()); ResolvedJavaType type = metaAccess.lookupJavaType(c); for (ResolvedJavaField field : type.getInstanceFields(false)) { assertTrue(field.getName().equals("fieldWithUnresolvableType")); field.getType(); field.toString(); + field.getAnnotations(); } } } diff -r 43efb4ca6d6c -r 74cf02d5f6e2 test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java Wed Nov 21 12:36:16 2018 -0800 +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java Wed Nov 21 22:02:17 2018 +0100 @@ -855,17 +855,25 @@ } + private static ResolvedJavaMethod getClassInitializer(Class c) { + ResolvedJavaMethod clinit = metaAccess.lookupJavaType(c).getClassInitializer(); + if (clinit != null) { + assertEquals(0, clinit.getAnnotations().length); + assertEquals(0, clinit.getDeclaredAnnotations().length); + } + return clinit; + } + @Test public void getClassInitializerTest() { - assertNotNull(metaAccess.lookupJavaType(A.class).getClassInitializer()); - assertNotNull(metaAccess.lookupJavaType(D.class).getClassInitializer()); - assertNull(metaAccess.lookupJavaType(B.class).getClassInitializer()); - assertNull(metaAccess.lookupJavaType(C.class).getClassInitializer()); - assertNull(metaAccess.lookupJavaType(int.class).getClassInitializer()); - assertNull(metaAccess.lookupJavaType(void.class).getClassInitializer()); + assertNotNull(getClassInitializer(A.class)); + assertNotNull(getClassInitializer(D.class)); + assertNull(getClassInitializer(B.class)); + assertNull(getClassInitializer(C.class)); + assertNull(getClassInitializer(int.class)); + assertNull(getClassInitializer(void.class)); for (Class c : classes) { - ResolvedJavaType type = metaAccess.lookupJavaType(c); - type.getClassInitializer(); + getClassInitializer(c); } }