Sat, 31 Jan 2009 00:15:00 -0800
6792421: assert(_bitMap->isMarked(addr+size-1),inconsistent Printezis mark)
Summary: The CMS concurrent precleaning and concurrent marking phases should work around classes that are undergoing redefinition.
Reviewed-by: ysr, tonyp
1.1 --- a/src/share/vm/gc_interface/collectedHeap.hpp Fri Jan 30 14:17:52 2009 -0800 1.2 +++ b/src/share/vm/gc_interface/collectedHeap.hpp Sat Jan 31 00:15:00 2009 -0800 1.3 @@ -42,6 +42,7 @@ 1.4 class CollectedHeap : public CHeapObj { 1.5 friend class VMStructs; 1.6 friend class IsGCActiveMark; // Block structured external access to _is_gc_active 1.7 + friend class constantPoolCacheKlass; // allocate() method inserts is_conc_safe 1.8 1.9 #ifdef ASSERT 1.10 static int _fire_out_of_memory_count; 1.11 @@ -82,8 +83,6 @@ 1.12 // Reinitialize tlabs before resuming mutators. 1.13 virtual void resize_all_tlabs(); 1.14 1.15 - debug_only(static void check_for_valid_allocation_state();) 1.16 - 1.17 protected: 1.18 // Allocate from the current thread's TLAB, with broken-out slow path. 1.19 inline static HeapWord* allocate_from_tlab(Thread* thread, size_t size); 1.20 @@ -142,6 +141,7 @@ 1.21 PRODUCT_RETURN; 1.22 virtual void check_for_non_bad_heap_word_value(HeapWord* addr, size_t size) 1.23 PRODUCT_RETURN; 1.24 + debug_only(static void check_for_valid_allocation_state();) 1.25 1.26 public: 1.27 enum Name {
2.1 --- a/src/share/vm/interpreter/rewriter.cpp Fri Jan 30 14:17:52 2009 -0800 2.2 +++ b/src/share/vm/interpreter/rewriter.cpp Sat Jan 31 00:15:00 2009 -0800 2.3 @@ -48,9 +48,14 @@ 2.4 2.5 2.6 // Creates a constant pool cache given an inverse_index_map 2.7 +// This creates the constant pool cache initially in a state 2.8 +// that is unsafe for concurrent GC processing but sets it to 2.9 +// a safe mode before the constant pool cache is returned. 2.10 constantPoolCacheHandle Rewriter::new_constant_pool_cache(intArray& inverse_index_map, TRAPS) { 2.11 const int length = inverse_index_map.length(); 2.12 - constantPoolCacheOop cache = oopFactory::new_constantPoolCache(length, CHECK_(constantPoolCacheHandle())); 2.13 + constantPoolCacheOop cache = oopFactory::new_constantPoolCache(length, 2.14 + methodOopDesc::IsUnsafeConc, 2.15 + CHECK_(constantPoolCacheHandle())); 2.16 cache->initialize(inverse_index_map); 2.17 return constantPoolCacheHandle(THREAD, cache); 2.18 }
3.1 --- a/src/share/vm/memory/oopFactory.cpp Fri Jan 30 14:17:52 2009 -0800 3.2 +++ b/src/share/vm/memory/oopFactory.cpp Sat Jan 31 00:15:00 2009 -0800 3.3 @@ -90,9 +90,11 @@ 3.4 } 3.5 3.6 3.7 -constantPoolCacheOop oopFactory::new_constantPoolCache(int length, TRAPS) { 3.8 +constantPoolCacheOop oopFactory::new_constantPoolCache(int length, 3.9 + bool is_conc_safe, 3.10 + TRAPS) { 3.11 constantPoolCacheKlass* ck = constantPoolCacheKlass::cast(Universe::constantPoolCacheKlassObj()); 3.12 - return ck->allocate(length, CHECK_NULL); 3.13 + return ck->allocate(length, is_conc_safe, CHECK_NULL); 3.14 } 3.15 3.16
4.1 --- a/src/share/vm/memory/oopFactory.hpp Fri Jan 30 14:17:52 2009 -0800 4.2 +++ b/src/share/vm/memory/oopFactory.hpp Sat Jan 31 00:15:00 2009 -0800 4.3 @@ -84,7 +84,9 @@ 4.4 static constantPoolOop new_constantPool (int length, 4.5 bool is_conc_safe, 4.6 TRAPS); 4.7 - static constantPoolCacheOop new_constantPoolCache(int length, TRAPS); 4.8 + static constantPoolCacheOop new_constantPoolCache(int length, 4.9 + bool is_conc_safe, 4.10 + TRAPS); 4.11 4.12 // Instance classes 4.13 static klassOop new_instanceKlass(int vtable_len, int itable_len, int static_field_size,
5.1 --- a/src/share/vm/oops/cpCacheKlass.cpp Fri Jan 30 14:17:52 2009 -0800 5.2 +++ b/src/share/vm/oops/cpCacheKlass.cpp Sat Jan 31 00:15:00 2009 -0800 5.3 @@ -32,13 +32,43 @@ 5.4 } 5.5 5.6 5.7 -constantPoolCacheOop constantPoolCacheKlass::allocate(int length, TRAPS) { 5.8 +constantPoolCacheOop constantPoolCacheKlass::allocate(int length, 5.9 + bool is_conc_safe, 5.10 + TRAPS) { 5.11 // allocate memory 5.12 int size = constantPoolCacheOopDesc::object_size(length); 5.13 + 5.14 KlassHandle klass (THREAD, as_klassOop()); 5.15 - constantPoolCacheOop cache = (constantPoolCacheOop) 5.16 - CollectedHeap::permanent_obj_allocate(klass, size, CHECK_NULL); 5.17 + 5.18 + // This is the original code. The code from permanent_obj_allocate() 5.19 + // was in-lined to allow the setting of is_conc_safe before the klass 5.20 + // is installed. 5.21 + // constantPoolCacheOop cache = (constantPoolCacheOop) 5.22 + // CollectedHeap::permanent_obj_allocate(klass, size, CHECK_NULL); 5.23 + 5.24 + oop obj = CollectedHeap::permanent_obj_allocate_no_klass_install(klass, size, CHECK_NULL); 5.25 + constantPoolCacheOop cache = (constantPoolCacheOop) obj; 5.26 + cache->set_is_conc_safe(is_conc_safe); 5.27 + // The store to is_conc_safe must be visible before the klass 5.28 + // is set. This should be done safely because _is_conc_safe has 5.29 + // been declared volatile. If there are any problems, consider adding 5.30 + // OrderAccess::storestore(); 5.31 + CollectedHeap::post_allocation_install_obj_klass(klass, obj, size); 5.32 + NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value((HeapWord*) obj, 5.33 + size)); 5.34 + 5.35 + // The length field affects the size of the object. The allocation 5.36 + // above allocates the correct size (see calculation of "size") but 5.37 + // the size() method of the constant pool cache oop will not reflect 5.38 + // that size until the correct length is set. 5.39 cache->set_length(length); 5.40 + 5.41 + // The store of the length must be visible before is_conc_safe is 5.42 + // set to a safe state. 5.43 + // This should be done safely because _is_conc_safe has 5.44 + // been declared volatile. If there are any problems, consider adding 5.45 + // OrderAccess::storestore(); 5.46 + cache->set_is_conc_safe(methodOopDesc::IsSafeConc); 5.47 cache->set_constant_pool(NULL); 5.48 return cache; 5.49 } 5.50 @@ -114,7 +144,6 @@ 5.51 return size; 5.52 } 5.53 5.54 - 5.55 int constantPoolCacheKlass::oop_adjust_pointers(oop obj) { 5.56 assert(obj->is_constantPoolCache(), "obj must be constant pool cache"); 5.57 constantPoolCacheOop cache = (constantPoolCacheOop)obj; 5.58 @@ -131,6 +160,11 @@ 5.59 return size; 5.60 } 5.61 5.62 +bool constantPoolCacheKlass::oop_is_conc_safe(oop obj) const { 5.63 + assert(obj->is_constantPoolCache(), "must be constMethod oop"); 5.64 + return constantPoolCacheOop(obj)->is_conc_safe(); 5.65 +} 5.66 + 5.67 #ifndef SERIALGC 5.68 void constantPoolCacheKlass::oop_copy_contents(PSPromotionManager* pm, 5.69 oop obj) {
6.1 --- a/src/share/vm/oops/cpCacheKlass.hpp Fri Jan 30 14:17:52 2009 -0800 6.2 +++ b/src/share/vm/oops/cpCacheKlass.hpp Sat Jan 31 00:15:00 2009 -0800 6.3 @@ -32,7 +32,7 @@ 6.4 6.5 // Allocation 6.6 DEFINE_ALLOCATE_PERMANENT(constantPoolCacheKlass); 6.7 - constantPoolCacheOop allocate(int length, TRAPS); 6.8 + constantPoolCacheOop allocate(int length, bool is_conc_safe, TRAPS); 6.9 static klassOop create_klass(TRAPS); 6.10 6.11 // Casting from klassOop 6.12 @@ -48,6 +48,7 @@ 6.13 // Garbage collection 6.14 void oop_follow_contents(oop obj); 6.15 int oop_adjust_pointers(oop obj); 6.16 + virtual bool oop_is_conc_safe(oop obj) const; 6.17 6.18 // Parallel Scavenge and Parallel Old 6.19 PARALLEL_GC_DECLS
7.1 --- a/src/share/vm/oops/cpCacheOop.hpp Fri Jan 30 14:17:52 2009 -0800 7.2 +++ b/src/share/vm/oops/cpCacheOop.hpp Sat Jan 31 00:15:00 2009 -0800 7.3 @@ -291,6 +291,9 @@ 7.4 private: 7.5 int _length; 7.6 constantPoolOop _constant_pool; // the corresponding constant pool 7.7 + // If true, safe for concurrent GC processing, 7.8 + // Set unconditionally in constantPoolCacheKlass::allocate() 7.9 + volatile bool _is_conc_safe; 7.10 7.11 // Sizing 7.12 debug_only(friend class ClassVerifier;) 7.13 @@ -316,6 +319,12 @@ 7.14 constantPoolOop constant_pool() const { return _constant_pool; } 7.15 ConstantPoolCacheEntry* entry_at(int i) const { assert(0 <= i && i < length(), "index out of bounds"); return base() + i; } 7.16 7.17 + // GC support 7.18 + // If the _length field has not been set, the size of the 7.19 + // constantPoolCache cannot be correctly calculated. 7.20 + bool is_conc_safe() { return _is_conc_safe; } 7.21 + void set_is_conc_safe(bool v) { _is_conc_safe = v; } 7.22 + 7.23 // Code generation 7.24 static ByteSize base_offset() { return in_ByteSize(sizeof(constantPoolCacheOopDesc)); } 7.25