changeset 59226:1b86798de6aa

8226411: C2: Avoid memory barriers around off-heap unsafe accesses Reviewed-by: kvn, thartmann, eosterlund, jrose, rkennke
author vlivanov
date Mon, 09 Dec 2019 19:29:35 +0300
parents 8df91a722672
children c3203a6a2ed4
files src/hotspot/share/gc/g1/c2/g1BarrierSetC2.cpp src/hotspot/share/gc/shared/c2/barrierSetC2.cpp src/hotspot/share/oops/accessDecorators.hpp src/hotspot/share/opto/library_call.cpp
diffstat 4 files changed, 25 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/gc/g1/c2/g1BarrierSetC2.cpp	Mon Dec 09 15:54:44 2019 +0000
+++ b/src/hotspot/share/gc/g1/c2/g1BarrierSetC2.cpp	Mon Dec 09 19:29:35 2019 +0300
@@ -597,12 +597,15 @@
   Node* adr = access.addr().node();
   Node* obj = access.base();
 
+  bool anonymous = (decorators & C2_UNSAFE_ACCESS) != 0;
   bool mismatched = (decorators & C2_MISMATCHED) != 0;
   bool unknown = (decorators & ON_UNKNOWN_OOP_REF) != 0;
   bool in_heap = (decorators & IN_HEAP) != 0;
+  bool in_native = (decorators & IN_NATIVE) != 0;
   bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
   bool is_unordered = (decorators & MO_UNORDERED) != 0;
-  bool need_cpu_mem_bar = !is_unordered || mismatched || !in_heap;
+  bool is_mixed = !in_heap && !in_native;
+  bool need_cpu_mem_bar = !is_unordered || mismatched || is_mixed;
 
   Node* top = Compile::current()->top();
   Node* offset = adr->is_AddP() ? adr->in(AddPNode::Offset) : top;
--- a/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp	Mon Dec 09 15:54:44 2019 +0000
+++ b/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp	Mon Dec 09 19:29:35 2019 +0300
@@ -43,13 +43,16 @@
 PhaseGVN& C2ParseAccess::gvn() const { return _kit->gvn(); }
 
 bool C2Access::needs_cpu_membar() const {
-  bool mismatched = (_decorators & C2_MISMATCHED) != 0;
+  bool mismatched   = (_decorators & C2_MISMATCHED) != 0;
   bool is_unordered = (_decorators & MO_UNORDERED) != 0;
+
   bool anonymous = (_decorators & C2_UNSAFE_ACCESS) != 0;
-  bool in_heap = (_decorators & IN_HEAP) != 0;
+  bool in_heap   = (_decorators & IN_HEAP) != 0;
+  bool in_native = (_decorators & IN_NATIVE) != 0;
+  bool is_mixed  = !in_heap && !in_native;
 
-  bool is_write = (_decorators & C2_WRITE_ACCESS) != 0;
-  bool is_read = (_decorators & C2_READ_ACCESS) != 0;
+  bool is_write  = (_decorators & C2_WRITE_ACCESS) != 0;
+  bool is_read   = (_decorators & C2_READ_ACCESS) != 0;
   bool is_atomic = is_read && is_write;
 
   if (is_atomic) {
@@ -63,9 +66,11 @@
     // the barriers get omitted and the unsafe reference begins to "pollute"
     // the alias analysis of the rest of the graph, either Compile::can_alias
     // or Compile::must_alias will throw a diagnostic assert.)
-    if (!in_heap || !is_unordered || (mismatched && !_addr.type()->isa_aryptr())) {
+    if (is_mixed || !is_unordered || (mismatched && !_addr.type()->isa_aryptr())) {
       return true;
     }
+  } else {
+    assert(!is_mixed, "not unsafe");
   }
 
   return false;
@@ -80,7 +85,7 @@
   bool requires_atomic_access = (decorators & MO_UNORDERED) == 0;
 
   bool in_native = (decorators & IN_NATIVE) != 0;
-  assert(!in_native, "not supported yet");
+  assert(!in_native || (unsafe && !access.is_oop()), "not supported yet");
 
   MemNode::MemOrd mo = access.mem_node_mo();
 
--- a/src/hotspot/share/oops/accessDecorators.hpp	Mon Dec 09 15:54:44 2019 +0000
+++ b/src/hotspot/share/oops/accessDecorators.hpp	Mon Dec 09 19:29:35 2019 +0300
@@ -176,11 +176,11 @@
                                         ON_PHANTOM_OOP_REF | ON_UNKNOWN_OOP_REF;
 
 // === Access Location ===
-// Accesses can take place in, e.g. the heap, old or young generation and different native roots.
+// Accesses can take place in, e.g. the heap, old or young generation, different native roots, or native memory off the heap.
 // The location is important to the GC as it may imply different actions. The following decorators are used:
 // * IN_HEAP: The access is performed in the heap. Many barriers such as card marking will
 //   be omitted if this decorator is not set.
-// * IN_NATIVE: The access is performed in an off-heap data structure pointing into the Java heap.
+// * IN_NATIVE: The access is performed in an off-heap data structure.
 const DecoratorSet IN_HEAP            = UCONST64(1) << 19;
 const DecoratorSet IN_NATIVE          = UCONST64(1) << 20;
 const DecoratorSet IN_DECORATOR_MASK  = IN_HEAP | IN_NATIVE;
--- a/src/hotspot/share/opto/library_call.cpp	Mon Dec 09 15:54:44 2019 +0000
+++ b/src/hotspot/share/opto/library_call.cpp	Mon Dec 09 19:29:35 2019 +0300
@@ -2447,10 +2447,14 @@
   offset = ConvL2X(offset);
   adr = make_unsafe_address(base, offset, is_store ? ACCESS_WRITE : ACCESS_READ, type, kind == Relaxed);
 
-  if (_gvn.type(base)->isa_ptr() != TypePtr::NULL_PTR) {
-    heap_base_oop = base;
-  } else if (type == T_OBJECT) {
-    return false; // off-heap oop accesses are not supported
+  if (_gvn.type(base)->isa_ptr() == TypePtr::NULL_PTR) {
+    if (type != T_OBJECT) {
+      decorators |= IN_NATIVE; // off-heap primitive access
+    } else {
+      return false; // off-heap oop accesses are not supported
+    }
+  } else {
+    heap_base_oop = base; // on-heap or mixed access
   }
 
   // Can base be NULL? Otherwise, always on-heap access.