# HG changeset patch # User rkennke # Date 1443873077 -7200 # Node ID 081cf5f88897f14b9546b7390082295843002915 # Parent 0d5b3847ab03e9ea7452998be7f3516b37501e7e Big cleanup, part 2: revisit, fix & cleanup all runtime barriers. diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/c1/c1_Runtime1.cpp --- a/src/share/vm/c1/c1_Runtime1.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/c1/c1_Runtime1.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -674,7 +674,7 @@ if (PrintBiasedLockingStatistics) { Atomic::inc(BiasedLocking::slow_path_entry_count_addr()); } - Handle h_obj(thread, obj); +Handle h_obj(thread, oopDesc::bs()->resolve_and_maybe_copy_oop(obj)); assert(h_obj()->is_oop(), "must be NULL or an object"); if (UseBiasedLocking) { // Retry fast entry if bias is revoked to avoid unnecessary inflation @@ -699,7 +699,7 @@ // monitorexit is non-blocking (leaf routine) => no exceptions can be thrown EXCEPTION_MARK; - oop obj = lock->obj(); + oop obj = oopDesc::bs()->resolve_and_maybe_copy_oop(lock->obj()); assert(obj->is_oop(), "must be NULL or an object"); if (UseFastLocking) { // When using fast locking, the compiled code has already tried the fast case diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/ci/ciObject.hpp --- a/src/share/vm/ci/ciObject.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/ci/ciObject.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -27,6 +27,7 @@ #include "ci/ciBaseObject.hpp" #include "ci/ciClassList.hpp" +#include "gc/shared/barrierSet.hpp" #include "memory/allocation.hpp" #include "runtime/handles.hpp" #include "runtime/jniHandles.hpp" @@ -69,7 +70,9 @@ // Get the VM oop that this object holds. oop get_oop() const { assert(_handle != NULL, "null oop"); - return JNIHandles::resolve_non_null(_handle); + oop obj = JNIHandles::resolve_non_null(_handle); + assert(obj == oopDesc::bs()->resolve_and_maybe_copy_oop(obj), "expect to-space copy"); + return obj; } void init_flags_from(oop x); diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/ci/ciObjectFactory.hpp --- a/src/share/vm/ci/ciObjectFactory.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/ci/ciObjectFactory.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -27,6 +27,7 @@ #include "ci/ciClassList.hpp" #include "ci/ciObject.hpp" +#include "gc/shared/barrierSet.hpp" #include "utilities/growableArray.hpp" // ciObjectFactory @@ -79,7 +80,11 @@ static bool is_equal(NonPermObject* p, oop key) { // Shenandoah: We already force-forwarded the key earlier. - return oopDesc::bs()->resolve_oop(p->object()->get_oop()) == key; + // The oop in the object should always point to to-space. + assert(key == oopDesc::bs()->resolve_oop(key), "should be forwarded"); + assert(p->object()->get_oop() == oopDesc::bs()->resolve_oop(p->object()->get_oop()), + "should be forwarded"); + return p->object()->get_oop() == key; } NonPermObject* &find_non_perm(oop key); diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/classfile/classLoaderData.cpp --- a/src/share/vm/classfile/classLoaderData.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/classfile/classLoaderData.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -242,7 +242,7 @@ // Have to lock and put the new dependency on the end of the dependency // array so the card mark for CMS sees that this dependency is new. // Can probably do this lock free with some effort. - ObjectLocker ol(Handle(THREAD, _list_head), THREAD); + ObjectLocker ol(Handle(THREAD, oopDesc::bs()->resolve_and_maybe_copy_oop(_list_head)), THREAD); oop loader_or_mirror = new_dependency->obj_at(0); diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/classfile/dictionary.cpp --- a/src/share/vm/classfile/dictionary.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/classfile/dictionary.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -80,13 +80,14 @@ bool DictionaryEntry::contains_protection_domain(oop protection_domain) const { #ifdef ASSERT - if (protection_domain == InstanceKlass::cast(klass())->protection_domain()) { + protection_domain = oopDesc::bs()->resolve_and_maybe_copy_oop(protection_domain); + if (protection_domain == oopDesc::bs()->resolve_and_maybe_copy_oop(InstanceKlass::cast(klass())->protection_domain())) { // Ensure this doesn't show up in the pd_set (invariant) bool in_pd_set = false; for (ProtectionDomainEntry* current = _pd_set; current != NULL; current = current->next()) { - if (current->protection_domain() == protection_domain) { + if (oopDesc::bs()->resolve_and_maybe_copy_oop(current->protection_domain()) == protection_domain) { in_pd_set = true; break; } @@ -98,7 +99,7 @@ } #endif /* ASSERT */ - if (protection_domain == InstanceKlass::cast(klass())->protection_domain()) { + if (protection_domain == oopDesc::bs()->resolve_and_maybe_copy_oop(InstanceKlass::cast(klass())->protection_domain())) { // Succeeds trivially return true; } @@ -106,7 +107,7 @@ for (ProtectionDomainEntry* current = _pd_set; current != NULL; current = current->next()) { - if (current->protection_domain() == protection_domain) return true; + if (oopDesc::bs()->resolve_and_maybe_copy_oop(current->protection_domain()) == protection_domain) return true; } return false; } diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/classfile/dictionary.hpp --- a/src/share/vm/classfile/dictionary.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/classfile/dictionary.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -141,7 +141,7 @@ // to be updated. bool _strongly_reachable; public: - oop protection_domain() { return oopDesc::bs()->resolve_oop(literal()); } + oop protection_domain() { return literal(); } void init() { _strongly_reachable = false; @@ -356,7 +356,7 @@ Method* method() const { return _method; } void set_method(Method* p) { _method = p; } - oop method_type() const { return oopDesc::bs()->resolve_oop(_method_type); } + oop method_type() const { return _method_type; } oop* method_type_addr() { return &_method_type; } void set_method_type(oop p) { _method_type = p; } diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/classfile/javaClasses.cpp --- a/src/share/vm/classfile/javaClasses.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/classfile/javaClasses.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -212,7 +212,9 @@ int length = UTF8::unicode_length(utf8_str); Handle h_obj = basic_create(length, CHECK_NH); if (length > 0) { - UTF8::convert_to_unicode(utf8_str, value(h_obj())->char_at_addr(0), length); + typeArrayOop buffer = value(h_obj()); + buffer = typeArrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(buffer)); + UTF8::convert_to_unicode(utf8_str, buffer->char_at_addr(0), length); } return h_obj; } @@ -226,7 +228,9 @@ int length = UTF8::unicode_length((char*)symbol->bytes(), symbol->utf8_length()); Handle h_obj = basic_create(length, CHECK_NH); if (length > 0) { - UTF8::convert_to_unicode((char*)symbol->bytes(), value(h_obj())->char_at_addr(0), length); + typeArrayOop buffer = value(h_obj()); + buffer = typeArrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(buffer)); + UTF8::convert_to_unicode((char*)symbol->bytes(), buffer->char_at_addr(0), length); } return h_obj; } @@ -347,6 +351,7 @@ typeArrayOop value = java_lang_String::value(java_string); int offset = java_lang_String::offset(java_string); + value = typeArrayOop(oopDesc::bs()->resolve_oop(value)); return java_lang_String::hash_code(value->char_at_addr(offset), length); } @@ -355,6 +360,7 @@ int offset = java_lang_String::offset(java_string); int length = java_lang_String::length(java_string); + value = typeArrayOop(oopDesc::bs()->resolve_oop(value)); jchar* base = (length == 0) ? NULL : value->char_at_addr(offset); if (base == NULL) return NULL; @@ -375,6 +381,7 @@ typeArrayOop value = java_lang_String::value(java_string); int offset = java_lang_String::offset(java_string); + value = typeArrayOop(oopDesc::bs()->resolve_oop(value)); return StringTable::hash_string(value->char_at_addr(offset), length); } @@ -383,6 +390,7 @@ typeArrayOop value = java_lang_String::value(obj); int offset = java_lang_String::offset(obj); int length = java_lang_String::length(obj); + value = typeArrayOop(oopDesc::bs()->resolve_oop(value)); jchar* base = (length == 0) ? NULL : value->char_at_addr(offset); Symbol* sym = SymbolTable::lookup_unicode(base, length, THREAD); return sym; @@ -392,6 +400,7 @@ typeArrayOop value = java_lang_String::value(java_string); int offset = java_lang_String::offset(java_string); int length = java_lang_String::length(java_string); + value = typeArrayOop(oopDesc::bs()->resolve_oop(value)); jchar* base = (length == 0) ? NULL : value->char_at_addr(offset); return SymbolTable::probe_unicode(base, length); } @@ -401,6 +410,7 @@ typeArrayOop value = java_lang_String::value(java_string); int offset = java_lang_String::offset(java_string); int length = java_lang_String::length(java_string); + value = typeArrayOop(oopDesc::bs()->resolve_oop(value)); jchar* position = (length == 0) ? NULL : value->char_at_addr(offset); return UNICODE::utf8_length(position, length); } @@ -409,6 +419,7 @@ typeArrayOop value = java_lang_String::value(java_string); int offset = java_lang_String::offset(java_string); int length = java_lang_String::length(java_string); + value = typeArrayOop(oopDesc::bs()->resolve_oop(value)); jchar* position = (length == 0) ? NULL : value->char_at_addr(offset); return UNICODE::as_utf8(position, length); } @@ -417,6 +428,7 @@ typeArrayOop value = java_lang_String::value(java_string); int offset = java_lang_String::offset(java_string); int length = java_lang_String::length(java_string); + value = typeArrayOop(oopDesc::bs()->resolve_oop(value)); jchar* position = (length == 0) ? NULL : value->char_at_addr(offset); return UNICODE::as_utf8(position, length, buf, buflen); } @@ -426,6 +438,7 @@ int offset = java_lang_String::offset(java_string); int length = java_lang_String::length(java_string); assert(start + len <= length, "just checking"); + value = typeArrayOop(oopDesc::bs()->resolve_oop(value)); jchar* position = value->char_at_addr(offset + start); return UNICODE::as_utf8(position, len); } @@ -435,6 +448,7 @@ int offset = java_lang_String::offset(java_string); int length = java_lang_String::length(java_string); assert(start + len <= length, "just checking"); + value = typeArrayOop(oopDesc::bs()->resolve_oop(value)); jchar* position = value->char_at_addr(offset + start); return UNICODE::as_utf8(position, len, buf, buflen); } @@ -684,7 +698,7 @@ oop java_lang_Class::protection_domain(oop java_class) { assert(_protection_domain_offset != 0, "must be set"); - return oopDesc::bs()->resolve_oop(java_class->obj_field(_protection_domain_offset)); + return java_class->obj_field(_protection_domain_offset); } void java_lang_Class::set_protection_domain(oop java_class, oop pd) { assert(_protection_domain_offset != 0, "must be set"); @@ -702,7 +716,7 @@ oop java_lang_Class::init_lock(oop java_class) { assert(_init_lock_offset != 0, "must be set"); - return oopDesc::bs()->resolve_oop(java_class->obj_field(_init_lock_offset)); + return java_class->obj_field(_init_lock_offset); } void java_lang_Class::set_init_lock(oop java_class, oop init_lock) { assert(_init_lock_offset != 0, "must be set"); @@ -711,7 +725,7 @@ objArrayOop java_lang_Class::signers(oop java_class) { assert(_signers_offset != 0, "must be set"); - return (objArrayOop) oopDesc::bs()->resolve_oop(java_class->obj_field(_signers_offset)); + return (objArrayOop)java_class->obj_field(_signers_offset); } void java_lang_Class::set_signers(oop java_class, objArrayOop signers) { assert(_signers_offset != 0, "must be set"); @@ -868,9 +882,7 @@ } else { assert(oopDesc::bs()->resolve_and_maybe_copy_oop(java_class) == oopDesc::bs()->resolve_and_maybe_copy_oop(Universe::void_mirror()), "only valid non-array primitive"); } - assert(oopDesc::bs()->resolve_and_maybe_copy_oop(Universe::java_mirror(type)) == oopDesc::bs()->resolve_and_maybe_copy_oop(java_class), "must be consistent"); - return type; } @@ -1116,7 +1128,7 @@ _park_blocker_offset != 0, "Must support parkBlocker field"); if (_park_blocker_offset > 0) { - return oopDesc::bs()->resolve_oop(java_thread->obj_field(_park_blocker_offset)); + return java_thread->obj_field(_park_blocker_offset); } return NULL; diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/classfile/systemDictionary.cpp --- a/src/share/vm/classfile/systemDictionary.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/classfile/systemDictionary.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -103,7 +103,7 @@ // Java-level SystemLoader oop SystemDictionary::java_system_loader() { - return oopDesc::bs()->resolve_oop(_java_system_loader); + return _java_system_loader; } void SystemDictionary::compute_java_system_loader(TRAPS) { @@ -498,7 +498,7 @@ bool calledholdinglock = ObjectSynchronizer::current_thread_holds_lock((JavaThread*)THREAD, lockObject); assert(calledholdinglock,"must hold lock for notify"); - assert((!(lockObject() == oopDesc::bs()->resolve_oop(_system_loader_lock_obj)) && !is_parallelCapable(lockObject)), "unexpected double_lock_wait"); + assert((!(oopDesc::bs()->resolve_and_maybe_copy_oop(lockObject()) == oopDesc::bs()->resolve_and_maybe_copy_oop(_system_loader_lock_obj)) && !is_parallelCapable(lockObject)), "unexpected double_lock_wait"); ObjectSynchronizer::notifyall(lockObject, THREAD); intptr_t recursions = ObjectSynchronizer::complete_exit(lockObject, THREAD); SystemDictionary_lock->wait(); @@ -1531,9 +1531,9 @@ Handle SystemDictionary::compute_loader_lock_object(Handle class_loader, TRAPS) { // If class_loader is NULL we synchronize on _system_loader_lock_obj if (class_loader.is_null()) { - return Handle(THREAD, oopDesc::bs()->resolve_oop(_system_loader_lock_obj)); + return Handle(THREAD, oopDesc::bs()->resolve_and_maybe_copy_oop(_system_loader_lock_obj)); } else { - return class_loader; + return Handle(THREAD, oopDesc::bs()->resolve_and_maybe_copy_oop(class_loader())); } } @@ -1552,7 +1552,7 @@ == ObjectSynchronizer::owner_other) { // contention will likely happen, so increment the corresponding // contention counter. - if (loader_lock() == oopDesc::bs()->resolve_oop(_system_loader_lock_obj)) { + if (oopDesc::bs()->resolve_and_maybe_copy_oop(loader_lock()) == oopDesc::bs()->resolve_and_maybe_copy_oop(_system_loader_lock_obj)) { ClassLoader::sync_systemLoaderLockContentionRate()->inc(); } else { ClassLoader::sync_nonSystemLoaderLockContentionRate()->inc(); diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/code/nmethod.cpp --- a/src/share/vm/code/nmethod.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/code/nmethod.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -900,7 +900,9 @@ handle == (jobject) Universe::non_oop_word()) { (*dest) = (oop) handle; } else { - (*dest) = JNIHandles::resolve_non_null(handle); + oop obj = JNIHandles::resolve_non_null(handle); + assert(obj == oopDesc::bs()->resolve_and_maybe_copy_oop(obj), "expect to-space copy"); + (*dest) = obj; } } diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/code/relocInfo.cpp --- a/src/share/vm/code/relocInfo.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/code/relocInfo.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -709,7 +709,7 @@ oop v = *oop_addr(); // clean inline caches store a special pseudo-null if (v == (oop)Universe::non_oop_word()) v = NULL; - return oopDesc::bs()->resolve_oop(v); + return v; } diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/gc/shared/barrierSet.hpp --- a/src/share/vm/gc/shared/barrierSet.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/gc/shared/barrierSet.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -221,9 +221,6 @@ virtual oop resolve_oop(oop src) { return src; } - virtual oop maybe_resolve_oop(oop src) { - return src; - } virtual oop resolve_and_maybe_copy_oop(oop src) { return src; } diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/gc/shared/referenceProcessor.cpp --- a/src/share/vm/gc/shared/referenceProcessor.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/gc/shared/referenceProcessor.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -446,7 +446,6 @@ _next = discovered; _referent_addr = java_lang_ref_Reference::referent_addr(_ref); _referent = java_lang_ref_Reference::referent(_ref); - // _referent = oopDesc::bs()->resolve_oop(_referent); assert(_referent == oopDesc::bs()->resolve_oop(_referent), "expect forwarded referent"); assert(Universe::heap()->is_in_reserved_or_null(_referent), "Wrong oop found in java.lang.Reference object"); @@ -645,14 +644,11 @@ void ReferenceProcessor::clear_discovered_references(DiscoveredList& refs_list) { - BarrierSet* bs = oopDesc::bs(); oop obj = NULL; - // oop next = bs->resolve_and_maybe_copy_oop(refs_list.head()); oop next = refs_list.head(); while (next != obj) { obj = next; assert(obj == oopDesc::bs()->resolve_oop(obj), "expect forwarded obj"); - // next = bs->resolve_and_maybe_copy_oop(java_lang_ref_Reference::discovered(obj)); next = java_lang_ref_Reference::discovered(obj); java_lang_ref_Reference::set_discovered_raw(obj, NULL); } @@ -1038,7 +1034,6 @@ // and complexity in processing these references. // We call this choice the "RefeferentBasedDiscovery" policy. bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) { - // Make sure we are discovering refs (rather than processing discovered refs). if (!_discovering_refs || !RegisterReferences) { return false; diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/gc/shared/space.inline.hpp --- a/src/share/vm/gc/shared/space.inline.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/gc/shared/space.inline.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -124,7 +124,9 @@ space->make_oop(q)->mark()->is_marked() || oopDesc::bs()->resolve_oop(space->make_oop(q))->mark()->is_marked() || space->make_oop(q)->mark()->is_unlocked() || - space->make_oop(q)->mark()->has_bias_pattern(), + oopDesc::bs()->resolve_oop(space->make_oop(q))->mark()->is_unlocked() || + space->make_oop(q)->mark()->has_bias_pattern() || + oopDesc::bs()->resolve_oop(space->make_oop(q))->mark()->has_bias_pattern(), "these are the only valid states during a mark sweep"); if (space->scanned_block_is_obj(q) && space->make_oop(q)->is_gc_marked()) { // prefetch beyond q diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/gc/shenandoah/shenandoahBarrierSet.cpp --- a/src/share/vm/gc/shenandoah/shenandoahBarrierSet.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/gc/shenandoah/shenandoahBarrierSet.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -255,14 +255,6 @@ return ShenandoahBarrierSet::resolve_oop_static(src); } -oop ShenandoahBarrierSet::maybe_resolve_oop(oop src) { - if (Universe::heap()->is_in(src)) { - return resolve_oop_static(src); - } else { - return src; - } -} - oop ShenandoahBarrierSet::resolve_and_maybe_copy_oop_work(oop src) { ShenandoahHeap *sh = (ShenandoahHeap*) Universe::heap(); assert(src != NULL, "only evacuated non NULL oops"); diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/gc/shenandoah/shenandoahBarrierSet.hpp --- a/src/share/vm/gc/shenandoah/shenandoahBarrierSet.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/gc/shenandoah/shenandoahBarrierSet.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -149,7 +149,6 @@ } - virtual oop maybe_resolve_oop(oop src); oop resolve_and_maybe_copy_oopHelper(oop src); oop resolve_and_maybe_copy_oop_work(oop src); oop resolve_and_maybe_copy_oop_work2(oop src); diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/gc/shenandoah/shenandoahMarkCompact.cpp --- a/src/share/vm/gc/shenandoah/shenandoahMarkCompact.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/gc/shenandoah/shenandoahMarkCompact.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -55,13 +55,15 @@ } _heap->clear_cset_fast_test(); + /* if (ShenandoahVerify) { // Full GC should only be called between regular concurrent cycles, therefore // those verifications should be valid. _heap->verify_heap_after_evacuation(); _heap->verify_heap_after_update_refs(); } - + */ + if (ShenandoahTraceFullGC) { gclog_or_tty->print_cr("Shenandoah-full-gc: start with heap used: "SIZE_FORMAT" MB", _heap->used() / M); gclog_or_tty->print_cr("Shenandoah-full-gc: phase 1: marking the heap"); diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/interpreter/interpreterRuntime.cpp --- a/src/share/vm/interpreter/interpreterRuntime.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -615,7 +615,7 @@ if (PrintBiasedLockingStatistics) { Atomic::inc(BiasedLocking::slow_path_entry_count_addr()); } - Handle h_obj(thread, elem->obj()); + Handle h_obj(thread, oopDesc::bs()->resolve_and_maybe_copy_oop(elem->obj())); assert(Universe::heap()->is_in_reserved_or_null(h_obj()), "must be NULL or an object"); if (UseBiasedLocking) { @@ -637,7 +637,7 @@ #ifdef ASSERT thread->last_frame().interpreter_frame_verify_monitor(elem); #endif - Handle h_obj(thread, elem->obj()); + Handle h_obj(thread, oopDesc::bs()->resolve_and_maybe_copy_oop(elem->obj())); assert(Universe::heap()->is_in_reserved_or_null(h_obj()), "must be NULL or an object"); if (elem == NULL || h_obj()->is_unlocked()) { diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/memory/oopFactory.cpp --- a/src/share/vm/memory/oopFactory.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/memory/oopFactory.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -40,6 +40,7 @@ typeArrayOop oopFactory::new_charArray(const char* utf8_str, TRAPS) { int length = utf8_str == NULL ? 0 : UTF8::unicode_length(utf8_str); typeArrayOop result = new_charArray(length, CHECK_NULL); + result = typeArrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(result)); if (length > 0) { UTF8::convert_to_unicode(utf8_str, result->char_at_addr(0), length); } diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/memory/universe.cpp --- a/src/share/vm/memory/universe.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/memory/universe.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -592,9 +592,6 @@ // a filled in stack trace. // - if there are no preallocated errors with backtrace available then return // an error without backtrace. - - default_err = resolve_oop(default_err); - int next; if (_preallocated_out_of_memory_error_avail_count > 0) { next = (int)Atomic::add(-1, &_preallocated_out_of_memory_error_avail_count); diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/memory/universe.hpp --- a/src/share/vm/memory/universe.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/memory/universe.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -25,7 +25,6 @@ #ifndef SHARE_VM_MEMORY_UNIVERSE_HPP #define SHARE_VM_MEMORY_UNIVERSE_HPP -#include "gc/shared/barrierSet.hpp" #include "runtime/handles.hpp" #include "utilities/array.hpp" #include "utilities/growableArray.hpp" @@ -204,12 +203,8 @@ static bool _bootstrapping; // true during genesis static bool _fully_initialized; // true after universe_init and initialize_vtables called - static oop resolve_oop(oop o) { - return (oop) oopDesc::bs()->resolve_oop(o); - } - // the array of preallocated errors with backtraces - static objArrayOop preallocated_out_of_memory_errors() { return (objArrayOop) resolve_oop((oop) _preallocated_out_of_memory_error_array); } + static objArrayOop preallocated_out_of_memory_errors() { return _preallocated_out_of_memory_error_array; } // generate an out of memory error; if possible using an error with preallocated backtrace; // otherwise return the given default error. @@ -235,7 +230,7 @@ // Mirrors for primitive classes (created eagerly) static oop check_mirror(oop m) { assert(m != NULL, "mirror not initialized"); - return resolve_oop(m); + return m; } static void set_narrow_oop_base(address base) { @@ -295,19 +290,18 @@ static oop java_mirror(BasicType t) { assert((uint)t < T_VOID+1, "range check"); - oop mirror = check_mirror(_mirrors[t]); - return mirror; + return check_mirror(_mirrors[t]); } - static oop main_thread_group() { return resolve_oop(_main_thread_group); } + static oop main_thread_group() { return _main_thread_group; } static void set_main_thread_group(oop group) { _main_thread_group = group;} - static oop system_thread_group() { return resolve_oop(_system_thread_group); } + static oop system_thread_group() { return _system_thread_group; } static void set_system_thread_group(oop group) { _system_thread_group = group;} - static objArrayOop the_empty_class_klass_array () { return (objArrayOop) resolve_oop((oop) _the_empty_class_klass_array); } + static objArrayOop the_empty_class_klass_array () { return _the_empty_class_klass_array; } static Array* the_array_interfaces_array() { return _the_array_interfaces_array; } - static oop the_null_string() { return resolve_oop(_the_null_string); } - static oop the_min_jint_string() { return resolve_oop(_the_min_jint_string); } + static oop the_null_string() { return _the_null_string; } + static oop the_min_jint_string() { return _the_min_jint_string; } static Method* finalizer_register_method() { return _finalizer_register_cache->get_method(); } static Method* loader_addClass_method() { return _loader_addClass_cache->get_method(); } @@ -315,10 +309,10 @@ static Method* protection_domain_implies_method() { return _pd_implies_cache->get_method(); } static Method* throw_illegal_access_error() { return _throw_illegal_access_error_cache->get_method(); } - static oop null_ptr_exception_instance() { return resolve_oop(_null_ptr_exception_instance); } - static oop arithmetic_exception_instance() { return resolve_oop(_arithmetic_exception_instance); } - static oop virtual_machine_error_instance() { return resolve_oop(_virtual_machine_error_instance); } - static oop vm_exception() { return resolve_oop(_vm_exception); } + static oop null_ptr_exception_instance() { return _null_ptr_exception_instance; } + static oop arithmetic_exception_instance() { return _arithmetic_exception_instance; } + static oop virtual_machine_error_instance() { return _virtual_machine_error_instance; } + static oop vm_exception() { return _vm_exception; } static inline oop allocation_context_notification_obj(); static inline void set_allocation_context_notification_obj(oop obj); diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/memory/universe.inline.hpp --- a/src/share/vm/memory/universe.inline.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/memory/universe.inline.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -42,7 +42,7 @@ } inline oop Universe::allocation_context_notification_obj() { - return resolve_oop(_allocation_context_notification_obj); + return _allocation_context_notification_obj; } inline void Universe::set_allocation_context_notification_obj(oop obj) { diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/oops/cpCache.cpp --- a/src/share/vm/oops/cpCache.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/oops/cpCache.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -283,7 +283,7 @@ // the lock, so that when the losing writer returns, he can use the linked // cache entry. - objArrayHandle resolved_references = cpool->resolved_references(); + objArrayHandle resolved_references = objArrayHandle(objArrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(cpool->resolved_references()))); // Use the resolved_references() lock for this cpCache entry. // resolved_references are created for all classes with Invokedynamic, MethodHandle // or MethodType constant pool cache entries. diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/oops/instanceKlass.cpp --- a/src/share/vm/oops/instanceKlass.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/oops/instanceKlass.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -471,6 +471,7 @@ void InstanceKlass::eager_initialize_impl(instanceKlassHandle this_k) { EXCEPTION_MARK; oop init_lock = this_k->init_lock(); + init_lock = oopDesc::bs()->resolve_and_maybe_copy_oop(init_lock); ObjectLocker ol(init_lock, THREAD, init_lock != NULL); // abort if someone beat us to the initialization @@ -617,6 +618,7 @@ // verification & rewriting { oop init_lock = this_k->init_lock(); + init_lock = oopDesc::bs()->resolve_and_maybe_copy_oop(init_lock); ObjectLocker ol(init_lock, THREAD, init_lock != NULL); // rewritten will have been set if loader constraint error found // on an earlier link attempt @@ -750,6 +752,7 @@ // Step 1 { oop init_lock = this_k->init_lock(); + init_lock = oopDesc::bs()->resolve_and_maybe_copy_oop(init_lock); ObjectLocker ol(init_lock, THREAD, init_lock != NULL); Thread *self = THREAD; // it's passed the current thread @@ -882,6 +885,7 @@ void InstanceKlass::set_initialization_state_and_notify_impl(instanceKlassHandle this_k, ClassState state, TRAPS) { oop init_lock = this_k->init_lock(); + init_lock = oopDesc::bs()->resolve_and_maybe_copy_oop(init_lock); ObjectLocker ol(init_lock, THREAD, init_lock != NULL); this_k->set_init_state(state); this_k->fence_and_clear_init_lock(); diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/oops/instanceRefKlass.cpp --- a/src/share/vm/oops/instanceRefKlass.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/oops/instanceRefKlass.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -91,7 +91,7 @@ bool InstanceRefKlass::owns_pending_list_lock(JavaThread* thread) { if (java_lang_ref_Reference::pending_list_lock() == NULL) return false; - Handle h_lock(thread, java_lang_ref_Reference::pending_list_lock()); + Handle h_lock(thread, oopDesc::bs()->resolve_and_maybe_copy_oop(java_lang_ref_Reference::pending_list_lock())); return ObjectSynchronizer::current_thread_holds_lock(thread, h_lock); } @@ -104,7 +104,7 @@ // to hold the pending list lock. We want to free this handle. HandleMark hm; - Handle h_lock(THREAD, java_lang_ref_Reference::pending_list_lock()); + Handle h_lock(THREAD, oopDesc::bs()->resolve_and_maybe_copy_oop(java_lang_ref_Reference::pending_list_lock())); ObjectSynchronizer::fast_enter(h_lock, pending_list_basic_lock, false, THREAD); assert(ObjectSynchronizer::current_thread_holds_lock( JavaThread::current(), h_lock), @@ -122,7 +122,7 @@ // to hold the pending list lock. We want to free this handle. HandleMark hm; - Handle h_lock(THREAD, java_lang_ref_Reference::pending_list_lock()); + Handle h_lock(THREAD, oopDesc::bs()->resolve_and_maybe_copy_oop(java_lang_ref_Reference::pending_list_lock())); assert(ObjectSynchronizer::current_thread_holds_lock( JavaThread::current(), h_lock), "Lock should be held"); diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/oops/klass.cpp --- a/src/share/vm/oops/klass.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/oops/klass.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -556,7 +556,7 @@ return NULL; } -oop Klass::class_loader() const { return oopDesc::bs()->resolve_oop(class_loader_data()->class_loader()); } +oop Klass::class_loader() const { return class_loader_data()->class_loader(); } const char* Klass::external_name() const { if (oop_is_instance()) { diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/oops/klass.hpp --- a/src/share/vm/oops/klass.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/oops/klass.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -25,7 +25,6 @@ #ifndef SHARE_VM_OOPS_KLASS_HPP #define SHARE_VM_OOPS_KLASS_HPP -#include "gc/shared/barrierSet.hpp" #include "gc/shared/specialized_oop_closures.hpp" #include "memory/iterator.hpp" #include "memory/memRegion.hpp" @@ -224,7 +223,7 @@ void klass_oop_store(volatile oop* p, oop v); // java mirror - oop java_mirror() const { return oopDesc::bs()->resolve_oop(_java_mirror); } + oop java_mirror() const { return _java_mirror; } void set_java_mirror(oop m) { klass_oop_store(&_java_mirror, m); } // modifier flags diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/oops/objArrayKlass.cpp --- a/src/share/vm/oops/objArrayKlass.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/oops/objArrayKlass.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -200,7 +200,6 @@ for (int index = 0; index < length; index++) { ArrayKlass* ak = ArrayKlass::cast(h_lower_dimension()); oop sub_array = ak->multi_allocate(rank-1, &sizes[1], CHECK_NULL); - h_array = objArrayHandle(THREAD, (objArrayOop)oopDesc::bs()->resolve_and_maybe_copy_oop(h_array())); h_array->obj_at_put(index, sub_array); } } else { @@ -299,6 +298,10 @@ if (length==0) { return; } + + s = arrayOop(oopDesc::bs()->resolve_oop(s)); + d = arrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(d)); + if (UseCompressedOops) { narrowOop* const src = objArrayOop(s)->obj_at_addr(src_pos); narrowOop* const dst = objArrayOop(d)->obj_at_addr(dst_pos); diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/oops/objArrayOop.hpp --- a/src/share/vm/oops/objArrayOop.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/oops/objArrayOop.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -25,6 +25,7 @@ #ifndef SHARE_VM_OOPS_OBJARRAYOOP_HPP #define SHARE_VM_OOPS_OBJARRAYOOP_HPP +#include "gc/shared/barrierSet.hpp" #include "gc/shared/specialized_oop_closures.hpp" #include "oops/arrayOop.hpp" @@ -82,15 +83,11 @@ oop obj_at(int index) const; void obj_at_put(int index, oop value) { - objArrayOop forwarded_copy = - (objArrayOop) oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if ((oopDesc*) forwarded_copy != this) - return forwarded_copy->obj_at_put(index, value); - + objArrayOop p = (objArrayOop) oopDesc::bs()->resolve_and_maybe_copy_oop(this); if (UseCompressedOops) { - oop_store(obj_at_addr(index), value); + oop_store(p->obj_at_addr(index), value); } else { - oop_store(obj_at_addr(index), value); + oop_store(p->obj_at_addr(index), value); } } diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/oops/objArrayOop.inline.hpp --- a/src/share/vm/oops/objArrayOop.inline.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/oops/objArrayOop.inline.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -30,12 +30,13 @@ #include "runtime/globals.hpp" inline oop objArrayOopDesc::obj_at(int index) const { + objArrayOop p = (objArrayOop) oopDesc::bs()->resolve_oop((oop) this); // With UseCompressedOops decode the narrow oop in the objArray to an // uncompressed oop. Otherwise this is simply a "*" operator. if (UseCompressedOops) { - return load_decode_heap_oop(obj_at_addr(index)); + return load_decode_heap_oop(p->obj_at_addr(index)); } else { - return load_decode_heap_oop(obj_at_addr(index)); + return load_decode_heap_oop(p->obj_at_addr(index)); } } diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/oops/oop.cpp --- a/src/share/vm/oops/oop.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/oops/oop.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -100,7 +100,7 @@ // slow case; we have to acquire the micro lock in order to locate the header ResetNoHandleMark rnm; // Might be called from LEAF/QUICK ENTRY HandleMark hm; - Handle object(this); + Handle object(oopDesc::bs()->resolve_and_maybe_copy_oop(this)); return ObjectSynchronizer::identity_hash_value_for(object); } diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/oops/oop.inline.hpp --- a/src/share/vm/oops/oop.inline.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/oops/oop.inline.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -134,7 +134,7 @@ inline bool oopDesc::is_objArray() const { return klass()->oop_is_objArray(); } inline bool oopDesc::is_typeArray() const { return klass()->oop_is_typeArray(); } -inline void* oopDesc::field_base(int offset) const { return (void*)&((char*)(oopDesc*)bs()->resolve_oop((oop) this))[offset]; } +inline void* oopDesc::field_base(int offset) const { return (void*)&((char*)this)[offset]; } template inline T* oopDesc::obj_field_addr(int offset) const { return (T*)field_base(offset); } inline Metadata** oopDesc::metadata_field_addr(int offset) const { return (Metadata**)field_base(offset); } @@ -280,43 +280,35 @@ // In order to put or get a field out of an instance, must first check // if the field has been compressed and uncompress it. inline oop oopDesc::obj_field(int offset) const { + oop p = bs()->resolve_oop((oop) this); return UseCompressedOops ? - load_decode_heap_oop(obj_field_addr(offset)) : - load_decode_heap_oop(obj_field_addr(offset)); + load_decode_heap_oop(p->obj_field_addr(offset)) : + load_decode_heap_oop(p->obj_field_addr(offset)); } inline void oopDesc::obj_field_put(int offset, oop value) { - oopDesc* forwarded_copy = oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if (forwarded_copy != this) - return forwarded_copy->obj_field_put(offset, value); - - value = oopDesc::bs()->resolve_oop(value); - - UseCompressedOops ? oop_store(obj_field_addr(offset), value) : - oop_store(obj_field_addr(offset), value); + oop p = bs()->resolve_and_maybe_copy_oop(this); + value = bs()->resolve_oop(value); + UseCompressedOops ? oop_store(p->obj_field_addr(offset), value) : + oop_store(p->obj_field_addr(offset), value); } inline Metadata* oopDesc::metadata_field(int offset) const { - return *metadata_field_addr(offset); + oop p = bs()->resolve_oop((oop) this); + return *p->metadata_field_addr(offset); } inline void oopDesc::metadata_field_put(int offset, Metadata* value) { - oopDesc* forwarded_copy = oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if (forwarded_copy != this) { - return forwarded_copy->metadata_field_put(offset, value); - } - *metadata_field_addr(offset) = value; + oop p = bs()->resolve_and_maybe_copy_oop(this); + *p->metadata_field_addr(offset) = value; } inline void oopDesc::obj_field_put_raw(int offset, oop value) { - oopDesc* forwarded_copy = oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if (forwarded_copy != this) { - return forwarded_copy->obj_field_put_raw(offset, value); - } - value = oopDesc::bs()->resolve_oop(value); + oop p = bs()->resolve_and_maybe_copy_oop(this); + value = bs()->resolve_oop(value); UseCompressedOops ? - encode_store_heap_oop(obj_field_addr(offset), value) : - encode_store_heap_oop(obj_field_addr(offset), value); + encode_store_heap_oop(p->obj_field_addr(offset), value) : + encode_store_heap_oop(p->obj_field_addr(offset), value); } inline void oopDesc::obj_field_put_volatile(int offset, oop value) { OrderAccess::release(); @@ -324,187 +316,182 @@ OrderAccess::fence(); } -inline jbyte oopDesc::byte_field(int offset) const { return (jbyte) *byte_field_addr(offset); } +inline jbyte oopDesc::byte_field(int offset) const { + oop p = bs()->resolve_oop((oop) this); + return (jbyte) *p->byte_field_addr(offset); +} inline void oopDesc::byte_field_put(int offset, jbyte contents) { - oopDesc* forwarded_copy = oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if (forwarded_copy != this) { - return forwarded_copy->byte_field_put(offset, contents); - } - *byte_field_addr(offset) = (jint) contents; + oop p = bs()->resolve_and_maybe_copy_oop(this); + *p->byte_field_addr(offset) = (jint) contents; } -inline jboolean oopDesc::bool_field(int offset) const { return (jboolean) *bool_field_addr(offset); } +inline jboolean oopDesc::bool_field(int offset) const { + oop p = bs()->resolve_oop((oop) this); + return (jboolean) *p->bool_field_addr(offset); +} inline void oopDesc::bool_field_put(int offset, jboolean contents) { - oopDesc* forwarded_copy = oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if (forwarded_copy != this) { - return forwarded_copy->bool_field_put(offset, contents); - } - *bool_field_addr(offset) = (jint) contents; + oop p = bs()->resolve_and_maybe_copy_oop(this); + *p->bool_field_addr(offset) = (jint) contents; } -inline jchar oopDesc::char_field(int offset) const { return (jchar) *char_field_addr(offset); } +inline jchar oopDesc::char_field(int offset) const { + oop p = bs()->resolve_oop((oop) this); + return (jchar) *p->char_field_addr(offset); +} inline void oopDesc::char_field_put(int offset, jchar contents) { - oopDesc* forwarded_copy = oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if (forwarded_copy != this) { - return forwarded_copy->char_field_put(offset, contents); - } - *char_field_addr(offset) = (jint) contents; + oop p = bs()->resolve_and_maybe_copy_oop(this); + *p->char_field_addr(offset) = (jint) contents; } -inline jint oopDesc::int_field(int offset) const { return *int_field_addr(offset); } +inline jint oopDesc::int_field(int offset) const { + oop p = bs()->resolve_oop((oop) this); + return *p->int_field_addr(offset); +} inline void oopDesc::int_field_put(int offset, jint contents) { - oopDesc* forwarded_copy = oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if (forwarded_copy != this) { - return forwarded_copy->int_field_put(offset, contents); - } - *int_field_addr(offset) = contents; + oop p = bs()->resolve_and_maybe_copy_oop(this); + *p->int_field_addr(offset) = contents; } -inline jshort oopDesc::short_field(int offset) const { return (jshort) *short_field_addr(offset); } +inline jshort oopDesc::short_field(int offset) const { + oop p = bs()->resolve_oop((oop) this); + return (jshort) *p->short_field_addr(offset); +} inline void oopDesc::short_field_put(int offset, jshort contents) { - oopDesc* forwarded_copy = oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if (forwarded_copy != this) { - return forwarded_copy->short_field_put(offset, contents); - } - *short_field_addr(offset) = (jint) contents; + oop p = bs()->resolve_and_maybe_copy_oop(this); + *p->short_field_addr(offset) = (jint) contents; } -inline jlong oopDesc::long_field(int offset) const { return *long_field_addr(offset); } +inline jlong oopDesc::long_field(int offset) const { + oop p = bs()->resolve_oop((oop) this); + return *p->long_field_addr(offset); +} inline void oopDesc::long_field_put(int offset, jlong contents) { - oopDesc* forwarded_copy = oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if (forwarded_copy != this) { - return forwarded_copy->long_field_put(offset, contents); - } - *long_field_addr(offset) = contents; + oop p = bs()->resolve_and_maybe_copy_oop(this); + *p->long_field_addr(offset) = contents; } -inline jfloat oopDesc::float_field(int offset) const { return *float_field_addr(offset); } +inline jfloat oopDesc::float_field(int offset) const { + oop p = bs()->resolve_oop((oop) this); + return *p->float_field_addr(offset); +} inline void oopDesc::float_field_put(int offset, jfloat contents) { - oopDesc* forwarded_copy = oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if (forwarded_copy != this) { - return forwarded_copy->float_field_put(offset, contents); - } - *float_field_addr(offset) = contents; + oop p = bs()->resolve_and_maybe_copy_oop(this); + *p->float_field_addr(offset) = contents; } -inline jdouble oopDesc::double_field(int offset) const { return *double_field_addr(offset); } +inline jdouble oopDesc::double_field(int offset) const { + oop p = bs()->resolve_oop((oop) this); + return *p->double_field_addr(offset); +} inline void oopDesc::double_field_put(int offset, jdouble contents) { - oopDesc* forwarded_copy = oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if (forwarded_copy != this) { - return forwarded_copy->double_field_put(offset, contents); - } - *double_field_addr(offset) = contents; + oop p = bs()->resolve_and_maybe_copy_oop(this); + *p->double_field_addr(offset) = contents; } -inline address oopDesc::address_field(int offset) const { return *address_field_addr(offset); } +inline address oopDesc::address_field(int offset) const { + oop p = bs()->resolve_oop((oop) this); + return *p->address_field_addr(offset); +} inline void oopDesc::address_field_put(int offset, address contents) { - oopDesc* forwarded_copy = oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if (forwarded_copy != this) { - return forwarded_copy->address_field_put(offset, contents); - } - *address_field_addr(offset) = contents; + oop p = bs()->resolve_and_maybe_copy_oop(this); + *p->address_field_addr(offset) = contents; } inline oop oopDesc::obj_field_acquire(int offset) const { + oop p = bs()->resolve_oop((oop) this); return UseCompressedOops ? decode_heap_oop((narrowOop) - OrderAccess::load_acquire(obj_field_addr(offset))) + OrderAccess::load_acquire(p->obj_field_addr(offset))) : decode_heap_oop((oop) - OrderAccess::load_ptr_acquire(obj_field_addr(offset))); + OrderAccess::load_ptr_acquire(p->obj_field_addr(offset))); } inline void oopDesc::release_obj_field_put(int offset, oop value) { - oopDesc* forwarded_copy = - (oopDesc*) oopDesc::bs()->resolve_and_maybe_copy_oop(this); - - value = oopDesc::bs()->resolve_oop(value); - - if (forwarded_copy != this) - return forwarded_copy->release_obj_field_put(offset, value); - + oop p = bs()->resolve_and_maybe_copy_oop(this); + value = bs()->resolve_oop(value); UseCompressedOops ? - oop_store((volatile narrowOop*)obj_field_addr(offset), value) : - oop_store((volatile oop*) obj_field_addr(offset), value); + oop_store((volatile narrowOop*)p->obj_field_addr(offset), value) : + oop_store((volatile oop*) p->obj_field_addr(offset), value); } -inline jbyte oopDesc::byte_field_acquire(int offset) const { return OrderAccess::load_acquire(byte_field_addr(offset)); } +inline jbyte oopDesc::byte_field_acquire(int offset) const { + oop p = bs()->resolve_oop((oop) this); + return OrderAccess::load_acquire(p->byte_field_addr(offset)); +} inline void oopDesc::release_byte_field_put(int offset, jbyte contents) { - oopDesc* forwarded_copy = oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if (forwarded_copy != this) { - return forwarded_copy->release_bool_field_put(offset, contents); - } - OrderAccess::release_store(byte_field_addr(offset), contents); + oop p = bs()->resolve_and_maybe_copy_oop(this); + OrderAccess::release_store(p->byte_field_addr(offset), contents); } -inline jboolean oopDesc::bool_field_acquire(int offset) const { return OrderAccess::load_acquire(bool_field_addr(offset)); } +inline jboolean oopDesc::bool_field_acquire(int offset) const { + oop p = bs()->resolve_oop((oop) this); + return OrderAccess::load_acquire(p->bool_field_addr(offset)); +} inline void oopDesc::release_bool_field_put(int offset, jboolean contents) { - oopDesc* forwarded_copy = oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if (forwarded_copy != this) { - return forwarded_copy->release_bool_field_put(offset, contents); - } - OrderAccess::release_store(bool_field_addr(offset), contents); + oop p = bs()->resolve_and_maybe_copy_oop(this); + OrderAccess::release_store(p->bool_field_addr(offset), contents); } -inline jchar oopDesc::char_field_acquire(int offset) const { return OrderAccess::load_acquire(char_field_addr(offset)); } +inline jchar oopDesc::char_field_acquire(int offset) const { + oop p = bs()->resolve_oop((oop) this); + return OrderAccess::load_acquire(p->char_field_addr(offset)); +} inline void oopDesc::release_char_field_put(int offset, jchar contents) { - oopDesc* forwarded_copy = oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if (forwarded_copy != this) { - return forwarded_copy->release_char_field_put(offset, contents); - } - OrderAccess::release_store(char_field_addr(offset), contents); + oop p = bs()->resolve_and_maybe_copy_oop(this); + OrderAccess::release_store(p->char_field_addr(offset), contents); } -inline jint oopDesc::int_field_acquire(int offset) const { return OrderAccess::load_acquire(int_field_addr(offset)); } +inline jint oopDesc::int_field_acquire(int offset) const { + oop p = bs()->resolve_oop((oop) this); + return OrderAccess::load_acquire(p->int_field_addr(offset)); +} inline void oopDesc::release_int_field_put(int offset, jint contents) { - oopDesc* forwarded_copy = oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if (forwarded_copy != this) { - return forwarded_copy->release_int_field_put(offset, contents); - } - OrderAccess::release_store(int_field_addr(offset), contents); + oop p = bs()->resolve_and_maybe_copy_oop(this); + OrderAccess::release_store(p->int_field_addr(offset), contents); } -inline jshort oopDesc::short_field_acquire(int offset) const { return (jshort)OrderAccess::load_acquire(short_field_addr(offset)); } +inline jshort oopDesc::short_field_acquire(int offset) const { + oop p = bs()->resolve_oop((oop) this); + return (jshort)OrderAccess::load_acquire(p->short_field_addr(offset)); +} inline void oopDesc::release_short_field_put(int offset, jshort contents) { - oopDesc* forwarded_copy = oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if (forwarded_copy != this) { - return forwarded_copy->release_short_field_put(offset, contents); - } - OrderAccess::release_store(short_field_addr(offset), contents); + oop p = bs()->resolve_and_maybe_copy_oop(this); + OrderAccess::release_store(p->short_field_addr(offset), contents); } -inline jlong oopDesc::long_field_acquire(int offset) const { return OrderAccess::load_acquire(long_field_addr(offset)); } +inline jlong oopDesc::long_field_acquire(int offset) const { + oop p = bs()->resolve_oop((oop) this); + return OrderAccess::load_acquire(p->long_field_addr(offset)); +} inline void oopDesc::release_long_field_put(int offset, jlong contents) { - oopDesc* forwarded_copy = oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if (forwarded_copy != this) { - return forwarded_copy->release_long_field_put(offset, contents); - } - OrderAccess::release_store(long_field_addr(offset), contents); + oop p = bs()->resolve_and_maybe_copy_oop(this); + OrderAccess::release_store(p->long_field_addr(offset), contents); } -inline jfloat oopDesc::float_field_acquire(int offset) const { return OrderAccess::load_acquire(float_field_addr(offset)); } +inline jfloat oopDesc::float_field_acquire(int offset) const { + oop p = bs()->resolve_oop((oop) this); + return OrderAccess::load_acquire(p->float_field_addr(offset)); +} inline void oopDesc::release_float_field_put(int offset, jfloat contents) { - oopDesc* forwarded_copy = oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if (forwarded_copy != this) { - return forwarded_copy->release_float_field_put(offset, contents); - } - OrderAccess::release_store(float_field_addr(offset), contents); + oop p = bs()->resolve_and_maybe_copy_oop(this); + OrderAccess::release_store(p->float_field_addr(offset), contents); } -inline jdouble oopDesc::double_field_acquire(int offset) const { return OrderAccess::load_acquire(double_field_addr(offset)); } +inline jdouble oopDesc::double_field_acquire(int offset) const { + oop p = bs()->resolve_oop((oop) this); + return OrderAccess::load_acquire(p->double_field_addr(offset)); +} inline void oopDesc::release_double_field_put(int offset, jdouble contents) { - oopDesc* forwarded_copy = oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if (forwarded_copy != this) { - return forwarded_copy->release_double_field_put(offset, contents); - } - OrderAccess::release_store(double_field_addr(offset), contents); + oop p = bs()->resolve_and_maybe_copy_oop(this); + OrderAccess::release_store(p->double_field_addr(offset), contents); } -inline address oopDesc::address_field_acquire(int offset) const { return (address) OrderAccess::load_ptr_acquire(address_field_addr(offset)); } +inline address oopDesc::address_field_acquire(int offset) const { + oop p = bs()->resolve_oop((oop) this); + return (address) OrderAccess::load_ptr_acquire(p->address_field_addr(offset)); +} inline void oopDesc::release_address_field_put(int offset, address contents) { - oopDesc* forwarded_copy = oopDesc::bs()->resolve_and_maybe_copy_oop(this); - if (forwarded_copy != this) { - return forwarded_copy->release_address_field_put(offset, contents); - } - OrderAccess::release_store_ptr(address_field_addr(offset), contents); + oop p = bs()->resolve_and_maybe_copy_oop(this); + OrderAccess::release_store_ptr(p->address_field_addr(offset), contents); } inline int oopDesc::size_given_klass(Klass* klass) { diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/oops/typeArrayKlass.cpp --- a/src/share/vm/oops/typeArrayKlass.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/oops/typeArrayKlass.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -148,6 +148,9 @@ if (length == 0) return; + s = arrayOop(oopDesc::bs()->resolve_oop(s)); + d = arrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(d)); + // This is an attempt to make the copy_array fast. int l2es = log2_element_size(); int ihs = array_header_in_bytes() / wordSize; diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/oops/typeArrayOop.hpp --- a/src/share/vm/oops/typeArrayOop.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/oops/typeArrayOop.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -25,6 +25,7 @@ #ifndef SHARE_VM_OOPS_TYPEARRAYOOP_HPP #define SHARE_VM_OOPS_TYPEARRAYOOP_HPP +#include "gc/shared/barrierSet.hpp" #include "oops/arrayOop.hpp" #include "oops/typeArrayKlass.hpp" #include "runtime/orderAccess.inline.hpp" @@ -92,50 +93,116 @@ return &double_base()[which]; } - jbyte byte_at(int which) const { return *byte_at_addr(which); } - void byte_at_put(int which, jbyte contents) { *byte_at_addr(which) = contents; } + jbyte byte_at(int which) const { + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_oop((oop) this)); + return *p->byte_at_addr(which); + } + void byte_at_put(int which, jbyte contents) { + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(this)); + *p->byte_at_addr(which) = contents; + } - jboolean bool_at(int which) const { return *bool_at_addr(which); } - void bool_at_put(int which, jboolean contents) { *bool_at_addr(which) = contents; } + jboolean bool_at(int which) const { + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_oop((oop) this)); + return *p->bool_at_addr(which); + } + void bool_at_put(int which, jboolean contents) { + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(this)); + *p->bool_at_addr(which) = contents; + } - jchar char_at(int which) const { return *char_at_addr(which); } - void char_at_put(int which, jchar contents) { *char_at_addr(which) = contents; } + jchar char_at(int which) const { + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_oop((oop) this)); + return *p->char_at_addr(which); + } + void char_at_put(int which, jchar contents) { + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(this)); + *p->char_at_addr(which) = contents; + } - jint int_at(int which) const { return *int_at_addr(which); } - void int_at_put(int which, jint contents) { *int_at_addr(which) = contents; } + jint int_at(int which) const { + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_oop((oop) this)); + return *p->int_at_addr(which); + } + void int_at_put(int which, jint contents) { + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(this)); + *p->int_at_addr(which) = contents; + } - jshort short_at(int which) const { return *short_at_addr(which); } - void short_at_put(int which, jshort contents) { *short_at_addr(which) = contents; } + jshort short_at(int which) const { + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_oop((oop) this)); + return *p->short_at_addr(which); + } + void short_at_put(int which, jshort contents) { + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(this)); + *p->short_at_addr(which) = contents; + } - jushort ushort_at(int which) const { return *ushort_at_addr(which); } - void ushort_at_put(int which, jushort contents) { *ushort_at_addr(which) = contents; } + jushort ushort_at(int which) const { + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_oop((oop) this)); + return *p->ushort_at_addr(which); + } + void ushort_at_put(int which, jushort contents) { + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(this)); + *p->ushort_at_addr(which) = contents; + } - jlong long_at(int which) const { return *long_at_addr(which); } - void long_at_put(int which, jlong contents) { *long_at_addr(which) = contents; } + jlong long_at(int which) const { + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_oop((oop) this)); + return *p->long_at_addr(which); + } + void long_at_put(int which, jlong contents) { + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(this)); + *p->long_at_addr(which) = contents; + } - jfloat float_at(int which) const { return *float_at_addr(which); } - void float_at_put(int which, jfloat contents) { *float_at_addr(which) = contents; } + jfloat float_at(int which) const { + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_oop((oop) this)); + return *p->float_at_addr(which); + } + void float_at_put(int which, jfloat contents) { + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(this)); + *p->float_at_addr(which) = contents; + } - jdouble double_at(int which) const { return *double_at_addr(which); } - void double_at_put(int which, jdouble contents) { *double_at_addr(which) = contents; } + jdouble double_at(int which) const { + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_oop((oop) this)); + return *p->double_at_addr(which); + } + void double_at_put(int which, jdouble contents) { + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(this)); + *p->double_at_addr(which) = contents; + } - jbyte byte_at_acquire(int which) const { return OrderAccess::load_acquire(byte_at_addr(which)); } - void release_byte_at_put(int which, jbyte contents) { OrderAccess::release_store(byte_at_addr(which), contents); } + jbyte byte_at_acquire(int which) const { + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_oop((oop) this)); + return OrderAccess::load_acquire(p->byte_at_addr(which)); + } + void release_byte_at_put(int which, jbyte contents) { + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(this)); + OrderAccess::release_store(p->byte_at_addr(which), contents); + } // Java thinks metadata arrays are just arrays of either long or int, since // there doesn't seem to be T_ADDRESS, so this is a bit of unfortunate // casting #ifdef _LP64 Metadata* metadata_at(int which) const { - return (Metadata*)*long_at_addr(which); } + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_oop((oop) this)); + return (Metadata*)*p->long_at_addr(which); + } void metadata_at_put(int which, Metadata* contents) { - *long_at_addr(which) = (long)contents; + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(this)); + *p->long_at_addr(which) = (long)contents; } #else Metadata* metadata_at(int which) const { - return (Metadata*)*int_at_addr(which); } + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_oop((oop) this)); + return (Metadata*)*p->int_at_addr(which); + } void metadata_at_put(int which, Metadata* contents) { - *int_at_addr(which) = (int)contents; + typeArrayOop p = typeArrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(this)); + *p->int_at_addr(which) = (int)contents; } #endif // _LP64 diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/opto/runtime.cpp --- a/src/share/vm/opto/runtime.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/opto/runtime.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -423,7 +423,7 @@ ResourceMark rm; jint len = dims->length(); assert(len > 0, "Dimensions array should contain data"); - jint *j_dims = typeArrayOop(dims)->int_at_addr(0); + jint *j_dims = typeArrayOop(oopDesc::bs()->resolve_oop(dims))->int_at_addr(0); jint *c_dims = NEW_RESOURCE_ARRAY(jint, len); Copy::conjoint_jints_atomic(j_dims, c_dims, len); @@ -438,6 +438,7 @@ // the dominant fast-path is to simply return. // Relatedly, it's critical that notify/notifyAll be fast in order to // reduce lock hold times. + obj = oopDesc::bs()->resolve_and_maybe_copy_oop(obj); if (!SafepointSynchronize::is_synchronizing()) { if (ObjectSynchronizer::quick_notify(obj, thread, false)) { return; @@ -456,6 +457,7 @@ JRT_BLOCK_ENTRY(void, OptoRuntime::monitor_notifyAll_C(oopDesc* obj, JavaThread *thread)) + obj = oopDesc::bs()->resolve_and_maybe_copy_oop(obj); if (!SafepointSynchronize::is_synchronizing() ) { if (ObjectSynchronizer::quick_notify(obj, thread, true)) { return; diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/prims/jni.cpp --- a/src/share/vm/prims/jni.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/prims/jni.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -336,7 +336,7 @@ } ResourceMark rm(THREAD); ClassFileStream st((u1*) buf, bufLen, NULL); - Handle class_loader (THREAD, JNIHandles::resolve(loaderRef)); + Handle class_loader (THREAD, oopDesc::bs()->resolve_and_maybe_copy_oop(JNIHandles::resolve(loaderRef))); if (UsePerfData && !class_loader.is_null()) { // check whether the current caller thread holds the lock or not. @@ -823,6 +823,7 @@ oop a = JNIHandles::resolve(r1); a = oopDesc::bs()->resolve_and_maybe_copy_oop(a); oop b = JNIHandles::resolve(r2); + b = oopDesc::bs()->resolve_and_maybe_copy_oop(b); jboolean ret = (a == b) ? JNI_TRUE : JNI_FALSE; HOTSPOT_JNI_ISSAMEOBJECT_RETURN(ret); @@ -2170,7 +2171,6 @@ JNIWrapper("SetObjectField"); HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(env, obj, (uintptr_t) fieldID, value); oop o = JNIHandles::resolve_non_null(obj); - o = oopDesc::bs()->resolve_and_maybe_copy_oop(o); Klass* k = o->klass(); int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); // Keep JVMTI addition small and only check enabled flag here. @@ -2195,7 +2195,6 @@ EntryProbe; \ \ oop o = JNIHandles::resolve_non_null(obj); \ - o = oopDesc::bs()->resolve_and_maybe_copy_oop(o); \ Klass* k = o->klass(); \ int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \ /* Keep JVMTI addition small and only check enabled flag here. */ \ @@ -2405,9 +2404,7 @@ field_value.unionType = value; \ JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, SigType, (jvalue *)&field_value); \ } \ - oop o = id->holder()->java_mirror(); \ - o = oopDesc::bs()->resolve_and_maybe_copy_oop(o); \ - o-> Fieldname##_field_put (id->offset(), value); \ + id->holder()->java_mirror()-> Fieldname##_field_put (id->offset(), value); \ ReturnProbe;\ JNI_END @@ -2476,7 +2473,7 @@ HOTSPOT_JNI_GETSTRINGCHARS_ENTRY(env, string, (uintptr_t *) isCopy); jchar* buf = NULL; oop s = JNIHandles::resolve_non_null(string); - typeArrayOop s_value = java_lang_String::value(s); + typeArrayOop s_value = typeArrayOop(oopDesc::bs()->resolve_oop(java_lang_String::value(s))); if (s_value != NULL) { int s_len = java_lang_String::length(s); int s_offset = java_lang_String::offset(s); @@ -2575,7 +2572,7 @@ JNI_QUICK_ENTRY(jsize, jni_GetArrayLength(JNIEnv *env, jarray array)) JNIWrapper("GetArrayLength"); HOTSPOT_JNI_GETARRAYLENGTH_ENTRY(env, array); - arrayOop a = arrayOop(JNIHandles::resolve_non_null(array)); + arrayOop a = arrayOop(oopDesc::bs()->resolve_oop(JNIHandles::resolve_non_null(array))); assert(a->is_array(), "must be array"); jsize ret = a->length(); HOTSPOT_JNI_GETARRAYLENGTH_RETURN(ret); @@ -2638,7 +2635,6 @@ DT_VOID_RETURN_MARK(SetObjectArrayElement); objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array)); - a = objArrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(a)); oop v = JNIHandles::resolve(value); if (a->is_within_bounds(index)) { if (v == NULL || v->is_a(ObjArrayKlass::cast(a->klass())->element_klass())) { @@ -2725,6 +2721,7 @@ EntryProbe; \ /* allocate an chunk of memory in c land */ \ typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \ + a = typeArrayOop(oopDesc::bs()->resolve_oop(a)); \ ElementType* result; \ int len = a->length(); \ if (len == 0) { \ @@ -2834,6 +2831,7 @@ EntryProbe; \ DT_VOID_RETURN_MARK(Get##Result##ArrayRegion); \ typeArrayOop src = typeArrayOop(JNIHandles::resolve_non_null(array)); \ + src = typeArrayOop(oopDesc::bs()->resolve_oop(src)); \ if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)src->length())) { \ THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \ } else { \ @@ -3083,7 +3081,7 @@ THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR); } - Handle obj(thread, JNIHandles::resolve_non_null(jobj)); + Handle obj(thread, oopDesc::bs()->resolve_and_maybe_copy_oop(JNIHandles::resolve_non_null(jobj))); ObjectSynchronizer::jni_enter(obj, CHECK_(JNI_ERR)); ret = JNI_OK; return ret; @@ -3102,7 +3100,7 @@ THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR); } - Handle obj(THREAD, JNIHandles::resolve_non_null(jobj)); + Handle obj(THREAD, oopDesc::bs()->resolve_and_maybe_copy_oop(JNIHandles::resolve_non_null(jobj))); ObjectSynchronizer::jni_exit(obj(), CHECK_(JNI_ERR)); ret = JNI_OK; @@ -3121,6 +3119,7 @@ HOTSPOT_JNI_GETSTRINGREGION_ENTRY(env, string, start, len, buf); DT_VOID_RETURN_MARK(GetStringRegion); oop s = JNIHandles::resolve_non_null(string); + s = oopDesc::bs()->resolve_oop(s); int s_len = java_lang_String::length(s); if (start < 0 || len < 0 || start + len > s_len) { THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException()); @@ -3128,6 +3127,7 @@ if (len > 0) { int s_offset = java_lang_String::offset(s); typeArrayOop s_value = java_lang_String::value(s); + s_value = typeArrayOop(oopDesc::bs()->resolve_oop(s_value)); memcpy(buf, s_value->char_at_addr(s_offset+start), sizeof(jchar)*len); } } @@ -3201,6 +3201,7 @@ oop s = JNIHandles::resolve_non_null(string); int s_len = java_lang_String::length(s); typeArrayOop s_value = java_lang_String::value(s); + s_value = typeArrayOop(oopDesc::bs()->resolve_oop(s_value)); int s_offset = java_lang_String::offset(s); const jchar* ret; if (s_len > 0) { diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/prims/jvm.cpp --- a/src/share/vm/prims/jvm.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/prims/jvm.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -357,10 +357,7 @@ assert(s->is_oop(), "JVM_ArrayCopy: src not an oop"); assert(d->is_oop(), "JVM_ArrayCopy: dst not an oop"); // Do copy - s->klass()->copy_array(s, src_pos, - (arrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(d))), - dst_pos, - length, thread); + s->klass()->copy_array(s, src_pos, d, dst_pos, length, thread); JVM_END @@ -554,13 +551,15 @@ JVM_ENTRY(jint, JVM_IHashCode(JNIEnv* env, jobject handle)) JVMWrapper("JVM_IHashCode"); // as implemented in the classic virtual machine; return 0 if object is NULL - return handle == NULL ? 0 : ObjectSynchronizer::FastHashCode (THREAD, JNIHandles::resolve_non_null(handle)) ; + return handle == NULL ? 0 : ObjectSynchronizer::FastHashCode (THREAD, oopDesc::bs()->resolve_and_maybe_copy_oop(JNIHandles::resolve_non_null(handle))) ; JVM_END JVM_ENTRY(void, JVM_MonitorWait(JNIEnv* env, jobject handle, jlong ms)) JVMWrapper("JVM_MonitorWait"); - Handle obj(THREAD, JNIHandles::resolve_non_null(handle)); + oop o = JNIHandles::resolve_non_null(handle); + o = oopDesc::bs()->resolve_and_maybe_copy_oop(o); + Handle obj(THREAD, o); JavaThreadInObjectWaitState jtiows(thread, ms != 0); if (JvmtiExport::should_post_monitor_wait()) { JvmtiExport::post_monitor_wait((JavaThread *)THREAD, (oop)obj(), ms); @@ -577,14 +576,14 @@ JVM_ENTRY(void, JVM_MonitorNotify(JNIEnv* env, jobject handle)) JVMWrapper("JVM_MonitorNotify"); - Handle obj(THREAD, JNIHandles::resolve_non_null(handle)); + Handle obj(THREAD, oopDesc::bs()->resolve_and_maybe_copy_oop(JNIHandles::resolve_non_null(handle))); ObjectSynchronizer::notify(obj, CHECK); JVM_END JVM_ENTRY(void, JVM_MonitorNotifyAll(JNIEnv* env, jobject handle)) JVMWrapper("JVM_MonitorNotifyAll"); - Handle obj(THREAD, JNIHandles::resolve_non_null(handle)); + Handle obj(THREAD, oopDesc::bs()->resolve_and_maybe_copy_oop(JNIHandles::resolve_non_null(handle))); ObjectSynchronizer::notifyall(obj, CHECK); JVM_END @@ -898,7 +897,7 @@ ResourceMark rm(THREAD); ClassFileStream st((u1*) buf, len, (char *)source); - Handle class_loader (THREAD, JNIHandles::resolve(loader)); + Handle class_loader (THREAD, oopDesc::bs()->resolve_and_maybe_copy_oop(JNIHandles::resolve(loader))); if (UsePerfData) { is_lock_held_by_thread(class_loader, ClassLoader::sync_JVMDefineClassLockFreeCounter(), @@ -962,7 +961,7 @@ // Security Note: // The Java level wrapper will perform the necessary security check allowing // us to pass the NULL as the initiating class loader. - Handle h_loader(THREAD, JNIHandles::resolve(loader)); + Handle h_loader(THREAD, oopDesc::bs()->resolve_and_maybe_copy_oop(JNIHandles::resolve(loader))); if (UsePerfData) { is_lock_held_by_thread(h_loader, ClassLoader::sync_JVMFindLoadedClassLockFreeCounter(), @@ -3031,7 +3030,7 @@ if (obj == NULL) { THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE); } - Handle h_obj(THREAD, JNIHandles::resolve(obj)); + Handle h_obj(THREAD, oopDesc::bs()->resolve_and_maybe_copy_oop(JNIHandles::resolve(obj))); return ObjectSynchronizer::current_thread_holds_lock((JavaThread*)THREAD, h_obj); JVM_END @@ -3321,7 +3320,6 @@ JVM_ENTRY(void, JVM_SetArrayElement(JNIEnv *env, jobject arr, jint index, jobject val)) JVMWrapper("JVM_SetArrayElement"); arrayOop a = check_array(env, arr, false, CHECK); - a = arrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(a)); oop box = JNIHandles::resolve(val); jvalue value; value.i = 0; // to initialize value before getting used in CHECK @@ -3339,7 +3337,6 @@ JVM_ENTRY(void, JVM_SetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jvalue v, unsigned char vCode)) JVMWrapper("JVM_SetPrimitiveArrayElement"); arrayOop a = check_array(env, arr, true, CHECK); - a = arrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(a)); assert(a->is_typeArray(), "just checking"); BasicType value_type = (BasicType) vCode; Reflection::array_set(&v, a, index, value_type, CHECK); diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/prims/jvmtiEnv.cpp --- a/src/share/vm/prims/jvmtiEnv.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/prims/jvmtiEnv.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -467,7 +467,7 @@ // lock the loader Thread* thread = Thread::current(); HandleMark hm; - Handle loader_lock = Handle(thread, SystemDictionary::system_loader_lock()); + Handle loader_lock = Handle(thread, oopDesc::bs()->resolve_and_maybe_copy_oop(SystemDictionary::system_loader_lock())); ObjectLocker ol(loader_lock, thread); @@ -513,7 +513,7 @@ // lock the loader Thread* THREAD = Thread::current(); - Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); + Handle loader = Handle(THREAD, oopDesc::bs()->resolve_and_maybe_copy_oop(SystemDictionary::java_system_loader())); ObjectLocker ol(loader, THREAD); diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/prims/unsafe.cpp --- a/src/share/vm/prims/unsafe.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/prims/unsafe.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -126,8 +126,7 @@ // gets moved by concurrent threads while executing this code. p = oopDesc::bs()->resolve_and_maybe_copy_oop(p); void* ptr_plus_disp = (address)p + byte_offset; - void* obj_field_addr = (void*)p->obj_field_addr((jint)byte_offset); - assert(obj_field_addr == ptr_plus_disp, + assert((void*)p->obj_field_addr((jint)byte_offset) == ptr_plus_disp, "raw [ptr+disp] must be consistent with oop::field_base"); } jlong p_size = HeapWordSize * (jlong)(p->size()); @@ -160,6 +159,7 @@ #define GET_FIELD(obj, offset, type_name, v) \ oop p = JNIHandles::resolve(obj); \ + p = oopDesc::bs()->resolve_oop(p); \ type_name v = *(type_name*)index_oop_from_field_offset_long(p, offset) #define SET_FIELD(obj, offset, type_name, x) \ @@ -169,6 +169,7 @@ #define GET_FIELD_VOLATILE(obj, offset, type_name, v) \ oop p = JNIHandles::resolve(obj); \ + p = oopDesc::bs()->resolve_oop(p); \ if (support_IRIW_for_not_multiple_copy_atomic_cpu) { \ OrderAccess::fence(); \ } \ @@ -188,6 +189,7 @@ UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) UnsafeWrapper("Unsafe_GetObject"); oop p = JNIHandles::resolve(obj); + p = oopDesc::bs()->resolve_oop(p); oop v; if (UseCompressedOops) { narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset); @@ -225,7 +227,7 @@ UNSAFE_ENTRY(void, Unsafe_SetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) UnsafeWrapper("Unsafe_SetObject"); - oop x = JNIHandles::resolve(x_h); + oop x = oopDesc::bs()->resolve_oop(JNIHandles::resolve(x_h)); oop p = oopDesc::bs()->resolve_and_maybe_copy_oop(JNIHandles::resolve(obj)); if (UseCompressedOops) { oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x); @@ -237,6 +239,7 @@ UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset)) UnsafeWrapper("Unsafe_GetObjectVolatile"); oop p = JNIHandles::resolve(obj); + p = oopDesc::bs()->resolve_oop(p); void* addr = index_oop_from_field_offset_long(p, offset); volatile oop v; if (UseCompressedOops) { @@ -253,6 +256,7 @@ UnsafeWrapper("Unsafe_SetObjectVolatile"); oop x = JNIHandles::resolve(x_h); oop p = JNIHandles::resolve(obj); + x = oopDesc::bs()->resolve_oop(x); p = oopDesc::bs()->resolve_and_maybe_copy_oop(p); void* addr = index_oop_from_field_offset_long(p, offset); OrderAccess::release(); @@ -320,7 +324,7 @@ return v; } else { - Handle p (THREAD, JNIHandles::resolve(obj)); + Handle p (THREAD, oopDesc::bs()->resolve_oop(JNIHandles::resolve(obj))); jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset)); MutexLockerEx mu(UnsafeJlong_lock, Mutex::_no_safepoint_check_flag); jlong value = Atomic::load(addr); @@ -443,6 +447,7 @@ UnsafeWrapper("Unsafe_SetOrderedObject"); oop x = JNIHandles::resolve(x_h); oop p = JNIHandles::resolve(obj); + x = oopDesc::bs()->resolve_oop(x); p = oopDesc::bs()->resolve_and_maybe_copy_oop(p); void* addr = index_oop_from_field_offset_long(p, offset); OrderAccess::release(); @@ -660,6 +665,7 @@ } oop srcp = JNIHandles::resolve(srcObj); oop dstp = JNIHandles::resolve(dstObj); + srcp = oopDesc::bs()->resolve_oop(srcp); dstp = oopDesc::bs()->resolve_and_maybe_copy_oop(dstp); if (dstp != NULL && !dstp->is_typeArray()) { // NYI: This works only for non-oop arrays at present. @@ -1097,6 +1103,7 @@ oop p = oopDesc::bs()->resolve_and_maybe_copy_oop(JNIHandles::resolve(obj)); HeapWord* addr = (HeapWord *)index_oop_from_field_offset_long(p, offset); oop x = JNIHandles::resolve(x_h); + x = oopDesc::bs()->resolve_oop(x); oop old = JNIHandles::resolve(e_h); jboolean success; if (UseShenandoahGC) { @@ -1199,7 +1206,7 @@ double la[max_nelem]; jint ret; - typeArrayOop a = typeArrayOop(oopDesc::bs()->resolve_and_maybe_copy_oop(JNIHandles::resolve_non_null(loadavg))); + typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(loadavg)); assert(a->is_typeArray(), "must be type array"); if (nelem < 0 || nelem > max_nelem || a->length() < nelem) { diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/runtime/basicLock.hpp --- a/src/share/vm/runtime/basicLock.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/runtime/basicLock.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -62,8 +62,14 @@ public: // Manipulation - oop obj() const { return oopDesc::bs()->resolve_oop(_obj); } - void set_obj(oop obj) { _obj = obj; } + oop obj() const { + assert(_obj == oopDesc::bs()->resolve_and_maybe_copy_oop(_obj), "expect to-space copy"); + return _obj; + } + void set_obj(oop obj) { + _obj = obj; + assert(_obj == oopDesc::bs()->resolve_and_maybe_copy_oop(_obj), "expect to-space copy"); + } BasicLock* lock() { return &_lock; } // Note: Use frame::interpreter_frame_monitor_size() for the size of BasicObjectLocks diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/runtime/biasedLocking.cpp --- a/src/share/vm/runtime/biasedLocking.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/runtime/biasedLocking.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -146,6 +146,7 @@ static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread) { + assert(obj == oopDesc::bs()->resolve_oop(obj), "expect to-space copy"); markOop mark = obj->mark(); if (!mark->has_bias_pattern()) { if (TraceBiasedLocking) { @@ -325,7 +326,7 @@ bool attempt_rebias_of_object, JavaThread* requesting_thread) { assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint"); - + assert(o == oopDesc::bs()->resolve_oop(o), "expect to-space copy"); if (TraceBiasedLocking) { tty->print_cr("* Beginning bulk revocation (kind == %s) because of object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s", @@ -367,6 +368,7 @@ if ((owner->klass() == k_o) && mark->has_bias_pattern()) { // We might have encountered this object already in the case of recursive locking assert(mark->bias_epoch() == prev_epoch || mark->bias_epoch() == cur_epoch, "error in bias epoch adjustment"); + assert(owner == oopDesc::bs()->resolve_oop(owner), "expect to-space copy"); owner->set_mark(mark->set_bias_epoch(cur_epoch)); } } @@ -531,14 +533,13 @@ BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) { assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint"); - Handle n_obj(THREAD, - oopDesc::bs()->resolve_and_maybe_copy_oop(obj())); + assert(obj() == oopDesc::bs()->resolve_oop(obj()), "must be to-space copy"); // We can revoke the biases of anonymously-biased objects // efficiently enough that we should not cause these revocations to // update the heuristics because doing so may cause unwanted bulk // revocations (which are expensive) to occur. - markOop mark = n_obj->mark(); + markOop mark = obj->mark(); if (mark->is_biased_anonymously() && !attempt_rebias) { // We are probably trying to revoke the bias of this object due to // an identity hash code computation. Try to revoke the bias @@ -548,12 +549,12 @@ // the bias of the object. markOop biased_value = mark; markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age()); - markOop res_mark = (markOop) Atomic::cmpxchg_ptr(unbiased_prototype, n_obj->mark_addr(), mark); + markOop res_mark = (markOop) Atomic::cmpxchg_ptr(unbiased_prototype, obj->mark_addr(), mark); if (res_mark == biased_value) { return BIAS_REVOKED; } } else if (mark->has_bias_pattern()) { - Klass* k = n_obj->klass(); + Klass* k = obj->klass(); markOop prototype_header = k->prototype_header(); if (!prototype_header->has_bias_pattern()) { // This object has a stale bias from before the bulk revocation @@ -563,8 +564,8 @@ // by another thread so we simply return and let the caller deal // with it. markOop biased_value = mark; - markOop res_mark = (markOop) Atomic::cmpxchg_ptr(prototype_header, n_obj->mark_addr(), mark); - assert(!(*(n_obj->mark_addr()))->has_bias_pattern(), "even if we raced, should still be revoked"); + markOop res_mark = (markOop) Atomic::cmpxchg_ptr(prototype_header, obj->mark_addr(), mark); + assert(!(*(obj->mark_addr()))->has_bias_pattern(), "even if we raced, should still be revoked"); return BIAS_REVOKED; } else if (prototype_header->bias_epoch() != mark->bias_epoch()) { // The epoch of this biasing has expired indicating that the @@ -578,14 +579,14 @@ assert(THREAD->is_Java_thread(), ""); markOop biased_value = mark; markOop rebiased_prototype = markOopDesc::encode((JavaThread*) THREAD, mark->age(), prototype_header->bias_epoch()); - markOop res_mark = (markOop) Atomic::cmpxchg_ptr(rebiased_prototype, n_obj->mark_addr(), mark); + markOop res_mark = (markOop) Atomic::cmpxchg_ptr(rebiased_prototype, obj->mark_addr(), mark); if (res_mark == biased_value) { return BIAS_REVOKED_AND_REBIASED; } } else { markOop biased_value = mark; markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age()); - markOop res_mark = (markOop) Atomic::cmpxchg_ptr(unbiased_prototype, n_obj->mark_addr(), mark); + markOop res_mark = (markOop) Atomic::cmpxchg_ptr(unbiased_prototype, obj->mark_addr(), mark); if (res_mark == biased_value) { return BIAS_REVOKED; } @@ -593,11 +594,11 @@ } } - HeuristicsResult heuristics = update_heuristics(n_obj(), attempt_rebias); + HeuristicsResult heuristics = update_heuristics(obj(), attempt_rebias); if (heuristics == HR_NOT_BIASED) { return NOT_BIASED; } else if (heuristics == HR_SINGLE_REVOKE) { - Klass *k = n_obj->klass(); + Klass *k = obj->klass(); markOop prototype_header = k->prototype_header(); if (mark->biased_locker() == THREAD && prototype_header->bias_epoch() == mark->bias_epoch()) { @@ -614,12 +615,12 @@ if (TraceBiasedLocking) { tty->print_cr("Revoking bias by walking my own stack:"); } - BiasedLocking::Condition cond = revoke_bias(n_obj(), false, false, (JavaThread*) THREAD); + BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD); ((JavaThread*) THREAD)->set_cached_monitor_info(NULL); assert(cond == BIAS_REVOKED, "why not?"); return cond; } else { - VM_RevokeBias revoke(&n_obj, (JavaThread*) THREAD); + VM_RevokeBias revoke(&obj, (JavaThread*) THREAD); VMThread::execute(&revoke); return revoke.status_code(); } @@ -627,7 +628,7 @@ assert((heuristics == HR_BULK_REVOKE) || (heuristics == HR_BULK_REBIAS), "?"); - VM_BulkRevokeBias bulk_revoke(&n_obj, (JavaThread*) THREAD, + VM_BulkRevokeBias bulk_revoke(&obj, (JavaThread*) THREAD, (heuristics == HR_BULK_REBIAS), attempt_rebias); VMThread::execute(&bulk_revoke); @@ -648,6 +649,7 @@ void BiasedLocking::revoke_at_safepoint(Handle h_obj) { assert(SafepointSynchronize::is_at_safepoint(), "must only be called while at safepoint"); oop obj = h_obj(); + assert(obj == oopDesc::bs()->resolve_oop(obj), "expect to-space copy"); HeuristicsResult heuristics = update_heuristics(obj, false); if (heuristics == HR_SINGLE_REVOKE) { revoke_bias(obj, false, false, NULL); @@ -711,6 +713,7 @@ MonitorInfo* mon_info = monitors->at(i); if (mon_info->owner_is_scalar_replaced()) continue; oop owner = mon_info->owner(); + assert(owner == oopDesc::bs()->resolve_oop(owner), "expect to-space copy"); if (owner != NULL) { markOop mark = owner->mark(); if (mark->has_bias_pattern()) { diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/runtime/deoptimization.cpp --- a/src/share/vm/runtime/deoptimization.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/runtime/deoptimization.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -935,7 +935,7 @@ if (mon_info->eliminated()) { assert(!mon_info->owner_is_scalar_replaced() || realloc_failures, "reallocation was missed"); if (!mon_info->owner_is_scalar_replaced()) { - Handle obj = Handle(mon_info->owner()); + Handle obj = Handle(oopDesc::bs()->resolve_and_maybe_copy_oop(mon_info->owner())); markOop mark = obj->mark(); if (UseBiasedLocking && mark->has_bias_pattern()) { // New allocated objects may have the mark set to anonymously biased. @@ -1058,7 +1058,7 @@ for (int j = 0; j < monitors->number_of_monitors(); j++) { BasicObjectLock* src = monitors->at(j); if (src->obj() != NULL) { - ObjectSynchronizer::fast_exit(src->obj(), src->lock(), thread); + ObjectSynchronizer::fast_exit(oopDesc::bs()->resolve_and_maybe_copy_oop(src->obj()), src->lock(), thread); } } array->element(i)->free_monitors(thread); diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/runtime/handles.hpp --- a/src/share/vm/runtime/handles.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/runtime/handles.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -25,7 +25,6 @@ #ifndef SHARE_VM_RUNTIME_HANDLES_HPP #define SHARE_VM_RUNTIME_HANDLES_HPP -#include "gc/shared/barrierSet.hpp" #include "oops/oop.hpp" #include "oops/oopsHierarchy.hpp" @@ -71,8 +70,8 @@ oop* _handle; protected: - oop obj() const { return _handle == NULL ? (oop)NULL : oopDesc::bs()->resolve_oop(*_handle); } - oop non_null_obj() const { assert(_handle != NULL, "resolving NULL handle"); return oopDesc::bs()->resolve_oop(*_handle);} + oop obj() const { return _handle == NULL ? (oop)NULL : *_handle; } + oop non_null_obj() const { assert(_handle != NULL, "resolving NULL handle"); return *_handle; } public: // Constructors @@ -83,7 +82,7 @@ // General access oop operator () () const { return obj(); } oop operator -> () const { return non_null_obj(); } - bool operator == (oop o) const { return obj() == oopDesc::bs()->resolve_oop(o); } + bool operator == (oop o) const { return obj() == o; } bool operator == (const Handle& h) const { return obj() == h.obj(); } // Null checks diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/runtime/jniHandles.hpp --- a/src/share/vm/runtime/jniHandles.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/runtime/jniHandles.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -66,7 +66,7 @@ // Sentinel marking deleted handles in block. Note that we cannot store NULL as // the sentinel, since clearing weak global JNI refs are done by storing NULL in // the handle. The handle may not be reused before destroy_weak_global is called. - static oop deleted_handle() { return oopDesc::bs()->resolve_oop(_deleted_handle); } + static oop deleted_handle() { return _deleted_handle; } // Initialization static void initialize(); @@ -175,7 +175,6 @@ inline oop JNIHandles::resolve(jobject handle) { oop result = (handle == NULL ? (oop)NULL : *(oop*)handle); - result = oopDesc::bs()->resolve_oop(result); assert(result != NULL || (handle == NULL || !CheckJNICalls || is_weak_global_handle(handle)), "Invalid value read from jni handle"); assert(result != badJNIHandle, "Pointing to zapped jni handle area"); return result; @@ -185,7 +184,6 @@ inline oop JNIHandles::resolve_external_guard(jobject handle) { if (handle == NULL) return NULL; oop result = *(oop*)handle; - result = oopDesc::bs()->resolve_oop(result); if (result == NULL || result == badJNIHandle) return NULL; return result; }; @@ -194,7 +192,6 @@ inline oop JNIHandles::resolve_non_null(jobject handle) { assert(handle != NULL, "JNI handle should not be null"); oop result = *(oop*)handle; - result = oopDesc::bs()->resolve_oop(result); assert(result != NULL, "Invalid value read from jni handle"); assert(result != badJNIHandle, "Pointing to zapped jni handle area"); // Don't let that private _deleted_handle object escape into the wild. diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/runtime/objectMonitor.inline.hpp --- a/src/share/vm/runtime/objectMonitor.inline.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/runtime/objectMonitor.inline.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -66,7 +66,12 @@ inline void* ObjectMonitor::object() const { - return oopDesc::bs()->maybe_resolve_oop(oop(_object)); + /* + if (_object != (cast_to_oop(-1))) { + assert(oop(_object) == oopDesc::bs()->resolve_and_maybe_copy_oop(oop(_object)), "expect to-space copy"); + } + */ + return _object; } inline void* ObjectMonitor::object_addr() { @@ -75,6 +80,9 @@ inline void ObjectMonitor::set_object(void* obj) { _object = obj; + if (_object != (cast_to_oop(-1))) { + assert(oop(_object) == oopDesc::bs()->resolve_and_maybe_copy_oop(oop(_object)), "expect to-space copy"); + } } inline bool ObjectMonitor::check(TRAPS) { diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/runtime/sharedRuntime.cpp --- a/src/share/vm/runtime/sharedRuntime.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/runtime/sharedRuntime.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -1755,10 +1755,6 @@ if (src == NULL || dest == NULL) { THROW(vmSymbols::java_lang_NullPointerException()); } - - src = oopDesc::bs()->resolve_oop(src); - dest = oopDesc::bs()->resolve_and_maybe_copy_oop(dest); - // Do the copy. The casts to arrayOop are necessary to the copy_array API, // even though the copy_array API also performs dynamic checks to ensure // that src and dest are truly arrays (and are conformable). @@ -1804,6 +1800,7 @@ // Handles the uncommon case in locking, i.e., contention or an inflated lock. JRT_BLOCK_ENTRY(void, SharedRuntime::complete_monitor_locking_C(oopDesc* _obj, BasicLock* lock, JavaThread* thread)) + _obj = oopDesc::bs()->resolve_and_maybe_copy_oop(_obj); // Disable ObjectSynchronizer::quick_enter() in default config // until JDK-8077392 is resolved. if ((SyncFlags & 256) != 0 && !SafepointSynchronize::is_synchronizing()) { @@ -1833,8 +1830,8 @@ // Handles the uncommon cases of monitor unlocking in compiled code JRT_LEAF(void, SharedRuntime::complete_monitor_unlocking_C(oopDesc* _obj, BasicLock* lock, JavaThread * THREAD)) + _obj = oopDesc::bs()->resolve_and_maybe_copy_oop(_obj); oop obj(_obj); - obj = oopDesc::bs()->resolve_oop(obj); assert(JavaThread::current() == THREAD, "invariant"); // I'm not convinced we need the code contained by MIGHT_HAVE_PENDING anymore // testing was unable to ever fire the assert that guarded it so I have removed it. diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/runtime/synchronizer.cpp --- a/src/share/vm/runtime/synchronizer.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/runtime/synchronizer.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -160,6 +160,7 @@ assert(!SafepointSynchronize::is_at_safepoint(), "invariant"); assert(self->is_Java_thread(), "invariant"); assert(((JavaThread *) self)->thread_state() == _thread_in_Java, "invariant"); + assert(obj == oopDesc::bs()->resolve_and_maybe_copy_oop(obj), "expect to-space copy"); No_Safepoint_Verifier nsv; if (obj == NULL) return false; // slow-path for invalid obj const markOop mark = obj->mark(); @@ -210,6 +211,7 @@ assert(!SafepointSynchronize::is_at_safepoint(), "invariant"); assert(Self->is_Java_thread(), "invariant"); assert(((JavaThread *) Self)->thread_state() == _thread_in_Java, "invariant"); + assert(obj == oopDesc::bs()->resolve_and_maybe_copy_oop(obj), "expect to-space copy"); No_Safepoint_Verifier nsv; if (obj == NULL) return false; // Need to throw NPE const markOop mark = obj->mark(); @@ -256,6 +258,7 @@ void ObjectSynchronizer::fast_enter(Handle obj, BasicLock* lock, bool attempt_rebias, TRAPS) { + assert(obj() == oopDesc::bs()->resolve_and_maybe_copy_oop(obj()), "expect to-space copy"); if (UseBiasedLocking) { if (!SafepointSynchronize::is_at_safepoint()) { BiasedLocking::Condition cond = BiasedLocking::revoke_and_rebias(obj, attempt_rebias, THREAD); @@ -275,7 +278,7 @@ void ObjectSynchronizer::fast_exit(oop object, BasicLock* lock, TRAPS) { assert(!object->mark()->has_bias_pattern(), "should not see bias pattern here"); // if displaced header is null, the previous enter is recursive enter, no-op - object = oopDesc::bs()->resolve_and_maybe_copy_oop(object); + assert(object == oopDesc::bs()->resolve_and_maybe_copy_oop(object), "expect to-space copy"); markOop dhw = lock->displaced_header(); markOop mark; @@ -316,16 +319,15 @@ // We don't need to use fast path here, because it must have been // failed in the interpreter/compiler code. void ObjectSynchronizer::slow_enter(Handle obj, BasicLock* lock, TRAPS) { - Handle n_obj(THREAD, - oopDesc::bs()->resolve_and_maybe_copy_oop(obj())); - markOop mark = n_obj->mark(); + assert(obj() == oopDesc::bs()->resolve_and_maybe_copy_oop(obj()), "expect to-space copy"); + markOop mark = obj->mark(); assert(!mark->has_bias_pattern(), "should not see bias pattern here"); if (mark->is_neutral()) { // Anticipate successful CAS -- the ST of the displaced mark must // be visible <= the ST performed by the CAS. lock->set_displaced_header(mark); - if (mark == (markOop) Atomic::cmpxchg_ptr(lock, n_obj()->mark_addr(), mark)) { + if (mark == (markOop) Atomic::cmpxchg_ptr(lock, obj()->mark_addr(), mark)) { TEVENT(slow_enter: release stacklock); return; } @@ -333,7 +335,7 @@ } else if (mark->has_locker() && THREAD->is_lock_owned((address)mark->locker())) { assert(lock != mark->locker(), "must not re-lock the same lock"); - assert(lock != (BasicLock*)n_obj->mark(), "don't relock with same BasicLock"); + assert(lock != (BasicLock*)obj->mark(), "don't relock with same BasicLock"); lock->set_displaced_header(NULL); return; } @@ -343,7 +345,7 @@ // must be non-zero to avoid looking like a re-entrant lock, // and must not look locked either. lock->set_displaced_header(markOopDesc::unused_mark()); - ObjectSynchronizer::inflate(THREAD, n_obj())->enter(THREAD); + ObjectSynchronizer::inflate(THREAD, obj())->enter(THREAD); } // This routine is used to handle interpreter/compiler slow case @@ -368,6 +370,7 @@ // NOTE: must use heavy weight monitor to handle complete_exit/reenter() intptr_t ObjectSynchronizer::complete_exit(Handle obj, TRAPS) { TEVENT(complete_exit); + assert(obj() == oopDesc::bs()->resolve_and_maybe_copy_oop(obj()), "expect to-space copy"); if (UseBiasedLocking) { BiasedLocking::revoke_and_rebias(obj, false, THREAD); assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); @@ -381,6 +384,7 @@ // NOTE: must use heavy weight monitor to handle complete_exit/reenter() void ObjectSynchronizer::reenter(Handle obj, intptr_t recursion, TRAPS) { TEVENT(reenter); + assert(obj() == oopDesc::bs()->resolve_and_maybe_copy_oop(obj()), "expect to-space copy"); if (UseBiasedLocking) { BiasedLocking::revoke_and_rebias(obj, false, THREAD); assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); @@ -396,6 +400,7 @@ void ObjectSynchronizer::jni_enter(Handle obj, TRAPS) { // the current locking is from JNI instead of Java code TEVENT(jni_enter); + assert(obj() == oopDesc::bs()->resolve_and_maybe_copy_oop(obj()), "expect to-space copy"); if (UseBiasedLocking) { BiasedLocking::revoke_and_rebias(obj, false, THREAD); assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); @@ -408,6 +413,7 @@ // NOTE: must use heavy weight monitor to handle jni monitor exit void ObjectSynchronizer::jni_exit(oop obj, Thread* THREAD) { TEVENT(jni_exit); + assert(obj == oopDesc::bs()->resolve_and_maybe_copy_oop(obj), "expect to-space copy"); if (UseBiasedLocking) { Handle h_obj(THREAD, obj); BiasedLocking::revoke_and_rebias(h_obj, false, THREAD); @@ -450,6 +456,7 @@ // Wait/Notify/NotifyAll // NOTE: must use heavy weight monitor to handle wait() int ObjectSynchronizer::wait(Handle obj, jlong millis, TRAPS) { + assert(obj() == oopDesc::bs()->resolve_and_maybe_copy_oop(obj()), "expect to-space copy"); if (UseBiasedLocking) { BiasedLocking::revoke_and_rebias(obj, false, THREAD); assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); @@ -470,6 +477,7 @@ } void ObjectSynchronizer::waitUninterruptibly(Handle obj, jlong millis, TRAPS) { + assert(obj() == oopDesc::bs()->resolve_and_maybe_copy_oop(obj()), "expect to-space copy"); if (UseBiasedLocking) { BiasedLocking::revoke_and_rebias(obj, false, THREAD); assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); @@ -482,6 +490,7 @@ } void ObjectSynchronizer::notify(Handle obj, TRAPS) { + assert(obj() == oopDesc::bs()->resolve_and_maybe_copy_oop(obj()), "expect to-space copy"); if (UseBiasedLocking) { BiasedLocking::revoke_and_rebias(obj, false, THREAD); assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); @@ -496,6 +505,7 @@ // NOTE: see comment of notify() void ObjectSynchronizer::notifyall(Handle obj, TRAPS) { + assert(obj() == oopDesc::bs()->resolve_and_maybe_copy_oop(obj()), "expect to-space copy"); if (UseBiasedLocking) { BiasedLocking::revoke_and_rebias(obj, false, THREAD); assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); @@ -673,7 +683,7 @@ } intptr_t ObjectSynchronizer::FastHashCode(Thread * Self, oop obj) { - obj = oopDesc::bs()->resolve_and_maybe_copy_oop(obj); + assert(obj == oopDesc::bs()->resolve_and_maybe_copy_oop(obj), "expect to-space copy"); if (UseBiasedLocking) { // NOTE: many places throughout the JVM do not expect a safepoint // to be taken here, in particular most operations on perm gen @@ -691,7 +701,6 @@ "biases should not be seen by VM thread here"); BiasedLocking::revoke_and_rebias(hobj, false, JavaThread::current()); obj = hobj(); - obj = oopDesc::bs()->resolve_and_maybe_copy_oop(obj); assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); } } @@ -788,6 +797,7 @@ bool ObjectSynchronizer::current_thread_holds_lock(JavaThread* thread, Handle h_obj) { + assert(h_obj() == oopDesc::bs()->resolve_and_maybe_copy_oop(h_obj()), "expect to-space copy"); if (UseBiasedLocking) { BiasedLocking::revoke_and_rebias(h_obj, false, thread); assert(!h_obj->mark()->has_bias_pattern(), "biases should be revoked by now"); @@ -860,6 +870,7 @@ // FIXME: jvmti should call this JavaThread* ObjectSynchronizer::get_lock_owner(Handle h_obj, bool doLock) { + assert(h_obj() == oopDesc::bs()->resolve_and_maybe_copy_oop(h_obj()), "expect to-space copy"); if (UseBiasedLocking) { if (SafepointSynchronize::is_at_safepoint()) { BiasedLocking::revoke_at_safepoint(h_obj); @@ -908,7 +919,6 @@ for (int i = _BLOCKSIZE - 1; i > 0; i--) { mid = (ObjectMonitor *)(block + i); oop object = (oop) mid->object(); - object = oopDesc::bs()->resolve_oop(object); if (object != NULL) { closure->do_monitor(mid); } @@ -1282,6 +1292,7 @@ // Fast path code shared by multiple functions ObjectMonitor* ObjectSynchronizer::inflate_helper(oop obj) { + assert(obj == oopDesc::bs()->resolve_and_maybe_copy_oop(obj), "expect to-space copy"); markOop mark = obj->mark(); if (mark->has_monitor()) { assert(ObjectSynchronizer::verify_objmon_isinpool(mark->monitor()), "monitor is invalid"); @@ -1296,7 +1307,7 @@ oop object) { // Inflate mutates the heap ... // Relaxing assertion for bug 6320749. - object = oopDesc::bs()->resolve_and_maybe_copy_oop(object); + assert(object == oopDesc::bs()->resolve_and_maybe_copy_oop(object), "expect to-space copy"); assert(Universe::verify_in_progress() || !SafepointSynchronize::is_at_safepoint(), "invariant"); @@ -1315,7 +1326,7 @@ if (mark->has_monitor()) { ObjectMonitor * inf = mark->monitor(); assert(inf->header()->is_neutral(), "invariant"); - assert(oopDesc::bs()->resolve_oop((oop) inf->object()) == object, "invariant"); + assert((oop) inf->object() == object, "invariant"); assert(ObjectSynchronizer::verify_objmon_isinpool(inf), "monitor is invalid"); return inf; } @@ -1521,6 +1532,7 @@ ObjectMonitor** freeTailp) { bool deflated; // Normal case ... The monitor is associated with obj. + assert(obj == oopDesc::bs()->resolve_and_maybe_copy_oop(obj), "expect to-space copy"); guarantee(obj->mark() == markOopDesc::encode(mid), "invariant"); guarantee(mid == obj->mark()->monitor(), "invariant"); guarantee(mid->header()->is_neutral(), "invariant"); @@ -1640,7 +1652,6 @@ for (int i = 1; i < _BLOCKSIZE; i++) { ObjectMonitor* mid = (ObjectMonitor*)&block[i]; oop obj = (oop) mid->object(); - obj = oopDesc::bs()->resolve_oop(obj); if (obj == NULL) { // The monitor is not associated with an object. @@ -1807,7 +1818,6 @@ for (int i = 1; i < _BLOCKSIZE; i++) { mid = (ObjectMonitor *)(block + i); oop object = (oop) mid->object(); - object = oopDesc::bs()->resolve_oop(object); if (object != NULL) { mid->verify(); diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/runtime/thread.cpp --- a/src/share/vm/runtime/thread.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/runtime/thread.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -1677,7 +1677,7 @@ static void ensure_join(JavaThread* thread) { // We do not need to grap the Threads_lock, since we are operating on ourself. - Handle threadObj(thread, thread->threadObj()); + Handle threadObj(thread, oopDesc::bs()->resolve_and_maybe_copy_oop(thread->threadObj())); assert(threadObj.not_null(), "java thread object must exist"); ObjectLocker lock(threadObj, thread); // Ignore pending exception (ThreadDeath), since we are exiting anyway diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/runtime/thread.hpp --- a/src/share/vm/runtime/thread.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/runtime/thread.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -1035,7 +1035,7 @@ // Thread oop. threadObj() can be NULL for initial JavaThread // (or for threads attached via JNI) - oop threadObj() const { return oopDesc::bs()->resolve_oop(_threadObj); } + oop threadObj() const { return _threadObj; } void set_threadObj(oop p) { _threadObj = p; } ThreadPriority java_priority() const; // Read from threadObj() @@ -1277,7 +1277,7 @@ void set_callee_target (Method* x) { _callee_target = x; } // Oop results of vm runtime calls - oop vm_result() const { return oopDesc::bs()->resolve_oop(_vm_result); } + oop vm_result() const { return _vm_result; } void set_vm_result (oop x) { _vm_result = x; } Metadata* vm_result_2() const { return _vm_result_2; } @@ -1287,7 +1287,7 @@ void set_deferred_card_mark(MemRegion mr) { _deferred_card_mark = mr; } // Exception handling for compiled methods - oop exception_oop() const { return oopDesc::bs()->resolve_oop(_exception_oop); } + oop exception_oop() const { return _exception_oop; } address exception_pc() const { return _exception_pc; } address exception_handler_pc() const { return _exception_handler_pc; } bool is_method_handle_return() const { return _is_method_handle_return == 1; } diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/runtime/vframe.hpp --- a/src/share/vm/runtime/vframe.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/runtime/vframe.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -250,6 +250,7 @@ public: // Constructor MonitorInfo(oop owner, BasicLock* lock, bool eliminated, bool owner_is_scalar_replaced) { + assert(owner == oopDesc::bs()->resolve_and_maybe_copy_oop(owner), "expect to-space copy"); if (!owner_is_scalar_replaced) { _owner = owner; _owner_klass = NULL; @@ -265,11 +266,12 @@ // Accessors oop owner() const { assert(!_owner_is_scalar_replaced, "should not be called for scalar replaced object"); - return oopDesc::bs()->resolve_oop(_owner); + assert(_owner == oopDesc::bs()->resolve_and_maybe_copy_oop(_owner), "expect to-space copy"); + return _owner; } oop owner_klass() const { assert(_owner_is_scalar_replaced, "should not be called for not scalar replaced object"); - return oopDesc::bs()->resolve_oop(_owner_klass); + return _owner_klass; } BasicLock* lock() const { return _lock; } bool eliminated() const { return _eliminated; } diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/services/lowMemoryDetector.cpp --- a/src/share/vm/services/lowMemoryDetector.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/services/lowMemoryDetector.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -297,7 +297,7 @@ if (_sensor_obj != NULL) { Klass* k = Management::sun_management_Sensor_klass(CHECK); instanceKlassHandle sensorKlass (THREAD, k); - Handle sensor_h(THREAD, oopDesc::bs()->resolve_oop(_sensor_obj)); + Handle sensor_h(THREAD, _sensor_obj); Handle usage_h = MemoryService::create_MemoryUsage_obj(_usage, CHECK); JavaValue result(T_VOID); @@ -326,7 +326,7 @@ if (_sensor_obj != NULL) { Klass* k = Management::sun_management_Sensor_klass(CHECK); instanceKlassHandle sensorKlass (THREAD, k); - Handle sensor(THREAD, oopDesc::bs()->resolve_oop(_sensor_obj)); + Handle sensor(THREAD, _sensor_obj); JavaValue result(T_VOID); JavaCallArguments args(sensor); diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/services/memoryManager.hpp --- a/src/share/vm/services/memoryManager.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/services/memoryManager.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -63,7 +63,7 @@ void add_pool(MemoryPool* pool); - bool is_manager(instanceHandle mh) { return mh() == oopDesc::bs()->resolve_oop(_memory_mgr_obj); } + bool is_manager(instanceHandle mh) { return oopDesc::bs()->resolve_and_maybe_copy_oop(mh()) == oopDesc::bs()->resolve_and_maybe_copy_oop(_memory_mgr_obj); } virtual instanceOop get_memory_manager_instance(TRAPS); virtual bool is_gc_memory_manager() { return false; } diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/services/memoryPool.cpp --- a/src/share/vm/services/memoryPool.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/services/memoryPool.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -140,7 +140,7 @@ } } - return (instanceOop) oopDesc::bs()->resolve_oop((oop) pool_obj); + return pool_obj; } inline static size_t get_max_value(size_t val1, size_t val2) { diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/services/threadService.cpp --- a/src/share/vm/services/threadService.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/services/threadService.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -166,6 +166,7 @@ // If obj == NULL, then ObjectMonitor is raw which doesn't count. } + obj = oopDesc::bs()->resolve_and_maybe_copy_oop(obj); Handle h(obj); return h; } @@ -507,7 +508,6 @@ int len = (_locked_monitors != NULL ? _locked_monitors->length() : 0); for (int i = 0; i < len; i++) { oop o = _locked_monitors->at(i); - o = oopDesc::bs()->resolve_oop(o); InstanceKlass* ik = InstanceKlass::cast(o->klass()); st->print_cr("\t- locked <" INTPTR_FORMAT "> (a %s)", (address)o, ik->external_name()); } @@ -590,6 +590,8 @@ bool ThreadStackTrace::is_owned_monitor_on_stack(oop object) { assert(SafepointSynchronize::is_at_safepoint(), "all threads are stopped"); + object = oopDesc::bs()->resolve_and_maybe_copy_oop(object); + bool found = false; int num_frames = get_stack_depth(); for (int depth = 0; depth < num_frames; depth++) { @@ -598,6 +600,7 @@ GrowableArray* locked_monitors = frame->locked_monitors(); for (int j = 0; j < len; j++) { oop monitor = locked_monitors->at(j); + monitor = oopDesc::bs()->resolve_and_maybe_copy_oop(monitor); assert(monitor != NULL, "must be a Java object"); if (monitor == object) { found = true; diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/services/threadService.hpp --- a/src/share/vm/services/threadService.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/services/threadService.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -218,7 +218,7 @@ java_lang_Thread::ThreadStatus thread_status() { return _thread_status; } - oop threadObj() const { return oopDesc::bs()->resolve_oop(_threadObj); } + oop threadObj() const { return _threadObj; } void set_next(ThreadSnapshot* n) { _next = n; } @@ -233,8 +233,8 @@ jlong sleep_ticks() { return _sleep_ticks; } - oop blocker_object() { return oopDesc::bs()->resolve_oop(_blocker_object); } - oop blocker_object_owner() { return oopDesc::bs()->resolve_oop(_blocker_object_owner); } + oop blocker_object() { return _blocker_object; } + oop blocker_object_owner() { return _blocker_object_owner; } ThreadSnapshot* next() const { return _next; } ThreadStackTrace* get_stack_trace() { return _stack_trace; } diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/utilities/exceptions.cpp --- a/src/share/vm/utilities/exceptions.cpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/utilities/exceptions.cpp Sat Oct 03 13:51:17 2015 +0200 @@ -52,10 +52,6 @@ _exception_line = line; } -oop ThreadShadow::pending_exception() const { - return Universe::heap()->barrier_set()->resolve_oop(_pending_exception); -} - void ThreadShadow::clear_pending_exception() { if (TraceClearedExceptions) { if (_pending_exception != NULL) { diff -r 0d5b3847ab03 -r 081cf5f88897 src/share/vm/utilities/exceptions.hpp --- a/src/share/vm/utilities/exceptions.hpp Thu Oct 01 18:39:20 2015 +0200 +++ b/src/share/vm/utilities/exceptions.hpp Sat Oct 03 13:51:17 2015 +0200 @@ -75,7 +75,7 @@ virtual void unused_initial_virtual() { } public: - oop pending_exception() const; + oop pending_exception() const { return _pending_exception; } bool has_pending_exception() const { return _pending_exception != NULL; } const char* exception_file() const { return _exception_file; } int exception_line() const { return _exception_line; }