changeset 49472:44122f767467

8198286: Direct memory accessors in typeArrayOop.hpp should use Access API Reviewed-by: pliden, rkennke
author eosterlund
date Thu, 22 Feb 2018 10:39:42 +0100
parents 079d100b3d0e
children a04a9bee2431
files src/hotspot/share/c1/c1_Runtime1.cpp src/hotspot/share/classfile/classLoaderData.cpp src/hotspot/share/classfile/javaClasses.cpp src/hotspot/share/classfile/javaClasses.hpp src/hotspot/share/classfile/javaClasses.inline.hpp src/hotspot/share/classfile/stringTable.cpp src/hotspot/share/classfile/systemDictionaryShared.cpp src/hotspot/share/gc/g1/g1StringDedupTable.cpp src/hotspot/share/gc/parallel/psCompactionManager.cpp src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp src/hotspot/share/gc/parallel/psParallelCompact.cpp src/hotspot/share/gc/parallel/psPromotionManager.cpp src/hotspot/share/gc/shared/barrierSet.hpp src/hotspot/share/gc/shared/barrierSetConfig.hpp src/hotspot/share/gc/shared/referenceProcessor.cpp src/hotspot/share/jvmci/jvmciCodeInstaller.cpp src/hotspot/share/memory/oopFactory.cpp src/hotspot/share/oops/access.hpp src/hotspot/share/oops/access.inline.hpp src/hotspot/share/oops/accessBackend.hpp src/hotspot/share/oops/arrayOop.hpp src/hotspot/share/oops/arrayOop.inline.hpp src/hotspot/share/oops/constantPool.hpp src/hotspot/share/oops/instanceKlass.inline.hpp src/hotspot/share/oops/instanceRefKlass.inline.hpp src/hotspot/share/oops/objArrayKlass.inline.hpp src/hotspot/share/oops/objArrayOop.cpp src/hotspot/share/oops/objArrayOop.hpp src/hotspot/share/oops/objArrayOop.inline.hpp src/hotspot/share/oops/oop.hpp src/hotspot/share/oops/oop.inline.hpp src/hotspot/share/oops/typeArrayOop.hpp src/hotspot/share/oops/typeArrayOop.inline.hpp src/hotspot/share/opto/library_call.cpp src/hotspot/share/prims/jni.cpp src/hotspot/share/prims/jvmtiTagMap.cpp src/hotspot/share/prims/unsafe.cpp src/hotspot/share/services/attachListener.cpp src/hotspot/share/services/diagnosticCommand.cpp
diffstat 39 files changed, 338 insertions(+), 197 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/c1/c1_Runtime1.cpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/c1/c1_Runtime1.cpp	Thu Feb 22 10:39:42 2018 +0100
@@ -47,6 +47,7 @@
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/access.inline.hpp"
+#include "oops/objArrayOop.inline.hpp"
 #include "oops/objArrayKlass.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.hpp"
