提交 251d4f53 编写于 作者: Y ysr

6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")

Summary: Fix block_size_if_printezis_bits() so it does not expect the bits, only uses them when available. Fix block_size_no_stall() so it does not stall when the bits are missing such cases, letting the caller deal with zero size returns. Constant pool cache oops do not need to be unparsable or conc_unsafe after their klass pointer is installed. Some cosmetic clean-ups and some assertion checking for conc-usafety which, in the presence of class file redefinition, has no a-priori time boundedness, so all GCs must be able to safely deal with putatively conc-unsafe objects in a stop-world pause.
Reviewed-by: jmasa, johnc
上级 5a6ed888
...@@ -331,7 +331,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) { ...@@ -331,7 +331,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
length, CHECK_(nullHandle)); length, CHECK_(nullHandle));
constantPoolOop constant_pool = constantPoolOop constant_pool =
oopFactory::new_constantPool(length, oopFactory::new_constantPool(length,
methodOopDesc::IsSafeConc, oopDesc::IsSafeConc,
CHECK_(nullHandle)); CHECK_(nullHandle));
constantPoolHandle cp (THREAD, constant_pool); constantPoolHandle cp (THREAD, constant_pool);
...@@ -1929,10 +1929,9 @@ methodHandle ClassFileParser::parse_method(constantPoolHandle cp, bool is_interf ...@@ -1929,10 +1929,9 @@ methodHandle ClassFileParser::parse_method(constantPoolHandle cp, bool is_interf
} }
// All sizing information for a methodOop is finally available, now create it // All sizing information for a methodOop is finally available, now create it
methodOop m_oop = oopFactory::new_method( methodOop m_oop = oopFactory::new_method(code_length, access_flags, linenumber_table_length,
code_length, access_flags, linenumber_table_length, total_lvt_length, checked_exceptions_length,
total_lvt_length, checked_exceptions_length, oopDesc::IsSafeConc, CHECK_(nullHandle));
methodOopDesc::IsSafeConc, CHECK_(nullHandle));
methodHandle m (THREAD, m_oop); methodHandle m (THREAD, m_oop);
ClassLoadingService::add_class_method_size(m_oop->size()*HeapWordSize); ClassLoadingService::add_class_method_size(m_oop->size()*HeapWordSize);
......
...@@ -1040,9 +1040,10 @@ const { ...@@ -1040,9 +1040,10 @@ const {
} else { } else {
// must read from what 'p' points to in each loop. // must read from what 'p' points to in each loop.
klassOop k = ((volatile oopDesc*)p)->klass_or_null(); klassOop k = ((volatile oopDesc*)p)->klass_or_null();
if (k != NULL && // We trust the size of any object that has a non-NULL
((oopDesc*)p)->is_parsable() && // klass and (for those in the perm gen) is parsable
((oopDesc*)p)->is_conc_safe()) { // -- irrespective of its conc_safe-ty.
if (k != NULL && ((oopDesc*)p)->is_parsable()) {
assert(k->is_oop(), "Should really be klass oop."); assert(k->is_oop(), "Should really be klass oop.");
oop o = (oop)p; oop o = (oop)p;
assert(o->is_oop(), "Should be an oop"); assert(o->is_oop(), "Should be an oop");
...@@ -1051,6 +1052,7 @@ const { ...@@ -1051,6 +1052,7 @@ const {
assert(res != 0, "Block size should not be 0"); assert(res != 0, "Block size should not be 0");
return res; return res;
} else { } else {
// May return 0 if P-bits not present.
return c->block_size_if_printezis_bits(p); return c->block_size_if_printezis_bits(p);
} }
} }
......
...@@ -6360,18 +6360,16 @@ size_t CMSCollector::block_size_using_printezis_bits(HeapWord* addr) const { ...@@ -6360,18 +6360,16 @@ size_t CMSCollector::block_size_using_printezis_bits(HeapWord* addr) const {
// A variant of the above (block_size_using_printezis_bits()) except // A variant of the above (block_size_using_printezis_bits()) except
// that we return 0 if the P-bits are not yet set. // that we return 0 if the P-bits are not yet set.
size_t CMSCollector::block_size_if_printezis_bits(HeapWord* addr) const { size_t CMSCollector::block_size_if_printezis_bits(HeapWord* addr) const {
if (_markBitMap.isMarked(addr)) { if (_markBitMap.isMarked(addr + 1)) {
assert(_markBitMap.isMarked(addr + 1), "Missing Printezis bit?"); assert(_markBitMap.isMarked(addr), "P-bit can be set only for marked objects");
HeapWord* nextOneAddr = _markBitMap.getNextMarkedWordAddress(addr + 2); HeapWord* nextOneAddr = _markBitMap.getNextMarkedWordAddress(addr + 2);
size_t size = pointer_delta(nextOneAddr + 1, addr); size_t size = pointer_delta(nextOneAddr + 1, addr);
assert(size == CompactibleFreeListSpace::adjustObjectSize(size), assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
"alignment problem"); "alignment problem");
assert(size >= 3, "Necessary for Printezis marks to work"); assert(size >= 3, "Necessary for Printezis marks to work");
return size; return size;
} else {
assert(!_markBitMap.isMarked(addr + 1), "Bit map inconsistency?");
return 0;
} }
return 0;
} }
HeapWord* CMSCollector::next_card_start_after_block(HeapWord* addr) const { HeapWord* CMSCollector::next_card_start_after_block(HeapWord* addr) const {
...@@ -9212,7 +9210,6 @@ bool MarkRefsIntoAndScanClosure::take_from_overflow_list() { ...@@ -9212,7 +9210,6 @@ bool MarkRefsIntoAndScanClosure::take_from_overflow_list() {
size_t MarkDeadObjectsClosure::do_blk(HeapWord* addr) { size_t MarkDeadObjectsClosure::do_blk(HeapWord* addr) {
size_t res = _sp->block_size_no_stall(addr, _collector); size_t res = _sp->block_size_no_stall(addr, _collector);
assert(res != 0, "Should always be able to compute a size");
if (_sp->block_is_obj(addr)) { if (_sp->block_is_obj(addr)) {
if (_live_bit_map->isMarked(addr)) { if (_live_bit_map->isMarked(addr)) {
// It can't have been dead in a previous cycle // It can't have been dead in a previous cycle
...@@ -9221,6 +9218,7 @@ size_t MarkDeadObjectsClosure::do_blk(HeapWord* addr) { ...@@ -9221,6 +9218,7 @@ size_t MarkDeadObjectsClosure::do_blk(HeapWord* addr) {
_dead_bit_map->mark(addr); // mark the dead object _dead_bit_map->mark(addr); // mark the dead object
} }
} }
// Could be 0, if the block size could not be computed without stalling.
return res; return res;
} }
......
...@@ -100,8 +100,7 @@ void CollectedHeap::check_for_bad_heap_word_value(HeapWord* addr, size_t size) { ...@@ -100,8 +100,7 @@ void CollectedHeap::check_for_bad_heap_word_value(HeapWord* addr, size_t size) {
} }
} }
void CollectedHeap::check_for_non_bad_heap_word_value(HeapWord* addr, size_t size) void CollectedHeap::check_for_non_bad_heap_word_value(HeapWord* addr, size_t size) {
{
if (CheckMemoryInitialization && ZapUnusedHeapArea) { if (CheckMemoryInitialization && ZapUnusedHeapArea) {
for (size_t slot = 0; slot < size; slot += 1) { for (size_t slot = 0; slot < size; slot += 1) {
assert((*(intptr_t*) (addr + slot)) == ((intptr_t) badHeapWordVal), assert((*(intptr_t*) (addr + slot)) == ((intptr_t) badHeapWordVal),
......
...@@ -67,13 +67,11 @@ void Rewriter::compute_index_maps() { ...@@ -67,13 +67,11 @@ void Rewriter::compute_index_maps() {
// Creates a constant pool cache given a CPC map // Creates a constant pool cache given a CPC 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.
void Rewriter::make_constant_pool_cache(TRAPS) { void Rewriter::make_constant_pool_cache(TRAPS) {
const int length = _cp_cache_map.length(); const int length = _cp_cache_map.length();
constantPoolCacheOop cache = constantPoolCacheOop cache =
oopFactory::new_constantPoolCache(length, methodOopDesc::IsUnsafeConc, CHECK); oopFactory::new_constantPoolCache(length, CHECK);
No_Safepoint_Verifier nsv;
cache->initialize(_cp_cache_map); cache->initialize(_cp_cache_map);
// Don't bother with the next pass if there is no JVM_CONSTANT_InvokeDynamic. // Don't bother with the next pass if there is no JVM_CONSTANT_InvokeDynamic.
......
...@@ -111,10 +111,9 @@ constantPoolOop oopFactory::new_constantPool(int length, ...@@ -111,10 +111,9 @@ constantPoolOop oopFactory::new_constantPool(int length,
constantPoolCacheOop oopFactory::new_constantPoolCache(int length, constantPoolCacheOop oopFactory::new_constantPoolCache(int length,
bool is_conc_safe,
TRAPS) { TRAPS) {
constantPoolCacheKlass* ck = constantPoolCacheKlass::cast(Universe::constantPoolCacheKlassObj()); constantPoolCacheKlass* ck = constantPoolCacheKlass::cast(Universe::constantPoolCacheKlassObj());
return ck->allocate(length, is_conc_safe, CHECK_NULL); return ck->allocate(length, CHECK_NULL);
} }
......
...@@ -69,7 +69,6 @@ class oopFactory: AllStatic { ...@@ -69,7 +69,6 @@ class oopFactory: AllStatic {
bool is_conc_safe, bool is_conc_safe,
TRAPS); TRAPS);
static constantPoolCacheOop new_constantPoolCache(int length, static constantPoolCacheOop new_constantPoolCache(int length,
bool is_conc_safe,
TRAPS); TRAPS);
// Instance classes // Instance classes
......
...@@ -71,6 +71,12 @@ constantPoolOop constantPoolKlass::allocate(int length, bool is_conc_safe, TRAPS ...@@ -71,6 +71,12 @@ constantPoolOop constantPoolKlass::allocate(int length, bool is_conc_safe, TRAPS
c->set_is_conc_safe(is_conc_safe); c->set_is_conc_safe(is_conc_safe);
// all fields are initialized; needed for GC // all fields are initialized; needed for GC
// Note: because we may be in this "conc_unsafe" state when allocating
// t_oop below, which may in turn cause a GC, it is imperative that our
// size be correct, consistent and henceforth stable, at this stage.
assert(c->is_parsable(), "Else size() below is unreliable");
DEBUG_ONLY(int sz = c->size();)
// initialize tag array // initialize tag array
// Note: cannot introduce constant pool handle before since it is not // Note: cannot introduce constant pool handle before since it is not
// completely initialized (no class) -> would cause assertion failure // completely initialized (no class) -> would cause assertion failure
...@@ -82,6 +88,8 @@ constantPoolOop constantPoolKlass::allocate(int length, bool is_conc_safe, TRAPS ...@@ -82,6 +88,8 @@ constantPoolOop constantPoolKlass::allocate(int length, bool is_conc_safe, TRAPS
} }
pool->set_tags(tags()); pool->set_tags(tags());
// Check that our size was stable at its old value.
assert(sz == c->size(), "size() changed");
return pool(); return pool();
} }
......
...@@ -49,43 +49,31 @@ int constantPoolCacheKlass::oop_size(oop obj) const { ...@@ -49,43 +49,31 @@ int constantPoolCacheKlass::oop_size(oop obj) const {
constantPoolCacheOop constantPoolCacheKlass::allocate(int length, constantPoolCacheOop constantPoolCacheKlass::allocate(int length,
bool is_conc_safe,
TRAPS) { 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());
// This is the original code. The code from permanent_obj_allocate() // Commented out below is the original code. The code from
// was in-lined to allow the setting of is_conc_safe before the klass // permanent_obj_allocate() was in-lined so that we could
// is installed. // set the _length field, necessary to correctly compute its
// size(), before setting its klass word further below.
// constantPoolCacheOop cache = (constantPoolCacheOop) // constantPoolCacheOop cache = (constantPoolCacheOop)
// CollectedHeap::permanent_obj_allocate(klass, size, CHECK_NULL); // CollectedHeap::permanent_obj_allocate(klass, size, CHECK_NULL);
oop obj = CollectedHeap::permanent_obj_allocate_no_klass_install(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, NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value((HeapWord*) obj,
size)); size));
constantPoolCacheOop cache = (constantPoolCacheOop) obj;
// The length field affects the size of the object. The allocation assert(!UseConcMarkSweepGC || obj->klass_or_null() == NULL,
// above allocates the correct size (see calculation of "size") but "klass should be NULL here when using CMS");
// the size() method of the constant pool cache oop will not reflect cache->set_length(length); // should become visible before klass is set below.
// that size until the correct length is set.
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);
OrderAccess::storestore();
obj->set_klass(klass());
assert(cache->size() == size, "Incorrect cache->size()");
return cache; return cache;
} }
...@@ -176,11 +164,6 @@ int constantPoolCacheKlass::oop_adjust_pointers(oop obj) { ...@@ -176,11 +164,6 @@ int constantPoolCacheKlass::oop_adjust_pointers(oop obj) {
return size; return size;
} }
bool constantPoolCacheKlass::oop_is_conc_safe(oop obj) const {
assert(obj->is_constantPoolCache(), "should be constant pool");
return constantPoolCacheOop(obj)->is_conc_safe();
}
#ifndef SERIALGC #ifndef SERIALGC
void constantPoolCacheKlass::oop_push_contents(PSPromotionManager* pm, void constantPoolCacheKlass::oop_push_contents(PSPromotionManager* pm,
oop obj) { oop obj) {
......
...@@ -39,7 +39,7 @@ class constantPoolCacheKlass: public Klass { ...@@ -39,7 +39,7 @@ class constantPoolCacheKlass: public Klass {
// Allocation // Allocation
DEFINE_ALLOCATE_PERMANENT(constantPoolCacheKlass); DEFINE_ALLOCATE_PERMANENT(constantPoolCacheKlass);
constantPoolCacheOop allocate(int length, bool is_conc_safe, TRAPS); constantPoolCacheOop allocate(int length, TRAPS);
static klassOop create_klass(TRAPS); static klassOop create_klass(TRAPS);
// Casting from klassOop // Casting from klassOop
...@@ -55,7 +55,6 @@ class constantPoolCacheKlass: public Klass { ...@@ -55,7 +55,6 @@ 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
......
...@@ -321,9 +321,6 @@ class constantPoolCacheOopDesc: public oopDesc { ...@@ -321,9 +321,6 @@ 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;)
...@@ -390,12 +387,6 @@ class constantPoolCacheOopDesc: public oopDesc { ...@@ -390,12 +387,6 @@ class constantPoolCacheOopDesc: public oopDesc {
return entry_at(primary_index); return entry_at(primary_index);
} }
// 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)); }
static ByteSize entry_offset(int raw_index) { static ByteSize entry_offset(int raw_index) {
......
...@@ -985,9 +985,11 @@ methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_cod ...@@ -985,9 +985,11 @@ methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_cod
IsUnsafeConc, IsUnsafeConc,
CHECK_(methodHandle())); CHECK_(methodHandle()));
methodHandle newm (THREAD, newm_oop); methodHandle newm (THREAD, newm_oop);
NOT_PRODUCT(int nmsz = newm->is_parsable() ? newm->size() : -1;)
int new_method_size = newm->method_size(); int new_method_size = newm->method_size();
// Create a shallow copy of methodOopDesc part, but be careful to preserve the new constMethodOop // Create a shallow copy of methodOopDesc part, but be careful to preserve the new constMethodOop
constMethodOop newcm = newm->constMethod(); constMethodOop newcm = newm->constMethod();
NOT_PRODUCT(int ncmsz = newcm->is_parsable() ? newcm->size() : -1;)
int new_const_method_size = newm->constMethod()->object_size(); int new_const_method_size = newm->constMethod()->object_size();
memcpy(newm(), m(), sizeof(methodOopDesc)); memcpy(newm(), m(), sizeof(methodOopDesc));
...@@ -999,9 +1001,19 @@ methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_cod ...@@ -999,9 +1001,19 @@ methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_cod
// or concurrent marking but those phases will be correct. Setting and // or concurrent marking but those phases will be correct. Setting and
// resetting is done in preference to a careful copying into newcm to // resetting is done in preference to a careful copying into newcm to
// avoid having to know the precise layout of a constMethodOop. // avoid having to know the precise layout of a constMethodOop.
m->constMethod()->set_is_conc_safe(false); m->constMethod()->set_is_conc_safe(oopDesc::IsUnsafeConc);
assert(m->constMethod()->is_parsable(), "Should remain parsable");
// NOTE: this is a reachable object that transiently signals "conc_unsafe"
// However, no allocations are done during this window
// during which it is tagged conc_unsafe, so we are assured that any concurrent
// thread will not wait forever for the object to revert to "conc_safe".
// Further, any such conc_unsafe object will indicate a stable size
// through the transition.
memcpy(newcm, m->constMethod(), sizeof(constMethodOopDesc)); memcpy(newcm, m->constMethod(), sizeof(constMethodOopDesc));
m->constMethod()->set_is_conc_safe(true); m->constMethod()->set_is_conc_safe(oopDesc::IsSafeConc);
assert(m->constMethod()->is_parsable(), "Should remain parsable");
// Reset correct method/const method, method size, and parameter info // Reset correct method/const method, method size, and parameter info
newcm->set_method(newm()); newcm->set_method(newm());
newm->set_constMethod(newcm); newm->set_constMethod(newcm);
...@@ -1035,6 +1047,8 @@ methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_cod ...@@ -1035,6 +1047,8 @@ methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_cod
// Only set is_conc_safe to true when changes to newcm are // Only set is_conc_safe to true when changes to newcm are
// complete. // complete.
assert(!newm->is_parsable() || nmsz < 0 || newm->size() == nmsz, "newm->size() inconsistency");
assert(!newcm->is_parsable() || ncmsz < 0 || newcm->size() == ncmsz, "newcm->size() inconsistency");
newcm->set_is_conc_safe(true); newcm->set_is_conc_safe(true);
return newm; return newm;
} }
......
...@@ -144,9 +144,6 @@ class methodOopDesc : public oopDesc { ...@@ -144,9 +144,6 @@ class methodOopDesc : public oopDesc {
public: public:
static const bool IsUnsafeConc = false;
static const bool IsSafeConc = true;
// accessors for instance variables // accessors for instance variables
constMethodOop constMethod() const { return _constMethod; } constMethodOop constMethod() const { return _constMethod; }
void set_constMethod(constMethodOop xconst) { oop_store_without_check((oop*)&_constMethod, (oop)xconst); } void set_constMethod(constMethodOop xconst) { oop_store_without_check((oop*)&_constMethod, (oop)xconst); }
......
...@@ -71,6 +71,11 @@ class oopDesc { ...@@ -71,6 +71,11 @@ class oopDesc {
static BarrierSet* _bs; static BarrierSet* _bs;
public: public:
enum ConcSafeType {
IsUnsafeConc = false,
IsSafeConc = true
};
markOop mark() const { return _mark; } markOop mark() const { return _mark; }
markOop* mark_addr() const { return (markOop*) &_mark; } markOop* mark_addr() const { return (markOop*) &_mark; }
......
...@@ -1247,12 +1247,12 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite( ...@@ -1247,12 +1247,12 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite(
// Constant pools are not easily reused so we allocate a new one // Constant pools are not easily reused so we allocate a new one
// each time. // each time.
// merge_cp is created unsafe for concurrent GC processing. It // merge_cp is created unsafe for concurrent GC processing. It
// should be marked safe before discarding it because, even if // should be marked safe before discarding it. Even though
// garbage. If it crosses a card boundary, it may be scanned // garbage, if it crosses a card boundary, it may be scanned
// in order to find the start of the first complete object on the card. // in order to find the start of the first complete object on the card.
constantPoolHandle merge_cp(THREAD, constantPoolHandle merge_cp(THREAD,
oopFactory::new_constantPool(merge_cp_length, oopFactory::new_constantPool(merge_cp_length,
methodOopDesc::IsUnsafeConc, oopDesc::IsUnsafeConc,
THREAD)); THREAD));
int orig_length = old_cp->orig_length(); int orig_length = old_cp->orig_length();
if (orig_length == 0) { if (orig_length == 0) {
...@@ -2343,7 +2343,7 @@ void VM_RedefineClasses::set_new_constant_pool( ...@@ -2343,7 +2343,7 @@ void VM_RedefineClasses::set_new_constant_pool(
// sized constant pool with the klass to save space. // sized constant pool with the klass to save space.
constantPoolHandle smaller_cp(THREAD, constantPoolHandle smaller_cp(THREAD,
oopFactory::new_constantPool(scratch_cp_length, oopFactory::new_constantPool(scratch_cp_length,
methodOopDesc::IsUnsafeConc, oopDesc::IsUnsafeConc,
THREAD)); THREAD));
// preserve orig_length() value in the smaller copy // preserve orig_length() value in the smaller copy
int orig_length = scratch_cp->orig_length(); int orig_length = scratch_cp->orig_length();
......
...@@ -1134,8 +1134,9 @@ int MethodHandleCompiler::cpool_primitive_put(BasicType bt, jvalue* con) { ...@@ -1134,8 +1134,9 @@ int MethodHandleCompiler::cpool_primitive_put(BasicType bt, jvalue* con) {
constantPoolHandle MethodHandleCompiler::get_constant_pool(TRAPS) const { constantPoolHandle MethodHandleCompiler::get_constant_pool(TRAPS) const {
constantPoolHandle nullHandle; constantPoolHandle nullHandle;
bool is_conc_safe = true; constantPoolOop cpool_oop = oopFactory::new_constantPool(_constants.length(),
constantPoolOop cpool_oop = oopFactory::new_constantPool(_constants.length(), is_conc_safe, CHECK_(nullHandle)); oopDesc::IsSafeConc,
CHECK_(nullHandle));
constantPoolHandle cpool(THREAD, cpool_oop); constantPoolHandle cpool(THREAD, cpool_oop);
// Fill the real constant pool skipping the zero element. // Fill the real constant pool skipping the zero element.
...@@ -1180,10 +1181,9 @@ methodHandle MethodHandleCompiler::get_method_oop(TRAPS) const { ...@@ -1180,10 +1181,9 @@ methodHandle MethodHandleCompiler::get_method_oop(TRAPS) const {
else else
flags_bits = (/*JVM_MH_INVOKE_BITS |*/ JVM_ACC_PUBLIC | JVM_ACC_FINAL | JVM_ACC_SYNTHETIC); flags_bits = (/*JVM_MH_INVOKE_BITS |*/ JVM_ACC_PUBLIC | JVM_ACC_FINAL | JVM_ACC_SYNTHETIC);
bool is_conc_safe = true;
methodOop m_oop = oopFactory::new_method(bytecode_length(), methodOop m_oop = oopFactory::new_method(bytecode_length(),
accessFlags_from(flags_bits), accessFlags_from(flags_bits),
0, 0, 0, is_conc_safe, CHECK_(nullHandle)); 0, 0, 0, oopDesc::IsSafeConc, CHECK_(nullHandle));
methodHandle m(THREAD, m_oop); methodHandle m(THREAD, m_oop);
m_oop = NULL; // oop not GC safe m_oop = NULL; // oop not GC safe
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册