8200555: OopHandle should use Access API
authorcoleenp
Wed, 18 Apr 2018 10:39:40 -0400
changeset 49816 a3e79f97e86b
parent 49815 76e3bcb9bee1
child 49817 a838e3707f3a
8200555: OopHandle should use Access API Summary: Add RootAccess<> to OopHandle.resolve() in runtime and interpreter code. Add comments for compiler code for later. Reviewed-by: eosterlund, stefank
src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp
src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp
src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp
src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
src/hotspot/cpu/sparc/interp_masm_sparc.cpp
src/hotspot/cpu/sparc/interp_masm_sparc.hpp
src/hotspot/cpu/sparc/macroAssembler_sparc.cpp
src/hotspot/cpu/sparc/macroAssembler_sparc.hpp
src/hotspot/cpu/sparc/templateInterpreterGenerator_sparc.cpp
src/hotspot/cpu/sparc/templateTable_sparc.cpp
src/hotspot/cpu/x86/interp_masm_x86.cpp
src/hotspot/cpu/x86/interp_masm_x86.hpp
src/hotspot/cpu/x86/macroAssembler_x86.cpp
src/hotspot/cpu/x86/macroAssembler_x86.hpp
src/hotspot/share/classfile/classLoaderData.cpp
src/hotspot/share/classfile/moduleEntry.cpp
src/hotspot/share/classfile/moduleEntry.hpp
src/hotspot/share/code/compiledMethod.inline.hpp
src/hotspot/share/oops/constantPool.inline.hpp
src/hotspot/share/oops/cpCache.hpp
src/hotspot/share/oops/cpCache.inline.hpp
src/hotspot/share/oops/klass.cpp
src/hotspot/share/oops/methodData.hpp
src/hotspot/share/oops/oopHandle.hpp
src/hotspot/share/oops/oopHandle.inline.hpp
src/hotspot/share/opto/library_call.cpp
src/hotspot/share/opto/memnode.cpp
src/hotspot/share/opto/phaseX.cpp
src/hotspot/share/opto/subnode.cpp
src/hotspot/share/prims/jvmtiEnvBase.cpp
src/hotspot/share/prims/jvmtiEnvBase.hpp
src/hotspot/share/runtime/javaFrameAnchor.hpp
src/hotspot/share/runtime/safepoint.hpp
--- a/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/cpu/aarch64/gc/g1/g1BarrierSetAssembler_aarch64.cpp	Wed Apr 18 10:39:40 2018 -0400
@@ -29,6 +29,9 @@
 #include "gc/g1/g1CardTable.hpp"
 #include "gc/g1/g1ThreadLocalData.hpp"
 #include "gc/g1/heapRegion.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "runtime/thread.hpp"
 #include "interpreter/interp_masm.hpp"
 #include "runtime/sharedRuntime.hpp"
 
--- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp	Wed Apr 18 10:39:40 2018 -0400
@@ -265,22 +265,21 @@
 
 // Load object from cpool->resolved_references(index)
 void InterpreterMacroAssembler::load_resolved_reference_at_index(
-                                           Register result, Register index) {
+                                           Register result, Register index, Register tmp) {
   assert_different_registers(result, index);
   // convert from field index to resolved_references() index and from
   // word index to byte offset. Since this is a java object, it can be compressed
-  Register tmp = index;  // reuse
-  lslw(tmp, tmp, LogBytesPerHeapOop);
+  lslw(index, index, LogBytesPerHeapOop);
 
   get_constant_pool(result);
   // load pointer for resolved_references[] objArray
   ldr(result, Address(result, ConstantPool::cache_offset_in_bytes()));
   ldr(result, Address(result, ConstantPoolCache::resolved_references_offset_in_bytes()));
-  resolve_oop_handle(result);
+  resolve_oop_handle(result, tmp);
   // Add in the index
-  add(result, result, tmp);
+  add(result, result, index);
   BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
-  bs->load_at(this, IN_HEAP, T_OBJECT, result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), /*tmp1*/ noreg, /*tmp_thread*/ noreg);
+  bs->load_at(this, IN_HEAP, T_OBJECT, result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), tmp, /*tmp_thread*/ noreg);
 }
 
 void InterpreterMacroAssembler::load_resolved_klass_at_offset(
--- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp	Wed Apr 18 10:39:40 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -122,7 +122,7 @@
   void get_method_counters(Register method, Register mcs, Label& skip);
 
   // load cpool->resolved_references(index);
-  void load_resolved_reference_at_index(Register result, Register index);
+  void load_resolved_reference_at_index(Register result, Register index, Register tmp = r5);
 
   // load cpool->resolved_klass_at(index);
   void load_resolved_klass_at_offset(Register cpool, Register index, Register klass, Register temp);
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Wed Apr 18 10:39:40 2018 -0400
@@ -2108,7 +2108,7 @@
 
   bind(not_weak);
   // Resolve (untagged) jobject.
-  bs->load_at(this, IN_ROOT | ON_STRONG_OOP_REF, T_OBJECT,
+  bs->load_at(this, IN_ROOT | IN_CONCURRENT_ROOT, T_OBJECT,
                     value, Address(value, 0), tmp, thread);
   verify_oop(value);
   bind(done);
@@ -3642,18 +3642,20 @@
 }
 
 // ((OopHandle)result).resolve();
-void MacroAssembler::resolve_oop_handle(Register result) {
+void MacroAssembler::resolve_oop_handle(Register result, Register tmp) {
   // OopHandle::resolve is an indirection.
-  ldr(result, Address(result, 0));
-}
-
-void MacroAssembler::load_mirror(Register dst, Register method) {
+  BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
+  bs->load_at(this, IN_ROOT | IN_CONCURRENT_ROOT, T_OBJECT,
+                    result, Address(result, 0), tmp, rthread);
+}
+
+void MacroAssembler::load_mirror(Register dst, Register method, Register tmp) {
   const int mirror_offset = in_bytes(Klass::java_mirror_offset());
   ldr(dst, Address(rmethod, Method::const_offset()));
   ldr(dst, Address(dst, ConstMethod::constants_offset()));
   ldr(dst, Address(dst, ConstantPool::pool_holder_offset_in_bytes()));
   ldr(dst, Address(dst, mirror_offset));
-  resolve_oop_handle(dst);
+  resolve_oop_handle(dst, tmp);
 }
 
 void MacroAssembler::cmp_klass(Register oop, Register trial_klass, Register tmp) {
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp	Wed Apr 18 10:39:40 2018 -0400
@@ -803,8 +803,8 @@
   void store_klass(Register dst, Register src);
   void cmp_klass(Register oop, Register trial_klass, Register tmp);
 
-  void resolve_oop_handle(Register result);
-  void load_mirror(Register dst, Register method);
+  void resolve_oop_handle(Register result, Register tmp = r5);
+  void load_mirror(Register dst, Register method, Register tmp = r5);
 
   void load_heap_oop(Register dst, Address src);
 
--- a/src/hotspot/cpu/sparc/interp_masm_sparc.cpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/cpu/sparc/interp_masm_sparc.cpp	Wed Apr 18 10:39:40 2018 -0400
@@ -739,20 +739,19 @@
 
 // Load object from cpool->resolved_references(index)
 void InterpreterMacroAssembler::load_resolved_reference_at_index(
-                                           Register result, Register index) {
-  assert_different_registers(result, index);
+                                           Register result, Register index, Register tmp) {
+  assert_different_registers(result, index, tmp);
   assert_not_delayed();
   // convert from field index to resolved_references() index and from
   // word index to byte offset. Since this is a java object, it can be compressed
-  Register tmp = index;  // reuse
-  sll(index, LogBytesPerHeapOop, tmp);
+  sll(index, LogBytesPerHeapOop, index);
   get_constant_pool(result);
   // load pointer for resolved_references[] objArray
   ld_ptr(result, ConstantPool::cache_offset_in_bytes(), result);
   ld_ptr(result, ConstantPoolCache::resolved_references_offset_in_bytes(), result);
-  resolve_oop_handle(result);
+  resolve_oop_handle(result, tmp);
   // Add in the index
-  add(result, tmp, result);
+  add(result, index, result);
   load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result, tmp);
 }
 
--- a/src/hotspot/cpu/sparc/interp_masm_sparc.hpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/cpu/sparc/interp_masm_sparc.hpp	Wed Apr 18 10:39:40 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -183,7 +183,7 @@
   void get_cache_index_at_bcp(Register temp, Register index, int bcp_offset, size_t index_size = sizeof(u2));
 
   // load cpool->resolved_references(index);
-  void load_resolved_reference_at_index(Register result, Register index);
+  void load_resolved_reference_at_index(Register result, Register index, Register tmp);
 
   // load cpool->resolved_klass_at(index)
   void load_resolved_klass_at_offset(Register Rcpool, Register Roffset, Register Rklass);
--- a/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp	Wed Apr 18 10:39:40 2018 -0400
@@ -3392,18 +3392,19 @@
   bind(no_reserved_zone_enabling);
 }
 // ((OopHandle)result).resolve();
-void MacroAssembler::resolve_oop_handle(Register result) {
+void MacroAssembler::resolve_oop_handle(Register result, Register tmp) {
   // OopHandle::resolve is an indirection.
-  ld_ptr(result, 0, result);
+  access_load_at(T_OBJECT, IN_ROOT | IN_CONCURRENT_ROOT,
+                 Address(result, 0), result, tmp);
 }
 
-void MacroAssembler::load_mirror(Register mirror, Register method) {
+void MacroAssembler::load_mirror(Register mirror, Register method, Register tmp) {
   const int mirror_offset = in_bytes(Klass::java_mirror_offset());
   ld_ptr(method, in_bytes(Method::const_offset()), mirror);
   ld_ptr(mirror, in_bytes(ConstMethod::constants_offset()), mirror);
   ld_ptr(mirror, ConstantPool::pool_holder_offset_in_bytes(), mirror);
   ld_ptr(mirror, mirror_offset, mirror);
-  resolve_oop_handle(mirror);
+  resolve_oop_handle(mirror, tmp);
 }
 
 void MacroAssembler::load_klass(Register src_oop, Register klass) {
--- a/src/hotspot/cpu/sparc/macroAssembler_sparc.hpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/cpu/sparc/macroAssembler_sparc.hpp	Wed Apr 18 10:39:40 2018 -0400
@@ -968,8 +968,8 @@
   inline void ldbool(const Address& a, Register d);
   inline void movbool( bool boolconst, Register d);
 
-  void resolve_oop_handle(Register result);
-  void load_mirror(Register mirror, Register method);
+  void resolve_oop_handle(Register result, Register tmp);
+  void load_mirror(Register mirror, Register method, Register tmp);
 
   // klass oop manipulations if compressed
   void load_klass(Register src_oop, Register klass);
--- a/src/hotspot/cpu/sparc/templateInterpreterGenerator_sparc.cpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/cpu/sparc/templateInterpreterGenerator_sparc.cpp	Wed Apr 18 10:39:40 2018 -0400
@@ -502,7 +502,7 @@
     __ delayed()->ld_ptr(Llocals, Interpreter::local_offset_in_bytes(0), O0); // get receiver for not-static case
 
     // lock the mirror, not the Klass*
-    __ load_mirror(O0, Lmethod);
+    __ load_mirror(O0, Lmethod, Lscratch);
 
 #ifdef ASSERT
     __ tst(O0);
@@ -810,7 +810,7 @@
   __ mov( G5_method, Lmethod);                 // set Lmethod
   // Get mirror and store it in the frame as GC root for this Method*
   Register mirror = LcpoolCache;
-  __ load_mirror(mirror, Lmethod);
+  __ load_mirror(mirror, Lmethod, Lscratch);
   __ st_ptr(mirror, FP, (frame::interpreter_frame_mirror_offset * wordSize) + STACK_BIAS);
   __ get_constant_pool_cache(LcpoolCache);     // set LcpoolCache
   __ sub(FP, rounded_vm_local_words * BytesPerWord, Lmonitors ); // set Lmonitors
@@ -1280,7 +1280,7 @@
     // get native function entry point(O0 is a good temp until the very end)
     __ delayed()->ld_ptr(Lmethod, in_bytes(Method::native_function_offset()), O0);
     // for static methods insert the mirror argument
-    __ load_mirror(O1, Lmethod);
+    __ load_mirror(O1, Lmethod, G3_scratch);
 #ifdef ASSERT
     if (!PrintSignatureHandlers)  // do not dirty the output with this
     { Label L;
--- a/src/hotspot/cpu/sparc/templateTable_sparc.cpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/cpu/sparc/templateTable_sparc.cpp	Wed Apr 18 10:39:40 2018 -0400
@@ -326,7 +326,7 @@
   // non-null object (CallSite, etc.)
   assert_different_registers(Otos_i, G3_scratch);
   __ get_cache_index_at_bcp(Otos_i, G3_scratch, 1, index_size);  // load index => G3_scratch
-  __ load_resolved_reference_at_index(Otos_i, G3_scratch);
+  __ load_resolved_reference_at_index(Otos_i, G3_scratch, Lscratch);
   __ tst(Otos_i);
   __ br(Assembler::notEqual, false, Assembler::pt, resolved);
   __ delayed()->set((int)bytecode(), O1);
@@ -2016,7 +2016,7 @@
                                               Register Roffset,
                                               Register Rflags,
                                               bool is_static) {
-  assert_different_registers(Rcache, Rflags, Roffset);
+  assert_different_registers(Rcache, Rflags, Roffset, Lscratch);
 
   ByteSize cp_base_offset = ConstantPoolCache::base_offset();
 
@@ -2026,7 +2026,7 @@
     __ ld_ptr(Rcache, cp_base_offset + ConstantPoolCacheEntry::f1_offset(), Robj);
     const int mirror_offset = in_bytes(Klass::java_mirror_offset());
     __ ld_ptr( Robj, mirror_offset, Robj);
-    __ resolve_oop_handle(Robj);
+    __ resolve_oop_handle(Robj, Lscratch);
   }
 }
 
@@ -2847,7 +2847,7 @@
     // This must be done before we get the receiver,
     // since the parameter_size includes it.
     assert(ConstantPoolCacheEntry::_indy_resolved_references_appendix_offset == 0, "appendix expected at index+0");
-    __ load_resolved_reference_at_index(temp, index);
+    __ load_resolved_reference_at_index(temp, index, /*tmp*/recv);
     __ verify_oop(temp);
     __ push_ptr(temp);  // push appendix (MethodType, CallSite, etc.)
     __ bind(L_no_push);
--- a/src/hotspot/cpu/x86/interp_masm_x86.cpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp	Wed Apr 18 10:39:40 2018 -0400
@@ -502,20 +502,19 @@
 
 // Load object from cpool->resolved_references(index)
 void InterpreterMacroAssembler::load_resolved_reference_at_index(
-                                           Register result, Register index) {
+                                           Register result, Register index, Register tmp) {
   assert_different_registers(result, index);
   // convert from field index to resolved_references() index and from
   // word index to byte offset. Since this is a java object, it can be compressed
-  Register tmp = index;  // reuse
-  shll(tmp, LogBytesPerHeapOop);
+  shll(index, LogBytesPerHeapOop);
 
   get_constant_pool(result);
   // load pointer for resolved_references[] objArray
   movptr(result, Address(result, ConstantPool::cache_offset_in_bytes()));
   movptr(result, Address(result, ConstantPoolCache::resolved_references_offset_in_bytes()));
-  resolve_oop_handle(result);
+  resolve_oop_handle(result, tmp);
   // Add in the index
-  addptr(result, tmp);
+  addptr(result, index);
   load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), tmp);
 }
 
--- a/src/hotspot/cpu/x86/interp_masm_x86.hpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/cpu/x86/interp_masm_x86.hpp	Wed Apr 18 10:39:40 2018 -0400
@@ -122,7 +122,7 @@
                               size_t index_size = sizeof(u2));
 
   // load cpool->resolved_references(index);
