提交 e0b329bb 编写于 作者: J jmasa

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
上级 86c6c645
...@@ -42,6 +42,7 @@ class Thread; ...@@ -42,6 +42,7 @@ class Thread;
class CollectedHeap : public CHeapObj { class CollectedHeap : public CHeapObj {
friend class VMStructs; friend class VMStructs;
friend class IsGCActiveMark; // Block structured external access to _is_gc_active friend class IsGCActiveMark; // Block structured external access to _is_gc_active
friend class constantPoolCacheKlass; // allocate() method inserts is_conc_safe
#ifdef ASSERT #ifdef ASSERT
static int _fire_out_of_memory_count; static int _fire_out_of_memory_count;
...@@ -82,8 +83,6 @@ class CollectedHeap : public CHeapObj { ...@@ -82,8 +83,6 @@ class CollectedHeap : public CHeapObj {
// Reinitialize tlabs before resuming mutators. // Reinitialize tlabs before resuming mutators.
virtual void resize_all_tlabs(); virtual void resize_all_tlabs();
debug_only(static void check_for_valid_allocation_state();)
protected: protected:
// Allocate from the current thread's TLAB, with broken-out slow path. // Allocate from the current thread's TLAB, with broken-out slow path.
inline static HeapWord* allocate_from_tlab(Thread* thread, size_t size); inline static HeapWord* allocate_from_tlab(Thread* thread, size_t size);
...@@ -142,6 +141,7 @@ class CollectedHeap : public CHeapObj { ...@@ -142,6 +141,7 @@ class CollectedHeap : public CHeapObj {
PRODUCT_RETURN; PRODUCT_RETURN;
virtual void check_for_non_bad_heap_word_value(HeapWord* addr, size_t size) virtual void check_for_non_bad_heap_word_value(HeapWord* addr, size_t size)
PRODUCT_RETURN; PRODUCT_RETURN;
debug_only(static void check_for_valid_allocation_state();)
public: public:
enum Name { enum Name {
......
...@@ -48,9 +48,14 @@ void Rewriter::compute_index_maps(constantPoolHandle pool, intArray*& index_map, ...@@ -48,9 +48,14 @@ void Rewriter::compute_index_maps(constantPoolHandle pool, intArray*& index_map,
// Creates a constant pool cache given an inverse_index_map // Creates a constant pool cache given an inverse_index_map
// This creates the constant pool cache initially in a state
// that is unsafe for concurrent GC processing but sets it to
// a safe mode before the constant pool cache is returned.
constantPoolCacheHandle Rewriter::new_constant_pool_cache(intArray& inverse_index_map, TRAPS) { constantPoolCacheHandle Rewriter::new_constant_pool_cache(intArray& inverse_index_map, TRAPS) {
const int length = inverse_index_map.length(); const int length = inverse_index_map.length();
constantPoolCacheOop cache = oopFactory::new_constantPoolCache(length, CHECK_(constantPoolCacheHandle())); constantPoolCacheOop cache = oopFactory::new_constantPoolCache(length,
methodOopDesc::IsUnsafeConc,
CHECK_(constantPoolCacheHandle()));
cache->initialize(inverse_index_map); cache->initialize(inverse_index_map);
return constantPoolCacheHandle(THREAD, cache); return constantPoolCacheHandle(THREAD, cache);
} }
......
...@@ -90,9 +90,11 @@ constantPoolOop oopFactory::new_constantPool(int length, ...@@ -90,9 +90,11 @@ constantPoolOop oopFactory::new_constantPool(int length,
} }
constantPoolCacheOop oopFactory::new_constantPoolCache(int length, TRAPS) { constantPoolCacheOop oopFactory::new_constantPoolCache(int length,
bool is_conc_safe,
TRAPS) {
constantPoolCacheKlass* ck = constantPoolCacheKlass::cast(Universe::constantPoolCacheKlassObj()); constantPoolCacheKlass* ck = constantPoolCacheKlass::cast(Universe::constantPoolCacheKlassObj());
return ck->allocate(length, CHECK_NULL); return ck->allocate(length, is_conc_safe, CHECK_NULL);
} }
......
...@@ -84,7 +84,9 @@ class oopFactory: AllStatic { ...@@ -84,7 +84,9 @@ class oopFactory: AllStatic {
static constantPoolOop new_constantPool (int length, static constantPoolOop new_constantPool (int length,
bool is_conc_safe, bool is_conc_safe,
TRAPS); TRAPS);
static constantPoolCacheOop new_constantPoolCache(int length, TRAPS); static constantPoolCacheOop new_constantPoolCache(int length,
bool is_conc_safe,
TRAPS);
// Instance classes // Instance classes
static klassOop new_instanceKlass(int vtable_len, int itable_len, int static_field_size, static klassOop new_instanceKlass(int vtable_len, int itable_len, int static_field_size,
......
...@@ -32,13 +32,43 @@ int constantPoolCacheKlass::oop_size(oop obj) const { ...@@ -32,13 +32,43 @@ int constantPoolCacheKlass::oop_size(oop obj) const {
} }
constantPoolCacheOop constantPoolCacheKlass::allocate(int length, TRAPS) { constantPoolCacheOop constantPoolCacheKlass::allocate(int length,
bool is_conc_safe,
TRAPS) {
// allocate memory // allocate memory
int size = constantPoolCacheOopDesc::object_size(length); int size = constantPoolCacheOopDesc::object_size(length);
KlassHandle klass (THREAD, as_klassOop()); KlassHandle klass (THREAD, as_klassOop());
constantPoolCacheOop cache = (constantPoolCacheOop)
CollectedHeap::permanent_obj_allocate(klass, size, CHECK_NULL); // This is the original code. The code from permanent_obj_allocate()
// was in-lined to allow the setting of is_conc_safe before the klass
// is installed.
// constantPoolCacheOop cache = (constantPoolCacheOop)
// CollectedHeap::permanent_obj_allocate(klass, size, CHECK_NULL);
oop obj = CollectedHeap::permanent_obj_allocate_no_klass_install(klass, size, CHECK_NULL);
constantPoolCacheOop cache = (constantPoolCacheOop) obj;
cache->set_is_conc_safe(is_conc_safe);
// The store to is_conc_safe must be visible before the klass
// is set. This should be done safely because _is_conc_safe has
// been declared volatile. If there are any problems, consider adding
// OrderAccess::storestore();
CollectedHeap::post_allocation_install_obj_klass(klass, obj, size);
NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value((HeapWord*) obj,
size));
// The length field affects the size of the object. The allocation
// above allocates the correct size (see calculation of "size") but
// the size() method of the constant pool cache oop will not reflect
// that size until the correct length is set.
cache->set_length(length); cache->set_length(length);
// The store of the length must be visible before is_conc_safe is
// set to a safe state.
// This should be done safely because _is_conc_safe has
// been declared volatile. If there are any problems, consider adding
// OrderAccess::storestore();
cache->set_is_conc_safe(methodOopDesc::IsSafeConc);
cache->set_constant_pool(NULL); cache->set_constant_pool(NULL);
return cache; return cache;
} }
...@@ -114,7 +144,6 @@ int constantPoolCacheKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegio ...@@ -114,7 +144,6 @@ int constantPoolCacheKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegio
return size; return size;
} }
int constantPoolCacheKlass::oop_adjust_pointers(oop obj) { int constantPoolCacheKlass::oop_adjust_pointers(oop obj) {
assert(obj->is_constantPoolCache(), "obj must be constant pool cache"); assert(obj->is_constantPoolCache(), "obj must be constant pool cache");
constantPoolCacheOop cache = (constantPoolCacheOop)obj; constantPoolCacheOop cache = (constantPoolCacheOop)obj;
...@@ -131,6 +160,11 @@ int constantPoolCacheKlass::oop_adjust_pointers(oop obj) { ...@@ -131,6 +160,11 @@ int constantPoolCacheKlass::oop_adjust_pointers(oop obj) {
return size; return size;
} }
bool constantPoolCacheKlass::oop_is_conc_safe(oop obj) const {
assert(obj->is_constantPoolCache(), "must be constMethod oop");
return constantPoolCacheOop(obj)->is_conc_safe();
}
#ifndef SERIALGC #ifndef SERIALGC
void constantPoolCacheKlass::oop_copy_contents(PSPromotionManager* pm, void constantPoolCacheKlass::oop_copy_contents(PSPromotionManager* pm,
oop obj) { oop obj) {
......
...@@ -32,7 +32,7 @@ class constantPoolCacheKlass: public Klass { ...@@ -32,7 +32,7 @@ class constantPoolCacheKlass: public Klass {
// Allocation // Allocation
DEFINE_ALLOCATE_PERMANENT(constantPoolCacheKlass); DEFINE_ALLOCATE_PERMANENT(constantPoolCacheKlass);
constantPoolCacheOop allocate(int length, TRAPS); constantPoolCacheOop allocate(int length, bool is_conc_safe, TRAPS);
static klassOop create_klass(TRAPS); static klassOop create_klass(TRAPS);
// Casting from klassOop // Casting from klassOop
...@@ -48,6 +48,7 @@ class constantPoolCacheKlass: public Klass { ...@@ -48,6 +48,7 @@ class constantPoolCacheKlass: public Klass {
// Garbage collection // Garbage collection
void oop_follow_contents(oop obj); void oop_follow_contents(oop obj);
int oop_adjust_pointers(oop obj); int oop_adjust_pointers(oop obj);
virtual bool oop_is_conc_safe(oop obj) const;
// Parallel Scavenge and Parallel Old // Parallel Scavenge and Parallel Old
PARALLEL_GC_DECLS PARALLEL_GC_DECLS
......
...@@ -291,6 +291,9 @@ class constantPoolCacheOopDesc: public oopDesc { ...@@ -291,6 +291,9 @@ class constantPoolCacheOopDesc: public oopDesc {
private: private:
int _length; int _length;
constantPoolOop _constant_pool; // the corresponding constant pool constantPoolOop _constant_pool; // the corresponding constant pool
// If true, safe for concurrent GC processing,
// Set unconditionally in constantPoolCacheKlass::allocate()
volatile bool _is_conc_safe;
// Sizing // Sizing
debug_only(friend class ClassVerifier;) debug_only(friend class ClassVerifier;)
...@@ -316,6 +319,12 @@ class constantPoolCacheOopDesc: public oopDesc { ...@@ -316,6 +319,12 @@ class constantPoolCacheOopDesc: public oopDesc {
constantPoolOop constant_pool() const { return _constant_pool; } constantPoolOop constant_pool() const { return _constant_pool; }
ConstantPoolCacheEntry* entry_at(int i) const { assert(0 <= i && i < length(), "index out of bounds"); return base() + i; } ConstantPoolCacheEntry* entry_at(int i) const { assert(0 <= i && i < length(), "index out of bounds"); return base() + i; }
// GC support
// If the _length field has not been set, the size of the
// constantPoolCache cannot be correctly calculated.
bool is_conc_safe() { return _is_conc_safe; }
void set_is_conc_safe(bool v) { _is_conc_safe = v; }
// Code generation // Code generation
static ByteSize base_offset() { return in_ByteSize(sizeof(constantPoolCacheOopDesc)); } static ByteSize base_offset() { return in_ByteSize(sizeof(constantPoolCacheOopDesc)); }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册