diff --git a/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java b/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java index 87de9700df3bb60d9451733ada01ba9a72671f93..2a3b941b4814d8364edd0d1169e4e9460f57b713 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java @@ -63,6 +63,8 @@ public class InstanceKlass extends Klass { private static int CLASS_STATE_FULLY_INITIALIZED; private static int CLASS_STATE_INITIALIZATION_ERROR; + private static int IS_MARKED_DEPENDENT_MASK; + private static synchronized void initialize(TypeDataBase db) throws WrongTypeException { Type type = db.lookupType("instanceKlass"); arrayKlasses = new OopField(type.getOopField("_array_klasses"), Oop.getHeaderSize()); @@ -90,7 +92,7 @@ public class InstanceKlass extends Klass { staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), Oop.getHeaderSize()); staticOopFieldCount = new CIntField(type.getCIntegerField("_static_oop_field_count"), Oop.getHeaderSize()); nonstaticOopMapSize = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), Oop.getHeaderSize()); - isMarkedDependent = new CIntField(type.getCIntegerField("_is_marked_dependent"), Oop.getHeaderSize()); + miscFlags = new CIntField(type.getCIntegerField("_misc_flags"), Oop.getHeaderSize()); initState = new CIntField(type.getCIntegerField("_init_state"), Oop.getHeaderSize()); vtableLen = new CIntField(type.getCIntegerField("_vtable_len"), Oop.getHeaderSize()); itableLen = new CIntField(type.getCIntegerField("_itable_len"), Oop.getHeaderSize()); @@ -118,6 +120,8 @@ public class InstanceKlass extends Klass { CLASS_STATE_FULLY_INITIALIZED = db.lookupIntConstant("instanceKlass::fully_initialized").intValue(); CLASS_STATE_INITIALIZATION_ERROR = db.lookupIntConstant("instanceKlass::initialization_error").intValue(); + IS_MARKED_DEPENDENT_MASK = db.lookupIntConstant("instanceKlass::IS_MARKED_DEPENDENT").intValue(); + } InstanceKlass(OopHandle handle, ObjectHeap heap) { @@ -151,7 +155,7 @@ public class InstanceKlass extends Klass { private static CIntField staticFieldSize; private static CIntField staticOopFieldCount; private static CIntField nonstaticOopMapSize; - private static CIntField isMarkedDependent; + private static CIntField miscFlags; private static CIntField initState; private static CIntField vtableLen; private static CIntField itableLen; @@ -333,7 +337,7 @@ public class InstanceKlass extends Klass { public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); } public long getStaticOopFieldCount() { return staticOopFieldCount.getValue(this); } public long getNonstaticOopMapSize() { return nonstaticOopMapSize.getValue(this); } - public boolean getIsMarkedDependent() { return isMarkedDependent.getValue(this) != 0; } + public boolean getIsMarkedDependent() { return (miscFlags.getValue(this) & IS_MARKED_DEPENDENT_MASK) != 0; } public long getVtableLen() { return vtableLen.getValue(this); } public long getItableLen() { return itableLen.getValue(this); } public Symbol getGenericSignature() { return getSymbol(genericSignature); } @@ -524,7 +528,7 @@ public class InstanceKlass extends Klass { visitor.doCInt(staticFieldSize, true); visitor.doCInt(staticOopFieldCount, true); visitor.doCInt(nonstaticOopMapSize, true); - visitor.doCInt(isMarkedDependent, true); + visitor.doCInt(miscFlags, true); visitor.doCInt(initState, true); visitor.doCInt(vtableLen, true); visitor.doCInt(itableLen, true); diff --git a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp index 97e86fd789fc60833195296de4b5048853d52fcc..3605c0a29f8456e2be7a6f47389aa3d5fcbf5e0a 100644 --- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp +++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp @@ -2455,7 +2455,7 @@ void LIR_Assembler::emit_alloc_obj(LIR_OpAllocObj* op) { op->obj()->as_register() == O0 && op->klass()->as_register() == G5, "must be"); if (op->init_check()) { - __ ld(op->klass()->as_register(), + __ ldub(op->klass()->as_register(), instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc), op->tmp1()->as_register()); add_debug_info_for_null_check_here(op->stub()->info()); diff --git a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp index 64f15e0b64a1107eac4017c7a890f73b10afe0d4..7f053b0466fbed8ea46f713d4f0e35c9b1ee5e7d 100644 --- a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp +++ b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp @@ -398,7 +398,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { if (id == fast_new_instance_init_check_id) { // make sure the klass is initialized - __ ld(G5_klass, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc), G3_t1); + __ ldub(G5_klass, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc), G3_t1); __ cmp_and_br_short(G3_t1, instanceKlass::fully_initialized, Assembler::notEqual, Assembler::pn, slow_path); } #ifdef ASSERT diff --git a/src/cpu/sparc/vm/templateTable_sparc.cpp b/src/cpu/sparc/vm/templateTable_sparc.cpp index 850dbe62a25ab43a6797c3b40a6ac91da9c772dc..01dc89212ab8db210f250a90b3d6a8d99e4021b3 100644 --- a/src/cpu/sparc/vm/templateTable_sparc.cpp +++ b/src/cpu/sparc/vm/templateTable_sparc.cpp @@ -3350,7 +3350,7 @@ void TemplateTable::_new() { __ ld_ptr(Rscratch, Roffset, RinstanceKlass); // make sure klass is fully initialized: - __ ld(RinstanceKlass, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc), G3_scratch); + __ ldub(RinstanceKlass, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc), G3_scratch); __ cmp(G3_scratch, instanceKlass::fully_initialized); __ br(Assembler::notEqual, false, Assembler::pn, slow_case); __ delayed()->ld(RinstanceKlass, Klass::layout_helper_offset_in_bytes() + sizeof(oopDesc), Roffset); diff --git a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp index dbdd7087fa75323a67a00774396f9731125fe907..b6035c2915e249dfabb7a3c41f2c26f11480fa34 100644 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @@ -1557,7 +1557,7 @@ void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) { void LIR_Assembler::emit_alloc_obj(LIR_OpAllocObj* op) { if (op->init_check()) { - __ cmpl(Address(op->klass()->as_register(), + __ cmpb(Address(op->klass()->as_register(), instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc)), instanceKlass::fully_initialized); add_debug_info_for_null_check_here(op->stub()->info()); diff --git a/src/cpu/x86/vm/c1_Runtime1_x86.cpp b/src/cpu/x86/vm/c1_Runtime1_x86.cpp index 9d13221705802a0dedab7e91646f50c40f4bfed9..cc71ccee3afa8796f7becf17046a01a7361aaa8a 100644 --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp @@ -1011,7 +1011,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { if (id == fast_new_instance_init_check_id) { // make sure the klass is initialized - __ cmpl(Address(klass, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc)), instanceKlass::fully_initialized); + __ cmpb(Address(klass, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc)), instanceKlass::fully_initialized); __ jcc(Assembler::notEqual, slow_path); } diff --git a/src/cpu/x86/vm/templateTable_x86_32.cpp b/src/cpu/x86/vm/templateTable_x86_32.cpp index 65e65ef5b511d655a041136910eeb0bd068ed8d0..955101721c2a67c9144d0bf5383ea8b236b5f622 100644 --- a/src/cpu/x86/vm/templateTable_x86_32.cpp +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp @@ -3188,7 +3188,7 @@ void TemplateTable::_new() { // make sure klass is initialized & doesn't have finalizer // make sure klass is fully initialized - __ cmpl(Address(rcx, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc)), instanceKlass::fully_initialized); + __ cmpb(Address(rcx, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc)), instanceKlass::fully_initialized); __ jcc(Assembler::notEqual, slow_case); // get instance_size in instanceKlass (scaled to a count of bytes) diff --git a/src/cpu/x86/vm/templateTable_x86_64.cpp b/src/cpu/x86/vm/templateTable_x86_64.cpp index 818fb44e0a59718a9b08e0ffc7b4a36bf3f40edc..cc837c789543ee50ac357fb3f30ef84ddd108b33 100644 --- a/src/cpu/x86/vm/templateTable_x86_64.cpp +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp @@ -3235,7 +3235,7 @@ void TemplateTable::_new() { // make sure klass is initialized & doesn't have finalizer // make sure klass is fully initialized - __ cmpl(Address(rsi, + __ cmpb(Address(rsi, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc)), instanceKlass::fully_initialized); diff --git a/src/share/vm/ci/ciInstanceKlass.cpp b/src/share/vm/ci/ciInstanceKlass.cpp index f10b92fa33dcc80895eb28ab126b42324f0c3352..b7c2ab758506ccd18dab2ec4d9a86ba74588e071 100644 --- a/src/share/vm/ci/ciInstanceKlass.cpp +++ b/src/share/vm/ci/ciInstanceKlass.cpp @@ -54,7 +54,7 @@ ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) : _flags = ciFlags(access_flags); _has_finalizer = access_flags.has_finalizer(); _has_subklass = ik->subklass() != NULL; - _init_state = (instanceKlass::ClassState)ik->get_init_state(); + _init_state = ik->init_state(); _nonstatic_field_size = ik->nonstatic_field_size(); _has_nonstatic_fields = ik->has_nonstatic_fields(); _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields: @@ -118,7 +118,7 @@ ciInstanceKlass::ciInstanceKlass(ciSymbol* name, void ciInstanceKlass::compute_shared_init_state() { GUARDED_VM_ENTRY( instanceKlass* ik = get_instanceKlass(); - _init_state = (instanceKlass::ClassState)ik->get_init_state(); + _init_state = ik->init_state(); ) } diff --git a/src/share/vm/code/dependencies.cpp b/src/share/vm/code/dependencies.cpp index a3fd99ecd45836080e53a9e74deb3a6bcc83774c..e80f222f7850acc77013750a2dc482dce0cad057 100644 --- a/src/share/vm/code/dependencies.cpp +++ b/src/share/vm/code/dependencies.cpp @@ -1631,7 +1631,7 @@ void KlassDepChange::initialize() { for (ContextStream str(*this); str.next(); ) { klassOop d = str.klass(); assert(!instanceKlass::cast(d)->is_marked_dependent(), "checking"); - instanceKlass::cast(d)->set_is_marked_dependent(true); + instanceKlass::cast(d)->set_is_marked_dependent(); } } @@ -1640,7 +1640,7 @@ KlassDepChange::~KlassDepChange() { // Unmark transitive interfaces for (ContextStream str(*this); str.next(); ) { klassOop d = str.klass(); - instanceKlass::cast(d)->set_is_marked_dependent(false); + instanceKlass::cast(d)->clear_is_marked_dependent(); } } diff --git a/src/share/vm/memory/dump.cpp b/src/share/vm/memory/dump.cpp index cb66e8608a7ff56df6531c629aa35818ac64805b..75a0f8b4a6047ecff4b89fb33baba288627711ea 100644 --- a/src/share/vm/memory/dump.cpp +++ b/src/share/vm/memory/dump.cpp @@ -1402,7 +1402,7 @@ class LinkClassesClosure : public ObjectClosure { instanceKlass* ik = (instanceKlass*) k; // Link the class to cause the bytecodes to be rewritten and the // cpcache to be created. - if (ik->get_init_state() < instanceKlass::linked) { + if (ik->init_state() < instanceKlass::linked) { ik->link_class(THREAD); guarantee(!HAS_PENDING_EXCEPTION, "exception in class rewriting"); } @@ -1535,7 +1535,7 @@ void GenCollectedHeap::preload_and_dump(TRAPS) { // are loaded in order that the related data structures (klass, // cpCache, Sting constants) are located together. - if (ik->get_init_state() < instanceKlass::linked) { + if (ik->init_state() < instanceKlass::linked) { ik->link_class(THREAD); guarantee(!(HAS_PENDING_EXCEPTION), "exception in class rewriting"); } diff --git a/src/share/vm/oops/instanceKlass.cpp b/src/share/vm/oops/instanceKlass.cpp index 04b3c2ffc32bcf8335b66d9f982cf651c3f1b756..e20a6ed1a1a78f5ffc592bcbca88237f75a12e1d 100644 --- a/src/share/vm/oops/instanceKlass.cpp +++ b/src/share/vm/oops/instanceKlass.cpp @@ -208,7 +208,7 @@ void instanceKlass::eager_initialize_impl(instanceKlassHandle this_oop) { // abort if someone beat us to the initialization if (!this_oop->is_not_initialized()) return; // note: not equivalent to is_initialized() - ClassState old_state = this_oop->_init_state; + ClassState old_state = this_oop->init_state(); link_class_impl(this_oop, true, THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; @@ -2479,7 +2479,7 @@ void instanceKlass::set_init_state(ClassState state) { bool good_state = as_klassOop()->is_shared() ? (_init_state <= state) : (_init_state < state); assert(good_state || state == allocated, "illegal state transition"); - _init_state = state; + _init_state = (u1)state; } #endif diff --git a/src/share/vm/oops/instanceKlass.hpp b/src/share/vm/oops/instanceKlass.hpp index a87448a7680310b6d5b4c77dbf8a7e50791fe669..36928ca2cd740fb59b25ae8e4dffe2dd1e24b024 100644 --- a/src/share/vm/oops/instanceKlass.hpp +++ b/src/share/vm/oops/instanceKlass.hpp @@ -230,13 +230,9 @@ class instanceKlass: public Klass { int _static_oop_field_count;// number of static oop fields in this klass int _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks int _java_fields_count; // The number of declared Java fields - 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 + u2 _minor_version; // minor version number of class file u2 _major_version; // major version number of class file - ClassState _init_state; // state of class Thread* _init_thread; // Pointer to current thread doing initialization (to handle recusive initialization) int _vtable_len; // length of Java vtable (in words) int _itable_len; // length of Java itable (in words) @@ -260,6 +256,24 @@ class instanceKlass: public Klass { JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change + // Class states are defined as ClassState (see above). + // Place the _init_state here to utilize the unused 2-byte after + // _idnum_allocated_count. + u1 _init_state; // state of class + + // Compact the following four boolean flags into 1-bit each. These four flags + // were defined as separate boolean fields and each was 1-byte before. Since + // there are 2 bytes unused after the _idnum_allocated_count field, place the + // _misc_flags field after _idnum_allocated_count to utilize the unused bits + // and save total 4-bytes. + enum { + IS_MARKED_DEPENDENT = 0x1, // used for marking during flushing and deoptimization + REWRITTEN = 0x2, // methods rewritten. + HAS_NONSTATIC_FIELDS = 0x4, // for sizing with UseCompressedOops + SHOULD_VERIFY_CLASS = 0x8 // allow caching of preverification + }; + u1 _misc_flags; + // embedded Java vtable follows here // embedded Java itables follows here // embedded static fields follows here @@ -269,8 +283,14 @@ class instanceKlass: public Klass { 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 & HAS_NONSTATIC_FIELDS) != 0; } + void set_has_nonstatic_fields(bool b) { + if (b) { + _misc_flags |= HAS_NONSTATIC_FIELDS; + } else { + _misc_flags &= ~HAS_NONSTATIC_FIELDS; + } + } // field sizes int nonstatic_field_size() const { return _nonstatic_field_size; } @@ -377,16 +397,24 @@ class instanceKlass: public Klass { bool is_being_initialized() const { return _init_state == being_initialized; } bool is_in_error_state() const { return _init_state == initialization_error; } bool is_reentrant_initialization(Thread *thread) { return thread == _init_thread; } - int get_init_state() { return _init_state; } // Useful for debugging - bool is_rewritten() const { return _rewritten; } + ClassState init_state() { return (ClassState)_init_state; } + bool is_rewritten() const { return (_misc_flags & 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 & SHOULD_VERIFY_CLASS) != 0; } + void set_should_verify_class(bool value) { + if (value) { + _misc_flags |= SHOULD_VERIFY_CLASS; + } else { + _misc_flags &= ~SHOULD_VERIFY_CLASS; + } + } + // marking - bool is_marked_dependent() const { return _is_marked_dependent; } - void set_is_marked_dependent(bool value) { _is_marked_dependent = value; } + bool is_marked_dependent() const { return (_misc_flags & IS_MARKED_DEPENDENT) != 0; } + void set_is_marked_dependent() { _misc_flags |= IS_MARKED_DEPENDENT; } + void clear_is_marked_dependent() { _misc_flags &= ~IS_MARKED_DEPENDENT; } // initialization (virtuals from Klass) bool should_be_initialized() const; // means that initialize should be called @@ -754,9 +782,9 @@ private: #ifdef ASSERT void set_init_state(ClassState state); #else - void set_init_state(ClassState state) { _init_state = state; } + void set_init_state(ClassState state) { _init_state = (u1)state; } #endif - void set_rewritten() { _rewritten = true; } + void set_rewritten() { _misc_flags |= REWRITTEN; } void set_init_thread(Thread *thread) { _init_thread = thread; } u2 idnum_allocated_count() const { return _idnum_allocated_count; } diff --git a/src/share/vm/oops/instanceKlassKlass.cpp b/src/share/vm/oops/instanceKlassKlass.cpp index fa13f17ede44e0ff6f48a488ed8185e1674f7c6a..681d03c91d83bc0165f53f386e0c88ff333acac0 100644 --- a/src/share/vm/oops/instanceKlassKlass.cpp +++ b/src/share/vm/oops/instanceKlassKlass.cpp @@ -399,7 +399,7 @@ instanceKlassKlass::allocate_instance_klass(Symbol* name, int vtable_len, int it ik->set_inner_classes(NULL); ik->set_static_oop_field_count(0); ik->set_nonstatic_field_size(0); - ik->set_is_marked_dependent(false); + ik->clear_is_marked_dependent(); ik->set_init_state(instanceKlass::allocated); ik->set_init_thread(NULL); ik->set_reference_type(rt); diff --git a/src/share/vm/opto/library_call.cpp b/src/share/vm/opto/library_call.cpp index d5ad00e16e0be155ba59440ec5073cfa2ee64876..7d4bb881ab92a4aab690a8b2a2dba1f38e5a30e9 100644 --- a/src/share/vm/opto/library_call.cpp +++ b/src/share/vm/opto/library_call.cpp @@ -2807,7 +2807,9 @@ bool LibraryCallKit::inline_unsafe_allocate() { // Serializable.class or Object[].class. The runtime will handle it. // But we must make an explicit check for initialization. Node* insp = basic_plus_adr(kls, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc)); - Node* inst = make_load(NULL, insp, TypeInt::INT, T_INT); + // Use T_BOOLEAN for instanceKlass::_init_state so the compiler + // can generate code to load it as unsigned byte. + Node* inst = make_load(NULL, insp, TypeInt::UBYTE, T_BOOLEAN); Node* bits = intcon(instanceKlass::fully_initialized); Node* test = _gvn.transform( new (C, 3) SubINode(inst, bits) ); // The 'test' is non-zero if we need to take a slow path. diff --git a/src/share/vm/opto/parseHelper.cpp b/src/share/vm/opto/parseHelper.cpp index 5a9d7e146f6c736f8fa4ba42bc07f3553bc1df63..1a5ce207db61998e90be26114c7cf4872b5d8232 100644 --- a/src/share/vm/opto/parseHelper.cpp +++ b/src/share/vm/opto/parseHelper.cpp @@ -230,7 +230,9 @@ void Parse::emit_guard_for_new(ciInstanceKlass* klass) { Node* init_state_offset = _gvn.MakeConX(instanceKlass::init_state_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()); adr_node = basic_plus_adr(kls, kls, init_state_offset); - Node* init_state = make_load(NULL, adr_node, TypeInt::INT, T_INT); + // Use T_BOOLEAN for instanceKlass::_init_state so the compiler + // can generate code to load it as unsigned byte. + Node* init_state = make_load(NULL, adr_node, TypeInt::UBYTE, T_BOOLEAN); Node* being_init = _gvn.intcon(instanceKlass::being_initialized); tst = Bool( CmpI( init_state, being_init), BoolTest::eq); iff = create_and_map_if(control(), tst, PROB_ALWAYS, COUNT_UNKNOWN); diff --git a/src/share/vm/runtime/mutex.cpp b/src/share/vm/runtime/mutex.cpp index 80d3d874273b32b8be79ee74e6af1c87167a42fd..dddd27cc2fa5196d440c960e048e5d0e4350ff7c 100644 --- a/src/share/vm/runtime/mutex.cpp +++ b/src/share/vm/runtime/mutex.cpp @@ -527,7 +527,21 @@ void Monitor::ILock (Thread * Self) { void Monitor::IUnlock (bool RelaxAssert) { assert (ILocked(), "invariant") ; - _LockWord.Bytes[_LSBINDEX] = 0 ; // drop outer lock + // Conceptually we need a MEMBAR #storestore|#loadstore barrier or fence immediately + // before the store that releases the lock. Crucially, all the stores and loads in the + // critical section must be globally visible before the store of 0 into the lock-word + // that releases the lock becomes globally visible. That is, memory accesses in the + // critical section should not be allowed to bypass or overtake the following ST that + // releases the lock. As such, to prevent accesses within the critical section + // from "leaking" out, we need a release fence between the critical section and the + // store that releases the lock. In practice that release barrier is elided on + // platforms with strong memory models such as TSO. + // + // Note that the OrderAccess::storeload() fence that appears after unlock store + // provides for progress conditions and succession and is _not related to exclusion + // safety or lock release consistency. + OrderAccess::release_store(&_LockWord.Bytes[_LSBINDEX], 0); // drop outer lock + OrderAccess::storeload (); ParkEvent * const w = _OnDeck ; assert (RelaxAssert || w != Thread::current()->_MutexEvent, "invariant") ; diff --git a/src/share/vm/runtime/vmStructs.cpp b/src/share/vm/runtime/vmStructs.cpp index 00fe3582e673aa76712d0bd4a6f9f280706525a8..46b5a19a2b521aa234a483619a35eb110cecb3d0 100644 --- a/src/share/vm/runtime/vmStructs.cpp +++ b/src/share/vm/runtime/vmStructs.cpp @@ -307,10 +307,10 @@ static inline uint64_t cast_uint64_t(size_t x) nonstatic_field(instanceKlass, _static_field_size, int) \ nonstatic_field(instanceKlass, _static_oop_field_count, int) \ nonstatic_field(instanceKlass, _nonstatic_oop_map_size, int) \ - nonstatic_field(instanceKlass, _is_marked_dependent, bool) \ + nonstatic_field(instanceKlass, _misc_flags, u1) \ nonstatic_field(instanceKlass, _minor_version, u2) \ nonstatic_field(instanceKlass, _major_version, u2) \ - nonstatic_field(instanceKlass, _init_state, instanceKlass::ClassState) \ + nonstatic_field(instanceKlass, _init_state, u1) \ nonstatic_field(instanceKlass, _init_thread, Thread*) \ nonstatic_field(instanceKlass, _vtable_len, int) \ nonstatic_field(instanceKlass, _itable_len, int) \ @@ -1362,6 +1362,7 @@ static inline uint64_t cast_uint64_t(size_t x) /* The compiler thinks this is a different type than */ \ /* unsigned short on Win32 */ \ declare_unsigned_integer_type(u2) \ + declare_unsigned_integer_type(u1) \ declare_unsigned_integer_type(unsigned) \ \ /*****************************/ \ @@ -2385,6 +2386,7 @@ static inline uint64_t cast_uint64_t(size_t x) declare_constant(instanceKlass::being_initialized) \ declare_constant(instanceKlass::fully_initialized) \ declare_constant(instanceKlass::initialization_error) \ + declare_constant(instanceKlass::IS_MARKED_DEPENDENT) \ \ /*********************************/ \ /* Symbol* - symbol max length */ \