--- a/src/hotspot/share/classfile/classLoaderData.cpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/classfile/classLoaderData.cpp	Thu Feb 22 10:39:42 2018 +0100
@@ -1001,9 +1001,8 @@
 
 
   if (!is_anonymous) {
-    ClassLoaderData** cld_addr = java_lang_ClassLoader::loader_data_addr(loader());
     // First, Atomically set it
-    ClassLoaderData* old = Atomic::cmpxchg(cld, cld_addr, (ClassLoaderData*)NULL);
+    ClassLoaderData* old = java_lang_ClassLoader::cmpxchg_loader_data(cld, loader(), NULL);
     if (old != NULL) {
       delete cld;
       // Returns the data.
--- a/src/hotspot/share/classfile/javaClasses.cpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Thu Feb 22 10:39:42 2018 +0100
@@ -3403,7 +3403,7 @@
 
 DependencyContext java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(oop call_site) {
   assert(java_lang_invoke_MethodHandleNatives_CallSiteContext::is_instance(call_site), "");
-  intptr_t* vmdeps_addr = (intptr_t*)call_site->address_field_addr(_vmdependencies_offset);
+  intptr_t* vmdeps_addr = (intptr_t*)call_site->field_addr(_vmdependencies_offset);
   DependencyContext dep_ctx(vmdeps_addr);
   return dep_ctx;
 }
@@ -3458,13 +3458,14 @@
 int  java_lang_ClassLoader::name_offset = -1;
 int  java_lang_ClassLoader::unnamedModule_offset = -1;
 
-ClassLoaderData** java_lang_ClassLoader::loader_data_addr(oop loader) {
-    assert(loader != NULL && oopDesc::is_oop(loader), "loader must be oop");
-    return (ClassLoaderData**) loader->address_field_addr(_loader_data_offset);
-}
-
 ClassLoaderData* java_lang_ClassLoader::loader_data(oop loader) {
-  return *java_lang_ClassLoader::loader_data_addr(loader);
+  assert(loader != NULL && oopDesc::is_oop(loader), "loader must be oop");
+  return HeapAccess<>::load_at(loader, _loader_data_offset);
+}
+
+ClassLoaderData* java_lang_ClassLoader::cmpxchg_loader_data(ClassLoaderData* new_data, oop loader, ClassLoaderData* expected_data) {
+  assert(loader != NULL && oopDesc::is_oop(loader), "loader must be oop");
+  return HeapAccess<>::atomic_cmpxchg_at(new_data, loader, _loader_data_offset, expected_data);
 }
 
 void java_lang_ClassLoader::compute_offsets() {
--- a/src/hotspot/share/classfile/javaClasses.hpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/classfile/javaClasses.hpp	Thu Feb 22 10:39:42 2018 +0100
@@ -881,15 +881,15 @@
   static inline oop referent(oop ref);
   static inline void set_referent(oop ref, oop value);
   static inline void set_referent_raw(oop ref, oop value);
-  static inline HeapWord* referent_addr(oop ref);
+  static inline HeapWord* referent_addr_raw(oop ref);
   static inline oop next(oop ref);
   static inline void set_next(oop ref, oop value);
   static inline void set_next_raw(oop ref, oop value);
-  static inline HeapWord* next_addr(oop ref);
+  static inline HeapWord* next_addr_raw(oop ref);
   static inline oop discovered(oop ref);
   static inline void set_discovered(oop ref, oop value);
   static inline void set_discovered_raw(oop ref, oop value);
-  static inline HeapWord* discovered_addr(oop ref);
+  static inline HeapWord* discovered_addr_raw(oop ref);
   static bool is_referent_field(oop obj, ptrdiff_t offset);
   static inline bool is_phantom(oop ref);
 };
@@ -1229,8 +1229,8 @@
  public:
   static void compute_offsets();
 
-  static ClassLoaderData** loader_data_addr(oop loader);
   static ClassLoaderData* loader_data(oop loader);
+  static ClassLoaderData* cmpxchg_loader_data(ClassLoaderData* new_data, oop loader, ClassLoaderData* expected_data);
 
   static oop parent(oop loader);
   static oop name(oop loader);
--- a/src/hotspot/share/classfile/javaClasses.inline.hpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/classfile/javaClasses.inline.hpp	Thu Feb 22 10:39:42 2018 +0100
@@ -100,8 +100,8 @@
 void java_lang_ref_Reference::set_referent_raw(oop ref, oop value) {
   ref->obj_field_put_raw(referent_offset, value);
 }
-HeapWord* java_lang_ref_Reference::referent_addr(oop ref) {
-  return ref->obj_field_addr<HeapWord>(referent_offset);
+HeapWord* java_lang_ref_Reference::referent_addr_raw(oop ref) {
+  return ref->obj_field_addr_raw<HeapWord>(referent_offset);
 }
 oop java_lang_ref_Reference::next(oop ref) {
   return ref->obj_field(next_offset);
@@ -112,8 +112,8 @@
 void java_lang_ref_Reference::set_next_raw(oop ref, oop value) {
   ref->obj_field_put_raw(next_offset, value);
 }
-HeapWord* java_lang_ref_Reference::next_addr(oop ref) {
-  return ref->obj_field_addr<HeapWord>(next_offset);
+HeapWord* java_lang_ref_Reference::next_addr_raw(oop ref) {
+  return ref->obj_field_addr_raw<HeapWord>(next_offset);
 }
 oop java_lang_ref_Reference::discovered(oop ref) {
   return ref->obj_field(discovered_offset);
@@ -124,8 +124,8 @@
 void java_lang_ref_Reference::set_discovered_raw(oop ref, oop value) {
   ref->obj_field_put_raw(discovered_offset, value);
 }
-HeapWord* java_lang_ref_Reference::discovered_addr(oop ref) {
-  return ref->obj_field_addr<HeapWord>(discovered_offset);
+HeapWord* java_lang_ref_Reference::discovered_addr_raw(oop ref) {
+  return ref->obj_field_addr_raw<HeapWord>(discovered_offset);
 }
 bool java_lang_ref_Reference::is_phantom(oop ref) {
   return InstanceKlass::cast(ref->klass())->reference_type() == REF_PHANTOM;
--- a/src/hotspot/share/classfile/stringTable.cpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/classfile/stringTable.cpp	Thu Feb 22 10:39:42 2018 +0100
@@ -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
@@ -37,6 +37,7 @@
 #include "memory/resourceArea.hpp"
 #include "oops/access.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "services/diagnosticCommand.hpp"
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp	Thu Feb 22 10:39:42 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -48,6 +48,7 @@
 #include "oops/klass.inline.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/mutexLocker.hpp"
--- a/src/hotspot/share/gc/g1/g1StringDedupTable.cpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/gc/g1/g1StringDedupTable.cpp	Thu Feb 22 10:39:42 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -32,6 +32,7 @@
 #include "gc/shared/gcLocker.hpp"
 #include "logging/log.hpp"
 #include "memory/padded.inline.hpp"
+#include "oops/arrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/typeArrayOop.hpp"
 #include "runtime/mutexLocker.hpp"
--- a/src/hotspot/share/gc/parallel/psCompactionManager.cpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/gc/parallel/psCompactionManager.cpp	Thu Feb 22 10:39:42 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -181,7 +181,7 @@
 
 template <class T>
 static void oop_pc_follow_contents_specialized(InstanceRefKlass* klass, oop obj, ParCompactionManager* cm) {
-  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr_raw(obj);
   T heap_oop = oopDesc::load_heap_oop(referent_addr);
   log_develop_trace(gc, ref)("InstanceRefKlass::oop_pc_follow_contents " PTR_FORMAT, p2i(obj));
   if (!oopDesc::is_null(heap_oop)) {
@@ -198,12 +198,12 @@
       cm->mark_and_push(referent_addr);
     }
   }
-  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+  T* next_addr = (T*)java_lang_ref_Reference::next_addr_raw(obj);
   // Treat discovered as normal oop, if ref is not "active",
   // i.e. if next is non-NULL.
   T  next_oop = oopDesc::load_heap_oop(next_addr);
   if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
-    T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+    T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr_raw(obj);
     log_develop_trace(gc, ref)("   Process discovered as normal " PTR_FORMAT, p2i(discovered_addr));
     cm->mark_and_push(discovered_addr);
   }
--- a/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp	Thu Feb 22 10:39:42 2018 +0100
@@ -29,7 +29,8 @@
 #include "gc/parallel/psCompactionManager.hpp"
 #include "gc/parallel/psParallelCompact.inline.hpp"
 #include "gc/shared/taskqueue.inline.hpp"
-#include "oops/objArrayOop.hpp"
+#include "oops/arrayOop.inline.hpp"
+#include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/globalDefinitions.hpp"
@@ -117,7 +118,7 @@
 
   const size_t stride = MIN2(len - beg_index, ObjArrayMarkingStride);
   const size_t end_index = beg_index + stride;
-  T* const base = (T*)obj->base();
+  T* const base = (T*)obj->base_raw();
   T* const beg = base + beg_index;
   T* const end = base + end_index;
 
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Thu Feb 22 10:39:42 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -3087,11 +3087,11 @@
 
 template <class T>
 static void oop_pc_update_pointers_specialized(oop obj, ParCompactionManager* cm) {
-  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr_raw(obj);
   PSParallelCompact::adjust_pointer(referent_addr, cm);
-  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+  T* next_addr = (T*)java_lang_ref_Reference::next_addr_raw(obj);
   PSParallelCompact::adjust_pointer(next_addr, cm);
-  T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+  T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr_raw(obj);
   PSParallelCompact::adjust_pointer(discovered_addr, cm);
   debug_only(trace_reference_gc("InstanceRefKlass::oop_update_ptrs", obj,
                                 referent_addr, next_addr, discovered_addr);)
--- a/src/hotspot/share/gc/parallel/psPromotionManager.cpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/gc/parallel/psPromotionManager.cpp	Thu Feb 22 10:39:42 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -38,9 +38,11 @@
 #include "memory/memRegion.hpp"
 #include "memory/padded.inline.hpp"
 #include "memory/resourceArea.hpp"
+#include "oops/arrayOop.inline.hpp"
 #include "oops/instanceKlass.inline.hpp"
 #include "oops/instanceMirrorKlass.inline.hpp"
 #include "oops/objArrayKlass.inline.hpp"
+#include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 
 PaddedEnd<PSPromotionManager>* PSPromotionManager::_manager_array = NULL;
@@ -434,7 +436,7 @@
 
 template <class T>
 static void oop_ps_push_contents_specialized(oop obj, InstanceRefKlass *klass, PSPromotionManager* pm) {
-  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr_raw(obj);
   if (PSScavenge::should_scavenge(referent_addr)) {
     ReferenceProcessor* rp = PSScavenge::reference_processor();
     if (rp->discover_reference(obj, klass->reference_type())) {
@@ -448,10 +450,10 @@
   }
   // Treat discovered as normal oop, if ref is not "active",
   // i.e. if next is non-NULL.
-  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+  T* next_addr = (T*)java_lang_ref_Reference::next_addr_raw(obj);
   T  next_oop = oopDesc::load_heap_oop(next_addr);
   if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
-    T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+    T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr_raw(obj);
     log_develop_trace(gc, ref)("   Process discovered as normal " PTR_FORMAT, p2i(discovered_addr));
     if (PSScavenge::should_scavenge(discovered_addr)) {
       pm->claim_or_forward_depth(discovered_addr);
--- a/src/hotspot/share/gc/shared/barrierSet.hpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/gc/shared/barrierSet.hpp	Thu Feb 22 10:39:42 2018 +0100
@@ -273,6 +273,10 @@
     static void clone_in_heap(oop src, oop dst, size_t size) {
       Raw::clone(src, dst, size);
     }
+
+    static oop resolve(oop obj) {
+      return Raw::resolve(obj);
+    }
   };
 };
 
--- a/src/hotspot/share/gc/shared/barrierSetConfig.hpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/gc/shared/barrierSetConfig.hpp	Thu Feb 22 10:39:42 2018 +0100
@@ -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
@@ -52,9 +52,17 @@
 // To enable runtime-resolution of GC barriers on primitives, please
 // define SUPPORT_BARRIER_ON_PRIMITIVES.
 #ifdef SUPPORT_BARRIER_ON_PRIMITIVES
-#define BT_BUILDTIME_DECORATORS INTERNAL_BT_BARRIER_ON_PRIMITIVES
+#define ACCESS_PRIMITIVE_SUPPORT INTERNAL_BT_BARRIER_ON_PRIMITIVES
 #else
-#define BT_BUILDTIME_DECORATORS INTERNAL_EMPTY
+#define ACCESS_PRIMITIVE_SUPPORT INTERNAL_EMPTY
 #endif
 
+#ifdef SUPPORT_NOT_TO_SPACE_INVARIANT
+#define ACCESS_TO_SPACE_INVARIANT_SUPPORT INTERNAL_EMPTY
+#else
+#define ACCESS_TO_SPACE_INVARIANT_SUPPORT INTERNAL_BT_TO_SPACE_INVARIANT
+#endif
+
+#define BT_BUILDTIME_DECORATORS (ACCESS_PRIMITIVE_SUPPORT | ACCESS_TO_SPACE_INVARIANT_SUPPORT)
+
 #endif // SHARE_VM_GC_SHARED_BARRIERSETCONFIG_HPP
--- a/src/hotspot/share/gc/shared/referenceProcessor.cpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/gc/shared/referenceProcessor.cpp	Thu Feb 22 10:39:42 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -363,12 +363,12 @@
 }
 
 void DiscoveredListIterator::load_ptrs(DEBUG_ONLY(bool allow_null_referent)) {
-  _discovered_addr = java_lang_ref_Reference::discovered_addr(_ref);
+  _discovered_addr = java_lang_ref_Reference::discovered_addr_raw(_ref);
   oop discovered = java_lang_ref_Reference::discovered(_ref);
   assert(_discovered_addr && oopDesc::is_oop_or_null(discovered),
          "Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered));
   _next = discovered;
-  _referent_addr = java_lang_ref_Reference::referent_addr(_ref);
+  _referent_addr = java_lang_ref_Reference::referent_addr_raw(_ref);
   _referent = java_lang_ref_Reference::referent(_ref);
   assert(Universe::heap()->is_in_reserved_or_null(_referent),
          "Wrong oop found in java.lang.Reference object");
@@ -494,7 +494,7 @@
   DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
   while (iter.has_next()) {
     iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
-    HeapWord* next_addr = java_lang_ref_Reference::next_addr(iter.obj());
+    HeapWord* next_addr = java_lang_ref_Reference::next_addr_raw(iter.obj());
     oop next = java_lang_ref_Reference::next(iter.obj());
     if ((iter.referent() == NULL || iter.is_referent_alive() ||
          next != NULL)) {
@@ -1019,7 +1019,7 @@
 
   ResourceMark rm;      // Needed for tracing.
 
-  HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr(obj);
+  HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr_raw(obj);
   const oop  discovered = java_lang_ref_Reference::discovered(obj);
   assert(oopDesc::is_oop_or_null(discovered), "Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered));
   if (discovered != NULL) {
@@ -1186,10 +1186,10 @@
       // Keep alive its cohort.
       iter.make_referent_alive();
       if (UseCompressedOops) {
-        narrowOop* next_addr = (narrowOop*)java_lang_ref_Reference::next_addr(obj);
+        narrowOop* next_addr = (narrowOop*)java_lang_ref_Reference::next_addr_raw(obj);
         keep_alive->do_oop(next_addr);
       } else {
-        oop* next_addr = (oop*)java_lang_ref_Reference::next_addr(obj);
+        oop* next_addr = (oop*)java_lang_ref_Reference::next_addr_raw(obj);
         keep_alive->do_oop(next_addr);
       }
       iter.move_to_next();
--- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp	Thu Feb 22 10:39:42 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -34,6 +34,7 @@
 #include "jvmci/jvmciJavaClasses.hpp"
 #include "jvmci/jvmciCompilerToVM.hpp"
 #include "jvmci/jvmciRuntime.hpp"
+#include "oops/arrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/typeArrayOop.inline.hpp"
--- a/src/hotspot/share/memory/oopFactory.cpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/memory/oopFactory.cpp	Thu Feb 22 10:39:42 2018 +0100
@@ -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
@@ -35,6 +35,7 @@
 #include "oops/instanceOop.hpp"
 #include "oops/objArrayOop.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 
 
 typeArrayOop oopFactory::new_charArray(const char* utf8_str, TRAPS) {
--- a/src/hotspot/share/oops/access.hpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/oops/access.hpp	Thu Feb 22 10:39:42 2018 +0100
@@ -55,6 +55,7 @@
 // * atomic_xchg_at: Atomically swap a new value at an internal pointer address if previous value matched the compared value.
 // * arraycopy: Copy data from one heap array to another heap array.
 // * clone: Clone the contents of an object to a newly allocated object.
+// * resolve: Resolve a stable to-space invariant oop that is guaranteed not to relocate its payload until a subsequent thread transition.
 
 typedef uint64_t DecoratorSet;
 
@@ -69,12 +70,15 @@
 
 // == Internal build-time Decorators ==
 // * INTERNAL_BT_BARRIER_ON_PRIMITIVES: This is set in the barrierSetConfig.hpp file.
+// * INTERNAL_BT_TO_SPACE_INVARIANT: This is set in the barrierSetConfig.hpp file iff
+//   no GC is bundled in the build that is to-space invariant.
 const DecoratorSet INTERNAL_BT_BARRIER_ON_PRIMITIVES = UCONST64(1) << 3;
+const DecoratorSet INTERNAL_BT_TO_SPACE_INVARIANT    = UCONST64(1) << 4;
 
 // == Internal run-time Decorators ==
 // * INTERNAL_RT_USE_COMPRESSED_OOPS: This decorator will be set in runtime resolved
 //   access backends iff UseCompressedOops is true.
-const DecoratorSet INTERNAL_RT_USE_COMPRESSED_OOPS   = UCONST64(1) << 4;
+const DecoratorSet INTERNAL_RT_USE_COMPRESSED_OOPS   = UCONST64(1) << 5;
 
 const DecoratorSet INTERNAL_DECORATOR_MASK           = INTERNAL_CONVERT_COMPRESSED_OOP | INTERNAL_VALUE_IS_OOP |
                                                        INTERNAL_BT_BARRIER_ON_PRIMITIVES | INTERNAL_RT_USE_COMPRESSED_OOPS;
@@ -138,12 +142,12 @@
 //    - Guarantees from MO_RELAXED loads and MO_RELAXED stores hold.
 //  * MO_SEQ_CST: Sequentially consistent xchg.
 //    - Guarantees from MO_SEQ_CST loads and MO_SEQ_CST stores hold.
-const DecoratorSet MO_UNORDERED      = UCONST64(1) << 5;
-const DecoratorSet MO_VOLATILE       = UCONST64(1) << 6;
-const DecoratorSet MO_RELAXED        = UCONST64(1) << 7;
-const DecoratorSet MO_ACQUIRE        = UCONST64(1) << 8;
-const DecoratorSet MO_RELEASE        = UCONST64(1) << 9;
-const DecoratorSet MO_SEQ_CST        = UCONST64(1) << 10;
+const DecoratorSet MO_UNORDERED      = UCONST64(1) << 6;
+const DecoratorSet MO_VOLATILE       = UCONST64(1) << 7;
+const DecoratorSet MO_RELAXED        = UCONST64(1) << 8;
+const DecoratorSet MO_ACQUIRE        = UCONST64(1) << 9;
+const DecoratorSet MO_RELEASE        = UCONST64(1) << 10;
+const DecoratorSet MO_SEQ_CST        = UCONST64(1) << 11;
 const DecoratorSet MO_DECORATOR_MASK = MO_UNORDERED | MO_VOLATILE | MO_RELAXED |
                                        MO_ACQUIRE | MO_RELEASE | MO_SEQ_CST;
 
@@ -166,10 +170,10 @@
 //   responsibility of performing the access and what barriers to be performed to the GC. This is the default.
 //   Note that primitive accesses will only be resolved on the barrier set if the appropriate build-time
 //   decorator for enabling primitive barriers is enabled for the build.
-const DecoratorSet AS_RAW                  = UCONST64(1) << 11;
-const DecoratorSet AS_DEST_NOT_INITIALIZED = UCONST64(1) << 12;
-const DecoratorSet AS_NO_KEEPALIVE         = UCONST64(1) << 13;
-const DecoratorSet AS_NORMAL               = UCONST64(1) << 14;
+const DecoratorSet AS_RAW                  = UCONST64(1) << 12;
+const DecoratorSet AS_DEST_NOT_INITIALIZED = UCONST64(1) << 13;
+const DecoratorSet AS_NO_KEEPALIVE         = UCONST64(1) << 14;
+const DecoratorSet AS_NORMAL               = UCONST64(1) << 15;
 const DecoratorSet AS_DECORATOR_MASK       = AS_RAW | AS_DEST_NOT_INITIALIZED |
                                              AS_NO_KEEPALIVE | AS_NORMAL;
 
@@ -182,10 +186,10 @@
 // * ON_UNKNOWN_OOP_REF: The memory access is performed on a reference of unknown strength.
 //   This could for example come from the unsafe API.
 // * Default (no explicit reference strength specified): ON_STRONG_OOP_REF
-const DecoratorSet ON_STRONG_OOP_REF  = UCONST64(1) << 15;
-const DecoratorSet ON_WEAK_OOP_REF    = UCONST64(1) << 16;
-const DecoratorSet ON_PHANTOM_OOP_REF = UCONST64(1) << 17;
-const DecoratorSet ON_UNKNOWN_OOP_REF = UCONST64(1) << 18;
+const DecoratorSet ON_STRONG_OOP_REF  = UCONST64(1) << 16;
+const DecoratorSet ON_WEAK_OOP_REF    = UCONST64(1) << 17;
+const DecoratorSet ON_PHANTOM_OOP_REF = UCONST64(1) << 18;
+const DecoratorSet ON_UNKNOWN_OOP_REF = UCONST64(1) << 19;
 const DecoratorSet ON_DECORATOR_MASK  = ON_STRONG_OOP_REF | ON_WEAK_OOP_REF |
                                         ON_PHANTOM_OOP_REF | ON_UNKNOWN_OOP_REF;
 
@@ -200,18 +204,18 @@
 // * IN_CONCURRENT_ROOT: The access is performed in an off-heap data structure pointing into the Java heap,
 //   but is notably not scanned during safepoints. This is sometimes a special case for some GCs and
 //   implies that it is also an IN_ROOT.
-const DecoratorSet IN_HEAP            = UCONST64(1) << 19;
-const DecoratorSet IN_HEAP_ARRAY      = UCONST64(1) << 20;
-const DecoratorSet IN_ROOT            = UCONST64(1) << 21;
-const DecoratorSet IN_CONCURRENT_ROOT = UCONST64(1) << 22;
-const DecoratorSet IN_ARCHIVE_ROOT    = UCONST64(1) << 23;
+const DecoratorSet IN_HEAP            = UCONST64(1) << 20;
+const DecoratorSet IN_HEAP_ARRAY      = UCONST64(1) << 21;
+const DecoratorSet IN_ROOT            = UCONST64(1) << 22;
+const DecoratorSet IN_CONCURRENT_ROOT = UCONST64(1) << 23;
+const DecoratorSet IN_ARCHIVE_ROOT    = UCONST64(1) << 24;
 const DecoratorSet IN_DECORATOR_MASK  = IN_HEAP | IN_HEAP_ARRAY |
                                         IN_ROOT | IN_CONCURRENT_ROOT |
                                         IN_ARCHIVE_ROOT;
 
 // == Value Decorators ==
 // * OOP_NOT_NULL: This property can make certain barriers faster such as compressing oops.
-const DecoratorSet OOP_NOT_NULL       = UCONST64(1) << 24;
+const DecoratorSet OOP_NOT_NULL       = UCONST64(1) << 25;
 const DecoratorSet OOP_DECORATOR_MASK = OOP_NOT_NULL;
 
 // == Arraycopy Decorators ==
@@ -224,11 +228,11 @@
 // * ARRAYCOPY_ARRAYOF: The copy is in the arrayof form.
 // * ARRAYCOPY_ATOMIC: The accesses have to be atomic over the size of its elements.
 // * ARRAYCOPY_ALIGNED: The accesses have to be aligned on a HeapWord.
-const DecoratorSet ARRAYCOPY_CHECKCAST            = UCONST64(1) << 25;
-const DecoratorSet ARRAYCOPY_DISJOINT             = UCONST64(1) << 26;
-const DecoratorSet ARRAYCOPY_ARRAYOF              = UCONST64(1) << 27;
-const DecoratorSet ARRAYCOPY_ATOMIC               = UCONST64(1) << 28;
-const DecoratorSet ARRAYCOPY_ALIGNED              = UCONST64(1) << 29;
+const DecoratorSet ARRAYCOPY_CHECKCAST            = UCONST64(1) << 26;
+const DecoratorSet ARRAYCOPY_DISJOINT             = UCONST64(1) << 27;
+const DecoratorSet ARRAYCOPY_ARRAYOF              = UCONST64(1) << 28;
+const DecoratorSet ARRAYCOPY_ATOMIC               = UCONST64(1) << 29;
+const DecoratorSet ARRAYCOPY_ALIGNED              = UCONST64(1) << 30;
 const DecoratorSet ARRAYCOPY_DECORATOR_MASK       = ARRAYCOPY_CHECKCAST | ARRAYCOPY_DISJOINT |
                                                     ARRAYCOPY_DISJOINT | ARRAYCOPY_ARRAYOF |
                                                     ARRAYCOPY_ATOMIC | ARRAYCOPY_ALIGNED;
@@ -297,6 +301,9 @@
   template <DecoratorSet decorators>
   void clone(oop src, oop dst, size_t size);
 
+  template <DecoratorSet decorators>
+  oop resolve(oop src);
+
   // Infer the type that should be returned from a load.
   template <typename P, DecoratorSet decorators>
   class LoadProxy: public StackObj {
@@ -500,6 +507,11 @@
     OopType new_oop_value = new_value;
     return AccessInternal::atomic_xchg<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, addr);
   }
+
+  static oop resolve(oop obj) {
+    verify_decorators<INTERNAL_EMPTY>();
+    return AccessInternal::resolve<decorators>(obj);
+  }
 };
 
 // Helper for performing raw accesses (knows only of memory ordering
--- a/src/hotspot/share/oops/access.inline.hpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/oops/access.inline.hpp	Thu Feb 22 10:39:42 2018 +0100
@@ -206,6 +206,13 @@
     }
   };
 
+  template <class GCBarrierType, DecoratorSet decorators>
+  struct PostRuntimeDispatch<GCBarrierType, BARRIER_RESOLVE, decorators>: public AllStatic {
+    static oop access_barrier(oop obj) {
+      return GCBarrierType::resolve(obj);
+    }
+  };
+
   // Resolving accessors with barriers from the barrier set happens in two steps.
   // 1. Expand paths with runtime-decorators, e.g. is UseCompressedOops on or off.
   // 2. Expand paths for each BarrierSet available in the system.
@@ -443,6 +450,22 @@
     }
   };
 
+  template <DecoratorSet decorators, typename T>
+  struct RuntimeDispatch<decorators, T, BARRIER_RESOLVE>: AllStatic {
+    typedef typename AccessFunction<decorators, T, BARRIER_RESOLVE>::type func_t;
+    static func_t _resolve_func;
+
+    static oop resolve_init(oop obj) {
+      func_t function = BarrierResolver<decorators, func_t, BARRIER_RESOLVE>::resolve_barrier();
+      _resolve_func = function;
+      return function(obj);
+    }
+
+    static inline oop resolve(oop obj) {
+      return _resolve_func(obj);
+    }
+  };
+
   // Initialize the function pointers to point to the resolving function.
   template <DecoratorSet decorators, typename T>
   typename AccessFunction<decorators, T, BARRIER_STORE>::type
@@ -484,6 +507,10 @@
   typename AccessFunction<decorators, T, BARRIER_CLONE>::type
   RuntimeDispatch<decorators, T, BARRIER_CLONE>::_clone_func = &clone_init;
 
+  template <DecoratorSet decorators, typename T>
+  typename AccessFunction<decorators, T, BARRIER_RESOLVE>::type
+  RuntimeDispatch<decorators, T, BARRIER_RESOLVE>::_resolve_func = &resolve_init;
+
   // Step 3: Pre-runtime dispatching.
   // The PreRuntimeDispatch class is responsible for filtering the barrier strength
   // decorators. That is, for AS_RAW, it hardwires the accesses without a runtime
@@ -766,6 +793,21 @@
     clone(oop src, oop dst, size_t size) {
       RuntimeDispatch<decorators, oop, BARRIER_CLONE>::clone(src, dst, size);
     }
+
+    template <DecoratorSet decorators>
+    inline static typename EnableIf<
+      HasDecorator<decorators, INTERNAL_BT_TO_SPACE_INVARIANT>::value, oop>::type
+    resolve(oop obj) {
+      typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw;
+      return Raw::resolve(obj);
+    }
+
+    template <DecoratorSet decorators>
+    inline static typename EnableIf<
+      !HasDecorator<decorators, INTERNAL_BT_TO_SPACE_INVARIANT>::value, oop>::type
+    resolve(oop obj) {
+      return RuntimeDispatch<decorators, oop, BARRIER_RESOLVE>::resolve(obj);
+    }
   };
 
   // This class adds implied decorators that follow according to decorator rules.
@@ -1051,6 +1093,12 @@
     const DecoratorSet expanded_decorators = DecoratorFixup<decorators>::value;
     PreRuntimeDispatch::clone<expanded_decorators>(src, dst, size);
   }
+
+  template <DecoratorSet decorators>
+  inline oop resolve(oop obj) {
+    const DecoratorSet expanded_decorators = DecoratorFixup<decorators>::value;
+    return PreRuntimeDispatch::resolve<expanded_decorators>(obj);
+  }
 }
 
 template <DecoratorSet decorators>
--- a/src/hotspot/share/oops/accessBackend.hpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/oops/accessBackend.hpp	Thu Feb 22 10:39:42 2018 +0100
@@ -52,7 +52,8 @@
     BARRIER_ATOMIC_XCHG,
     BARRIER_ATOMIC_XCHG_AT,
     BARRIER_ARRAYCOPY,
-    BARRIER_CLONE
+    BARRIER_CLONE,
+    BARRIER_RESOLVE
   };
 
   template <DecoratorSet decorators, typename T>
@@ -100,6 +101,7 @@
 
     typedef bool (*arraycopy_func_t)(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length);
     typedef void (*clone_func_t)(oop src, oop dst, size_t size);
+    typedef oop (*resolve_func_t)(oop obj);
   };
 
   template <DecoratorSet decorators, typename T, BarrierType barrier> struct AccessFunction {};
@@ -119,6 +121,7 @@
   ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_ATOMIC_XCHG_AT, atomic_xchg_at_func_t);
   ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_ARRAYCOPY, arraycopy_func_t);
   ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_CLONE, clone_func_t);
+  ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_RESOLVE, resolve_func_t);
 #undef ACCESS_GENERATE_ACCESS_FUNCTION
 
   template <DecoratorSet decorators, typename T, BarrierType barrier_type>
@@ -379,6 +382,8 @@
   static bool oop_arraycopy(arrayOop src_obj, arrayOop dst_obj, HeapWord* src, HeapWord* dst, size_t length);
 
   static void clone(oop src, oop dst, size_t size);
+
+  static oop resolve(oop obj) { return obj; }
 };
 
 #endif // SHARE_VM_RUNTIME_ACCESSBACKEND_HPP
--- a/src/hotspot/share/oops/arrayOop.hpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/oops/arrayOop.hpp	Thu Feb 22 10:39:42 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, 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
@@ -76,10 +76,10 @@
     return header_size(type) * HeapWordSize;
   }
 
-  // Returns the address of the first element.
-  void* base(BasicType type) const {
-    return (void*) (((intptr_t) this) + base_offset_in_bytes(type));
-  }
+  // Returns the address of the first element. The elements in the array will not
+  // relocate from this address until a subsequent thread transition.
+  inline void* base(BasicType type) const;
+  inline void* base_raw(BasicType type) const; // GC barrier invariant
 
   // Tells whether index is within bounds.
   bool is_within_bounds(int index) const        { return 0 <= index && index < length(); }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/oops/arrayOop.inline.hpp	Thu Feb 22 10:39:42 2018 +0100
@@ -0,0 +1,40 @@
+/*
+ * 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_OOPS_ARRAYOOP_INLINE_HPP
+#define SHARE_OOPS_ARRAYOOP_INLINE_HPP
+
+#include "oops/access.inline.hpp"
+#include "oops/arrayOop.hpp"
+
+void* arrayOopDesc::base(BasicType type) const {
+  oop resolved_obj = Access<>::resolve(as_oop());
+  return arrayOop(resolved_obj)->base_raw(type);
+}
+
+void* arrayOopDesc::base_raw(BasicType type) const {
+  return reinterpret_cast<void*>(cast_from_oop<intptr_t>(as_oop()) + base_offset_in_bytes(type));
+}
+
+#endif // SHARE_OOPS_ARRAYOOP_INLINE_HPP
--- a/src/hotspot/share/oops/constantPool.hpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/oops/constantPool.hpp	Thu Feb 22 10:39:42 2018 +0100
@@ -147,7 +147,7 @@
     assert(is_within_bounds(which), "index out of bounds");
     assert(!tag_at(which).is_unresolved_klass() && !tag_at(which).is_unresolved_klass_in_error(), "Corrupted constant pool");
     // Uses volatile because the klass slot changes without a lock.
-    intptr_t adr = OrderAccess::load_acquire(obj_at_addr_raw(which));
+    intptr_t adr = OrderAccess::load_acquire(obj_at_addr(which));
     assert(adr != 0 || which == 0, "cp entry for klass should not be zero");
     return CPSlot(adr);
   }
@@ -157,7 +157,7 @@
     assert(s.value() != 0, "Caught something");
     *(intptr_t*)&base()[which] = s.value();
   }
-  intptr_t* obj_at_addr_raw(int which) const {
+  intptr_t* obj_at_addr(int which) const {
     assert(is_within_bounds(which), "index out of bounds");
     return (intptr_t*) &base()[which];
   }
--- a/src/hotspot/share/oops/instanceKlass.inline.hpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/oops/instanceKlass.inline.hpp	Thu Feb 22 10:39:42 2018 +0100
@@ -56,7 +56,7 @@
 
 template <bool nv, typename T, class OopClosureType>
 ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_map(OopMapBlock* map, oop obj, OopClosureType* closure) {
-  T* p         = (T*)obj->obj_field_addr<T>(map->offset());
+  T* p         = (T*)obj->obj_field_addr_raw<T>(map->offset());
   T* const end = p + map->count();
 
   for (; p < end; ++p) {
@@ -67,7 +67,7 @@
 #if INCLUDE_ALL_GCS
 template <bool nv, typename T, class OopClosureType>
 ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_map_reverse(OopMapBlock* map, oop obj, OopClosureType* closure) {
-  T* const start = (T*)obj->obj_field_addr<T>(map->offset());
+  T* const start = (T*)obj->obj_field_addr_raw<T>(map->offset());
   T*       p     = start + map->count();
 
   while (start < p) {
@@ -79,7 +79,7 @@
 
 template <bool nv, typename T, class OopClosureType>
 ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_map_bounded(OopMapBlock* map, oop obj, OopClosureType* closure, MemRegion mr) {
-  T* p   = (T*)obj->obj_field_addr<T>(map->offset());
+  T* p   = (T*)obj->obj_field_addr_raw<T>(map->offset());
   T* end = p + map->count();
 
   T* const l   = (T*)mr.start();
--- a/src/hotspot/share/oops/instanceRefKlass.inline.hpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/oops/instanceRefKlass.inline.hpp	Thu Feb 22 10:39:42 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -37,7 +37,7 @@
 
 template <bool nv, typename T, class OopClosureType, class Contains>
 void InstanceRefKlass::do_referent(oop obj, OopClosureType* closure, Contains& contains) {
-  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr_raw(obj);
   if (contains(referent_addr)) {
     Devirtualizer<nv>::do_oop(closure, referent_addr);
   }
@@ -45,7 +45,7 @@
 
 template <bool nv, typename T, class OopClosureType, class Contains>
 void InstanceRefKlass::do_next(oop obj, OopClosureType* closure, Contains& contains) {
-  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+  T* next_addr = (T*)java_lang_ref_Reference::next_addr_raw(obj);
   if (contains(next_addr)) {
     Devirtualizer<nv>::do_oop(closure, next_addr);
   }
@@ -53,7 +53,7 @@
 
 template <bool nv, typename T, class OopClosureType, class Contains>
 void InstanceRefKlass::do_discovered(oop obj, OopClosureType* closure, Contains& contains) {
-  T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+  T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr_raw(obj);
   if (contains(discovered_addr)) {
     Devirtualizer<nv>::do_oop(closure, discovered_addr);
   }
@@ -63,7 +63,7 @@
 bool InstanceRefKlass::try_discover(oop obj, ReferenceType type, OopClosureType* closure) {
   ReferenceProcessor* rp = closure->ref_processor();
   if (rp != NULL) {
-    T referent_oop = oopDesc::load_heap_oop((T*)java_lang_ref_Reference::referent_addr(obj));
+    T referent_oop = oopDesc::load_heap_oop((T*)java_lang_ref_Reference::referent_addr_raw(obj));
     if (!oopDesc::is_null(referent_oop)) {
       oop referent = oopDesc::decode_heap_oop_not_null(referent_oop);
       if (!referent->is_gc_marked()) {
@@ -86,7 +86,7 @@
   do_referent<nv, T>(obj, closure, contains);
 
   // Treat discovered as normal oop, if ref is not "active" (next non-NULL).
-  T next_oop  = oopDesc::load_heap_oop((T*)java_lang_ref_Reference::next_addr(obj));
+  T next_oop  = oopDesc::load_heap_oop((T*)java_lang_ref_Reference::next_addr_raw(obj));
   if (!oopDesc::is_null(next_oop)) {
     do_discovered<nv, T>(obj, closure, contains);
   }
@@ -189,9 +189,9 @@
 #ifdef ASSERT
 template <typename T>
 void InstanceRefKlass::trace_reference_gc(const char *s, oop obj) {
-  T* referent_addr   = (T*) java_lang_ref_Reference::referent_addr(obj);
-  T* next_addr       = (T*) java_lang_ref_Reference::next_addr(obj);
-  T* discovered_addr = (T*) java_lang_ref_Reference::discovered_addr(obj);
+  T* referent_addr   = (T*) java_lang_ref_Reference::referent_addr_raw(obj);
+  T* next_addr       = (T*) java_lang_ref_Reference::next_addr_raw(obj);
+  T* discovered_addr = (T*) java_lang_ref_Reference::discovered_addr_raw(obj);
 
   log_develop_trace(gc, ref)("InstanceRefKlass %s for obj " PTR_FORMAT, s, p2i(obj));
   log_develop_trace(gc, ref)("     referent_addr/* " PTR_FORMAT " / " PTR_FORMAT,
--- a/src/hotspot/share/oops/objArrayKlass.inline.hpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/oops/objArrayKlass.inline.hpp	Thu Feb 22 10:39:42 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -27,6 +27,7 @@
 
 #include "memory/memRegion.hpp"
 #include "memory/iterator.inline.hpp"
+#include "oops/arrayOop.inline.hpp"
 #include "oops/arrayKlass.hpp"
 #include "oops/klass.hpp"
 #include "oops/objArrayKlass.hpp"
@@ -110,7 +111,7 @@
 
 template <bool nv, typename T, class OopClosureType>
 void ObjArrayKlass::oop_oop_iterate_range_specialized(objArrayOop a, OopClosureType* closure, int start, int end) {
-  T* low = start == 0 ? cast_from_oop<T*>(a) : a->obj_at_addr<T>(start);
+  T* low = start == 0 ? cast_from_oop<T*>(a) : a->obj_at_addr_raw<T>(start);
   T* high = (T*)a->base() + end;
 
   oop_oop_iterate_elements_specialized_bounded<nv, T>(a, closure, low, high);
--- a/src/hotspot/share/oops/objArrayOop.cpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/oops/objArrayOop.cpp	Thu Feb 22 10:39:42 2018 +0100
@@ -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
@@ -26,7 +26,7 @@
 #include "gc/shared/specialized_oop_closures.hpp"
 #include "oops/access.inline.hpp"
 #include "oops/objArrayKlass.hpp"
-#include "oops/objArrayOop.hpp"
+#include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 
 oop objArrayOopDesc::atomic_compare_exchange_oop(int index, oop exchange_value,
--- a/src/hotspot/share/oops/objArrayOop.hpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/oops/objArrayOop.hpp	Thu Feb 22 10:39:42 2018 +0100
@@ -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
@@ -41,10 +41,8 @@
   friend class CSetMarkOopClosure;
   friend class G1ParScanPartialArrayClosure;
 
-  template <class T> T* obj_at_addr(int index) const {
-    assert(is_within_bounds(index), "index out of bounds");
-    return &((T*)base())[index];
-  }
+  template <class T> T* obj_at_addr(int index) const;
+  template <class T> T* obj_at_addr_raw(int index) const;
 
   template <class T>
   static ptrdiff_t obj_at_offset(int index) {
@@ -84,7 +82,8 @@
   }
 
   // base is the address following the header.
-  HeapWord* base() const      { return (HeapWord*) arrayOopDesc::base(T_OBJECT); }
+  HeapWord* base() const;
+  HeapWord* base_raw() const;
 
   // Accessing
   oop obj_at(int index) const;
--- a/src/hotspot/share/oops/objArrayOop.inline.hpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/oops/objArrayOop.inline.hpp	Thu Feb 22 10:39:42 2018 +0100
@@ -26,10 +26,24 @@
 #define SHARE_VM_OOPS_OBJARRAYOOP_INLINE_HPP
 
 #include "oops/access.inline.hpp"
+#include "oops/arrayOop.inline.hpp"
 #include "oops/objArrayOop.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/globals.hpp"
 
+inline HeapWord* objArrayOopDesc::base() const { return (HeapWord*) arrayOopDesc::base(T_OBJECT); }
+inline HeapWord* objArrayOopDesc::base_raw() const { return (HeapWord*) arrayOopDesc::base_raw(T_OBJECT); }
+
+template <class T> T* objArrayOopDesc::obj_at_addr(int index) const {
+  assert(is_within_bounds(index), "index out of bounds");
+  return &((T*)base())[index];
+}
+
+template <class T> T* objArrayOopDesc::obj_at_addr_raw(int index) const {
+  assert(is_within_bounds(index), "index out of bounds");
+  return &((T*)base_raw())[index];
+}
+
 inline oop objArrayOopDesc::obj_at(int index) const {
   ptrdiff_t offset = UseCompressedOops ? obj_at_offset<narrowOop>(index) : obj_at_offset<oop>(index);
   return HeapAccess<IN_HEAP_ARRAY>::oop_load_at(as_oop(), offset);
--- a/src/hotspot/share/oops/oop.hpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/oops/oop.hpp	Thu Feb 22 10:39:42 2018 +0100
@@ -119,26 +119,13 @@
  protected:
   inline oop        as_oop() const { return const_cast<oopDesc*>(this); }
 
- private:
+ public:
   // field addresses in oop
-  inline void*      field_base(int offset)          const;
+  inline void* field_addr(int offset)     const;
+  inline void* field_addr_raw(int offset) const;
 
-  inline jbyte*     byte_field_addr(int offset)     const;
-  inline jchar*     char_field_addr(int offset)     const;
-  inline jboolean*  bool_field_addr(int offset)     const;
-  inline jint*      int_field_addr(int offset)      const;
-  inline jshort*    short_field_addr(int offset)    const;
-  inline jlong*     long_field_addr(int offset)     const;
-  inline jfloat*    float_field_addr(int offset)    const;
-  inline jdouble*   double_field_addr(int offset)   const;
-  inline Metadata** metadata_field_addr(int offset) const;
-
- public:
   // Need this as public for garbage collection.
-  template <class T> inline T* obj_field_addr(int offset) const;
-
-  // Needed for javaClasses
-  inline address* address_field_addr(int offset) const;
+  template <class T> inline T* obj_field_addr_raw(int offset) const;
 
   inline static bool is_null(oop obj)       { return obj == NULL; }
   inline static bool is_null(narrowOop obj) { return obj == 0; }
--- a/src/hotspot/share/oops/oop.inline.hpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/oops/oop.inline.hpp	Thu Feb 22 10:39:42 2018 +0100
@@ -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
@@ -233,21 +233,11 @@
 bool oopDesc::is_objArray()  const { return klass()->is_objArray_klass();  }
 bool oopDesc::is_typeArray() const { return klass()->is_typeArray_klass(); }
 
-void*      oopDesc::field_base(int offset)          const { return (void*)&((char*)this)[offset]; }
+void*    oopDesc::field_addr_raw(int offset)     const { return reinterpret_cast<void*>(cast_from_oop<intptr_t>(as_oop()) + offset); }
+void*    oopDesc::field_addr(int offset)         const { return Access<>::resolve(as_oop())->field_addr_raw(offset); }
 
-jbyte*     oopDesc::byte_field_addr(int offset)     const { return (jbyte*)    field_base(offset); }
-jchar*     oopDesc::char_field_addr(int offset)     const { return (jchar*)    field_base(offset); }
-jboolean*  oopDesc::bool_field_addr(int offset)     const { return (jboolean*) field_base(offset); }
-jint*      oopDesc::int_field_addr(int offset)      const { return (jint*)     field_base(offset); }
-jshort*    oopDesc::short_field_addr(int offset)    const { return (jshort*)   field_base(offset); }
-jlong*     oopDesc::long_field_addr(int offset)     const { return (jlong*)    field_base(offset); }
-jfloat*    oopDesc::float_field_addr(int offset)    const { return (jfloat*)   field_base(offset); }
-jdouble*   oopDesc::double_field_addr(int offset)   const { return (jdouble*)  field_base(offset); }
-Metadata** oopDesc::metadata_field_addr(int offset) const { return (Metadata**)field_base(offset); }
-
-template <class T> T* oopDesc::obj_field_addr(int offset) const { return (T*)  field_base(offset); }
-address*   oopDesc::address_field_addr(int offset)  const { return (address*)  field_base(offset); }
-
+template <class T>
+T*       oopDesc::obj_field_addr_raw(int offset) const { return (T*) field_addr_raw(offset); }
 
 // Functions for getting and setting oops within instance objects.
 // If the oops are compressed, the type passed to these overloaded functions
--- a/src/hotspot/share/oops/typeArrayOop.hpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/oops/typeArrayOop.hpp	Thu Feb 22 10:39:42 2018 +0100
@@ -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
@@ -41,62 +41,27 @@
   }
 
  protected:
-  jchar*    char_base()   const { return (jchar*)   base(T_CHAR); }
-  jboolean* bool_base()   const { return (jboolean*)base(T_BOOLEAN); }
-  jbyte*    byte_base()   const { return (jbyte*)   base(T_BYTE); }
-  jint*     int_base()    const { return (jint*)    base(T_INT); }
-  jlong*    long_base()   const { return (jlong*)   base(T_LONG); }
-  jshort*   short_base()  const { return (jshort*)  base(T_SHORT); }
-  jfloat*   float_base()  const { return (jfloat*)  base(T_FLOAT); }
-  jdouble*  double_base() const { return (jdouble*) base(T_DOUBLE); }
+  jchar*    char_base()   const;
+  jboolean* bool_base()   const;
+  jbyte*    byte_base()   const;
+  jint*     int_base()    const;
+  jlong*    long_base()   const;
+  jshort*   short_base()  const;
+  jfloat*   float_base()  const;
+  jdouble*  double_base() const;
 
   friend class TypeArrayKlass;
 
  public:
-  jbyte* byte_at_addr(int which) const {
-    assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
-    return &byte_base()[which];
-  }
-
-  jboolean* bool_at_addr(int which) const {
-    assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
-    return &bool_base()[which];
-  }
-
-  jchar* char_at_addr(int which) const {
-    assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
-    return &char_base()[which];
-  }
-
-  jint* int_at_addr(int which) const {
-    assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
-    return &int_base()[which];
-  }
-
-  jshort* short_at_addr(int which) const {
-    assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
-    return &short_base()[which];
-  }
-
-  jushort* ushort_at_addr(int which) const {  // for field descriptor arrays
-    assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
-    return (jushort*) &short_base()[which];
-  }
-
-  jlong* long_at_addr(int which) const {
-    assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
-    return &long_base()[which];
-  }
-
-  jfloat* float_at_addr(int which) const {
-    assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
-    return &float_base()[which];
-  }
-
-  jdouble* double_at_addr(int which) const {
-    assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
-    return &double_base()[which];
-  }
+  jbyte* byte_at_addr(int which) const;
+  jboolean* bool_at_addr(int which) const;
+  jchar* char_at_addr(int which) const;
+  jint* int_at_addr(int which) const;
+  jshort* short_at_addr(int which) const;
+  jushort* ushort_at_addr(int which) const;
+  jlong* long_at_addr(int which) const;
+  jfloat* float_at_addr(int which) const;
+  jdouble* double_at_addr(int which) const;
 
   jbyte byte_at(int which) const;
   void byte_at_put(int which, jbyte contents);
--- a/src/hotspot/share/oops/typeArrayOop.inline.hpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/oops/typeArrayOop.inline.hpp	Thu Feb 22 10:39:42 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, 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
@@ -27,6 +27,7 @@
 
 #include "oops/access.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/arrayOop.inline.hpp"
 #include "oops/typeArrayOop.hpp"
 
 int typeArrayOopDesc::object_size() {
@@ -34,6 +35,60 @@
   return object_size(tk->layout_helper(), length());
 }
 
+inline jchar*    typeArrayOopDesc::char_base()   const { return (jchar*)   base(T_CHAR); }
+inline jboolean* typeArrayOopDesc::bool_base()   const { return (jboolean*)base(T_BOOLEAN); }
+inline jbyte*    typeArrayOopDesc::byte_base()   const { return (jbyte*)   base(T_BYTE); }
+inline jint*     typeArrayOopDesc::int_base()    const { return (jint*)    base(T_INT); }
+inline jlong*    typeArrayOopDesc::long_base()   const { return (jlong*)   base(T_LONG); }
+inline jshort*   typeArrayOopDesc::short_base()  const { return (jshort*)  base(T_SHORT); }
+inline jfloat*   typeArrayOopDesc::float_base()  const { return (jfloat*)  base(T_FLOAT); }
+inline jdouble*  typeArrayOopDesc::double_base() const { return (jdouble*) base(T_DOUBLE); }
+
+inline jbyte* typeArrayOopDesc::byte_at_addr(int which) const {
+  assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+  return &byte_base()[which];
+}
+
+inline jboolean* typeArrayOopDesc::bool_at_addr(int which) const {
+  assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+  return &bool_base()[which];
+}
+
+inline jchar* typeArrayOopDesc::char_at_addr(int which) const {
+  assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+  return &char_base()[which];
+}
+
+inline jint* typeArrayOopDesc::int_at_addr(int which) const {
+  assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+  return &int_base()[which];
+}
+
+inline jshort* typeArrayOopDesc::short_at_addr(int which) const {
+  assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+  return &short_base()[which];
+}
+
+inline jushort* typeArrayOopDesc::ushort_at_addr(int which) const {  // for field descriptor arrays
+  assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+  return (jushort*) &short_base()[which];
+}
+
+inline jlong* typeArrayOopDesc::long_at_addr(int which) const {
+  assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+  return &long_base()[which];
+}
+
+inline jfloat* typeArrayOopDesc::float_at_addr(int which) const {
+  assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+  return &float_base()[which];
+}
+
+inline jdouble* typeArrayOopDesc::double_at_addr(int which) const {
+  assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+  return &double_base()[which];
+}
+
 inline jbyte typeArrayOopDesc::byte_at(int which) const {
   ptrdiff_t offset = element_offset<jbyte>(T_BYTE, which);
   return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
--- a/src/hotspot/share/opto/library_call.cpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/opto/library_call.cpp	Thu Feb 22 10:39:42 2018 +0100
@@ -2408,7 +2408,7 @@
   offset = argument(2);  // type: long
   // We currently rely on the cookies produced by Unsafe.xxxFieldOffset
   // to be plain byte offsets, which are also the same as those accepted
-  // by oopDesc::field_base.
+  // by oopDesc::field_addr.
   assert(Unsafe_field_offset_to_byte_offset(11) == 11,
          "fieldOffset must be byte-scaled");
   // 32-bit machines ignore the high half!
@@ -2838,7 +2838,7 @@
   // Build field offset expression.
   // We currently rely on the cookies produced by Unsafe.xxxFieldOffset
   // to be plain byte offsets, which are also the same as those accepted
-  // by oopDesc::field_base.
+  // by oopDesc::field_addr.
   assert(Unsafe_field_offset_to_byte_offset(11) == 11, "fieldOffset must be byte-scaled");
   // 32-bit machines ignore the high half of long offsets
   offset = ConvL2X(offset);
--- a/src/hotspot/share/prims/jni.cpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/prims/jni.cpp	Thu Feb 22 10:39:42 2018 +0100
@@ -44,6 +44,7 @@
 #include "memory/resourceArea.hpp"
 #include "memory/universe.inline.hpp"
 #include "oops/access.inline.hpp"
+#include "oops/arrayOop.inline.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/instanceOop.hpp"
 #include "oops/markOop.hpp"
--- a/src/hotspot/share/prims/jvmtiTagMap.cpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/prims/jvmtiTagMap.cpp	Thu Feb 22 10:39:42 2018 +0100
@@ -31,6 +31,7 @@
 #include "jvmtifiles/jvmtiEnv.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/access.inline.hpp"
+#include "oops/arrayOop.inline.hpp"
 #include "oops/instanceMirrorKlass.hpp"
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.inline.hpp"
--- a/src/hotspot/share/prims/unsafe.cpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/prims/unsafe.cpp	Thu Feb 22 10:39:42 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -109,8 +109,8 @@
     assert(byte_offset >= 0 && byte_offset <= (jlong)MAX_OBJECT_SIZE, "sane offset");
     if (byte_offset == (jint)byte_offset) {
       void* ptr_plus_disp = (address)p + byte_offset;
-      assert((void*)p->obj_field_addr<oop>((jint)byte_offset) == ptr_plus_disp,
-             "raw [ptr+disp] must be consistent with oop::field_base");
+      assert(p->field_addr_raw((jint)byte_offset) == ptr_plus_disp,
+             "raw [ptr+disp] must be consistent with oop::field_addr_raw");
     }
     jlong p_size = HeapWordSize * (jlong)(p->size());
     assert(byte_offset < p_size, "Unsafe access: offset " INT64_FORMAT " > object's size " INT64_FORMAT, (int64_t)byte_offset, (int64_t)p_size);
--- a/src/hotspot/share/services/attachListener.cpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/services/attachListener.cpp	Thu Feb 22 10:39:42 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -28,6 +28,7 @@
 #include "gc/shared/vmGCOperations.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/globals.hpp"
--- a/src/hotspot/share/services/diagnosticCommand.cpp	Wed Feb 21 23:30:01 2018 -0500
+++ b/src/hotspot/share/services/diagnosticCommand.cpp	Thu Feb 22 10:39:42 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -31,6 +31,7 @@
 #include "gc/shared/vmGCOperations.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/os.hpp"