# HG changeset patch # User twisti # Date 1393283282 28800 # Node ID 1f34717ccaface2e8ff5926dcda6b8a8cb17aa68 # Parent 134491e79cde217b48942bae3ecd6292b91a5321 remove CompilerToVM.getInstanceFields diff -r 134491e79cde -r 1f34717ccafa graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedJavaFieldTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedJavaFieldTest.java Mon Feb 24 15:06:07 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotResolvedJavaFieldTest.java Mon Feb 24 15:08:02 2014 -0800 @@ -58,8 +58,7 @@ } /** - * Tests that - * {@link HotSpotResolvedObjectType#createField(String, JavaType, long, int, boolean)} always + * Tests that {@link HotSpotResolvedObjectType#createField(String, JavaType, long, int)} always * returns the same object for an internal field. */ @Test @@ -69,7 +68,7 @@ for (ResolvedJavaField field : type.getInstanceFields(false)) { if (field.isInternal()) { HotSpotResolvedJavaField expected = (HotSpotResolvedJavaField) field; - ResolvedJavaField actual = type.createField(expected.getName(), expected.getType(), expected.offset(), expected.getModifiers(), expected.isInternal()); + ResolvedJavaField actual = type.createField(expected.getName(), expected.getType(), expected.offset(), expected.getModifiers()); Assert.assertEquals(expected, actual); } } diff -r 134491e79cde -r 1f34717ccafa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Mon Feb 24 15:06:07 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Mon Feb 24 15:08:02 2014 -0800 @@ -806,6 +806,43 @@ @HotSpotVMField(name = "Klass::_secondary_super_cache", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int secondarySuperCacheOffset; @HotSpotVMField(name = "Klass::_secondary_supers", type = "Array*", get = HotSpotVMField.Type.OFFSET) @Stable public int secondarySupersOffset; + /** + * The offset of the _java_mirror field (of type {@link Class}) in a Klass. + */ + @HotSpotVMField(name = "Klass::_java_mirror", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int classMirrorOffset; + + @HotSpotVMField(name = "Klass::_super", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int klassSuperKlassOffset; + @HotSpotVMField(name = "Klass::_modifier_flags", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassModifierFlagsOffset; + @HotSpotVMField(name = "Klass::_access_flags", type = "AccessFlags", get = HotSpotVMField.Type.OFFSET) @Stable public int klassAccessFlagsOffset; + @HotSpotVMField(name = "Klass::_layout_helper", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassLayoutHelperOffset; + @HotSpotVMField(name = "Klass::_layout_helper", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassInstanceSizeOffset; + + @HotSpotVMConstant(name = "Klass::_lh_neutral_value") @Stable public int klassLayoutHelperNeutralValue; + @HotSpotVMConstant(name = "Klass::_lh_instance_slow_path_bit") @Stable public int klassLayoutHelperInstanceSlowPathBit; + @HotSpotVMConstant(name = "Klass::_lh_log2_element_size_shift") @Stable public int layoutHelperLog2ElementSizeShift; + @HotSpotVMConstant(name = "Klass::_lh_log2_element_size_mask") @Stable public int layoutHelperLog2ElementSizeMask; + @HotSpotVMConstant(name = "Klass::_lh_element_type_shift") @Stable public int layoutHelperElementTypeShift; + @HotSpotVMConstant(name = "Klass::_lh_element_type_mask") @Stable public int layoutHelperElementTypeMask; + @HotSpotVMConstant(name = "Klass::_lh_header_size_shift") @Stable public int layoutHelperHeaderSizeShift; + @HotSpotVMConstant(name = "Klass::_lh_header_size_mask") @Stable public int layoutHelperHeaderSizeMask; + @HotSpotVMConstant(name = "Klass::_lh_array_tag_shift") @Stable public int layoutHelperArrayTagShift; + @HotSpotVMConstant(name = "Klass::_lh_array_tag_type_value") @Stable public int layoutHelperArrayTagTypeValue; + @HotSpotVMConstant(name = "Klass::_lh_array_tag_obj_value") @Stable public int layoutHelperArrayTagObjectValue; + + /** + * This filters out the bit that differentiates a type array from an object array. + */ + public int layoutHelperElementTypePrimitiveInPlace() { + return (layoutHelperArrayTagTypeValue & ~layoutHelperArrayTagObjectValue) << layoutHelperArrayTagShift; + } + + /** + * Bit pattern in the klass layout helper that can be used to identify arrays. + */ + public final int arrayKlassLayoutHelperIdentifier = 0x80000000; + + @HotSpotVMField(name = "ArrayKlass::_component_mirror", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayKlassComponentMirrorOffset; + @HotSpotVMType(name = "vtableEntry", get = HotSpotVMType.Type.SIZE) @Stable public int vtableEntrySize; @HotSpotVMField(name = "vtableEntry::_method", type = "Method*", get = HotSpotVMField.Type.OFFSET) @Stable public int vtableEntryMethodOffset; @Stable public int instanceKlassVtableStartOffset; @@ -817,18 +854,34 @@ @HotSpotVMField(name = "Array::_length", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayU1LengthOffset; @HotSpotVMField(name = "Array::_data", type = "", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayU1DataOffset; + @HotSpotVMField(name = "Array::_data", type = "", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayU2DataOffset; @HotSpotVMField(name = "Array::_length", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int metaspaceArrayLengthOffset; @HotSpotVMField(name = "Array::_data[0]", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int metaspaceArrayBaseOffset; @HotSpotVMField(name = "InstanceKlass::_source_file_name_index", type = "u2", get = HotSpotVMField.Type.OFFSET) @Stable public int klassSourceFileNameIndexOffset; @HotSpotVMField(name = "InstanceKlass::_init_state", type = "u1", get = HotSpotVMField.Type.OFFSET) @Stable public int klassStateOffset; @HotSpotVMField(name = "InstanceKlass::_constants", type = "ConstantPool*", get = HotSpotVMField.Type.OFFSET) @Stable public int instanceKlassConstantsOffset; + @HotSpotVMField(name = "InstanceKlass::_fields", type = "Array*", get = HotSpotVMField.Type.OFFSET) @Stable public int instanceKlassFieldsOffset; @HotSpotVMConstant(name = "InstanceKlass::linked") @Stable public int klassStateLinked; @HotSpotVMConstant(name = "InstanceKlass::fully_initialized") @Stable public int klassStateFullyInitialized; @HotSpotVMField(name = "ObjArrayKlass::_element_klass", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayClassElementOffset; + @HotSpotVMConstant(name = "FieldInfo::access_flags_offset") @Stable public int fieldInfoAccessFlagsOffset; + @HotSpotVMConstant(name = "FieldInfo::name_index_offset") @Stable public int fieldInfoNameIndexOffset; + @HotSpotVMConstant(name = "FieldInfo::signature_index_offset") @Stable public int fieldInfoSignatureIndexOffset; + @HotSpotVMConstant(name = "FieldInfo::initval_index_offset") @Stable public int fieldInfoInitvalIndexOffset; + @HotSpotVMConstant(name = "FieldInfo::low_packed_offset") @Stable public int fieldInfoLowPackedOffset; + @HotSpotVMConstant(name = "FieldInfo::high_packed_offset") @Stable public int fieldInfoHighPackedOffset; + @HotSpotVMConstant(name = "FieldInfo::field_slots") @Stable public int fieldInfoFieldSlots; + + @HotSpotVMConstant(name = "FIELDINFO_TAG_SIZE") @Stable public int fieldInfoTagSize; + + @HotSpotVMConstant(name = "JVM_ACC_FIELD_INTERNAL") @Stable public int jvmAccFieldInternal; + @HotSpotVMConstant(name = "JVM_ACC_FIELD_STABLE") @Stable public int jvmAccFieldStable; + @HotSpotVMConstant(name = "JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE") @Stable public int jvmAccFieldHasGenericSignature; + @HotSpotVMField(name = "Thread::_tlab", type = "ThreadLocalAllocBuffer", get = HotSpotVMField.Type.OFFSET) @Stable public int threadTlabOffset; @HotSpotVMField(name = "JavaThread::_anchor", type = "JavaFrameAnchor", get = HotSpotVMField.Type.OFFSET) @Stable public int javaThreadAnchorOffset; @@ -909,6 +962,8 @@ return javaThreadAnchorOffset + javaFrameAnchorFlagsOffset; } + @HotSpotVMConstant(name = "frame::arg_reg_save_area_bytes", archs = {"amd64"}) @Stable public int runtimeCallStackSize; + @HotSpotVMField(name = "PtrQueue::_active", type = "bool", get = HotSpotVMField.Type.OFFSET) @Stable public int ptrQueueActiveOffset; @HotSpotVMField(name = "PtrQueue::_buf", type = "void**", get = HotSpotVMField.Type.OFFSET) @Stable public int ptrQueueBufferOffset; @HotSpotVMField(name = "PtrQueue::_index", type = "size_t", get = HotSpotVMField.Type.OFFSET) @Stable public int ptrQueueIndexOffset; @@ -1028,9 +1083,14 @@ @HotSpotVMConstant(name = "HeapWordSize") @Stable public int heapWordSize; + @HotSpotVMType(name = "Symbol*", get = HotSpotVMType.Type.SIZE) @Stable public int symbolPointerSize; @HotSpotVMField(name = "Symbol::_length", type = "unsigned short", get = HotSpotVMField.Type.OFFSET) @Stable public int symbolLengthOffset; @HotSpotVMField(name = "Symbol::_body[0]", type = "jbyte", get = HotSpotVMField.Type.OFFSET) @Stable public int symbolBodyOffset; + @HotSpotVMField(name = "vmSymbols::_symbols[0]", type = "Symbol*", get = HotSpotVMField.Type.ADDRESS) @Stable public long vmSymbolsSymbols; + @HotSpotVMConstant(name = "vmSymbols::FIRST_SID") @Stable public int vmSymbolsFirstSID; + @HotSpotVMConstant(name = "vmSymbols::SID_LIMIT") @Stable public int vmSymbolsSIDLimit; + @HotSpotVMConstant(name = "JVM_ACC_HAS_FINALIZER") @Stable public int klassHasFinalizerFlag; // Modifier.SYNTHETIC is not public so we get it via vmStructs. @@ -1118,40 +1178,6 @@ return javaThreadSatbMarkQueueOffset + ptrQueueBufferOffset; } - /** - * The offset of the _java_mirror field (of type {@link Class}) in a Klass. - */ - @HotSpotVMField(name = "Klass::_java_mirror", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int classMirrorOffset; - - @HotSpotVMConstant(name = "frame::arg_reg_save_area_bytes", archs = {"amd64"}) @Stable public int runtimeCallStackSize; - - @HotSpotVMField(name = "Klass::_super", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int klassSuperKlassOffset; - @HotSpotVMField(name = "Klass::_modifier_flags", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassModifierFlagsOffset; - @HotSpotVMField(name = "Klass::_access_flags", type = "AccessFlags", get = HotSpotVMField.Type.OFFSET) @Stable public int klassAccessFlagsOffset; - @HotSpotVMField(name = "Klass::_layout_helper", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassLayoutHelperOffset; - @HotSpotVMField(name = "Klass::_layout_helper", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int klassInstanceSizeOffset; - - @HotSpotVMConstant(name = "Klass::_lh_neutral_value") @Stable public int klassLayoutHelperNeutralValue; - @HotSpotVMConstant(name = "Klass::_lh_instance_slow_path_bit") @Stable public int klassLayoutHelperInstanceSlowPathBit; - @HotSpotVMConstant(name = "Klass::_lh_log2_element_size_shift") @Stable public int layoutHelperLog2ElementSizeShift; - @HotSpotVMConstant(name = "Klass::_lh_log2_element_size_mask") @Stable public int layoutHelperLog2ElementSizeMask; - @HotSpotVMConstant(name = "Klass::_lh_element_type_shift") @Stable public int layoutHelperElementTypeShift; - @HotSpotVMConstant(name = "Klass::_lh_element_type_mask") @Stable public int layoutHelperElementTypeMask; - @HotSpotVMConstant(name = "Klass::_lh_header_size_shift") @Stable public int layoutHelperHeaderSizeShift; - @HotSpotVMConstant(name = "Klass::_lh_header_size_mask") @Stable public int layoutHelperHeaderSizeMask; - @HotSpotVMConstant(name = "Klass::_lh_array_tag_shift") @Stable public int layoutHelperArrayTagShift; - @HotSpotVMConstant(name = "Klass::_lh_array_tag_type_value") @Stable public int layoutHelperArrayTagTypeValue; - @HotSpotVMConstant(name = "Klass::_lh_array_tag_obj_value") @Stable public int layoutHelperArrayTagObjectValue; - - /** - * This filters out the bit that differentiates a type array from an object array. - */ - public int layoutHelperElementTypePrimitiveInPlace() { - return (layoutHelperArrayTagTypeValue & ~layoutHelperArrayTagObjectValue) << layoutHelperArrayTagShift; - } - - @HotSpotVMField(name = "ArrayKlass::_component_mirror", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int arrayKlassComponentMirrorOffset; - @HotSpotVMField(name = "java_lang_Class::_klass_offset", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int klassOffset; @HotSpotVMField(name = "java_lang_Class::_array_klass_offset", type = "int", get = HotSpotVMField.Type.VALUE) @Stable public int arrayKlassOffset; diff -r 134491e79cde -r 1f34717ccafa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVmSymbols.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVmSymbols.java Mon Feb 24 15:08:02 2014 -0800 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot; + +import static com.oracle.graal.graph.UnsafeAccess.*; +import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; +import sun.misc.*; + +/** + * Class to access the C++ {@code vmSymbols} table. + */ +public final class HotSpotVmSymbols { + + /** + * Returns the {@link HotSpotSymbol} in the {@code vmSymbols} table at position {@code index} as + * {@link String}. + * + * @param index position in the symbol table + * @return the symbol at position id + */ + public static String symbolAt(int index) { + HotSpotVMConfig config = runtime().getConfig(); + assert config.vmSymbolsFirstSID <= index && index < config.vmSymbolsSIDLimit : "index " + index + " is out of bounds"; + assert config.symbolPointerSize == Unsafe.ADDRESS_SIZE : "the following address read is broken"; + final long metaspaceSymbol = unsafe.getAddress(config.vmSymbolsSymbols + index * config.symbolPointerSize); + return new HotSpotSymbol(metaspaceSymbol).asString(); + } +} diff -r 134491e79cde -r 1f34717ccafa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Mon Feb 24 15:06:07 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Mon Feb 24 15:08:02 2014 -0800 @@ -204,8 +204,6 @@ long resolveMethod(HotSpotResolvedObjectType klass, String name, String signature); - HotSpotResolvedJavaField[] getInstanceFields(HotSpotResolvedObjectType klass); - long getClassInitializer(HotSpotResolvedObjectType klass); boolean hasFinalizableSubclass(HotSpotResolvedObjectType klass); diff -r 134491e79cde -r 1f34717ccafa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Mon Feb 24 15:06:07 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Mon Feb 24 15:08:02 2014 -0800 @@ -92,9 +92,6 @@ public native void initializeMethod(long metaspaceMethod, HotSpotResolvedJavaMethod method); @Override - public native HotSpotResolvedJavaField[] getInstanceFields(HotSpotResolvedObjectType klass); - - @Override public native long getClassInitializer(HotSpotResolvedObjectType klass); @Override diff -r 134491e79cde -r 1f34717ccafa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Mon Feb 24 15:06:07 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Mon Feb 24 15:08:02 2014 -0800 @@ -579,7 +579,7 @@ public JavaField createJavaField(JavaType holder, String name, JavaType type, int offset, int flags, boolean internal) { if (offset != -1) { HotSpotResolvedObjectType resolved = (HotSpotResolvedObjectType) holder; - return resolved.createField(name, type, offset, flags, internal); + return resolved.createField(name, type, offset, flags); } return new HotSpotUnresolvedField(holder, name, type); } diff -r 134491e79cde -r 1f34717ccafa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java Mon Feb 24 15:06:07 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java Mon Feb 24 15:08:02 2014 -0800 @@ -112,14 +112,13 @@ // are not used (yet). final int modifiers = reflectionField.getModifiers(); final long offset = Modifier.isStatic(modifiers) ? unsafe.staticFieldOffset(reflectionField) : unsafe.objectFieldOffset(reflectionField); - final boolean internal = false; ResolvedJavaType holder = HotSpotResolvedObjectType.fromClass(fieldHolder); ResolvedJavaType type = HotSpotResolvedObjectType.fromClass(fieldType); if (offset != -1) { HotSpotResolvedObjectType resolved = (HotSpotResolvedObjectType) holder; - return resolved.createField(name, type, offset, modifiers, internal); + return resolved.createField(name, type, offset, modifiers); } else { // TODO this cast will not succeed return (ResolvedJavaField) new HotSpotUnresolvedField(holder, name, type); diff -r 134491e79cde -r 1f34717ccafa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Mon Feb 24 15:06:07 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Mon Feb 24 15:08:02 2014 -0800 @@ -46,10 +46,6 @@ */ public class HotSpotResolvedJavaField extends CompilerObject implements ResolvedJavaField { - // Must not conflict with any fields flags used by the VM - the assertion in the constructor - // checks this assumption - private static final int FIELD_INTERNAL_FLAG = 0x80000000; - private static final long serialVersionUID = 7692985878836955683L; private final HotSpotResolvedObjectType holder; private final String name; @@ -61,32 +57,29 @@ * The {@linkplain HotSpotResolvedObjectType#getReflectionFieldModifiers() reflection} modifiers * for this field plus the {@link #FIELD_INTERNAL_FLAG} if it applies. */ - private final int modifiersWithInternal; + /** + * This value contains all flags as stored in the VM including internal ones. + */ + private final int modifiers; - public HotSpotResolvedJavaField(HotSpotResolvedObjectType holder, String name, JavaType type, long offset, int modifiers, boolean internal) { - assert (modifiers & FIELD_INTERNAL_FLAG) == 0; - assert (modifiers & ~getReflectionFieldModifiers()) == 0; + public HotSpotResolvedJavaField(HotSpotResolvedObjectType holder, String name, JavaType type, long offset, int modifiers) { this.holder = holder; this.name = name; this.type = type; assert offset != -1; assert offset == (int) offset : "offset larger than int"; this.offset = (int) offset; - if (internal) { - this.modifiersWithInternal = modifiers | FIELD_INTERNAL_FLAG; - } else { - this.modifiersWithInternal = modifiers; - } + this.modifiers = modifiers; } @Override public int getModifiers() { - return modifiersWithInternal & getReflectionFieldModifiers(); + return modifiers & getReflectionFieldModifiers(); } @Override public boolean isInternal() { - return (modifiersWithInternal & FIELD_INTERNAL_FLAG) != 0; + return (modifiers & runtime().getConfig().jvmAccFieldInternal) != 0; } /** @@ -188,7 +181,7 @@ assert !ImmutableCode.getValue() || isCalledForSnippets() : receiver; if (receiver == null) { - assert isStatic(modifiersWithInternal); + assert isStatic(modifiers); if (constant == null) { if (holder.isInitialized() && !holder.getName().equals(SystemClassName) && isEmbeddable()) { if (Modifier.isFinal(getModifiers())) { @@ -202,7 +195,7 @@ * for non-static final fields, we must assume that they are only initialized if they * have a non-default value. */ - assert !isStatic(modifiersWithInternal); + assert !isStatic(modifiers); Object object = receiver.asObject(); // Canonicalization may attempt to process an unsafe read before @@ -239,7 +232,7 @@ * {@code object}'s class */ public boolean isInObject(Object object) { - if (isStatic(modifiersWithInternal)) { + if (isStatic(modifiers)) { return false; } return getDeclaringClass().isAssignableFrom(HotSpotResolvedObjectType.fromClass(object.getClass())); @@ -248,13 +241,13 @@ @Override public Constant readValue(Constant receiver) { if (receiver == null) { - assert isStatic(modifiersWithInternal); + assert isStatic(modifiers); if (holder.isInitialized()) { return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), holder.mirror(), offset, getKind() == Kind.Object); } return null; } else { - assert !isStatic(modifiersWithInternal); + assert !isStatic(modifiers); Object object = receiver.asObject(); assert object != null && isInObject(object); return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), object, offset, getKind() == Kind.Object); @@ -310,7 +303,7 @@ @Override public boolean isSynthetic() { - return (runtime().getConfig().syntheticFlag & modifiersWithInternal) != 0; + return (runtime().getConfig().syntheticFlag & modifiers) != 0; } /** diff -r 134491e79cde -r 1f34717ccafa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Mon Feb 24 15:06:07 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Mon Feb 24 15:08:02 2014 -0800 @@ -53,7 +53,7 @@ */ private NodeClass nodeClass; - private HashMap fieldCache; + private HashMap fieldCache; private HashMap methodCache; private HotSpotResolvedJavaField[] instanceFields; private ResolvedJavaType[] interfaces; @@ -427,12 +427,12 @@ return runtime().getConfig().recognizedFieldModifiers; } - public synchronized ResolvedJavaField createField(String fieldName, JavaType type, long offset, int rawFlags, boolean internal) { - ResolvedJavaField result = null; + public synchronized HotSpotResolvedJavaField createField(String fieldName, JavaType type, long offset, int rawFlags) { + HotSpotResolvedJavaField result = null; - int flags = rawFlags & getReflectionFieldModifiers(); + final int flags = rawFlags & getReflectionFieldModifiers(); - long id = offset + ((long) flags << 32); + final long id = offset + ((long) flags << 32); // (thomaswue) Must cache the fields, because the local load elimination only works if the // objects from two field lookups are identical. @@ -443,10 +443,12 @@ } if (result == null) { - result = new HotSpotResolvedJavaField(this, fieldName, type, offset, flags, internal); + result = new HotSpotResolvedJavaField(this, fieldName, type, offset, rawFlags); fieldCache.put(id, result); } else { assert result.getName().equals(fieldName); + // assert result.getType().equals(type); + assert result.offset() == offset; assert result.getModifiers() == flags; } @@ -458,8 +460,134 @@ return ((HotSpotResolvedJavaMethod) method).uniqueConcreteMethod(); } + /** + * This class represents the field information for one field contained in the fields array of an + * {@code InstanceKlass}. The implementation is similar to the native {@code FieldInfo} class. + */ + private class FieldInfo { + /** + * Native pointer into the array of Java shorts. + */ + private final long metaspaceData; + + /** + * Creates a field info for the field in the fields array at index {@code index}. + * + * @param index index to the fields array + */ + public FieldInfo(int index) { + HotSpotVMConfig config = runtime().getConfig(); + // Get Klass::_fields + final long metaspaceFields = unsafe.getAddress(metaspaceKlass() + config.instanceKlassFieldsOffset); + assert config.fieldInfoFieldSlots == 6 : "revisit the field parsing code"; + metaspaceData = metaspaceFields + config.arrayU2DataOffset + config.fieldInfoFieldSlots * 2 * index; // TODO + // Short.BYTES + } + + private int getAccessFlags() { + return readFieldSlot(runtime().getConfig().fieldInfoAccessFlagsOffset); + } + + private int getNameIndex() { + return readFieldSlot(runtime().getConfig().fieldInfoNameIndexOffset); + } + + private int getSignatureIndex() { + return readFieldSlot(runtime().getConfig().fieldInfoSignatureIndexOffset); + } + + public int getOffset() { + HotSpotVMConfig config = runtime().getConfig(); + final int lowPacked = readFieldSlot(config.fieldInfoLowPackedOffset); + final int highPacked = readFieldSlot(config.fieldInfoHighPackedOffset); + final int offset = ((highPacked << Short.SIZE) | lowPacked) >> config.fieldInfoTagSize; + return offset; + } + + /** + * Helper method to read an entry (slot) from the field array. Currently field info is laid + * on top an array of Java shorts. + */ + private int readFieldSlot(int index) { + return unsafe.getChar(metaspaceData + 2 * index); // TODO Short.BYTES + } + + /** + * Returns the name of this field as a {@link String}. If the field is an internal field the + * name index is pointing into the vmSymbols table. + */ + public String getName() { + final int nameIndex = getNameIndex(); + return isInternal() ? HotSpotVmSymbols.symbolAt(nameIndex) : constantPool().lookupUtf8(nameIndex); + } + + /** + * Returns the signature of this field as {@link String}. If the field is an internal field + * the signature index is pointing into the vmSymbols table. + */ + public String getSignature() { + final int signatureIndex = getSignatureIndex(); + return isInternal() ? HotSpotVmSymbols.symbolAt(signatureIndex) : constantPool().lookupUtf8(signatureIndex); + } + + public JavaType getType() { + String signature = getSignature(); + Kind kind = Kind.fromTypeString(signature); + + JavaType type; + if (kind.isPrimitive()) { + type = HotSpotResolvedPrimitiveType.fromKind(kind); + } else { + String signatureClass = getNameForClassForName(signature); + Class c = null; + try { + // This class is the accessing class so we use its classloader. + c = Class.forName(signatureClass, false, mirror().getClassLoader()); + } catch (ClassNotFoundException e) { + throw new GraalInternalError(e); + } + if (c == null) { + type = runtime().getVMToCompiler().createUnresolvedJavaType(signature); + } else { + type = HotSpotResolvedObjectType.fromClass(c); + } + } + return type; + } + + /** + * Returns a name that is suitable to be passed to {@link Class#forName}. + */ + private String getNameForClassForName(String name) { + // If this is an array type just return it. + if (name.charAt(0) == '[') { + return name.replace('/', '.'); + } + + // Decode name if necessary. + if (name.charAt(name.length() - 1) == ';') { + assert name.charAt(0) == 'L'; + return name.substring(1, name.length() - 1).replace('/', '.'); + } + + // Primitive type name. + return name; + } + + private boolean isInternal() { + return (getAccessFlags() & runtime().getConfig().jvmAccFieldInternal) != 0; + } + + public boolean isStatic() { + return Modifier.isStatic(getAccessFlags()); + } + + public boolean hasGenericSignature() { + return (getAccessFlags() & runtime().getConfig().jvmAccFieldHasGenericSignature) != 0; + } + } + private static class OffsetComparator implements Comparator { - @Override public int compare(HotSpotResolvedJavaField o1, HotSpotResolvedJavaField o2) { return o1.offset() - o2.offset(); @@ -472,8 +600,24 @@ if (isArray() || isInterface()) { instanceFields = new HotSpotResolvedJavaField[0]; } else { - HotSpotResolvedJavaField[] myFields = runtime().getCompilerToVM().getInstanceFields(this); - Arrays.sort(myFields, new OffsetComparator()); + final int fieldCount = getFieldCount(); + ArrayList fieldsArray = new ArrayList<>(fieldCount); + + for (int i = 0; i < fieldCount; i++) { + FieldInfo field = new FieldInfo(i); + + // We are only interested in instance fields. + if (!field.isStatic()) { + HotSpotResolvedJavaField resolvedJavaField = createField(field.getName(), field.getType(), field.getOffset(), field.getAccessFlags()); + fieldsArray.add(resolvedJavaField); + } + } + + // TODO use in 1.8: fieldsArray.sort(new OffsetComparator()); + Collections.sort(fieldsArray, new OffsetComparator()); + + HotSpotResolvedJavaField[] myFields = fieldsArray.toArray(new HotSpotResolvedJavaField[0]); + if (javaClass != Object.class) { HotSpotResolvedJavaField[] superFields = (HotSpotResolvedJavaField[]) getSuperclass().getInstanceFields(true); HotSpotResolvedJavaField[] fields = Arrays.copyOf(superFields, superFields.length + myFields.length); @@ -483,6 +627,7 @@ assert myFields.length == 0 : "java.lang.Object has fields!"; instanceFields = myFields; } + } } if (!includeSuperclasses) { @@ -501,6 +646,29 @@ return instanceFields; } + /** + * Returns the actual field count of this class's internal {@code InstanceKlass::_fields} array + * by walking the array and discounting the generic signature slots at the end of the array. + * + *

