Wed, 02 May 2012 13:21:36 -0400
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
1.1 --- a/src/share/vm/classfile/classFileParser.cpp Thu Apr 26 16:24:15 2012 -0400 1.2 +++ b/src/share/vm/classfile/classFileParser.cpp Wed May 02 13:21:36 2012 -0400 1.3 @@ -3355,7 +3355,8 @@ 1.4 static_field_size, 1.5 total_oop_map_count, 1.6 access_flags, 1.7 - rt, CHECK_(nullHandle)); 1.8 + rt, host_klass, 1.9 + CHECK_(nullHandle)); 1.10 instanceKlassHandle this_klass (THREAD, ik); 1.11 1.12 assert(this_klass->static_field_size() == static_field_size, "sanity");
2.1 --- a/src/share/vm/memory/oopFactory.cpp Thu Apr 26 16:24:15 2012 -0400 2.2 +++ b/src/share/vm/memory/oopFactory.cpp Wed May 02 13:21:36 2012 -0400 2.3 @@ -128,11 +128,12 @@ 2.4 int static_field_size, 2.5 unsigned int nonstatic_oop_map_count, 2.6 AccessFlags access_flags, 2.7 - ReferenceType rt, TRAPS) { 2.8 + ReferenceType rt, 2.9 + KlassHandle host_klass, TRAPS) { 2.10 instanceKlassKlass* ikk = instanceKlassKlass::cast(Universe::instanceKlassKlassObj()); 2.11 return ikk->allocate_instance_klass(name, vtable_len, itable_len, 2.12 static_field_size, nonstatic_oop_map_count, 2.13 - access_flags, rt, CHECK_NULL); 2.14 + access_flags, rt, host_klass, CHECK_NULL); 2.15 } 2.16 2.17
3.1 --- a/src/share/vm/memory/oopFactory.hpp Thu Apr 26 16:24:15 2012 -0400 3.2 +++ b/src/share/vm/memory/oopFactory.hpp Wed May 02 13:21:36 2012 -0400 3.3 @@ -78,7 +78,8 @@ 3.4 int static_field_size, 3.5 unsigned int nonstatic_oop_map_count, 3.6 AccessFlags access_flags, 3.7 - ReferenceType rt, TRAPS); 3.8 + ReferenceType rt, 3.9 + KlassHandle host_klass, TRAPS); 3.10 3.11 // Methods 3.12 private:
4.1 --- a/src/share/vm/oops/instanceKlass.cpp Thu Apr 26 16:24:15 2012 -0400 4.2 +++ b/src/share/vm/oops/instanceKlass.cpp Wed May 02 13:21:36 2012 -0400 4.3 @@ -1862,7 +1862,7 @@ 4.4 if (impl != NULL) { 4.5 if (!is_alive->do_object_b(impl)) { 4.6 // remove this guy 4.7 - *start_of_implementor() = NULL; 4.8 + *adr_implementor() = NULL; 4.9 } 4.10 } 4.11 } else {
5.1 --- a/src/share/vm/oops/instanceKlass.hpp Thu Apr 26 16:24:15 2012 -0400 5.2 +++ b/src/share/vm/oops/instanceKlass.hpp Wed May 02 13:21:36 2012 -0400 5.3 @@ -78,6 +78,7 @@ 5.4 // The embedded nonstatic oop-map blocks are short pairs (offset, length) 5.5 // indicating where oops are located in instances of this klass. 5.6 // [EMBEDDED implementor of the interface] only exist for interface 5.7 +// [EMBEDDED host klass ] only exist for an anonymous class (JSR 292 enabled) 5.8 5.9 5.10 // forward declaration for class -- see below for definition 5.11 @@ -176,10 +177,6 @@ 5.12 oop _class_loader; 5.13 // Protection domain. 5.14 oop _protection_domain; 5.15 - // Host class, which grants its access privileges to this class also. 5.16 - // This is only non-null for an anonymous class (JSR 292 enabled). 5.17 - // The host class is either named, or a previously loaded anonymous class. 5.18 - klassOop _host_klass; 5.19 // Class signers. 5.20 objArrayOop _signers; 5.21 // The InnerClasses attribute and EnclosingMethod attribute. The 5.22 @@ -234,9 +231,13 @@ 5.23 int _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks 5.24 5.25 bool _is_marked_dependent; // used for marking during flushing and deoptimization 5.26 - bool _rewritten; // methods rewritten. 5.27 - bool _has_nonstatic_fields; // for sizing with UseCompressedOops 5.28 - bool _should_verify_class; // allow caching of preverification 5.29 + enum { 5.30 + _misc_rewritten = 1 << 0, // methods rewritten. 5.31 + _misc_has_nonstatic_fields = 1 << 1, // for sizing with UseCompressedOops 5.32 + _misc_should_verify_class = 1 << 2, // allow caching of preverification 5.33 + _misc_is_anonymous = 1 << 3 // has embedded _inner_classes field 5.34 + }; 5.35 + u2 _misc_flags; 5.36 u2 _minor_version; // minor version number of class file 5.37 u2 _major_version; // major version number of class file 5.38 Thread* _init_thread; // Pointer to current thread doing initialization (to handle recusive initialization) 5.39 @@ -276,13 +277,29 @@ 5.40 // NULL: no implementor. 5.41 // A klassOop that's not itself: one implementor. 5.42 // Itsef: more than one implementors. 5.43 + // embedded host klass follows here 5.44 + // The embedded host klass only exists in an anonymous class for 5.45 + // dynamic language support (JSR 292 enabled). The host class grants 5.46 + // its access privileges to this class also. The host class is either 5.47 + // named, or a previously loaded anonymous class. A non-anonymous class 5.48 + // or an anonymous class loaded through normal classloading does not 5.49 + // have this embedded field. 5.50 + // 5.51 5.52 friend class instanceKlassKlass; 5.53 friend class SystemDictionary; 5.54 5.55 public: 5.56 - bool has_nonstatic_fields() const { return _has_nonstatic_fields; } 5.57 - void set_has_nonstatic_fields(bool b) { _has_nonstatic_fields = b; } 5.58 + bool has_nonstatic_fields() const { 5.59 + return (_misc_flags & _misc_has_nonstatic_fields) != 0; 5.60 + } 5.61 + void set_has_nonstatic_fields(bool b) { 5.62 + if (b) { 5.63 + _misc_flags |= _misc_has_nonstatic_fields; 5.64 + } else { 5.65 + _misc_flags &= ~_misc_has_nonstatic_fields; 5.66 + } 5.67 + } 5.68 5.69 // field sizes 5.70 int nonstatic_field_size() const { return _nonstatic_field_size; } 5.71 @@ -396,11 +413,19 @@ 5.72 bool is_in_error_state() const { return _init_state == initialization_error; } 5.73 bool is_reentrant_initialization(Thread *thread) { return thread == _init_thread; } 5.74 ClassState init_state() { return (ClassState)_init_state; } 5.75 - bool is_rewritten() const { return _rewritten; } 5.76 + bool is_rewritten() const { return (_misc_flags & _misc_rewritten) != 0; } 5.77 5.78 // defineClass specified verification 5.79 - bool should_verify_class() const { return _should_verify_class; } 5.80 - void set_should_verify_class(bool value) { _should_verify_class = value; } 5.81 + bool should_verify_class() const { 5.82 + return (_misc_flags & _misc_should_verify_class) != 0; 5.83 + } 5.84 + void set_should_verify_class(bool value) { 5.85 + if (value) { 5.86 + _misc_flags |= _misc_should_verify_class; 5.87 + } else { 5.88 + _misc_flags &= ~_misc_should_verify_class; 5.89 + } 5.90 + } 5.91 5.92 // marking 5.93 bool is_marked_dependent() const { return _is_marked_dependent; } 5.94 @@ -469,9 +494,30 @@ 5.95 void set_protection_domain(oop pd) { oop_store((oop*) &_protection_domain, pd); } 5.96 5.97 // host class 5.98 - oop host_klass() const { return _host_klass; } 5.99 - void set_host_klass(oop host) { oop_store((oop*) &_host_klass, host); } 5.100 - bool is_anonymous() const { return _host_klass != NULL; } 5.101 + oop host_klass() const { 5.102 + oop* hk = adr_host_klass(); 5.103 + if (hk == NULL) { 5.104 + return NULL; 5.105 + } else { 5.106 + return *hk; 5.107 + } 5.108 + } 5.109 + void set_host_klass(oop host) { 5.110 + assert(is_anonymous(), "not anonymous"); 5.111 + oop* addr = adr_host_klass(); 5.112 + assert(addr != NULL, "no reversed space"); 5.113 + oop_store(addr, host); 5.114 + } 5.115 + bool is_anonymous() const { 5.116 + return (_misc_flags & _misc_is_anonymous) != 0; 5.117 + } 5.118 + void set_is_anonymous(bool value) { 5.119 + if (value) { 5.120 + _misc_flags |= _misc_is_anonymous; 5.121 + } else { 5.122 + _misc_flags &= ~_misc_is_anonymous; 5.123 + } 5.124 + } 5.125 5.126 // signers 5.127 objArrayOop signers() const { return _signers; } 5.128 @@ -651,7 +697,7 @@ 5.129 // Access to the implementor of an interface. 5.130 klassOop implementor() const 5.131 { 5.132 - klassOop* k = start_of_implementor(); 5.133 + klassOop* k = (klassOop*)adr_implementor(); 5.134 if (k == NULL) { 5.135 return NULL; 5.136 } else { 5.137 @@ -661,7 +707,7 @@ 5.138 5.139 void set_implementor(klassOop k) { 5.140 assert(is_interface(), "not interface"); 5.141 - oop* addr = (oop*)start_of_implementor(); 5.142 + oop* addr = adr_implementor(); 5.143 oop_store_without_check(addr, k); 5.144 } 5.145 5.146 @@ -717,9 +763,11 @@ 5.147 { 5.148 return object_size(align_object_offset(vtable_length()) + 5.149 align_object_offset(itable_length()) + 5.150 - (is_interface() ? 5.151 - (align_object_offset(nonstatic_oop_map_size()) + (int)sizeof(klassOop)/HeapWordSize) : 5.152 - nonstatic_oop_map_size())); 5.153 + ((is_interface() || is_anonymous()) ? 5.154 + align_object_offset(nonstatic_oop_map_size()) : 5.155 + nonstatic_oop_map_size()) + 5.156 + (is_interface() ? (int)sizeof(klassOop)/HeapWordSize : 0) + 5.157 + (is_anonymous() ? (int)sizeof(klassOop)/HeapWordSize : 0)); 5.158 } 5.159 static int vtable_start_offset() { return header_size(); } 5.160 static int vtable_length_offset() { return oopDesc::header_size() + offset_of(instanceKlass, _vtable_len) / HeapWordSize; } 5.161 @@ -737,15 +785,29 @@ 5.162 return (OopMapBlock*)(start_of_itable() + align_object_offset(itable_length())); 5.163 } 5.164 5.165 - klassOop* start_of_implementor() const { 5.166 + oop* adr_implementor() const { 5.167 if (is_interface()) { 5.168 - return (klassOop*)(start_of_nonstatic_oop_maps() + 5.169 - nonstatic_oop_map_count()); 5.170 + return (oop*)(start_of_nonstatic_oop_maps() + 5.171 + nonstatic_oop_map_count()); 5.172 } else { 5.173 return NULL; 5.174 } 5.175 }; 5.176 5.177 + oop* adr_host_klass() const { 5.178 + if (is_anonymous()) { 5.179 + oop* adr_impl = adr_implementor(); 5.180 + if (adr_impl != NULL) { 5.181 + return adr_impl + 1; 5.182 + } else { 5.183 + return (oop*)(start_of_nonstatic_oop_maps() + 5.184 + nonstatic_oop_map_count()); 5.185 + } 5.186 + } else { 5.187 + return NULL; 5.188 + } 5.189 + } 5.190 + 5.191 // Allocation profiling support 5.192 juint alloc_size() const { return _alloc_count * size_helper(); } 5.193 void set_alloc_size(juint n) {} 5.194 @@ -819,7 +881,7 @@ 5.195 #else 5.196 void set_init_state(ClassState state) { _init_state = (u1)state; } 5.197 #endif 5.198 - void set_rewritten() { _rewritten = true; } 5.199 + void set_rewritten() { _misc_flags |= _misc_rewritten; } 5.200 void set_init_thread(Thread *thread) { _init_thread = thread; } 5.201 5.202 u2 idnum_allocated_count() const { return _idnum_allocated_count; } 5.203 @@ -852,10 +914,8 @@ 5.204 oop* adr_constants() const { return (oop*)&this->_constants;} 5.205 oop* adr_class_loader() const { return (oop*)&this->_class_loader;} 5.206 oop* adr_protection_domain() const { return (oop*)&this->_protection_domain;} 5.207 - oop* adr_host_klass() const { return (oop*)&this->_host_klass;} 5.208 oop* adr_signers() const { return (oop*)&this->_signers;} 5.209 oop* adr_inner_classes() const { return (oop*)&this->_inner_classes;} 5.210 - oop* adr_implementor() const { return (oop*)start_of_implementor(); } 5.211 oop* adr_methods_jmethod_ids() const { return (oop*)&this->_methods_jmethod_ids;} 5.212 oop* adr_methods_cached_itable_indices() const { return (oop*)&this->_methods_cached_itable_indices;} 5.213 oop* adr_class_annotations() const { return (oop*)&this->_class_annotations;}
6.1 --- a/src/share/vm/oops/instanceKlassKlass.cpp Thu Apr 26 16:24:15 2012 -0400 6.2 +++ b/src/share/vm/oops/instanceKlassKlass.cpp Wed May 02 13:21:36 2012 -0400 6.3 @@ -103,7 +103,9 @@ 6.4 MarkSweep::mark_and_push(ik->adr_class_loader()); 6.5 MarkSweep::mark_and_push(ik->adr_inner_classes()); 6.6 MarkSweep::mark_and_push(ik->adr_protection_domain()); 6.7 - MarkSweep::mark_and_push(ik->adr_host_klass()); 6.8 + if (ik->adr_host_klass() != NULL) { 6.9 + MarkSweep::mark_and_push(ik->adr_host_klass()); 6.10 + } 6.11 MarkSweep::mark_and_push(ik->adr_signers()); 6.12 MarkSweep::mark_and_push(ik->adr_class_annotations()); 6.13 MarkSweep::mark_and_push(ik->adr_fields_annotations()); 6.14 @@ -139,7 +141,9 @@ 6.15 PSParallelCompact::mark_and_push(cm, ik->adr_class_loader()); 6.16 PSParallelCompact::mark_and_push(cm, ik->adr_inner_classes()); 6.17 PSParallelCompact::mark_and_push(cm, ik->adr_protection_domain()); 6.18 - PSParallelCompact::mark_and_push(cm, ik->adr_host_klass()); 6.19 + if (ik->adr_host_klass() != NULL) { 6.20 + PSParallelCompact::mark_and_push(cm, ik->adr_host_klass()); 6.21 + } 6.22 PSParallelCompact::mark_and_push(cm, ik->adr_signers()); 6.23 PSParallelCompact::mark_and_push(cm, ik->adr_class_annotations()); 6.24 PSParallelCompact::mark_and_push(cm, ik->adr_fields_annotations()); 6.25 @@ -177,10 +181,12 @@ 6.26 blk->do_oop(ik->adr_constants()); 6.27 blk->do_oop(ik->adr_class_loader()); 6.28 blk->do_oop(ik->adr_protection_domain()); 6.29 - blk->do_oop(ik->adr_host_klass()); 6.30 + if (ik->adr_host_klass() != NULL) { 6.31 + blk->do_oop(ik->adr_host_klass()); 6.32 + } 6.33 blk->do_oop(ik->adr_signers()); 6.34 blk->do_oop(ik->adr_inner_classes()); 6.35 - if (ik->is_interface()) { 6.36 + if (ik->adr_implementor() != NULL) { 6.37 blk->do_oop(ik->adr_implementor()); 6.38 } 6.39 blk->do_oop(ik->adr_class_annotations()); 6.40 @@ -227,15 +233,13 @@ 6.41 adr = ik->adr_protection_domain(); 6.42 if (mr.contains(adr)) blk->do_oop(adr); 6.43 adr = ik->adr_host_klass(); 6.44 - if (mr.contains(adr)) blk->do_oop(adr); 6.45 + if (adr != NULL && mr.contains(adr)) blk->do_oop(adr); 6.46 adr = ik->adr_signers(); 6.47 if (mr.contains(adr)) blk->do_oop(adr); 6.48 adr = ik->adr_inner_classes(); 6.49 if (mr.contains(adr)) blk->do_oop(adr); 6.50 - if (ik->is_interface()) { 6.51 - adr = ik->adr_implementor(); 6.52 - if (mr.contains(adr)) blk->do_oop(adr); 6.53 - } 6.54 + adr = ik->adr_implementor(); 6.55 + if (adr != NULL && mr.contains(adr)) blk->do_oop(adr); 6.56 adr = ik->adr_class_annotations(); 6.57 if (mr.contains(adr)) blk->do_oop(adr); 6.58 adr = ik->adr_fields_annotations(); 6.59 @@ -270,10 +274,12 @@ 6.60 MarkSweep::adjust_pointer(ik->adr_constants()); 6.61 MarkSweep::adjust_pointer(ik->adr_class_loader()); 6.62 MarkSweep::adjust_pointer(ik->adr_protection_domain()); 6.63 - MarkSweep::adjust_pointer(ik->adr_host_klass()); 6.64 + if (ik->adr_host_klass() != NULL) { 6.65 + MarkSweep::adjust_pointer(ik->adr_host_klass()); 6.66 + } 6.67 MarkSweep::adjust_pointer(ik->adr_signers()); 6.68 MarkSweep::adjust_pointer(ik->adr_inner_classes()); 6.69 - if (ik->is_interface()) { 6.70 + if (ik->adr_implementor() != NULL) { 6.71 MarkSweep::adjust_pointer(ik->adr_implementor()); 6.72 } 6.73 MarkSweep::adjust_pointer(ik->adr_class_annotations()); 6.74 @@ -302,7 +308,7 @@ 6.75 } 6.76 6.77 oop* hk_addr = ik->adr_host_klass(); 6.78 - if (PSScavenge::should_scavenge(hk_addr)) { 6.79 + if (hk_addr != NULL && PSScavenge::should_scavenge(hk_addr)) { 6.80 pm->claim_or_forward_depth(hk_addr); 6.81 } 6.82 6.83 @@ -328,9 +334,13 @@ 6.84 for (oop* cur_oop = beg_oop; cur_oop < end_oop; ++cur_oop) { 6.85 PSParallelCompact::adjust_pointer(cur_oop); 6.86 } 6.87 - if (ik->is_interface()) { 6.88 + // embedded oops 6.89 + if (ik->adr_implementor() != NULL) { 6.90 PSParallelCompact::adjust_pointer(ik->adr_implementor()); 6.91 } 6.92 + if (ik->adr_host_klass() != NULL) { 6.93 + PSParallelCompact::adjust_pointer(ik->adr_host_klass()); 6.94 + } 6.95 6.96 OopClosure* closure = PSParallelCompact::adjust_root_pointer_closure(); 6.97 iterate_c_heap_oops(ik, closure); 6.98 @@ -346,16 +356,23 @@ 6.99 int static_field_size, 6.100 unsigned nonstatic_oop_map_count, 6.101 AccessFlags access_flags, 6.102 - ReferenceType rt, TRAPS) { 6.103 + ReferenceType rt, 6.104 + KlassHandle host_klass, TRAPS) { 6.105 6.106 const int nonstatic_oop_map_size = 6.107 instanceKlass::nonstatic_oop_map_size(nonstatic_oop_map_count); 6.108 int size = align_object_offset(vtable_len) + align_object_offset(itable_len); 6.109 - if (access_flags.is_interface()) { 6.110 - size += align_object_offset(nonstatic_oop_map_size) + (int)sizeof(klassOop)/HeapWordSize; 6.111 + if (access_flags.is_interface() || !host_klass.is_null()) { 6.112 + size += align_object_offset(nonstatic_oop_map_size); 6.113 } else { 6.114 size += nonstatic_oop_map_size; 6.115 } 6.116 + if (access_flags.is_interface()) { 6.117 + size += (int)sizeof(klassOop)/HeapWordSize; 6.118 + } 6.119 + if (!host_klass.is_null()) { 6.120 + size += (int)sizeof(klassOop)/HeapWordSize; 6.121 + } 6.122 size = instanceKlass::object_size(size); 6.123 6.124 // Allocation 6.125 @@ -389,6 +406,7 @@ 6.126 ik->set_static_field_size(static_field_size); 6.127 ik->set_nonstatic_oop_map_size(nonstatic_oop_map_size); 6.128 ik->set_access_flags(access_flags); 6.129 + ik->set_is_anonymous(!host_klass.is_null()); 6.130 assert(k()->size() == size, "wrong size for object"); 6.131 6.132 ik->set_array_klasses(NULL); 6.133 @@ -401,7 +419,6 @@ 6.134 ik->set_constants(NULL); 6.135 ik->set_class_loader(NULL); 6.136 ik->set_protection_domain(NULL); 6.137 - ik->set_host_klass(NULL); 6.138 ik->set_signers(NULL); 6.139 ik->set_source_file_name(NULL); 6.140 ik->set_source_debug_extension(NULL); 6.141 @@ -503,7 +520,9 @@ 6.142 st->print(BULLET"constants: "); ik->constants()->print_value_on(st); st->cr(); 6.143 st->print(BULLET"class loader: "); ik->class_loader()->print_value_on(st); st->cr(); 6.144 st->print(BULLET"protection domain: "); ik->protection_domain()->print_value_on(st); st->cr(); 6.145 - st->print(BULLET"host class: "); ik->host_klass()->print_value_on(st); st->cr(); 6.146 + if (ik->host_klass() != NULL) { 6.147 + st->print(BULLET"host class: "); ik->host_klass()->print_value_on(st); st->cr(); 6.148 + } 6.149 st->print(BULLET"signers: "); ik->signers()->print_value_on(st); st->cr(); 6.150 if (ik->source_file_name() != NULL) { 6.151 st->print(BULLET"source file: ");
7.1 --- a/src/share/vm/oops/instanceKlassKlass.hpp Thu Apr 26 16:24:15 2012 -0400 7.2 +++ b/src/share/vm/oops/instanceKlassKlass.hpp Wed May 02 13:21:36 2012 -0400 7.3 @@ -48,6 +48,7 @@ 7.4 unsigned int nonstatic_oop_map_count, 7.5 AccessFlags access_flags, 7.6 ReferenceType rt, 7.7 + KlassHandle host_klass, 7.8 TRAPS); 7.9 7.10 // Casting from klassOop