--- old/src/hotspot/share/prims/jvmtiTagMap.cpp 2017-11-27 11:04:14.141674002 +0100 +++ new/src/hotspot/share/prims/jvmtiTagMap.cpp 2017-11-27 11:04:13.877674011 +0100 @@ -30,6 +30,7 @@ #include "code/codeCache.hpp" #include "jvmtifiles/jvmtiEnv.hpp" #include "memory/resourceArea.hpp" +#include "oops/access.inline.hpp" #include "oops/instanceMirrorKlass.hpp" #include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.inline.hpp" @@ -52,10 +53,6 @@ #include "runtime/vm_operations.hpp" #include "services/serviceUtil.hpp" #include "utilities/macros.hpp" -#if INCLUDE_ALL_GCS -#include "gc/g1/g1SATBCardTableModRefBS.hpp" -#include "gc/parallel/parallelScavengeHeap.hpp" -#endif // INCLUDE_ALL_GCS // JvmtiTagHashmapEntry // @@ -78,22 +75,31 @@ } // constructor - JvmtiTagHashmapEntry(oop object, jlong tag) { init(object, tag); } + JvmtiTagHashmapEntry(oop object, jlong tag) { init(object, tag); } public: // accessor methods - inline oop object() const { return _object; } - inline oop* object_addr() { return &_object; } - inline jlong tag() const { return _tag; } + inline oop* object_addr() { return &_object; } + inline oop object() { return RootAccess::oop_load(object_addr()); } + // Peek at the object without keeping it alive. The returned object must be + // kept alive using a normal access if it leaks out of a thread transition from VM. + inline oop object_peek() { + return RootAccess::oop_load(object_addr()); + } + inline jlong tag() const { return _tag; } inline void set_tag(jlong tag) { assert(tag != 0, "can't be zero"); _tag = tag; } - inline JvmtiTagHashmapEntry* next() const { return _next; } - inline void set_next(JvmtiTagHashmapEntry* next) { _next = next; } + inline bool equals(oop object) { + return object == object_peek(); + } + + inline JvmtiTagHashmapEntry* next() const { return _next; } + inline void set_next(JvmtiTagHashmapEntry* next) { _next = next; } }; @@ -211,7 +217,7 @@ JvmtiTagHashmapEntry* entry = _table[i]; while (entry != NULL) { JvmtiTagHashmapEntry* next = entry->next(); - oop key = entry->object(); + oop key = entry->object_peek(); assert(key != NULL, "jni weak reference cleared!!"); unsigned int h = hash(key, new_size); JvmtiTagHashmapEntry* anchor = new_table[h]; @@ -304,7 +310,7 @@ unsigned int h = hash(key); JvmtiTagHashmapEntry* entry = _table[h]; while (entry != NULL) { - if (entry->object() == key) { + if (entry->equals(key)) { return entry; } entry = entry->next(); @@ -345,7 +351,7 @@ JvmtiTagHashmapEntry* entry = _table[h]; JvmtiTagHashmapEntry* prev = NULL; while (entry != NULL) { - if (key == entry->object()) { + if (entry->equals(key)) { break; } prev = entry; @@ -1535,16 +1541,12 @@ void do_entry(JvmtiTagHashmapEntry* entry) { for (int i=0; i<_tag_count; i++) { if (_tags[i] == entry->tag()) { + // The reference in this tag map could be the only (implicitly weak) + // reference to that object. If we hand it out, we need to keep it live wrt + // SATB marking similar to other j.l.ref.Reference referents. This is + // achieved by using a phantom load in the object() accessor. oop o = entry->object(); assert(o != NULL && Universe::heap()->is_in_reserved(o), "sanity check"); -#if INCLUDE_ALL_GCS - if (UseG1GC) { - // The reference in this tag map could be the only (implicitly weak) - // reference to that object. If we hand it out, we need to keep it live wrt - // SATB marking similar to other j.l.ref.Reference referents. - G1SATBCardTableModRefBS::enqueue(o); - } -#endif jobject ref = JNIHandles::make_local(JavaThread::current(), o); _object_results->append(ref); _tag_results->append((uint64_t)entry->tag()); @@ -3363,10 +3365,8 @@ while (entry != NULL) { JvmtiTagHashmapEntry* next = entry->next(); - oop* obj = entry->object_addr(); - // has object been GC'ed - if (!is_alive->do_object_b(entry->object())) { + if (!is_alive->do_object_b(entry->object_peek())) { // grab the tag jlong tag = entry->tag(); guarantee(tag != 0, "checking"); @@ -3384,7 +3384,7 @@ ++freed; } else { f->do_oop(entry->object_addr()); - oop new_oop = entry->object(); + oop new_oop = entry->object_peek(); // if the object has moved then re-hash it and move its // entry to its new location. @@ -3418,7 +3418,7 @@ // Re-add all the entries which were kept aside while (delayed_add != NULL) { JvmtiTagHashmapEntry* next = delayed_add->next(); - unsigned int pos = JvmtiTagHashmap::hash(delayed_add->object(), size); + unsigned int pos = JvmtiTagHashmap::hash(delayed_add->object_peek(), size); delayed_add->set_next(table[pos]); table[pos] = delayed_add; delayed_add = next;