# HG changeset patch # User jiangli # Date 1335979296 14400 # Node ID 8bafad97cd26a47c99aa65a9b821d269a12f7c0e # Parent 973046802b6fea1c550217f90ecdaf14be778afb 7158552: The instanceKlsss::_host_klass is only needed for anonymous class for JSR 292 support. Summary: Change the _host_klass to be conditionally created embedded instanceKlass field. Reviewed-by: jrose, coleenp, dholmes diff -r 973046802b6f -r 8bafad97cd26 src/share/vm/classfile/classFileParser.cpp --- a/src/share/vm/classfile/classFileParser.cpp Thu Apr 26 16:24:15 2012 -0400 +++ b/src/share/vm/classfile/classFileParser.cpp Wed May 02 13:21:36 2012 -0400 @@ -3355,7 +3355,8 @@ static_field_size, total_oop_map_count, access_flags, - rt, CHECK_(nullHandle)); + rt, host_klass, + CHECK_(nullHandle)); instanceKlassHandle this_klass (THREAD, ik); assert(this_klass->static_field_size() == static_field_size, "sanity"); diff -r 973046802b6f -r 8bafad97cd26 src/share/vm/memory/oopFactory.cpp --- a/src/share/vm/memory/oopFactory.cpp Thu Apr 26 16:24:15 2012 -0400 +++ b/src/share/vm/memory/oopFactory.cpp Wed May 02 13:21:36 2012 -0400 @@ -128,11 +128,12 @@ int static_field_size, unsigned int nonstatic_oop_map_count, AccessFlags access_flags, - ReferenceType rt, TRAPS) { + ReferenceType rt, + KlassHandle host_klass, TRAPS) { instanceKlassKlass* ikk = instanceKlassKlass::cast(Universe::instanceKlassKlassObj()); return ikk->allocate_instance_klass(name, vtable_len, itable_len, static_field_size, nonstatic_oop_map_count, - access_flags, rt, CHECK_NULL); + access_flags, rt, host_klass, CHECK_NULL); } diff -r 973046802b6f -r 8bafad97cd26 src/share/vm/memory/oopFactory.hpp --- a/src/share/vm/memory/oopFactory.hpp Thu Apr 26 16:24:15 2012 -0400 +++ b/src/share/vm/memory/oopFactory.hpp Wed May 02 13:21:36 2012 -0400 @@ -78,7 +78,8 @@ int static_field_size, unsigned int nonstatic_oop_map_count, AccessFlags access_flags, - ReferenceType rt, TRAPS); + ReferenceType rt, + KlassHandle host_klass, TRAPS); // Methods private: diff -r 973046802b6f -r 8bafad97cd26 src/share/vm/oops/instanceKlass.cpp --- a/src/share/vm/oops/instanceKlass.cpp Thu Apr 26 16:24:15 2012 -0400 +++ b/src/share/vm/oops/instanceKlass.cpp Wed May 02 13:21:36 2012 -0400 @@ -1862,7 +1862,7 @@ if (impl != NULL) { if (!is_alive->do_object_b(impl)) { // remove this guy - *start_of_implementor() = NULL; + *adr_implementor() = NULL; } } } else { diff -r 973046802b6f -r 8bafad97cd26 src/share/vm/oops/instanceKlass.hpp --- a/src/share/vm/oops/instanceKlass.hpp Thu Apr 26 16:24:15 2012 -0400 +++ b/src/share/vm/oops/instanceKlass.hpp Wed May 02 13:21:36 2012 -0400 @@ -78,6 +78,7 @@ // The embedded nonstatic oop-map blocks are short pairs (offset, length) // indicating where oops are located in instances of this klass. // [EMBEDDED implementor of the interface] only exist for interface +// [EMBEDDED host klass ] only exist for an anonymous class (JSR 292 enabled) // forward declaration for class -- see below for definition @@ -176,10 +177,6 @@ oop _class_loader; // Protection domain. oop _protection_domain; - // Host class, which grants its access privileges to this class also. - // This is only non-null for an anonymous class (JSR 292 enabled). - // The host class is either named, or a previously loaded anonymous class. - klassOop _host_klass; // Class signers. objArrayOop _signers; // The InnerClasses attribute and EnclosingMethod attribute. The @@ -234,9 +231,13 @@ int _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks bool _is_marked_dependent; // used for marking during flushing and deoptimization - bool _rewritten; // methods rewritten. - bool _has_nonstatic_fields; // for sizing with UseCompressedOops - bool _should_verify_class; // allow caching of preverification + enum { + _misc_rewritten = 1 << 0, // methods rewritten. + _misc_has_nonstatic_fields = 1 << 1, // for sizing with UseCompressedOops + _misc_should_verify_class = 1 << 2, // allow caching of preverification + _misc_is_anonymous = 1 << 3 // has embedded _inner_classes field + }; + u2 _misc_flags; u2 _minor_version; // minor version number of class file u2 _major_version; // major version number of class file Thread* _init_thread; // Pointer to current thread doing initialization (to handle recusive initialization) @@ -276,13 +277,29 @@ // NULL: no implementor. // A klassOop that's not itself: one implementor. // Itsef: more than one implementors. + // embedded host klass follows here + // The embedded host klass only exists in an anonymous class for + // dynamic language support (JSR 292 enabled). The host class grants + // its access privileges to this class also. The host class is either + // named, or a previously loaded anonymous class. A non-anonymous class + // or an anonymous class loaded through normal classloading does not + // have this embedded field. + // friend class instanceKlassKlass; friend class SystemDictionary; public: - bool has_nonstatic_fields() const { return _has_nonstatic_fields; } - void set_has_nonstatic_fields(bool b) { _has_nonstatic_fields = b; } + bool has_nonstatic_fields() const { + return (_misc_flags & _misc_has_nonstatic_fields) != 0; + } + void set_has_nonstatic_fields(bool b) { + if (b) { + _misc_flags |= _misc_has_nonstatic_fields; + } else { + _misc_flags &= ~_misc_has_nonstatic_fields; + } + } // field sizes int nonstatic_field_size() const { return _nonstatic_field_size; } @@ -396,11 +413,19 @@ bool is_in_error_state() const { return _init_state == initialization_error; } bool is_reentrant_initialization(Thread *thread) { return thread == _init_thread; } ClassState init_state() { return (ClassState)_init_state; } - bool is_rewritten() const { return _rewritten; } + bool is_rewritten() const { return (_misc_flags & _misc_rewritten) != 0; } // defineClass specified verification - bool should_verify_class() const { return _should_verify_class; } - void set_should_verify_class(bool value) { _should_verify_class = value; } + bool should_verify_class() const { + return (_misc_flags & _misc_should_verify_class) != 0; + } + void set_should_verify_class(bool value) { + if (value) { + _misc_flags |= _misc_should_verify_class; + } else { + _misc_flags &= ~_misc_should_verify_class; + } + } // marking bool is_marked_dependent() const { return _is_marked_dependent; } @@ -469,9 +494,30 @@ void set_protection_domain(oop pd) { oop_store((oop*) &_protection_domain, pd); } // host class - oop host_klass() const { return _host_klass; } - void set_host_klass(oop host) { oop_store((oop*) &_host_klass, host); } - bool is_anonymous() const { return _host_klass != NULL; } + oop host_klass() const { + oop* hk = adr_host_klass(); + if (hk == NULL) { + return NULL; + } else { + return *hk; + } + } + void set_host_klass(oop host) { + assert(is_anonymous(), "not anonymous"); + oop* addr = adr_host_klass(); + assert(addr != NULL, "no reversed space"); + oop_store(addr, host); + } + bool is_anonymous() const { + return (_misc_flags & _misc_is_anonymous) != 0; + } + void set_is_anonymous(bool value) { + if (value) { + _misc_flags |= _misc_is_anonymous; + } else { + _misc_flags &= ~_misc_is_anonymous; + } + } // signers objArrayOop signers() const { return _signers; } @@ -651,7 +697,7 @@ // Access to the implementor of an interface. klassOop implementor() const { - klassOop* k = start_of_implementor(); + klassOop* k = (klassOop*)adr_implementor(); if (k == NULL) { return NULL; } else { @@ -661,7 +707,7 @@ void set_implementor(klassOop k) { assert(is_interface(), "not interface"); - oop* addr = (oop*)start_of_implementor(); + oop* addr = adr_implementor(); oop_store_without_check(addr, k); } @@ -717,9 +763,11 @@ { return object_size(align_object_offset(vtable_length()) + align_object_offset(itable_length()) + - (is_interface() ? - (align_object_offset(nonstatic_oop_map_size()) + (int)sizeof(klassOop)/HeapWordSize) : - nonstatic_oop_map_size())); + ((is_interface() || is_anonymous()) ? + align_object_offset(nonstatic_oop_map_size()) : + nonstatic_oop_map_size()) + + (is_interface() ? (int)sizeof(klassOop)/HeapWordSize : 0) + + (is_anonymous() ? (int)sizeof(klassOop)/HeapWordSize : 0)); } static int vtable_start_offset() { return header_size(); } static int vtable_length_offset() { return oopDesc::header_size() + offset_of(instanceKlass, _vtable_len) / HeapWordSize; } @@ -737,15 +785,29 @@ return (OopMapBlock*)(start_of_itable() + align_object_offset(itable_length())); } - klassOop* start_of_implementor() const { + oop* adr_implementor() const { if (is_interface()) { - return (klassOop*)(start_of_nonstatic_oop_maps() + - nonstatic_oop_map_count()); + return (oop*)(start_of_nonstatic_oop_maps() + + nonstatic_oop_map_count()); } else { return NULL; } }; + oop* adr_host_klass() const { + if (is_anonymous()) { + oop* adr_impl = adr_implementor(); + if (adr_impl != NULL) { + return adr_impl + 1; + } else { + return (oop*)(start_of_nonstatic_oop_maps() + + nonstatic_oop_map_count()); + } + } else { + return NULL; + } + } + // Allocation profiling support juint alloc_size() const { return _alloc_count * size_helper(); } void set_alloc_size(juint n) {} @@ -819,7 +881,7 @@ #else void set_init_state(ClassState state) { _init_state = (u1)state; } #endif - void set_rewritten() { _rewritten = true; } + void set_rewritten() { _misc_flags |= _misc_rewritten; } void set_init_thread(Thread *thread) { _init_thread = thread; } u2 idnum_allocated_count() const { return _idnum_allocated_count; } @@ -852,10 +914,8 @@ oop* adr_constants() const { return (oop*)&this->_constants;} oop* adr_class_loader() const { return (oop*)&this->_class_loader;} oop* adr_protection_domain() const { return (oop*)&this->_protection_domain;} - oop* adr_host_klass() const { return (oop*)&this->_host_klass;} oop* adr_signers() const { return (oop*)&this->_signers;} oop* adr_inner_classes() const { return (oop*)&this->_inner_classes;} - oop* adr_implementor() const { return (oop*)start_of_implementor(); } oop* adr_methods_jmethod_ids() const { return (oop*)&this->_methods_jmethod_ids;} oop* adr_methods_cached_itable_indices() const { return (oop*)&this->_methods_cached_itable_indices;} oop* adr_class_annotations() const { return (oop*)&this->_class_annotations;} diff -r 973046802b6f -r 8bafad97cd26 src/share/vm/oops/instanceKlassKlass.cpp --- a/src/share/vm/oops/instanceKlassKlass.cpp Thu Apr 26 16:24:15 2012 -0400 +++ b/src/share/vm/oops/instanceKlassKlass.cpp Wed May 02 13:21:36 2012 -0400 @@ -103,7 +103,9 @@ MarkSweep::mark_and_push(ik->adr_class_loader()); MarkSweep::mark_and_push(ik->adr_inner_classes()); MarkSweep::mark_and_push(ik->adr_protection_domain()); - MarkSweep::mark_and_push(ik->adr_host_klass()); + if (ik->adr_host_klass() != NULL) { + MarkSweep::mark_and_push(ik->adr_host_klass()); + } MarkSweep::mark_and_push(ik->adr_signers()); MarkSweep::mark_and_push(ik->adr_class_annotations()); MarkSweep::mark_and_push(ik->adr_fields_annotations()); @@ -139,7 +141,9 @@ PSParallelCompact::mark_and_push(cm, ik->adr_class_loader()); PSParallelCompact::mark_and_push(cm, ik->adr_inner_classes()); PSParallelCompact::mark_and_push(cm, ik->adr_protection_domain()); - PSParallelCompact::mark_and_push(cm, ik->adr_host_klass()); + if (ik->adr_host_klass() != NULL) { + PSParallelCompact::mark_and_push(cm, ik->adr_host_klass()); + } PSParallelCompact::mark_and_push(cm, ik->adr_signers()); PSParallelCompact::mark_and_push(cm, ik->adr_class_annotations()); PSParallelCompact::mark_and_push(cm, ik->adr_fields_annotations()); @@ -177,10 +181,12 @@ blk->do_oop(ik->adr_constants()); blk->do_oop(ik->adr_class_loader()); blk->do_oop(ik->adr_protection_domain()); - blk->do_oop(ik->adr_host_klass()); + if (ik->adr_host_klass() != NULL) { + blk->do_oop(ik->adr_host_klass()); + } blk->do_oop(ik->adr_signers()); blk->do_oop(ik->adr_inner_classes()); - if (ik->is_interface()) { + if (ik->adr_implementor() != NULL) { blk->do_oop(ik->adr_implementor()); } blk->do_oop(ik->adr_class_annotations()); @@ -227,15 +233,13 @@ adr = ik->adr_protection_domain(); if (mr.contains(adr)) blk->do_oop(adr); adr = ik->adr_host_klass(); - if (mr.contains(adr)) blk->do_oop(adr); + if (adr != NULL && mr.contains(adr)) blk->do_oop(adr); adr = ik->adr_signers(); if (mr.contains(adr)) blk->do_oop(adr); adr = ik->adr_inner_classes(); if (mr.contains(adr)) blk->do_oop(adr); - if (ik->is_interface()) { - adr = ik->adr_implementor(); - if (mr.contains(adr)) blk->do_oop(adr); - } + adr = ik->adr_implementor(); + if (adr != NULL && mr.contains(adr)) blk->do_oop(adr); adr = ik->adr_class_annotations(); if (mr.contains(adr)) blk->do_oop(adr); adr = ik->adr_fields_annotations(); @@ -270,10 +274,12 @@ MarkSweep::adjust_pointer(ik->adr_constants()); MarkSweep::adjust_pointer(ik->adr_class_loader()); MarkSweep::adjust_pointer(ik->adr_protection_domain()); - MarkSweep::adjust_pointer(ik->adr_host_klass()); + if (ik->adr_host_klass() != NULL) { + MarkSweep::adjust_pointer(ik->adr_host_klass()); + } MarkSweep::adjust_pointer(ik->adr_signers()); MarkSweep::adjust_pointer(ik->adr_inner_classes()); - if (ik->is_interface()) { + if (ik->adr_implementor() != NULL) { MarkSweep::adjust_pointer(ik->adr_implementor()); } MarkSweep::adjust_pointer(ik->adr_class_annotations()); @@ -302,7 +308,7 @@ } oop* hk_addr = ik->adr_host_klass(); - if (PSScavenge::should_scavenge(hk_addr)) { + if (hk_addr != NULL && PSScavenge::should_scavenge(hk_addr)) { pm->claim_or_forward_depth(hk_addr); } @@ -328,9 +334,13 @@ for (oop* cur_oop = beg_oop; cur_oop < end_oop; ++cur_oop) { PSParallelCompact::adjust_pointer(cur_oop); } - if (ik->is_interface()) { + // embedded oops + if (ik->adr_implementor() != NULL) { PSParallelCompact::adjust_pointer(ik->adr_implementor()); } + if (ik->adr_host_klass() != NULL) { + PSParallelCompact::adjust_pointer(ik->adr_host_klass()); + } OopClosure* closure = PSParallelCompact::adjust_root_pointer_closure(); iterate_c_heap_oops(ik, closure); @@ -346,16 +356,23 @@ int static_field_size, unsigned nonstatic_oop_map_count, AccessFlags access_flags, - ReferenceType rt, TRAPS) { + ReferenceType rt, + KlassHandle host_klass, TRAPS) { const int nonstatic_oop_map_size = instanceKlass::nonstatic_oop_map_size(nonstatic_oop_map_count); int size = align_object_offset(vtable_len) + align_object_offset(itable_len); - if (access_flags.is_interface()) { - size += align_object_offset(nonstatic_oop_map_size) + (int)sizeof(klassOop)/HeapWordSize; + if (access_flags.is_interface() || !host_klass.is_null()) { + size += align_object_offset(nonstatic_oop_map_size); } else { size += nonstatic_oop_map_size; } + if (access_flags.is_interface()) { + size += (int)sizeof(klassOop)/HeapWordSize; + } + if (!host_klass.is_null()) { + size += (int)sizeof(klassOop)/HeapWordSize; + } size = instanceKlass::object_size(size); // Allocation @@ -389,6 +406,7 @@ ik->set_static_field_size(static_field_size); ik->set_nonstatic_oop_map_size(nonstatic_oop_map_size); ik->set_access_flags(access_flags); + ik->set_is_anonymous(!host_klass.is_null()); assert(k()->size() == size, "wrong size for object"); ik->set_array_klasses(NULL); @@ -401,7 +419,6 @@ ik->set_constants(NULL); ik->set_class_loader(NULL); ik->set_protection_domain(NULL); - ik->set_host_klass(NULL); ik->set_signers(NULL); ik->set_source_file_name(NULL); ik->set_source_debug_extension(NULL); @@ -503,7 +520,9 @@ st->print(BULLET"constants: "); ik->constants()->print_value_on(st); st->cr(); st->print(BULLET"class loader: "); ik->class_loader()->print_value_on(st); st->cr(); st->print(BULLET"protection domain: "); ik->protection_domain()->print_value_on(st); st->cr(); - st->print(BULLET"host class: "); ik->host_klass()->print_value_on(st); st->cr(); + if (ik->host_klass() != NULL) { + st->print(BULLET"host class: "); ik->host_klass()->print_value_on(st); st->cr(); + } st->print(BULLET"signers: "); ik->signers()->print_value_on(st); st->cr(); if (ik->source_file_name() != NULL) { st->print(BULLET"source file: "); diff -r 973046802b6f -r 8bafad97cd26 src/share/vm/oops/instanceKlassKlass.hpp --- a/src/share/vm/oops/instanceKlassKlass.hpp Thu Apr 26 16:24:15 2012 -0400 +++ b/src/share/vm/oops/instanceKlassKlass.hpp Wed May 02 13:21:36 2012 -0400 @@ -48,6 +48,7 @@ unsigned int nonstatic_oop_map_count, AccessFlags access_flags, ReferenceType rt, + KlassHandle host_klass, TRAPS); // Casting from klassOop