+ * See {@code FieldStreamBase::init_generic_signature_start_slot} + */ + private int getFieldCount() { + HotSpotVMConfig config = runtime().getConfig(); + final long metaspaceFields = unsafe.getAddress(metaspaceKlass() + config.instanceKlassFieldsOffset); + int metaspaceFieldsLength = unsafe.getInt(metaspaceFields + config.arrayU1LengthOffset); + int fieldCount = 0; + + for (int i = 0, index = 0; i < metaspaceFieldsLength; i += config.fieldInfoFieldSlots, index++) { + FieldInfo field = new FieldInfo(index); + if (field.hasGenericSignature()) { + metaspaceFieldsLength--; + } + fieldCount++; + } + return fieldCount; + } + @Override public Class mirror() { return javaClass; diff -r 134491e79cde -r 1f34717ccafa src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Mon Feb 24 15:06:07 2014 +0100 +++ b/src/share/vm/classfile/systemDictionary.hpp Mon Feb 24 15:08:02 2014 -0800 @@ -197,8 +197,6 @@ do_klass(HotSpotInstalledCode_klass, com_oracle_graal_hotspot_meta_HotSpotInstalledCode, Opt) \ do_klass(HotSpotNmethod_klass, com_oracle_graal_hotspot_meta_HotSpotNmethod, Opt) \ do_klass(HotSpotJavaType_klass, com_oracle_graal_hotspot_meta_HotSpotJavaType, Opt) \ - do_klass(HotSpotMethodData_klass, com_oracle_graal_hotspot_meta_HotSpotMethodData, Opt) \ - do_klass(HotSpotResolvedJavaField_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedJavaField, Opt) \ do_klass(HotSpotResolvedJavaMethod_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethod, Opt) \ do_klass(HotSpotResolvedObjectType_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedObjectType, Opt) \ do_klass(HotSpotMonitorValue_klass, com_oracle_graal_hotspot_meta_HotSpotMonitorValue, Opt) \ diff -r 134491e79cde -r 1f34717ccafa src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Mon Feb 24 15:06:07 2014 +0100 +++ b/src/share/vm/classfile/vmSymbols.hpp Mon Feb 24 15:08:02 2014 -0800 @@ -308,8 +308,6 @@ template(com_oracle_graal_hotspot_meta_HotSpotInstalledCode, "com/oracle/graal/hotspot/meta/HotSpotInstalledCode") \ template(com_oracle_graal_hotspot_meta_HotSpotNmethod, "com/oracle/graal/hotspot/meta/HotSpotNmethod") \ template(com_oracle_graal_hotspot_meta_HotSpotJavaType, "com/oracle/graal/hotspot/meta/HotSpotJavaType") \ - template(com_oracle_graal_hotspot_meta_HotSpotMethodData, "com/oracle/graal/hotspot/meta/HotSpotMethodData") \ - template(com_oracle_graal_hotspot_meta_HotSpotResolvedJavaField, "com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField") \ template(com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethod, "com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod") \ template(com_oracle_graal_hotspot_meta_HotSpotResolvedObjectType, "com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType") \ template(com_oracle_graal_hotspot_meta_HotSpotMonitorValue, "com/oracle/graal/hotspot/meta/HotSpotMonitorValue") \ diff -r 134491e79cde -r 1f34717ccafa src/share/vm/graal/graalCompiler.cpp --- a/src/share/vm/graal/graalCompiler.cpp Mon Feb 24 15:06:07 2014 +0100 +++ b/src/share/vm/graal/graalCompiler.cpp Mon Feb 24 15:08:02 2014 -0800 @@ -259,11 +259,6 @@ } } -Handle GraalCompiler::get_JavaField(int offset, int flags, Symbol* field_name, Handle field_holder, Handle field_type, TRAPS) { - Handle name = java_lang_String::create_from_symbol(field_name, CHECK_NH); - return VMToCompiler::createJavaField(field_holder, name, field_type, offset, flags, false, CHECK_NH); -} - BasicType GraalCompiler::kindToBasicType(jchar ch) { switch(ch) { case 'z': return T_BOOLEAN; diff -r 134491e79cde -r 1f34717ccafa src/share/vm/graal/graalCompiler.hpp --- a/src/share/vm/graal/graalCompiler.hpp Mon Feb 24 15:06:07 2014 +0100 +++ b/src/share/vm/graal/graalCompiler.hpp Mon Feb 24 15:08:02 2014 -0800 @@ -73,7 +73,6 @@ static Handle get_JavaTypeFromSignature(Symbol* signature, KlassHandle accessor, TRAPS); static Handle get_JavaType(constantPoolHandle cp, int index, KlassHandle accessor, TRAPS); - static Handle get_JavaField(int offset, int flags, Symbol* field_name, Handle field_holder, Handle field_type, TRAPS); void exit(); diff -r 134491e79cde -r 1f34717ccafa src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Mon Feb 24 15:06:07 2014 +0100 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Mon Feb 24 15:08:02 2014 -0800 @@ -352,7 +352,8 @@ } Handle type = GraalCompiler::get_JavaTypeFromSignature(signature, cp->pool_holder(), CHECK_NULL); - Handle field_handle = GraalCompiler::get_JavaField(offset, flags.as_int(), name, holder, type, THREAD); + Handle java_name = java_lang_String::create_from_symbol(name, CHECK_NULL); + Handle field_handle = VMToCompiler::createJavaField(holder, java_name, type, offset, flags.as_int(), false, CHECK_NULL); return JNIHandles::make_local(THREAD, field_handle()); C2V_END @@ -379,29 +380,6 @@ return Dependencies::find_finalizable_subclass(klass) != NULL; C2V_END -C2V_VMENTRY(jobject, getInstanceFields, (JNIEnv *, jobject, jobject klass)) - ResourceMark rm; - - instanceKlassHandle k = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(klass)); - GrowableArray fields(k->java_fields_count()); - - for (AllFieldStream fs(k()); !fs.done(); fs.next()) { - if (!fs.access_flags().is_static()) { - Handle type = GraalCompiler::get_JavaTypeFromSignature(fs.signature(), k, THREAD); - int flags = fs.access_flags().as_int(); - bool internal = fs.access_flags().is_internal(); - Handle name = java_lang_String::create_from_symbol(fs.name(), THREAD); - Handle field = VMToCompiler::createJavaField(JNIHandles::resolve(klass), name, type, fs.offset(), flags, internal, THREAD); - fields.append(field()); - } - } - objArrayHandle field_array = oopFactory::new_objArray(SystemDictionary::HotSpotResolvedJavaField_klass(), fields.length(), CHECK_NULL); - for (int i = 0; i < fields.length(); ++i) { - field_array->obj_at_put(i, fields.at(i)()); - } - return JNIHandles::make_local(THREAD, field_array()); -C2V_END - C2V_VMENTRY(jlong, getClassInitializer, (JNIEnv *, jobject, jobject klass)) instanceKlassHandle k(THREAD, java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(klass))); Method* clinit = k->class_initializer(); @@ -869,7 +847,6 @@ #define STACK_TRACE_ELEMENT "Ljava/lang/StackTraceElement;" #define HS_RESOLVED_TYPE "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedObjectType;" #define HS_RESOLVED_METHOD "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;" -#define HS_RESOLVED_FIELD "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaField;" #define HS_COMPILED_CODE "Lcom/oracle/graal/hotspot/HotSpotCompiledCode;" #define HS_CONFIG "Lcom/oracle/graal/hotspot/HotSpotVMConfig;" #define HS_INSTALLED_CODE "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;" @@ -898,7 +875,6 @@ {CC"lookupReferencedTypeInPool", CC"("METASPACE_CONSTANT_POOL"IB)V", FN_PTR(lookupReferencedTypeInPool)}, {CC"lookupFieldInPool", CC"("METASPACE_CONSTANT_POOL"IB)"FIELD, FN_PTR(lookupFieldInPool)}, {CC"resolveMethod", CC"("HS_RESOLVED_TYPE STRING STRING")"METASPACE_METHOD, FN_PTR(resolveMethod)}, - {CC"getInstanceFields", CC"("HS_RESOLVED_TYPE")["HS_RESOLVED_FIELD, FN_PTR(getInstanceFields)}, {CC"getClassInitializer", CC"("HS_RESOLVED_TYPE")"METASPACE_METHOD, FN_PTR(getClassInitializer)}, {CC"hasFinalizableSubclass", CC"("HS_RESOLVED_TYPE")Z", FN_PTR(hasFinalizableSubclass)}, {CC"getMaxCallTargetOffset", CC"(J)J", FN_PTR(getMaxCallTargetOffset)}, diff -r 134491e79cde -r 1f34717ccafa src/share/vm/runtime/vmStructs.cpp --- a/src/share/vm/runtime/vmStructs.cpp Mon Feb 24 15:06:07 2014 +0100 +++ b/src/share/vm/runtime/vmStructs.cpp Mon Feb 24 15:08:02 2014 -0800 @@ -2340,6 +2340,9 @@ declare_constant(JVM_ACC_PROMOTED_FLAGS) \ declare_constant(JVM_ACC_FIELD_ACCESS_WATCHED) \ declare_constant(JVM_ACC_FIELD_MODIFICATION_WATCHED) \ + declare_constant(JVM_ACC_FIELD_INTERNAL) \ + declare_constant(JVM_ACC_FIELD_STABLE) \ + declare_constant(JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE) \ \ declare_constant(JVM_CONSTANT_Utf8) \ declare_constant(JVM_CONSTANT_Unicode) \