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