Fri, 16 Dec 2011 17:33:08 -0500
Merge
1.1 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java Wed Dec 14 20:06:21 2011 -0500 1.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java Fri Dec 16 17:33:08 2011 -0500 1.3 @@ -63,6 +63,8 @@ 1.4 private static int CLASS_STATE_FULLY_INITIALIZED; 1.5 private static int CLASS_STATE_INITIALIZATION_ERROR; 1.6 1.7 + private static int IS_MARKED_DEPENDENT_MASK; 1.8 + 1.9 private static synchronized void initialize(TypeDataBase db) throws WrongTypeException { 1.10 Type type = db.lookupType("instanceKlass"); 1.11 arrayKlasses = new OopField(type.getOopField("_array_klasses"), Oop.getHeaderSize()); 1.12 @@ -90,7 +92,7 @@ 1.13 staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), Oop.getHeaderSize()); 1.14 staticOopFieldCount = new CIntField(type.getCIntegerField("_static_oop_field_count"), Oop.getHeaderSize()); 1.15 nonstaticOopMapSize = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), Oop.getHeaderSize()); 1.16 - isMarkedDependent = new CIntField(type.getCIntegerField("_is_marked_dependent"), Oop.getHeaderSize()); 1.17 + miscFlags = new CIntField(type.getCIntegerField("_misc_flags"), Oop.getHeaderSize()); 1.18 initState = new CIntField(type.getCIntegerField("_init_state"), Oop.getHeaderSize()); 1.19 vtableLen = new CIntField(type.getCIntegerField("_vtable_len"), Oop.getHeaderSize()); 1.20 itableLen = new CIntField(type.getCIntegerField("_itable_len"), Oop.getHeaderSize()); 1.21 @@ -118,6 +120,8 @@ 1.22 CLASS_STATE_FULLY_INITIALIZED = db.lookupIntConstant("instanceKlass::fully_initialized").intValue(); 1.23 CLASS_STATE_INITIALIZATION_ERROR = db.lookupIntConstant("instanceKlass::initialization_error").intValue(); 1.24 1.25 + IS_MARKED_DEPENDENT_MASK = db.lookupIntConstant("instanceKlass::IS_MARKED_DEPENDENT").intValue(); 1.26 + 1.27 } 1.28 1.29 InstanceKlass(OopHandle handle, ObjectHeap heap) { 1.30 @@ -151,7 +155,7 @@ 1.31 private static CIntField staticFieldSize; 1.32 private static CIntField staticOopFieldCount; 1.33 private static CIntField nonstaticOopMapSize; 1.34 - private static CIntField isMarkedDependent; 1.35 + private static CIntField miscFlags; 1.36 private static CIntField initState; 1.37 private static CIntField vtableLen; 1.38 private static CIntField itableLen; 1.39 @@ -333,7 +337,7 @@ 1.40 public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); } 1.41 public long getStaticOopFieldCount() { return staticOopFieldCount.getValue(this); } 1.42 public long getNonstaticOopMapSize() { return nonstaticOopMapSize.getValue(this); } 1.43 - public boolean getIsMarkedDependent() { return isMarkedDependent.getValue(this) != 0; } 1.44 + public boolean getIsMarkedDependent() { return (miscFlags.getValue(this) & IS_MARKED_DEPENDENT_MASK) != 0; } 1.45 public long getVtableLen() { return vtableLen.getValue(this); } 1.46 public long getItableLen() { return itableLen.getValue(this); } 1.47 public Symbol getGenericSignature() { return getSymbol(genericSignature); } 1.48 @@ -524,7 +528,7 @@ 1.49 visitor.doCInt(staticFieldSize, true); 1.50 visitor.doCInt(staticOopFieldCount, true); 1.51 visitor.doCInt(nonstaticOopMapSize, true); 1.52 - visitor.doCInt(isMarkedDependent, true); 1.53 + visitor.doCInt(miscFlags, true); 1.54 visitor.doCInt(initState, true); 1.55 visitor.doCInt(vtableLen, true); 1.56 visitor.doCInt(itableLen, true);
2.1 --- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Wed Dec 14 20:06:21 2011 -0500 2.2 +++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Fri Dec 16 17:33:08 2011 -0500 2.3 @@ -2455,7 +2455,7 @@ 2.4 op->obj()->as_register() == O0 && 2.5 op->klass()->as_register() == G5, "must be"); 2.6 if (op->init_check()) { 2.7 - __ ld(op->klass()->as_register(), 2.8 + __ ldub(op->klass()->as_register(), 2.9 instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc), 2.10 op->tmp1()->as_register()); 2.11 add_debug_info_for_null_check_here(op->stub()->info());
3.1 --- a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Wed Dec 14 20:06:21 2011 -0500 3.2 +++ b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp Fri Dec 16 17:33:08 2011 -0500 3.3 @@ -398,7 +398,7 @@ 3.4 3.5 if (id == fast_new_instance_init_check_id) { 3.6 // make sure the klass is initialized 3.7 - __ ld(G5_klass, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc), G3_t1); 3.8 + __ ldub(G5_klass, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc), G3_t1); 3.9 __ cmp_and_br_short(G3_t1, instanceKlass::fully_initialized, Assembler::notEqual, Assembler::pn, slow_path); 3.10 } 3.11 #ifdef ASSERT
4.1 --- a/src/cpu/sparc/vm/templateTable_sparc.cpp Wed Dec 14 20:06:21 2011 -0500 4.2 +++ b/src/cpu/sparc/vm/templateTable_sparc.cpp Fri Dec 16 17:33:08 2011 -0500 4.3 @@ -3350,7 +3350,7 @@ 4.4 __ ld_ptr(Rscratch, Roffset, RinstanceKlass); 4.5 4.6 // make sure klass is fully initialized: 4.7 - __ ld(RinstanceKlass, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc), G3_scratch); 4.8 + __ ldub(RinstanceKlass, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc), G3_scratch); 4.9 __ cmp(G3_scratch, instanceKlass::fully_initialized); 4.10 __ br(Assembler::notEqual, false, Assembler::pn, slow_case); 4.11 __ delayed()->ld(RinstanceKlass, Klass::layout_helper_offset_in_bytes() + sizeof(oopDesc), Roffset);
5.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Wed Dec 14 20:06:21 2011 -0500 5.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Fri Dec 16 17:33:08 2011 -0500 5.3 @@ -1557,7 +1557,7 @@ 5.4 5.5 void LIR_Assembler::emit_alloc_obj(LIR_OpAllocObj* op) { 5.6 if (op->init_check()) { 5.7 - __ cmpl(Address(op->klass()->as_register(), 5.8 + __ cmpb(Address(op->klass()->as_register(), 5.9 instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc)), 5.10 instanceKlass::fully_initialized); 5.11 add_debug_info_for_null_check_here(op->stub()->info());
6.1 --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp Wed Dec 14 20:06:21 2011 -0500 6.2 +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp Fri Dec 16 17:33:08 2011 -0500 6.3 @@ -1011,7 +1011,7 @@ 6.4 6.5 if (id == fast_new_instance_init_check_id) { 6.6 // make sure the klass is initialized 6.7 - __ cmpl(Address(klass, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc)), instanceKlass::fully_initialized); 6.8 + __ cmpb(Address(klass, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc)), instanceKlass::fully_initialized); 6.9 __ jcc(Assembler::notEqual, slow_path); 6.10 } 6.11
7.1 --- a/src/cpu/x86/vm/templateTable_x86_32.cpp Wed Dec 14 20:06:21 2011 -0500 7.2 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp Fri Dec 16 17:33:08 2011 -0500 7.3 @@ -3188,7 +3188,7 @@ 7.4 7.5 // make sure klass is initialized & doesn't have finalizer 7.6 // make sure klass is fully initialized 7.7 - __ cmpl(Address(rcx, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc)), instanceKlass::fully_initialized); 7.8 + __ cmpb(Address(rcx, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc)), instanceKlass::fully_initialized); 7.9 __ jcc(Assembler::notEqual, slow_case); 7.10 7.11 // get instance_size in instanceKlass (scaled to a count of bytes)
8.1 --- a/src/cpu/x86/vm/templateTable_x86_64.cpp Wed Dec 14 20:06:21 2011 -0500 8.2 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp Fri Dec 16 17:33:08 2011 -0500 8.3 @@ -3235,7 +3235,7 @@ 8.4 8.5 // make sure klass is initialized & doesn't have finalizer 8.6 // make sure klass is fully initialized 8.7 - __ cmpl(Address(rsi, 8.8 + __ cmpb(Address(rsi, 8.9 instanceKlass::init_state_offset_in_bytes() + 8.10 sizeof(oopDesc)), 8.11 instanceKlass::fully_initialized);
9.1 --- a/src/share/vm/ci/ciInstanceKlass.cpp Wed Dec 14 20:06:21 2011 -0500 9.2 +++ b/src/share/vm/ci/ciInstanceKlass.cpp Fri Dec 16 17:33:08 2011 -0500 9.3 @@ -54,7 +54,7 @@ 9.4 _flags = ciFlags(access_flags); 9.5 _has_finalizer = access_flags.has_finalizer(); 9.6 _has_subklass = ik->subklass() != NULL; 9.7 - _init_state = (instanceKlass::ClassState)ik->get_init_state(); 9.8 + _init_state = ik->init_state(); 9.9 _nonstatic_field_size = ik->nonstatic_field_size(); 9.10 _has_nonstatic_fields = ik->has_nonstatic_fields(); 9.11 _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields: 9.12 @@ -118,7 +118,7 @@ 9.13 void ciInstanceKlass::compute_shared_init_state() { 9.14 GUARDED_VM_ENTRY( 9.15 instanceKlass* ik = get_instanceKlass(); 9.16 - _init_state = (instanceKlass::ClassState)ik->get_init_state(); 9.17 + _init_state = ik->init_state(); 9.18 ) 9.19 } 9.20
10.1 --- a/src/share/vm/code/dependencies.cpp Wed Dec 14 20:06:21 2011 -0500 10.2 +++ b/src/share/vm/code/dependencies.cpp Fri Dec 16 17:33:08 2011 -0500 10.3 @@ -1631,7 +1631,7 @@ 10.4 for (ContextStream str(*this); str.next(); ) { 10.5 klassOop d = str.klass(); 10.6 assert(!instanceKlass::cast(d)->is_marked_dependent(), "checking"); 10.7 - instanceKlass::cast(d)->set_is_marked_dependent(true); 10.8 + instanceKlass::cast(d)->set_is_marked_dependent(); 10.9 } 10.10 } 10.11 10.12 @@ -1640,7 +1640,7 @@ 10.13 // Unmark transitive interfaces 10.14 for (ContextStream str(*this); str.next(); ) { 10.15 klassOop d = str.klass(); 10.16 - instanceKlass::cast(d)->set_is_marked_dependent(false); 10.17 + instanceKlass::cast(d)->clear_is_marked_dependent(); 10.18 } 10.19 } 10.20
11.1 --- a/src/share/vm/memory/dump.cpp Wed Dec 14 20:06:21 2011 -0500 11.2 +++ b/src/share/vm/memory/dump.cpp Fri Dec 16 17:33:08 2011 -0500 11.3 @@ -1402,7 +1402,7 @@ 11.4 instanceKlass* ik = (instanceKlass*) k; 11.5 // Link the class to cause the bytecodes to be rewritten and the 11.6 // cpcache to be created. 11.7 - if (ik->get_init_state() < instanceKlass::linked) { 11.8 + if (ik->init_state() < instanceKlass::linked) { 11.9 ik->link_class(THREAD); 11.10 guarantee(!HAS_PENDING_EXCEPTION, "exception in class rewriting"); 11.11 } 11.12 @@ -1535,7 +1535,7 @@ 11.13 // are loaded in order that the related data structures (klass, 11.14 // cpCache, Sting constants) are located together. 11.15 11.16 - if (ik->get_init_state() < instanceKlass::linked) { 11.17 + if (ik->init_state() < instanceKlass::linked) { 11.18 ik->link_class(THREAD); 11.19 guarantee(!(HAS_PENDING_EXCEPTION), "exception in class rewriting"); 11.20 }
12.1 --- a/src/share/vm/oops/instanceKlass.cpp Wed Dec 14 20:06:21 2011 -0500 12.2 +++ b/src/share/vm/oops/instanceKlass.cpp Fri Dec 16 17:33:08 2011 -0500 12.3 @@ -208,7 +208,7 @@ 12.4 // abort if someone beat us to the initialization 12.5 if (!this_oop->is_not_initialized()) return; // note: not equivalent to is_initialized() 12.6 12.7 - ClassState old_state = this_oop->_init_state; 12.8 + ClassState old_state = this_oop->init_state(); 12.9 link_class_impl(this_oop, true, THREAD); 12.10 if (HAS_PENDING_EXCEPTION) { 12.11 CLEAR_PENDING_EXCEPTION; 12.12 @@ -2479,7 +2479,7 @@ 12.13 bool good_state = as_klassOop()->is_shared() ? (_init_state <= state) 12.14 : (_init_state < state); 12.15 assert(good_state || state == allocated, "illegal state transition"); 12.16 - _init_state = state; 12.17 + _init_state = (u1)state; 12.18 } 12.19 #endif 12.20
13.1 --- a/src/share/vm/oops/instanceKlass.hpp Wed Dec 14 20:06:21 2011 -0500 13.2 +++ b/src/share/vm/oops/instanceKlass.hpp Fri Dec 16 17:33:08 2011 -0500 13.3 @@ -230,13 +230,9 @@ 13.4 int _static_oop_field_count;// number of static oop fields in this klass 13.5 int _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks 13.6 int _java_fields_count; // The number of declared Java fields 13.7 - bool _is_marked_dependent; // used for marking during flushing and deoptimization 13.8 - bool _rewritten; // methods rewritten. 13.9 - bool _has_nonstatic_fields; // for sizing with UseCompressedOops 13.10 - bool _should_verify_class; // allow caching of preverification 13.11 + 13.12 u2 _minor_version; // minor version number of class file 13.13 u2 _major_version; // major version number of class file 13.14 - ClassState _init_state; // state of class 13.15 Thread* _init_thread; // Pointer to current thread doing initialization (to handle recusive initialization) 13.16 int _vtable_len; // length of Java vtable (in words) 13.17 int _itable_len; // length of Java itable (in words) 13.18 @@ -260,6 +256,24 @@ 13.19 JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration 13.20 volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change 13.21 13.22 + // Class states are defined as ClassState (see above). 13.23 + // Place the _init_state here to utilize the unused 2-byte after 13.24 + // _idnum_allocated_count. 13.25 + u1 _init_state; // state of class 13.26 + 13.27 + // Compact the following four boolean flags into 1-bit each. These four flags 13.28 + // were defined as separate boolean fields and each was 1-byte before. Since 13.29 + // there are 2 bytes unused after the _idnum_allocated_count field, place the 13.30 + // _misc_flags field after _idnum_allocated_count to utilize the unused bits 13.31 + // and save total 4-bytes. 13.32 + enum { 13.33 + IS_MARKED_DEPENDENT = 0x1, // used for marking during flushing and deoptimization 13.34 + REWRITTEN = 0x2, // methods rewritten. 13.35 + HAS_NONSTATIC_FIELDS = 0x4, // for sizing with UseCompressedOops 13.36 + SHOULD_VERIFY_CLASS = 0x8 // allow caching of preverification 13.37 + }; 13.38 + u1 _misc_flags; 13.39 + 13.40 // embedded Java vtable follows here 13.41 // embedded Java itables follows here 13.42 // embedded static fields follows here 13.43 @@ -269,8 +283,14 @@ 13.44 friend class SystemDictionary; 13.45 13.46 public: 13.47 - bool has_nonstatic_fields() const { return _has_nonstatic_fields; } 13.48 - void set_has_nonstatic_fields(bool b) { _has_nonstatic_fields = b; } 13.49 + bool has_nonstatic_fields() const { return (_misc_flags & HAS_NONSTATIC_FIELDS) != 0; } 13.50 + void set_has_nonstatic_fields(bool b) { 13.51 + if (b) { 13.52 + _misc_flags |= HAS_NONSTATIC_FIELDS; 13.53 + } else { 13.54 + _misc_flags &= ~HAS_NONSTATIC_FIELDS; 13.55 + } 13.56 + } 13.57 13.58 // field sizes 13.59 int nonstatic_field_size() const { return _nonstatic_field_size; } 13.60 @@ -377,16 +397,24 @@ 13.61 bool is_being_initialized() const { return _init_state == being_initialized; } 13.62 bool is_in_error_state() const { return _init_state == initialization_error; } 13.63 bool is_reentrant_initialization(Thread *thread) { return thread == _init_thread; } 13.64 - int get_init_state() { return _init_state; } // Useful for debugging 13.65 - bool is_rewritten() const { return _rewritten; } 13.66 + ClassState init_state() { return (ClassState)_init_state; } 13.67 + bool is_rewritten() const { return (_misc_flags & REWRITTEN) != 0; } 13.68 13.69 // defineClass specified verification 13.70 - bool should_verify_class() const { return _should_verify_class; } 13.71 - void set_should_verify_class(bool value) { _should_verify_class = value; } 13.72 + bool should_verify_class() const { return (_misc_flags & SHOULD_VERIFY_CLASS) != 0; } 13.73 + void set_should_verify_class(bool value) { 13.74 + if (value) { 13.75 + _misc_flags |= SHOULD_VERIFY_CLASS; 13.76 + } else { 13.77 + _misc_flags &= ~SHOULD_VERIFY_CLASS; 13.78 + } 13.79 + } 13.80 + 13.81 13.82 // marking 13.83 - bool is_marked_dependent() const { return _is_marked_dependent; } 13.84 - void set_is_marked_dependent(bool value) { _is_marked_dependent = value; } 13.85 + bool is_marked_dependent() const { return (_misc_flags & IS_MARKED_DEPENDENT) != 0; } 13.86 + void set_is_marked_dependent() { _misc_flags |= IS_MARKED_DEPENDENT; } 13.87 + void clear_is_marked_dependent() { _misc_flags &= ~IS_MARKED_DEPENDENT; } 13.88 13.89 // initialization (virtuals from Klass) 13.90 bool should_be_initialized() const; // means that initialize should be called 13.91 @@ -754,9 +782,9 @@ 13.92 #ifdef ASSERT 13.93 void set_init_state(ClassState state); 13.94 #else 13.95 - void set_init_state(ClassState state) { _init_state = state; } 13.96 + void set_init_state(ClassState state) { _init_state = (u1)state; } 13.97 #endif 13.98 - void set_rewritten() { _rewritten = true; } 13.99 + void set_rewritten() { _misc_flags |= REWRITTEN; } 13.100 void set_init_thread(Thread *thread) { _init_thread = thread; } 13.101 13.102 u2 idnum_allocated_count() const { return _idnum_allocated_count; }
14.1 --- a/src/share/vm/oops/instanceKlassKlass.cpp Wed Dec 14 20:06:21 2011 -0500 14.2 +++ b/src/share/vm/oops/instanceKlassKlass.cpp Fri Dec 16 17:33:08 2011 -0500 14.3 @@ -399,7 +399,7 @@ 14.4 ik->set_inner_classes(NULL); 14.5 ik->set_static_oop_field_count(0); 14.6 ik->set_nonstatic_field_size(0); 14.7 - ik->set_is_marked_dependent(false); 14.8 + ik->clear_is_marked_dependent(); 14.9 ik->set_init_state(instanceKlass::allocated); 14.10 ik->set_init_thread(NULL); 14.11 ik->set_reference_type(rt);
15.1 --- a/src/share/vm/opto/library_call.cpp Wed Dec 14 20:06:21 2011 -0500 15.2 +++ b/src/share/vm/opto/library_call.cpp Fri Dec 16 17:33:08 2011 -0500 15.3 @@ -2807,7 +2807,9 @@ 15.4 // Serializable.class or Object[].class. The runtime will handle it. 15.5 // But we must make an explicit check for initialization. 15.6 Node* insp = basic_plus_adr(kls, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc)); 15.7 - Node* inst = make_load(NULL, insp, TypeInt::INT, T_INT); 15.8 + // Use T_BOOLEAN for instanceKlass::_init_state so the compiler 15.9 + // can generate code to load it as unsigned byte. 15.10 + Node* inst = make_load(NULL, insp, TypeInt::UBYTE, T_BOOLEAN); 15.11 Node* bits = intcon(instanceKlass::fully_initialized); 15.12 Node* test = _gvn.transform( new (C, 3) SubINode(inst, bits) ); 15.13 // The 'test' is non-zero if we need to take a slow path.
16.1 --- a/src/share/vm/opto/parseHelper.cpp Wed Dec 14 20:06:21 2011 -0500 16.2 +++ b/src/share/vm/opto/parseHelper.cpp Fri Dec 16 17:33:08 2011 -0500 16.3 @@ -230,7 +230,9 @@ 16.4 16.5 Node* init_state_offset = _gvn.MakeConX(instanceKlass::init_state_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()); 16.6 adr_node = basic_plus_adr(kls, kls, init_state_offset); 16.7 - Node* init_state = make_load(NULL, adr_node, TypeInt::INT, T_INT); 16.8 + // Use T_BOOLEAN for instanceKlass::_init_state so the compiler 16.9 + // can generate code to load it as unsigned byte. 16.10 + Node* init_state = make_load(NULL, adr_node, TypeInt::UBYTE, T_BOOLEAN); 16.11 Node* being_init = _gvn.intcon(instanceKlass::being_initialized); 16.12 tst = Bool( CmpI( init_state, being_init), BoolTest::eq); 16.13 iff = create_and_map_if(control(), tst, PROB_ALWAYS, COUNT_UNKNOWN);
17.1 --- a/src/share/vm/runtime/mutex.cpp Wed Dec 14 20:06:21 2011 -0500 17.2 +++ b/src/share/vm/runtime/mutex.cpp Fri Dec 16 17:33:08 2011 -0500 17.3 @@ -527,7 +527,21 @@ 17.4 17.5 void Monitor::IUnlock (bool RelaxAssert) { 17.6 assert (ILocked(), "invariant") ; 17.7 - _LockWord.Bytes[_LSBINDEX] = 0 ; // drop outer lock 17.8 + // Conceptually we need a MEMBAR #storestore|#loadstore barrier or fence immediately 17.9 + // before the store that releases the lock. Crucially, all the stores and loads in the 17.10 + // critical section must be globally visible before the store of 0 into the lock-word 17.11 + // that releases the lock becomes globally visible. That is, memory accesses in the 17.12 + // critical section should not be allowed to bypass or overtake the following ST that 17.13 + // releases the lock. As such, to prevent accesses within the critical section 17.14 + // from "leaking" out, we need a release fence between the critical section and the 17.15 + // store that releases the lock. In practice that release barrier is elided on 17.16 + // platforms with strong memory models such as TSO. 17.17 + // 17.18 + // Note that the OrderAccess::storeload() fence that appears after unlock store 17.19 + // provides for progress conditions and succession and is _not related to exclusion 17.20 + // safety or lock release consistency. 17.21 + OrderAccess::release_store(&_LockWord.Bytes[_LSBINDEX], 0); // drop outer lock 17.22 + 17.23 OrderAccess::storeload (); 17.24 ParkEvent * const w = _OnDeck ; 17.25 assert (RelaxAssert || w != Thread::current()->_MutexEvent, "invariant") ;
18.1 --- a/src/share/vm/runtime/vmStructs.cpp Wed Dec 14 20:06:21 2011 -0500 18.2 +++ b/src/share/vm/runtime/vmStructs.cpp Fri Dec 16 17:33:08 2011 -0500 18.3 @@ -307,10 +307,10 @@ 18.4 nonstatic_field(instanceKlass, _static_field_size, int) \ 18.5 nonstatic_field(instanceKlass, _static_oop_field_count, int) \ 18.6 nonstatic_field(instanceKlass, _nonstatic_oop_map_size, int) \ 18.7 - nonstatic_field(instanceKlass, _is_marked_dependent, bool) \ 18.8 + nonstatic_field(instanceKlass, _misc_flags, u1) \ 18.9 nonstatic_field(instanceKlass, _minor_version, u2) \ 18.10 nonstatic_field(instanceKlass, _major_version, u2) \ 18.11 - nonstatic_field(instanceKlass, _init_state, instanceKlass::ClassState) \ 18.12 + nonstatic_field(instanceKlass, _init_state, u1) \ 18.13 nonstatic_field(instanceKlass, _init_thread, Thread*) \ 18.14 nonstatic_field(instanceKlass, _vtable_len, int) \ 18.15 nonstatic_field(instanceKlass, _itable_len, int) \ 18.16 @@ -1362,6 +1362,7 @@ 18.17 /* The compiler thinks this is a different type than */ \ 18.18 /* unsigned short on Win32 */ \ 18.19 declare_unsigned_integer_type(u2) \ 18.20 + declare_unsigned_integer_type(u1) \ 18.21 declare_unsigned_integer_type(unsigned) \ 18.22 \ 18.23 /*****************************/ \ 18.24 @@ -2385,6 +2386,7 @@ 18.25 declare_constant(instanceKlass::being_initialized) \ 18.26 declare_constant(instanceKlass::fully_initialized) \ 18.27 declare_constant(instanceKlass::initialization_error) \ 18.28 + declare_constant(instanceKlass::IS_MARKED_DEPENDENT) \ 18.29 \ 18.30 /*********************************/ \ 18.31 /* Symbol* - symbol max length */ \