-  void load_resolved_reference_at_index(Register result, Register index);
+  void load_resolved_reference_at_index(Register result, Register index, Register tmp = rscratch2);
 
   // load cpool->resolved_klass_at(index)
   void load_resolved_klass_at_index(Register cpool,  // the constant pool (corrupted on return)
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Wed Apr 18 10:39:40 2018 -0400
@@ -6274,19 +6274,22 @@
 }
 
 // ((OopHandle)result).resolve();
-void MacroAssembler::resolve_oop_handle(Register result) {
-  // OopHandle::resolve is an indirection.
-  movptr(result, Address(result, 0));
-}
-
-void MacroAssembler::load_mirror(Register mirror, Register method) {
+void MacroAssembler::resolve_oop_handle(Register result, Register tmp) {
+  // Only 64 bit platforms support GCs that require a tmp register
+  // Only IN_HEAP loads require a thread_tmp register
+  // OopHandle::resolve is an indirection like jobject.
+  access_load_at(T_OBJECT, IN_ROOT | IN_CONCURRENT_ROOT,
+                 result, Address(result, 0), tmp, /*tmp_thread*/noreg);
+}
+
+void MacroAssembler::load_mirror(Register mirror, Register method, Register tmp) {
   // get mirror
   const int mirror_offset = in_bytes(Klass::java_mirror_offset());
   movptr(mirror, Address(method, Method::const_offset()));
   movptr(mirror, Address(mirror, ConstMethod::constants_offset()));
   movptr(mirror, Address(mirror, ConstantPool::pool_holder_offset_in_bytes()));
   movptr(mirror, Address(mirror, mirror_offset));
-  resolve_oop_handle(mirror);
+  resolve_oop_handle(mirror, tmp);
 }
 
 void MacroAssembler::load_klass(Register dst, Register src) {
--- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp	Wed Apr 18 10:39:40 2018 -0400
@@ -307,8 +307,8 @@
   void movbool(Address dst, Register src);
   void testbool(Register dst);
 
-  void resolve_oop_handle(Register result);
-  void load_mirror(Register mirror, Register method);
+  void resolve_oop_handle(Register result, Register tmp = rscratch2);
+  void load_mirror(Register mirror, Register method, Register tmp = rscratch2);
 
   // oop manipulations
   void load_klass(Register dst, Register src);
--- a/src/hotspot/share/classfile/classLoaderData.cpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/share/classfile/classLoaderData.cpp	Wed Apr 18 10:39:40 2018 -0400
@@ -64,6 +64,7 @@
 #include "memory/universe.hpp"
 #include "oops/access.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/oopHandle.inline.hpp"
 #include "oops/weakHandle.inline.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/handles.inline.hpp"
--- a/src/hotspot/share/classfile/moduleEntry.cpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/share/classfile/moduleEntry.cpp	Wed Apr 18 10:39:40 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
 #include "classfile/moduleEntry.hpp"
 #include "logging/log.hpp"
 #include "memory/resourceArea.hpp"
+#include "oops/oopHandle.inline.hpp"
 #include "oops/symbol.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/safepoint.hpp"
@@ -40,6 +41,8 @@
 
 ModuleEntry* ModuleEntryTable::_javabase_module = NULL;
 
+oop ModuleEntry::module() const { return _module.resolve(); }
+
 void ModuleEntry::set_location(Symbol* location) {
   if (_location != NULL) {
     // _location symbol's refcounts are managed by ModuleEntry,
--- a/src/hotspot/share/classfile/moduleEntry.hpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/share/classfile/moduleEntry.hpp	Wed Apr 18 10:39:40 2018 -0400
@@ -90,7 +90,7 @@
   Symbol*          name() const                        { return literal(); }
   void             set_name(Symbol* n)                 { set_literal(n); }
 
-  oop              module() const                      { return _module.resolve(); }
+  oop              module() const;
   OopHandle        module_handle() const               { return _module; }
   void             set_module(OopHandle j)             { _module = j; }
 
--- a/src/hotspot/share/code/compiledMethod.inline.hpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/share/code/compiledMethod.inline.hpp	Wed Apr 18 10:39:40 2018 -0400
@@ -28,6 +28,7 @@
 #include "code/compiledMethod.hpp"
 #include "code/nativeInst.hpp"
 #include "runtime/frame.hpp"
+#include "runtime/orderAccess.hpp"
 
 inline bool CompiledMethod::is_deopt_pc(address pc) { return is_deopt_entry(pc) || is_deopt_mh_entry(pc); }
 
--- a/src/hotspot/share/oops/constantPool.inline.hpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/share/oops/constantPool.inline.hpp	Wed Apr 18 10:39:40 2018 -0400
@@ -26,6 +26,7 @@
 #define SHARE_VM_OOPS_CONSTANTPOOL_INLINE_HPP
 
 #include "oops/constantPool.hpp"
+#include "oops/cpCache.inline.hpp"
 #include "runtime/orderAccess.inline.hpp"
 
 inline CPSlot ConstantPool::slot_at(int which) const {
--- a/src/hotspot/share/oops/cpCache.hpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/share/oops/cpCache.hpp	Wed Apr 18 10:39:40 2018 -0400
@@ -453,7 +453,7 @@
   oop  archived_references() NOT_CDS_JAVA_HEAP_RETURN_(NULL);
   void set_archived_references(oop o) NOT_CDS_JAVA_HEAP_RETURN;
 
-  oop resolved_references()                 { return _resolved_references.resolve(); }
+  inline oop resolved_references();
   void set_resolved_references(OopHandle s) { _resolved_references = s; }
   Array<u2>* reference_map() const        { return _reference_map; }
   void set_reference_map(Array<u2>* o)    { _reference_map = o; }
--- a/src/hotspot/share/oops/cpCache.inline.hpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/share/oops/cpCache.inline.hpp	Wed Apr 18 10:39:40 2018 -0400
@@ -26,6 +26,7 @@
 #define SHARE_VM_OOPS_CPCACHEOOP_INLINE_HPP
 
 #include "oops/cpCache.hpp"
+#include "oops/oopHandle.inline.hpp"
 #include "runtime/orderAccess.inline.hpp"
 
 inline int ConstantPoolCacheEntry::indices_ord() const { return OrderAccess::load_acquire(&_indices); }
@@ -96,4 +97,6 @@
   }
 }
 
+inline oop ConstantPoolCache::resolved_references() { return _resolved_references.resolve(); }
+
 #endif // SHARE_VM_OOPS_CPCACHEOOP_INLINE_HPP
--- a/src/hotspot/share/oops/klass.cpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/share/oops/klass.cpp	Wed Apr 18 10:39:40 2018 -0400
@@ -39,6 +39,7 @@
 #include "oops/instanceKlass.hpp"
 #include "oops/klass.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/oopHandle.inline.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/orderAccess.inline.hpp"
--- a/src/hotspot/share/oops/methodData.hpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/share/oops/methodData.hpp	Wed Apr 18 10:39:40 2018 -0400
@@ -30,6 +30,7 @@
 #include "oops/metadata.hpp"
 #include "oops/method.hpp"
 #include "oops/oop.hpp"
+#include "runtime/atomic.hpp"
 #include "utilities/align.hpp"
 #if INCLUDE_JVMCI
 #include "jvmci/jvmci_globals.hpp"
--- a/src/hotspot/share/oops/oopHandle.hpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/share/oops/oopHandle.hpp	Wed Apr 18 10:39:40 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,8 +26,6 @@
 #define SHARE_VM_OOPS_OOPHANDLE_HPP
 
 #include "oops/oop.hpp"
-#include "runtime/atomic.hpp"
-#include "runtime/orderAccess.hpp"
 
 // Simple class for encapsulating oop pointers stored in metadata.
 // These are different from Handle.  The Handle class stores pointers
@@ -45,7 +43,7 @@
   OopHandle() : _obj(NULL) {}
   OopHandle(oop* w) : _obj(w) {}
 
-  oop resolve() const { return (_obj == NULL) ? (oop)NULL : *_obj; }
+  inline oop resolve() const;
 
   // Used only for removing handle.
   oop* ptr_raw() { return _obj; }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/oops/oopHandle.inline.hpp	Wed Apr 18 10:39:40 2018 -0400
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_OOPS_OOPHANDLE_INLINE_HPP
+#define SHARE_VM_OOPS_OOPHANDLE_INLINE_HPP
+
+#include "oops/access.inline.hpp"
+#include "oops/oopHandle.hpp"
+
+inline oop OopHandle::resolve() const {
+  return (_obj == NULL) ? (oop)NULL : RootAccess<IN_CONCURRENT_ROOT>::oop_load(_obj);
+}
+
+#endif //  SHARE_VM_OOPS_OOPHANDLE_INLINE_HPP
+
--- a/src/hotspot/share/opto/library_call.cpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/share/opto/library_call.cpp	Wed Apr 18 10:39:40 2018 -0400
@@ -3488,6 +3488,7 @@
 Node* LibraryCallKit::load_mirror_from_klass(Node* klass) {
   Node* p = basic_plus_adr(klass, in_bytes(Klass::java_mirror_offset()));
   Node* load = make_load(NULL, p, TypeRawPtr::NOTNULL, T_ADDRESS, MemNode::unordered);
+  // mirror = ((OopHandle)mirror)->resolve();
   return make_load(NULL, load, TypeInstPtr::MIRROR, T_OBJECT, MemNode::unordered);
 }
 
--- a/src/hotspot/share/opto/memnode.cpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/share/opto/memnode.cpp	Wed Apr 18 10:39:40 2018 -0400
@@ -2215,12 +2215,16 @@
   // mirror go completely dead.  (Current exception:  Class
   // mirrors may appear in debug info, but we could clean them out by
   // introducing a new debug info operator for Klass.java_mirror).
+  //
+  // If the code pattern requires a barrier for
+  //   mirror = ((OopHandle)mirror)->resolve();
+  // this won't match.
 
   if (toop->isa_instptr() && toop->klass() == phase->C->env()->Class_klass()
       && offset == java_lang_Class::klass_offset_in_bytes()) {
     if (base->is_Load()) {
       Node* base2 = base->in(MemNode::Address);
-      if (base2->is_Load()) { /* direct load of a load which is the oophandle */
+      if (base2->is_Load()) { /* direct load of a load which is the OopHandle */
         Node* adr2 = base2->in(MemNode::Address);
         const TypeKlassPtr* tkls = phase->type(adr2)->isa_klassptr();
         if (tkls != NULL && !tkls->empty()
--- a/src/hotspot/share/opto/phaseX.cpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/share/opto/phaseX.cpp	Wed Apr 18 10:39:40 2018 -0400
@@ -1628,8 +1628,11 @@
       Node* imem = use->as_Initialize()->proj_out_or_null(TypeFunc::Memory);
       if (imem != NULL)  add_users_to_worklist0(imem);
     }
-    // Loading the java mirror from a klass oop requires two loads and the type
+    // Loading the java mirror from a Klass requires two loads and the type
     // of the mirror load depends on the type of 'n'. See LoadNode::Value().
+    // If the code pattern requires a barrier for
+    //   mirror = ((OopHandle)mirror)->resolve();
+    // this won't match.
     if (use_op == Op_LoadP && use->bottom_type()->isa_rawptr()) {
       for (DUIterator_Fast i2max, i2 = use->fast_outs(i2max); i2 < i2max; i2++) {
         Node* u = use->fast_out(i2);
@@ -1774,8 +1777,11 @@
             worklist.push(phi);
           }
         }
-        // Loading the java mirror from a klass oop requires two loads and the type
+        // Loading the java mirror from a Klass requires two loads and the type
         // of the mirror load depends on the type of 'n'. See LoadNode::Value().
+        // If the code pattern requires a barrier for
+        //   mirror = ((OopHandle)mirror)->resolve();
+        // this won't match.
         if (m_op == Op_LoadP && m->bottom_type()->isa_rawptr()) {
           for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) {
             Node* u = m->fast_out(i2);
--- a/src/hotspot/share/opto/subnode.cpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/share/opto/subnode.cpp	Wed Apr 18 10:39:40 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -886,7 +886,7 @@
   if (!tp || tp->klass() != phase->C->env()->Class_klass()) return NULL;
 
   Node* adr = n->in(MemNode::Address);
-  // First load from OopHandle
+  // First load from OopHandle: ((OopHandle)mirror)->resolve(); may need barrier.
   if (adr->Opcode() != Op_LoadP || !phase->type(adr)->isa_rawptr()) return NULL;
   adr = adr->in(MemNode::Address);
 
--- a/src/hotspot/share/prims/jvmtiEnvBase.cpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp	Wed Apr 18 10:39:40 2018 -0400
@@ -29,6 +29,7 @@
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/oopHandle.inline.hpp"
 #include "prims/jvmtiEnvBase.hpp"
 #include "prims/jvmtiEventController.inline.hpp"
 #include "prims/jvmtiExtensions.hpp"
@@ -1478,6 +1479,13 @@
 
 GrowableArray<OopHandle>* JvmtiModuleClosure::_tbl = NULL;
 
+void JvmtiModuleClosure::do_module(ModuleEntry* entry) {
+  assert_locked_or_safepoint(Module_lock);
+  OopHandle module = entry->module_handle();
+  guarantee(module.resolve() != NULL, "module object is NULL");
+  _tbl->push(module);
+}
+
 jvmtiError
 JvmtiModuleClosure::get_all_modules(JvmtiEnv* env, jint* module_count_ptr, jobject** modules_ptr) {
   ResourceMark rm;
--- a/src/hotspot/share/prims/jvmtiEnvBase.hpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/share/prims/jvmtiEnvBase.hpp	Wed Apr 18 10:39:40 2018 -0400
@@ -639,13 +639,7 @@
 private:
   static GrowableArray<OopHandle> *_tbl; // Protected with Module_lock
 
-  static void do_module(ModuleEntry* entry) {
-    assert_locked_or_safepoint(Module_lock);
-    OopHandle module = entry->module_handle();
-    guarantee(module.resolve() != NULL, "module object is NULL");
-    _tbl->push(module);
-  }
-
+  static void do_module(ModuleEntry* entry);
 public:
   jvmtiError get_all_modules(JvmtiEnv* env, jint* module_count_ptr, jobject** modules_ptr);
 };
--- a/src/hotspot/share/runtime/javaFrameAnchor.hpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/share/runtime/javaFrameAnchor.hpp	Wed Apr 18 10:39:40 2018 -0400
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_RUNTIME_JAVAFRAMEANCHOR_HPP
 #define SHARE_VM_RUNTIME_JAVAFRAMEANCHOR_HPP
 
+#include "runtime/orderAccess.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/macros.hpp"
 
--- a/src/hotspot/share/runtime/safepoint.hpp	Wed Apr 18 15:57:19 2018 +0200
+++ b/src/hotspot/share/runtime/safepoint.hpp	Wed Apr 18 10:39:40 2018 -0400
@@ -28,6 +28,7 @@
 #include "asm/assembler.hpp"
 #include "code/nmethod.hpp"
 #include "memory/allocation.hpp"
+#include "runtime/atomic.hpp"
 #include "runtime/extendedPC.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/os.hpp"