# HG changeset patch # User rkennke # Date 1538397806 -7200 # Mon Oct 01 14:43:26 2018 +0200 # Node ID edf172bcab3adefab8827cbcd0f1ec44e0eb872c # Parent 5ba442f148181897248b2da73fc954cfa9339527 8211279: Verify missing object equals barriers diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -2340,7 +2340,7 @@ for (int i = 0; i < oops_count(); i++) { oop o = oop_at(i); tty->print("#%3d: " INTPTR_FORMAT " ", i, p2i(o)); - if (o == (oop)Universe::non_oop_word()) { + if (o == Universe::non_oop_word()) { tty->print("non-oop word"); } else { if (o != NULL) { diff --git a/src/hotspot/share/code/relocInfo.cpp b/src/hotspot/share/code/relocInfo.cpp --- a/src/hotspot/share/code/relocInfo.cpp +++ b/src/hotspot/share/code/relocInfo.cpp @@ -574,7 +574,7 @@ oop oop_Relocation::oop_value() { oop v = *oop_addr(); // clean inline caches store a special pseudo-null - if (v == (oop)Universe::non_oop_word()) v = NULL; + if (v == Universe::non_oop_word()) v = NULL; return v; } diff --git a/src/hotspot/share/compiler/oopMap.cpp b/src/hotspot/share/compiler/oopMap.cpp --- a/src/hotspot/share/compiler/oopMap.cpp +++ b/src/hotspot/share/compiler/oopMap.cpp @@ -350,7 +350,7 @@ // implicit null check is used in compiled code. // The narrow_oop_base could be NULL or be the address // of the page below heap depending on compressed oops mode. - if (base_loc != NULL && *base_loc != (oop)NULL && !Universe::is_narrow_oop_base(*base_loc)) { + if (base_loc != NULL && *base_loc != NULL && !Universe::is_narrow_oop_base(*base_loc)) { derived_oop_fn(base_loc, derived_loc); } oms.next(); @@ -371,7 +371,7 @@ guarantee(loc != NULL, "missing saved register"); if ( omv.type() == OopMapValue::oop_value ) { oop val = *loc; - if (val == (oop)NULL || Universe::is_narrow_oop_base(val)) { + if (val == NULL || Universe::is_narrow_oop_base(val)) { // Ignore NULL oops and decoded NULL narrow oops which // equal to Universe::narrow_oop_base when a narrow oop // implicit null check is used in compiled code. @@ -769,7 +769,7 @@ assert(Universe::heap()->is_in_or_null(*base_loc), "not an oop"); assert(derived_loc != base_loc, "Base and derived in same location"); if (_active) { - assert(*derived_loc != (oop)base_loc, "location already added"); + assert(*derived_loc != (void*)base_loc, "location already added"); assert(_list != NULL, "list must exist"); intptr_t offset = value_of_loc(derived_loc) - value_of_loc(base_loc); // This assert is invalid because derived pointers can be diff --git a/src/hotspot/share/gc/shared/barrierSet.hpp b/src/hotspot/share/gc/shared/barrierSet.hpp --- a/src/hotspot/share/gc/shared/barrierSet.hpp +++ b/src/hotspot/share/gc/shared/barrierSet.hpp @@ -130,6 +130,10 @@ virtual void on_thread_detach(JavaThread* thread) {} virtual void make_parsable(JavaThread* thread) {} +#ifdef CHECK_UNHANDLED_OOPS + virtual void verify_equals(oop o1, oop o2) { } +#endif + public: // Print a description of the memory for the barrier set virtual void print_on(outputStream* st) const = 0; diff --git a/src/hotspot/share/gc/shared/referenceProcessor.cpp b/src/hotspot/share/gc/shared/referenceProcessor.cpp --- a/src/hotspot/share/gc/shared/referenceProcessor.cpp +++ b/src/hotspot/share/gc/shared/referenceProcessor.cpp @@ -284,7 +284,7 @@ // First _prev_next ref actually points into DiscoveredList (gross). oop new_next; - if (_next_discovered == _current_discovered) { + if (oopDesc::unsafe_equals(_next_discovered, _current_discovered)) { // At the end of the list, we should make _prev point to itself. // If _ref is the first ref, then _prev_next will be in the DiscoveredList, // and _prev will be NULL. @@ -474,7 +474,7 @@ ReferenceProcessor::clear_discovered_references(DiscoveredList& refs_list) { oop obj = NULL; oop next = refs_list.head(); - while (next != obj) { + while (! oopDesc::unsafe_equals(next, obj)) { obj = next; next = java_lang_ref_Reference::discovered(obj); java_lang_ref_Reference::set_discovered_raw(obj, NULL); @@ -746,7 +746,7 @@ ref_lists[to_idx].inc_length(refs_to_move); // Remove the chain from the from list. - if (move_tail == new_head) { + if (oopDesc::unsafe_equals(move_tail, new_head)) { // We found the end of the from list. ref_lists[from_idx].set_head(NULL); } else { diff --git a/src/hotspot/share/gc/shared/referenceProcessor.hpp b/src/hotspot/share/gc/shared/referenceProcessor.hpp --- a/src/hotspot/share/gc/shared/referenceProcessor.hpp +++ b/src/hotspot/share/gc/shared/referenceProcessor.hpp @@ -143,13 +143,13 @@ inline size_t removed() const { return _removed; } inline void move_to_next() { - if (_current_discovered == _next_discovered) { + if (oopDesc::unsafe_equals(_current_discovered, _next_discovered)) { // End of the list. _current_discovered = NULL; } else { _current_discovered = _next_discovered; } - assert(_current_discovered != _first_seen, "cyclic ref_list found"); + assert(! oopDesc::unsafe_equals(_current_discovered, _first_seen), "cyclic ref_list found"); _processed++; } }; diff --git a/src/hotspot/share/gc/shared/stringdedup/stringDedupTable.cpp b/src/hotspot/share/gc/shared/stringdedup/stringDedupTable.cpp --- a/src/hotspot/share/gc/shared/stringdedup/stringDedupTable.cpp +++ b/src/hotspot/share/gc/shared/stringdedup/stringDedupTable.cpp @@ -375,7 +375,7 @@ } typeArrayOop existing_value = lookup_or_add(value, latin1, hash); - if (existing_value == value) { + if (oopDesc::unsafe_equals(existing_value, value)) { // Same value, already known stat->inc_known(); return; diff --git a/src/hotspot/share/oops/accessBackend.hpp b/src/hotspot/share/oops/accessBackend.hpp --- a/src/hotspot/share/oops/accessBackend.hpp +++ b/src/hotspot/share/oops/accessBackend.hpp @@ -410,7 +410,7 @@ static oop resolve(oop obj) { return obj; } - static bool equals(oop o1, oop o2) { return o1 == o2; } + static bool equals(oop o1, oop o2) { return (void*) o1 == (void*) o2; } }; // Below is the implementation of the first 4 steps of the template pipeline: diff --git a/src/hotspot/share/oops/oop.hpp b/src/hotspot/share/oops/oop.hpp --- a/src/hotspot/share/oops/oop.hpp +++ b/src/hotspot/share/oops/oop.hpp @@ -154,6 +154,10 @@ inline static bool equals(oop o1, oop o2) { return Access<>::equals(o1, o2); } + inline static bool unsafe_equals(oop o1, oop o2) { + return (void*) o1 == (void*) o2; + } + // Access to fields in a instanceOop through these methods. template oop obj_field_access(int offset) const; diff --git a/src/hotspot/share/oops/oopsHierarchy.cpp b/src/hotspot/share/oops/oopsHierarchy.cpp --- a/src/hotspot/share/oops/oopsHierarchy.cpp +++ b/src/hotspot/share/oops/oopsHierarchy.cpp @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "gc/shared/barrierSet.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/collectedHeap.inline.hpp" #include "oops/oopsHierarchy.hpp" @@ -53,4 +54,15 @@ t->unhandled_oops()->unregister_unhandled_oop(this); } } + +bool oop::operator==(const oop o) const { + BarrierSet::barrier_set()->verify_equals(this, o); + return obj() == o.obj(); +} + +bool oop::operator!=(const volatile oop o) const { + BarrierSet::barrier_set()->verify_equals(this, o); + return obj() != o.obj(); +} + #endif // CHECK_UNHANDLED_OOPS diff --git a/src/hotspot/share/oops/oopsHierarchy.hpp b/src/hotspot/share/oops/oopsHierarchy.hpp --- a/src/hotspot/share/oops/oopsHierarchy.hpp +++ b/src/hotspot/share/oops/oopsHierarchy.hpp @@ -101,9 +101,9 @@ // General access oopDesc* operator->() const { return obj(); } - bool operator==(const oop o) const { return obj() == o.obj(); } + bool operator==(const oop o) const; bool operator==(void *p) const { return obj() == p; } - bool operator!=(const volatile oop o) const { return obj() != o.obj(); } + bool operator!=(const volatile oop o) const; bool operator!=(void *p) const { return obj() != p; } // Assignment