mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
6792421: assert(_bitMap->isMarked(addr+size-1),inconsistent Printezis mark)
The CMS concurrent precleaning and concurrent marking phases should work around classes that are undergoing redefinition. Reviewed-by: ysr, tonyp
This commit is contained in:
parent
d981bd442b
commit
39b23ff0a0
7 changed files with 64 additions and 11 deletions
|
@ -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 {
|
||||||
// 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 {
|
||||||
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,
|
||||||
|
|
||||||
|
|
||||||
// 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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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 {
|
||||||
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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
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) {
|
||||||
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 {
|
||||||
|
|
||||||
// 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 {
|
||||||
// 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 {
|
||||||
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 {
|
||||||
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)); }
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue