changeset 52070:e4d72440d60e

8211279: Verify missing object equals barriers Reviewed-by: pliden, shade, zgu
author rkennke
date Wed, 03 Oct 2018 15:22:16 +0200
parents 3ecaae33241a
children c4a39588a075
files src/hotspot/share/code/nmethod.cpp src/hotspot/share/code/relocInfo.cpp src/hotspot/share/compiler/oopMap.cpp src/hotspot/share/gc/shared/barrierSet.hpp src/hotspot/share/gc/shared/referenceProcessor.cpp src/hotspot/share/gc/shared/referenceProcessor.hpp src/hotspot/share/gc/shared/stringdedup/stringDedupTable.cpp src/hotspot/share/oops/access.hpp src/hotspot/share/oops/accessBackend.hpp src/hotspot/share/oops/oop.hpp src/hotspot/share/oops/oopsHierarchy.cpp src/hotspot/share/oops/oopsHierarchy.hpp
diffstat 12 files changed, 33 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/code/nmethod.cpp	Wed Oct 10 08:36:31 2018 +0200
+++ b/src/hotspot/share/code/nmethod.cpp	Wed Oct 03 15:22:16 2018 +0200
@@ -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) {
--- a/src/hotspot/share/code/relocInfo.cpp	Wed Oct 10 08:36:31 2018 +0200
+++ b/src/hotspot/share/code/relocInfo.cpp	Wed Oct 03 15:22:16 2018 +0200
@@ -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;
 }
 
--- a/src/hotspot/share/compiler/oopMap.cpp	Wed Oct 10 08:36:31 2018 +0200
+++ b/src/hotspot/share/compiler/oopMap.cpp	Wed Oct 03 15:22:16 2018 +0200
@@ -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
--- a/src/hotspot/share/gc/shared/barrierSet.hpp	Wed Oct 10 08:36:31 2018 +0200
+++ b/src/hotspot/share/gc/shared/barrierSet.hpp	Wed Oct 03 15:22:16 2018 +0200
@@ -130,6 +130,10 @@
   virtual void on_thread_detach(JavaThread* thread) {}
   virtual void make_parsable(JavaThread* thread) {}
 
+#ifdef CHECK_UNHANDLED_OOPS
+  virtual bool oop_equals_operator_allowed() { return true; }
+#endif
+
 public:
   // Print a description of the memory for the barrier set
   virtual void print_on(outputStream* st) const = 0;
--- a/src/hotspot/share/gc/shared/referenceProcessor.cpp	Wed Oct 10 08:36:31 2018 +0200
+++ b/src/hotspot/share/gc/shared/referenceProcessor.cpp	Wed Oct 03 15:22:16 2018 +0200
@@ -284,7 +284,7 @@
 
   // First _prev_next ref actually points into DiscoveredList (gross).
   oop new_next;
-  if (_next_discovered == _current_discovered) {
+  if (oopDesc::equals_raw(_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::equals_raw(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::equals_raw(move_tail, new_head)) {
           // We found the end of the from list.
           ref_lists[from_idx].set_head(NULL);
         } else {
--- a/src/hotspot/share/gc/shared/referenceProcessor.hpp	Wed Oct 10 08:36:31 2018 +0200
+++ b/src/hotspot/share/gc/shared/referenceProcessor.hpp	Wed Oct 03 15:22:16 2018 +0200
@@ -143,13 +143,13 @@
   inline size_t removed() const { return _removed; }
 
   inline void move_to_next() {
-    if (_current_discovered == _next_discovered) {
+    if (oopDesc::equals_raw(_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::equals_raw(_current_discovered, _first_seen), "cyclic ref_list found");
     _processed++;
   }
 };
--- a/src/hotspot/share/gc/shared/stringdedup/stringDedupTable.cpp	Wed Oct 10 08:36:31 2018 +0200
+++ b/src/hotspot/share/gc/shared/stringdedup/stringDedupTable.cpp	Wed Oct 03 15:22:16 2018 +0200
@@ -375,7 +375,7 @@
   }
 
   typeArrayOop existing_value = lookup_or_add(value, latin1, hash);
-  if (existing_value == value) {
+  if (oopDesc::equals_raw(existing_value, value)) {
     // Same value, already known
     stat->inc_known();
     return;
--- a/src/hotspot/share/oops/access.hpp	Wed Oct 10 08:36:31 2018 +0200
+++ b/src/hotspot/share/oops/access.hpp	Wed Oct 03 15:22:16 2018 +0200
@@ -277,7 +277,7 @@
   }
 
   static bool equals(oop o1, oop o2) {
-    verify_decorators<INTERNAL_EMPTY>();
+    verify_decorators<AS_RAW>();
     return AccessInternal::equals<decorators>(o1, o2);
   }
 };
--- a/src/hotspot/share/oops/accessBackend.hpp	Wed Oct 10 08:36:31 2018 +0200
+++ b/src/hotspot/share/oops/accessBackend.hpp	Wed Oct 03 15:22:16 2018 +0200
@@ -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:
--- a/src/hotspot/share/oops/oop.hpp	Wed Oct 10 08:36:31 2018 +0200
+++ b/src/hotspot/share/oops/oop.hpp	Wed Oct 03 15:22:16 2018 +0200
@@ -153,6 +153,8 @@
 
   inline static bool equals(oop o1, oop o2) { return Access<>::equals(o1, o2); }
 
+  inline static bool equals_raw(oop o1, oop o2) { return RawAccess<>::equals(o1, o2); }
+
   // Access to fields in a instanceOop through these methods.
   template <DecoratorSet decorator>
   oop obj_field_access(int offset) const;
--- a/src/hotspot/share/oops/oopsHierarchy.cpp	Wed Oct 10 08:36:31 2018 +0200
+++ b/src/hotspot/share/oops/oopsHierarchy.cpp	Wed Oct 03 15:22:16 2018 +0200
@@ -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 {
+  assert(BarrierSet::barrier_set()->oop_equals_operator_allowed(), "Not allowed");
+  return obj() == o.obj();
+}
+
+bool oop::operator!=(const volatile oop o) const {
+  assert(BarrierSet::barrier_set()->oop_equals_operator_allowed(), "Not allowed");
+  return obj() != o.obj();
+}
+
 #endif // CHECK_UNHANDLED_OOPS
--- a/src/hotspot/share/oops/oopsHierarchy.hpp	Wed Oct 10 08:36:31 2018 +0200
+++ b/src/hotspot/share/oops/oopsHierarchy.hpp	Wed Oct 03 15:22:16 2018 +0200
@@ -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