src/share/vm/classfile/classFileParser.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 7086585 Cdiff src/share/vm/classfile/classFileParser.cpp

src/share/vm/classfile/classFileParser.cpp

Print this page

        

*** 34,43 **** --- 34,44 ---- #include "memory/allocation.hpp" #include "memory/gcLocker.hpp" #include "memory/oopFactory.hpp" #include "memory/universe.inline.hpp" #include "oops/constantPoolOop.hpp" + #include "oops/fieldStreams.hpp" #include "oops/instanceKlass.hpp" #include "oops/instanceMirrorKlass.hpp" #include "oops/klass.inline.hpp" #include "oops/klassOop.hpp" #include "oops/klassVtable.hpp"
*** 989,1034 **** enum FieldAllocationType { STATIC_OOP, // Oops STATIC_BYTE, // Boolean, Byte, char STATIC_SHORT, // shorts STATIC_WORD, // ints ! STATIC_DOUBLE, // long or double ! STATIC_ALIGNED_DOUBLE,// aligned long or double NONSTATIC_OOP, NONSTATIC_BYTE, NONSTATIC_SHORT, NONSTATIC_WORD, NONSTATIC_DOUBLE, ! NONSTATIC_ALIGNED_DOUBLE }; ! struct FieldAllocationCount { ! unsigned int static_oop_count; ! unsigned int static_byte_count; ! unsigned int static_short_count; ! unsigned int static_word_count; ! unsigned int static_double_count; ! unsigned int nonstatic_oop_count; ! unsigned int nonstatic_byte_count; ! unsigned int nonstatic_short_count; ! unsigned int nonstatic_word_count; ! unsigned int nonstatic_double_count; }; ! typeArrayHandle ClassFileParser::parse_fields(constantPoolHandle cp, bool is_interface, ! struct FieldAllocationCount *fac, ! objArrayHandle* fields_annotations, TRAPS) { ClassFileStream* cfs = stream(); typeArrayHandle nullHandle; cfs->guarantee_more(2, CHECK_(nullHandle)); // length u2 length = cfs->get_u2_fast(); // Tuples of shorts [access, name index, sig index, initial value index, byte offset, generic signature index] ! typeArrayOop new_fields = oopFactory::new_permanent_shortArray(length*instanceKlass::next_offset, CHECK_(nullHandle)); typeArrayHandle fields(THREAD, new_fields); - int index = 0; typeArrayHandle field_annotations; for (int n = 0; n < length; n++) { cfs->guarantee_more(8, CHECK_(nullHandle)); // access_flags, name_index, descriptor_index, attributes_count AccessFlags access_flags; --- 990,1091 ---- enum FieldAllocationType { STATIC_OOP, // Oops STATIC_BYTE, // Boolean, Byte, char STATIC_SHORT, // shorts STATIC_WORD, // ints ! STATIC_DOUBLE, // aligned long or double NONSTATIC_OOP, NONSTATIC_BYTE, NONSTATIC_SHORT, NONSTATIC_WORD, NONSTATIC_DOUBLE, ! MAX_FIELD_ALLOCATION_TYPE, ! BAD_ALLOCATION_TYPE = -1 }; + static FieldAllocationType _basic_type_to_atype[2 * (T_CONFLICT + 1)] = { + BAD_ALLOCATION_TYPE, // 0 + BAD_ALLOCATION_TYPE, // 1 + BAD_ALLOCATION_TYPE, // 2 + BAD_ALLOCATION_TYPE, // 3 + NONSTATIC_BYTE , // T_BOOLEAN = 4, + NONSTATIC_SHORT, // T_CHAR = 5, + NONSTATIC_WORD, // T_FLOAT = 6, + NONSTATIC_DOUBLE, // T_DOUBLE = 7, + NONSTATIC_BYTE, // T_BYTE = 8, + NONSTATIC_SHORT, // T_SHORT = 9, + NONSTATIC_WORD, // T_INT = 10, + NONSTATIC_DOUBLE, // T_LONG = 11, + NONSTATIC_OOP, // T_OBJECT = 12, + NONSTATIC_OOP, // T_ARRAY = 13, + BAD_ALLOCATION_TYPE, // T_VOID = 14, + BAD_ALLOCATION_TYPE, // T_ADDRESS = 15, + BAD_ALLOCATION_TYPE, // T_NARROWOOP= 16, + BAD_ALLOCATION_TYPE, // T_CONFLICT = 17, + BAD_ALLOCATION_TYPE, // 0 + BAD_ALLOCATION_TYPE, // 1 + BAD_ALLOCATION_TYPE, // 2 + BAD_ALLOCATION_TYPE, // 3 + STATIC_BYTE , // T_BOOLEAN = 4, + STATIC_SHORT, // T_CHAR = 5, + STATIC_WORD, // T_FLOAT = 6, + STATIC_DOUBLE, // T_DOUBLE = 7, + STATIC_BYTE, // T_BYTE = 8, + STATIC_SHORT, // T_SHORT = 9, + STATIC_WORD, // T_INT = 10, + STATIC_DOUBLE, // T_LONG = 11, + STATIC_OOP, // T_OBJECT = 12, + STATIC_OOP, // T_ARRAY = 13, + BAD_ALLOCATION_TYPE, // T_VOID = 14, + BAD_ALLOCATION_TYPE, // T_ADDRESS = 15, + BAD_ALLOCATION_TYPE, // T_NARROWOOP= 16, + BAD_ALLOCATION_TYPE, // T_CONFLICT = 17, + }; ! static FieldAllocationType basic_type_to_atype(bool is_static, BasicType type) { ! assert(type >= T_BOOLEAN && type < T_VOID, "only allowable values"); ! FieldAllocationType result = _basic_type_to_atype[type + (is_static ? (T_CONFLICT + 1) : 0)]; ! assert(result != BAD_ALLOCATION_TYPE, "bad type"); ! return result; ! } ! ! class FieldAllocationCount: public ResourceObj { ! public: ! unsigned int count[MAX_FIELD_ALLOCATION_TYPE]; ! ! FieldAllocationCount() { ! for (int i = 0; i < MAX_FIELD_ALLOCATION_TYPE; i++) { ! count[i] = 0; ! } ! } ! ! FieldAllocationType update(bool is_static, BasicType type) { ! FieldAllocationType atype = basic_type_to_atype(is_static, type); ! count[atype]++; ! return atype; ! } }; ! ! typeArrayHandle ClassFileParser::parse_fields(Symbol* class_name, ! constantPoolHandle cp, bool is_interface, ! FieldAllocationCount *fac, ! objArrayHandle* fields_annotations, ! int* java_fields_count_ptr, TRAPS) { ClassFileStream* cfs = stream(); typeArrayHandle nullHandle; cfs->guarantee_more(2, CHECK_(nullHandle)); // length u2 length = cfs->get_u2_fast(); + *java_fields_count_ptr = length; + + int num_injected = 0; + InjectedField* injected = JavaClasses::get_injected(class_name, &num_injected); + // Tuples of shorts [access, name index, sig index, initial value index, byte offset, generic signature index] ! typeArrayOop new_fields = oopFactory::new_permanent_shortArray((length + num_injected) * FieldInfo::field_slots, CHECK_(nullHandle)); typeArrayHandle fields(THREAD, new_fields); typeArrayHandle field_annotations; for (int n = 0; n < length; n++) { cfs->guarantee_more(8, CHECK_(nullHandle)); // access_flags, name_index, descriptor_index, attributes_count AccessFlags access_flags;
*** 1075,1187 **** if (is_synthetic) { access_flags.set_is_synthetic(); } } ! fields->short_at_put(index++, access_flags.as_short()); ! fields->short_at_put(index++, name_index); ! fields->short_at_put(index++, signature_index); ! fields->short_at_put(index++, constantvalue_index); - // Remember how many oops we encountered and compute allocation type BasicType type = cp->basic_type_for_signature_at(signature_index); ! FieldAllocationType atype; ! if ( is_static ) { ! switch ( type ) { ! case T_BOOLEAN: ! case T_BYTE: ! fac->static_byte_count++; ! atype = STATIC_BYTE; ! break; ! case T_LONG: ! case T_DOUBLE: ! if (Universe::field_type_should_be_aligned(type)) { ! atype = STATIC_ALIGNED_DOUBLE; ! } else { ! atype = STATIC_DOUBLE; } ! fac->static_double_count++; break; - case T_CHAR: - case T_SHORT: - fac->static_short_count++; - atype = STATIC_SHORT; - break; - case T_FLOAT: - case T_INT: - fac->static_word_count++; - atype = STATIC_WORD; - break; - case T_ARRAY: - case T_OBJECT: - fac->static_oop_count++; - atype = STATIC_OOP; - break; - case T_ADDRESS: - case T_VOID: - default: - assert(0, "bad field type"); } - } else { - switch ( type ) { - case T_BOOLEAN: - case T_BYTE: - fac->nonstatic_byte_count++; - atype = NONSTATIC_BYTE; - break; - case T_LONG: - case T_DOUBLE: - if (Universe::field_type_should_be_aligned(type)) { - atype = NONSTATIC_ALIGNED_DOUBLE; - } else { - atype = NONSTATIC_DOUBLE; } ! fac->nonstatic_double_count++; ! break; ! case T_CHAR: ! case T_SHORT: ! fac->nonstatic_short_count++; ! atype = NONSTATIC_SHORT; ! break; ! case T_FLOAT: ! case T_INT: ! fac->nonstatic_word_count++; ! atype = NONSTATIC_WORD; ! break; ! case T_ARRAY: ! case T_OBJECT: ! fac->nonstatic_oop_count++; ! atype = NONSTATIC_OOP; ! break; ! case T_ADDRESS: ! case T_VOID: ! default: ! assert(0, "bad field type"); } } // The correct offset is computed later (all oop fields will be located together) // We temporarily store the allocation type in the offset field ! fields->short_at_put(index++, atype); ! fields->short_at_put(index++, 0); // Clear out high word of byte offset ! fields->short_at_put(index++, generic_signature_index); } if (_need_verify && length > 1) { // Check duplicated fields ResourceMark rm(THREAD); NameSigHash** names_and_sigs = NEW_RESOURCE_ARRAY_IN_THREAD( THREAD, NameSigHash*, HASH_ROW_SIZE); initialize_hashtable(names_and_sigs); bool dup = false; { debug_only(No_Safepoint_Verifier nsv;) ! for (int i = 0; i < length*instanceKlass::next_offset; i += instanceKlass::next_offset) { ! int name_index = fields->ushort_at(i + instanceKlass::name_index_offset); ! Symbol* name = cp->symbol_at(name_index); ! int sig_index = fields->ushort_at(i + instanceKlass::signature_index_offset); ! Symbol* sig = cp->symbol_at(sig_index); // If no duplicates, add name/signature in hashtable names_and_sigs. if (!put_after_lookup(name, sig, names_and_sigs)) { dup = true; break; } --- 1132,1226 ---- if (is_synthetic) { access_flags.set_is_synthetic(); } } ! FieldInfo* field = FieldInfo::from_field_array(fields(), n); ! field->initialize(access_flags.as_short(), ! name_index, ! signature_index, ! constantvalue_index, ! generic_signature_index, ! 0); BasicType type = cp->basic_type_for_signature_at(signature_index); ! ! // Remember how many oops we encountered and compute allocation type ! FieldAllocationType atype = fac->update(is_static, type); ! ! // The correct offset is computed later (all oop fields will be located together) ! // We temporarily store the allocation type in the offset field ! field->set_offset(atype); } ! ! if (num_injected != 0) { ! int index = length; ! for (int n = 0; n < num_injected; n++) { ! // Check for duplicates ! if (injected[n].may_be_java) { ! Symbol* name = injected[n].name(); ! Symbol* signature = injected[n].signature(); ! bool duplicate = false; ! for (int i = 0; i < length; i++) { ! FieldInfo* f = FieldInfo::from_field_array(fields(), i); ! if (name == cp->symbol_at(f->name_index()) && ! signature == cp->symbol_at(f->signature_index())) { ! // Symbol is desclared in Java so skip this one ! duplicate = true; break; } } ! if (duplicate) { ! // These will be removed from the field array at the end ! continue; } } + // Injected field + FieldInfo* field = FieldInfo::from_field_array(fields(), index); + field->initialize(JVM_ACC_FIELD_INTERNAL, + injected[n].name_index, + injected[n].signature_index, + 0, + 0, + 0); + + BasicType type = FieldType::basic_type(injected[n].signature()); + + // Remember how many oops we encountered and compute allocation type + FieldAllocationType atype = fac->update(false, type); + // The correct offset is computed later (all oop fields will be located together) // We temporarily store the allocation type in the offset field ! field->set_offset(atype); ! index++; } + if (index < length + num_injected) { + // sometimes injected fields already exist in the Java source so + // the fields array could be too long. In that case trim the + // fields array. + new_fields = oopFactory::new_permanent_shortArray(index * FieldInfo::field_slots, CHECK_(nullHandle)); + for (int i = 0; i < index * FieldInfo::field_slots; i++) { + new_fields->short_at_put(i, fields->short_at(i)); + } + fields = new_fields; + } + } + if (_need_verify && length > 1) { // Check duplicated fields ResourceMark rm(THREAD); NameSigHash** names_and_sigs = NEW_RESOURCE_ARRAY_IN_THREAD( THREAD, NameSigHash*, HASH_ROW_SIZE); initialize_hashtable(names_and_sigs); bool dup = false; { debug_only(No_Safepoint_Verifier nsv;) ! for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { ! Symbol* name = fs.name(); ! Symbol* sig = fs.signature(); // If no duplicates, add name/signature in hashtable names_and_sigs. if (!put_after_lookup(name, sig, names_and_sigs)) { dup = true; break; }
*** 2590,2820 **** } return annotations; } - void ClassFileParser::java_lang_ref_Reference_fix_pre(typeArrayHandle* fields_ptr, - constantPoolHandle cp, FieldAllocationCount *fac_ptr, TRAPS) { - // This code is for compatibility with earlier jdk's that do not - // have the "discovered" field in java.lang.ref.Reference. For 1.5 - // the check for the "discovered" field should issue a warning if - // the field is not found. For 1.6 this code should be issue a - // fatal error if the "discovered" field is not found. - // - // Increment fac.nonstatic_oop_count so that the start of the - // next type of non-static oops leaves room for the fake oop. - // Do not increment next_nonstatic_oop_offset so that the - // fake oop is place after the java.lang.ref.Reference oop - // fields. - // - // Check the fields in java.lang.ref.Reference for the "discovered" - // field. If it is not present, artifically create a field for it. - // This allows this VM to run on early JDK where the field is not - // present. - int reference_sig_index = 0; - int reference_name_index = 0; - int reference_index = 0; - int extra = java_lang_ref_Reference::number_of_fake_oop_fields; - const int n = (*fields_ptr)()->length(); - for (int i = 0; i < n; i += instanceKlass::next_offset ) { - int name_index = - (*fields_ptr)()->ushort_at(i + instanceKlass::name_index_offset); - int sig_index = - (*fields_ptr)()->ushort_at(i + instanceKlass::signature_index_offset); - Symbol* f_name = cp->symbol_at(name_index); - Symbol* f_sig = cp->symbol_at(sig_index); - if (f_sig == vmSymbols::reference_signature() && reference_index == 0) { - // Save the index for reference signature for later use. - // The fake discovered field does not entries in the - // constant pool so the index for its signature cannot - // be extracted from the constant pool. It will need - // later, however. It's signature is vmSymbols::reference_signature() - // so same an index for that signature. - reference_sig_index = sig_index; - reference_name_index = name_index; - reference_index = i; - } - if (f_name == vmSymbols::reference_discovered_name() && - f_sig == vmSymbols::reference_signature()) { - // The values below are fake but will force extra - // non-static oop fields and a corresponding non-static - // oop map block to be allocated. - extra = 0; - break; - } - } - if (extra != 0) { - fac_ptr->nonstatic_oop_count += extra; - // Add the additional entry to "fields" so that the klass - // contains the "discoverd" field and the field will be initialized - // in instances of the object. - int fields_with_fix_length = (*fields_ptr)()->length() + - instanceKlass::next_offset; - typeArrayOop ff = oopFactory::new_permanent_shortArray( - fields_with_fix_length, CHECK); - typeArrayHandle fields_with_fix(THREAD, ff); - - // Take everything from the original but the length. - for (int idx = 0; idx < (*fields_ptr)->length(); idx++) { - fields_with_fix->ushort_at_put(idx, (*fields_ptr)->ushort_at(idx)); - } - - // Add the fake field at the end. - int i = (*fields_ptr)->length(); - // There is no name index for the fake "discovered" field nor - // signature but a signature is needed so that the field will - // be properly initialized. Use one found for - // one of the other reference fields. Be sure the index for the - // name is 0. In fieldDescriptor::initialize() the index of the - // name is checked. That check is by passed for the last nonstatic - // oop field in a java.lang.ref.Reference which is assumed to be - // this artificial "discovered" field. An assertion checks that - // the name index is 0. - assert(reference_index != 0, "Missing signature for reference"); - - int j; - for (j = 0; j < instanceKlass::next_offset; j++) { - fields_with_fix->ushort_at_put(i + j, - (*fields_ptr)->ushort_at(reference_index +j)); - } - // Clear the public access flag and set the private access flag. - short flags; - flags = - fields_with_fix->ushort_at(i + instanceKlass::access_flags_offset); - assert(!(flags & JVM_RECOGNIZED_FIELD_MODIFIERS), "Unexpected access flags set"); - flags = flags & (~JVM_ACC_PUBLIC); - flags = flags | JVM_ACC_PRIVATE; - AccessFlags access_flags; - access_flags.set_flags(flags); - assert(!access_flags.is_public(), "Failed to clear public flag"); - assert(access_flags.is_private(), "Failed to set private flag"); - fields_with_fix->ushort_at_put(i + instanceKlass::access_flags_offset, - flags); - - assert(fields_with_fix->ushort_at(i + instanceKlass::name_index_offset) - == reference_name_index, "The fake reference name is incorrect"); - assert(fields_with_fix->ushort_at(i + instanceKlass::signature_index_offset) - == reference_sig_index, "The fake reference signature is incorrect"); - // The type of the field is stored in the low_offset entry during - // parsing. - assert(fields_with_fix->ushort_at(i + instanceKlass::low_offset) == - NONSTATIC_OOP, "The fake reference type is incorrect"); - - // "fields" is allocated in the permanent generation. Disgard - // it and let it be collected. - (*fields_ptr) = fields_with_fix; - } - return; - } - - - void ClassFileParser::java_lang_Class_fix_pre(int* nonstatic_field_size, - FieldAllocationCount *fac_ptr) { - // Add fake fields for java.lang.Class instances - // - // This is not particularly nice. We should consider adding a - // private transient object field at the Java level to - // java.lang.Class. Alternatively we could add a subclass of - // instanceKlass which provides an accessor and size computer for - // this field, but that appears to be more code than this hack. - // - // NOTE that we wedge these in at the beginning rather than the - // end of the object because the Class layout changed between JDK - // 1.3 and JDK 1.4 with the new reflection implementation; some - // nonstatic oop fields were added at the Java level. The offsets - // of these fake fields can't change between these two JDK - // versions because when the offsets are computed at bootstrap - // time we don't know yet which version of the JDK we're running in. - - // The values below are fake but will force three non-static oop fields and - // a corresponding non-static oop map block to be allocated. - const int extra = java_lang_Class::number_of_fake_oop_fields; - fac_ptr->nonstatic_oop_count += extra; - - // Reserve some leading space for fake ints - *nonstatic_field_size += align_size_up(java_lang_Class::hc_number_of_fake_int_fields * BytesPerInt, heapOopSize) / heapOopSize; - } - - - void ClassFileParser::java_lang_Class_fix_post(int* next_nonstatic_oop_offset_ptr) { - // Cause the extra fake fields in java.lang.Class to show up before - // the Java fields for layout compatibility between 1.3 and 1.4 - // Incrementing next_nonstatic_oop_offset here advances the - // location where the real java fields are placed. - const int extra = java_lang_Class::number_of_fake_oop_fields; - (*next_nonstatic_oop_offset_ptr) += (extra * heapOopSize); - } - - - // Force MethodHandle.vmentry to be an unmanaged pointer. - // There is no way for a classfile to express this, so we must help it. - void ClassFileParser::java_lang_invoke_MethodHandle_fix_pre(constantPoolHandle cp, - typeArrayHandle fields, - FieldAllocationCount *fac_ptr, - TRAPS) { - // Add fake fields for java.lang.invoke.MethodHandle instances - // - // This is not particularly nice, but since there is no way to express - // a native wordSize field in Java, we must do it at this level. - - if (!EnableInvokeDynamic) return; - - int word_sig_index = 0; - const int cp_size = cp->length(); - for (int index = 1; index < cp_size; index++) { - if (cp->tag_at(index).is_utf8() && - cp->symbol_at(index) == vmSymbols::machine_word_signature()) { - word_sig_index = index; - break; - } - } - - if (word_sig_index == 0) - THROW_MSG(vmSymbols::java_lang_VirtualMachineError(), - "missing I or J signature (for vmentry) in java.lang.invoke.MethodHandle"); - - // Find vmentry field and change the signature. - bool found_vmentry = false; - for (int i = 0; i < fields->length(); i += instanceKlass::next_offset) { - int name_index = fields->ushort_at(i + instanceKlass::name_index_offset); - int sig_index = fields->ushort_at(i + instanceKlass::signature_index_offset); - int acc_flags = fields->ushort_at(i + instanceKlass::access_flags_offset); - Symbol* f_name = cp->symbol_at(name_index); - Symbol* f_sig = cp->symbol_at(sig_index); - if (f_name == vmSymbols::vmentry_name() && (acc_flags & JVM_ACC_STATIC) == 0) { - if (f_sig == vmSymbols::machine_word_signature()) { - // If the signature of vmentry is already changed, we're done. - found_vmentry = true; - break; - } - else if (f_sig == vmSymbols::byte_signature()) { - // Adjust the field type from byte to an unmanaged pointer. - assert(fac_ptr->nonstatic_byte_count > 0, ""); - fac_ptr->nonstatic_byte_count -= 1; - - fields->ushort_at_put(i + instanceKlass::signature_index_offset, word_sig_index); - assert(wordSize == longSize || wordSize == jintSize, "ILP32 or LP64"); - if (wordSize == longSize) fac_ptr->nonstatic_double_count += 1; - else fac_ptr->nonstatic_word_count += 1; - - FieldAllocationType atype = (FieldAllocationType) fields->ushort_at(i + instanceKlass::low_offset); - assert(atype == NONSTATIC_BYTE, ""); - FieldAllocationType new_atype = (wordSize == longSize) ? NONSTATIC_DOUBLE : NONSTATIC_WORD; - fields->ushort_at_put(i + instanceKlass::low_offset, new_atype); - - found_vmentry = true; - break; - } - } - } - - if (!found_vmentry) - THROW_MSG(vmSymbols::java_lang_VirtualMachineError(), - "missing vmentry byte field in java.lang.invoke.MethodHandle"); - } - - instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, Handle class_loader, Handle protection_domain, KlassHandle host_klass, GrowableArray<Handle>* cp_patches, --- 2629,2638 ----
*** 3023,3036 **** local_interfaces = objArrayHandle(THREAD, Universe::the_empty_system_obj_array()); } else { local_interfaces = parse_interfaces(cp, itfs_len, class_loader, protection_domain, _class_name, CHECK_(nullHandle)); } // Fields (offsets are filled in later) ! struct FieldAllocationCount fac = {0,0,0,0,0,0,0,0,0,0}; objArrayHandle fields_annotations; ! typeArrayHandle fields = parse_fields(cp, access_flags.is_interface(), &fac, &fields_annotations, CHECK_(nullHandle)); // Methods bool has_final_method = false; AccessFlags promoted_flags; promoted_flags.set_flags(0); // These need to be oop pointers because they are allocated lazily --- 2841,2857 ---- local_interfaces = objArrayHandle(THREAD, Universe::the_empty_system_obj_array()); } else { local_interfaces = parse_interfaces(cp, itfs_len, class_loader, protection_domain, _class_name, CHECK_(nullHandle)); } + int java_fields_count = 0; // Fields (offsets are filled in later) ! FieldAllocationCount fac; objArrayHandle fields_annotations; ! typeArrayHandle fields = parse_fields(class_name, cp, access_flags.is_interface(), &fac, &fields_annotations, ! &java_fields_count, ! CHECK_(nullHandle)); // Methods bool has_final_method = false; AccessFlags promoted_flags; promoted_flags.set_flags(0); // These need to be oop pointers because they are allocated lazily
*** 3144,3199 **** int next_nonstatic_field_offset; // Calculate the starting byte offsets next_static_oop_offset = instanceMirrorKlass::offset_of_static_fields(); next_static_double_offset = next_static_oop_offset + ! (fac.static_oop_count * heapOopSize); ! if ( fac.static_double_count && (Universe::field_type_should_be_aligned(T_DOUBLE) || Universe::field_type_should_be_aligned(T_LONG)) ) { next_static_double_offset = align_size_up(next_static_double_offset, BytesPerLong); } next_static_word_offset = next_static_double_offset + ! (fac.static_double_count * BytesPerLong); next_static_short_offset = next_static_word_offset + ! (fac.static_word_count * BytesPerInt); next_static_byte_offset = next_static_short_offset + ! (fac.static_short_count * BytesPerShort); next_static_type_offset = align_size_up((next_static_byte_offset + ! fac.static_byte_count ), wordSize ); static_field_size = (next_static_type_offset - next_static_oop_offset) / wordSize; - // Add fake fields for java.lang.Class instances (also see below) - if (class_name == vmSymbols::java_lang_Class() && class_loader.is_null()) { - java_lang_Class_fix_pre(&nonstatic_field_size, &fac); - } - first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size * heapOopSize; next_nonstatic_field_offset = first_nonstatic_field_offset; ! // adjust the vmentry field declaration in java.lang.invoke.MethodHandle ! if (EnableInvokeDynamic && class_name == vmSymbols::java_lang_invoke_MethodHandle() && class_loader.is_null()) { ! java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle)); ! } - // Add a fake "discovered" field if it is not present - // for compatibility with earlier jdk's. - if (class_name == vmSymbols::java_lang_ref_Reference() - && class_loader.is_null()) { - java_lang_ref_Reference_fix_pre(&fields, cp, &fac, CHECK_(nullHandle)); - } - // end of "discovered" field compactibility fix - - unsigned int nonstatic_double_count = fac.nonstatic_double_count; - unsigned int nonstatic_word_count = fac.nonstatic_word_count; - unsigned int nonstatic_short_count = fac.nonstatic_short_count; - unsigned int nonstatic_byte_count = fac.nonstatic_byte_count; - unsigned int nonstatic_oop_count = fac.nonstatic_oop_count; - bool super_has_nonstatic_fields = (super_klass() != NULL && super_klass->has_nonstatic_fields()); bool has_nonstatic_fields = super_has_nonstatic_fields || ((nonstatic_double_count + nonstatic_word_count + nonstatic_short_count + nonstatic_byte_count + --- 2965,3002 ---- int next_nonstatic_field_offset; // Calculate the starting byte offsets next_static_oop_offset = instanceMirrorKlass::offset_of_static_fields(); next_static_double_offset = next_static_oop_offset + ! (fac.count[STATIC_OOP] * heapOopSize); ! if ( fac.count[STATIC_DOUBLE] && (Universe::field_type_should_be_aligned(T_DOUBLE) || Universe::field_type_should_be_aligned(T_LONG)) ) { next_static_double_offset = align_size_up(next_static_double_offset, BytesPerLong); } next_static_word_offset = next_static_double_offset + ! (fac.count[STATIC_DOUBLE] * BytesPerLong); next_static_short_offset = next_static_word_offset + ! (fac.count[STATIC_WORD] * BytesPerInt); next_static_byte_offset = next_static_short_offset + ! (fac.count[STATIC_SHORT] * BytesPerShort); next_static_type_offset = align_size_up((next_static_byte_offset + ! fac.count[STATIC_BYTE] ), wordSize ); static_field_size = (next_static_type_offset - next_static_oop_offset) / wordSize; first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size * heapOopSize; next_nonstatic_field_offset = first_nonstatic_field_offset; ! unsigned int nonstatic_double_count = fac.count[NONSTATIC_DOUBLE]; ! unsigned int nonstatic_word_count = fac.count[NONSTATIC_WORD]; ! unsigned int nonstatic_short_count = fac.count[NONSTATIC_SHORT]; ! unsigned int nonstatic_byte_count = fac.count[NONSTATIC_BYTE]; ! unsigned int nonstatic_oop_count = fac.count[NONSTATIC_OOP]; bool super_has_nonstatic_fields = (super_klass() != NULL && super_klass->has_nonstatic_fields()); bool has_nonstatic_fields = super_has_nonstatic_fields || ((nonstatic_double_count + nonstatic_word_count + nonstatic_short_count + nonstatic_byte_count +
*** 3208,3231 **** nonstatic_oop_offsets = NEW_RESOURCE_ARRAY_IN_THREAD( THREAD, int, nonstatic_oop_count + 1); nonstatic_oop_counts = NEW_RESOURCE_ARRAY_IN_THREAD( THREAD, unsigned int, nonstatic_oop_count + 1); - // Add fake fields for java.lang.Class instances (also see above). - // FieldsAllocationStyle and CompactFields values will be reset to default. - if(class_name == vmSymbols::java_lang_Class() && class_loader.is_null()) { - java_lang_Class_fix_post(&next_nonstatic_field_offset); - nonstatic_oop_offsets[0] = first_nonstatic_field_offset; - const uint fake_oop_count = (next_nonstatic_field_offset - - first_nonstatic_field_offset) / heapOopSize; - nonstatic_oop_counts[0] = fake_oop_count; - nonstatic_oop_map_count = 1; - nonstatic_oop_count -= fake_oop_count; - first_nonstatic_oop_offset = first_nonstatic_field_offset; - } else { first_nonstatic_oop_offset = 0; // will be set for first oop field - } #ifndef PRODUCT if( PrintCompactFieldsSavings ) { next_nonstatic_double_offset = next_nonstatic_field_offset + (nonstatic_oop_count * heapOopSize); --- 3011,3021 ----
*** 3376,3389 **** - first_nonstatic_field_offset)/heapOopSize); // Iterate over fields again and compute correct offsets. // The field allocation type was temporarily stored in the offset slot. // oop fields are located before non-oop fields (static and non-static). ! int len = fields->length(); ! for (int i = 0; i < len; i += instanceKlass::next_offset) { int real_offset; ! FieldAllocationType atype = (FieldAllocationType) fields->ushort_at(i + instanceKlass::low_offset); switch (atype) { case STATIC_OOP: real_offset = next_static_oop_offset; next_static_oop_offset += heapOopSize; break; --- 3166,3178 ---- - first_nonstatic_field_offset)/heapOopSize); // Iterate over fields again and compute correct offsets. // The field allocation type was temporarily stored in the offset slot. // oop fields are located before non-oop fields (static and non-static). ! for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { int real_offset; ! FieldAllocationType atype = (FieldAllocationType) fs.offset(); switch (atype) { case STATIC_OOP: real_offset = next_static_oop_offset; next_static_oop_offset += heapOopSize; break;
*** 3397,3407 **** break; case STATIC_WORD: real_offset = next_static_word_offset; next_static_word_offset += BytesPerInt; break; - case STATIC_ALIGNED_DOUBLE: case STATIC_DOUBLE: real_offset = next_static_double_offset; next_static_double_offset += BytesPerLong; break; case NONSTATIC_OOP: --- 3186,3195 ----
*** 3459,3478 **** } else { real_offset = next_nonstatic_word_offset; next_nonstatic_word_offset += BytesPerInt; } break; - case NONSTATIC_ALIGNED_DOUBLE: case NONSTATIC_DOUBLE: real_offset = next_nonstatic_double_offset; next_nonstatic_double_offset += BytesPerLong; break; default: ShouldNotReachHere(); } ! fields->short_at_put(i + instanceKlass::low_offset, extract_low_short_from_int(real_offset)); ! fields->short_at_put(i + instanceKlass::high_offset, extract_high_short_from_int(real_offset)); } // Size of instances int instance_size; --- 3247,3264 ---- } else { real_offset = next_nonstatic_word_offset; next_nonstatic_word_offset += BytesPerInt; } break; case NONSTATIC_DOUBLE: real_offset = next_nonstatic_double_offset; next_nonstatic_double_offset += BytesPerLong; break; default: ShouldNotReachHere(); } ! fs.set_offset(real_offset); } // Size of instances int instance_size;
*** 3515,3530 **** // Not yet: supers are done below to support the new subtype-checking fields //this_klass->set_super(super_klass()); this_klass->set_class_loader(class_loader()); this_klass->set_nonstatic_field_size(nonstatic_field_size); this_klass->set_has_nonstatic_fields(has_nonstatic_fields); ! this_klass->set_static_oop_field_count(fac.static_oop_count); cp->set_pool_holder(this_klass()); error_handler.set_in_error(false); // turn off error handler for cp this_klass->set_constants(cp()); this_klass->set_local_interfaces(local_interfaces()); ! this_klass->set_fields(fields()); this_klass->set_methods(methods()); if (has_final_method) { this_klass->set_has_final_method(); } this_klass->set_method_ordering(method_ordering()); --- 3301,3316 ---- // Not yet: supers are done below to support the new subtype-checking fields //this_klass->set_super(super_klass()); this_klass->set_class_loader(class_loader()); this_klass->set_nonstatic_field_size(nonstatic_field_size); this_klass->set_has_nonstatic_fields(has_nonstatic_fields); ! this_klass->set_static_oop_field_count(fac.count[STATIC_OOP]); cp->set_pool_holder(this_klass()); error_handler.set_in_error(false); // turn off error handler for cp this_klass->set_constants(cp()); this_klass->set_local_interfaces(local_interfaces()); ! this_klass->set_fields(fields(), java_fields_count); this_klass->set_methods(methods()); if (has_final_method) { this_klass->set_has_final_method(); } this_klass->set_method_ordering(method_ordering());
src/share/vm/classfile/classFileParser.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File