8206457: Code paths from oop_iterate() must use barrier-free access
authorrkennke
Fri, 06 Jul 2018 16:04:19 +0200
changeset 51516 7c3891b9f1e0
parent 51515 fa378e035b81
child 51517 edcf0d527658
8206457: Code paths from oop_iterate() must use barrier-free access Reviewed-by: eosterlund, shade
src/hotspot/share/classfile/javaClasses.cpp
src/hotspot/share/classfile/javaClasses.hpp
src/hotspot/share/oops/instanceClassLoaderKlass.inline.hpp
src/hotspot/share/oops/instanceMirrorKlass.cpp
src/hotspot/share/oops/instanceMirrorKlass.inline.hpp
src/hotspot/share/oops/instanceRefKlass.inline.hpp
src/hotspot/share/oops/oop.cpp
src/hotspot/share/oops/oop.hpp
src/hotspot/share/oops/oop.inline.hpp
--- a/src/hotspot/share/classfile/javaClasses.cpp	Fri Aug 24 09:38:11 2018 +0200
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Fri Jul 06 16:04:19 2018 +0200
@@ -1271,6 +1271,13 @@
   return size;
 }
 
+int  java_lang_Class::oop_size_raw(oop java_class) {
+  assert(_oop_size_offset != 0, "must be set");
+  int size = java_class->int_field_raw(_oop_size_offset);
+  assert(size > 0, "Oop size must be greater than zero, not %d", size);
+  return size;
+}
+
 void java_lang_Class::set_oop_size(HeapWord* java_class, int size) {
   assert(_oop_size_offset != 0, "must be set");
   assert(size > 0, "Oop size must be greater than zero, not %d", size);
@@ -1281,6 +1288,12 @@
   assert(_static_oop_field_count_offset != 0, "must be set");
   return java_class->int_field(_static_oop_field_count_offset);
 }
+
+int  java_lang_Class::static_oop_field_count_raw(oop java_class) {
+  assert(_static_oop_field_count_offset != 0, "must be set");
+  return java_class->int_field_raw(_static_oop_field_count_offset);
+}
+
 void java_lang_Class::set_static_oop_field_count(oop java_class, int size) {
   assert(_static_oop_field_count_offset != 0, "must be set");
   java_class->int_field_put(_static_oop_field_count_offset, size);
@@ -1370,6 +1383,14 @@
   return k;
 }
 
+Klass* java_lang_Class::as_Klass_raw(oop java_class) {
+  //%note memory_2
+  assert(java_lang_Class::is_instance(java_class), "must be a Class object");
+  Klass* k = ((Klass*)java_class->metadata_field_raw(_klass_offset));
+  assert(k == NULL || k->is_klass(), "type check");
+  return k;
+}
+
 
 void java_lang_Class::set_klass(oop java_class, Klass* klass) {
   assert(java_lang_Class::is_instance(java_class), "must be a Class object");
@@ -4007,6 +4028,11 @@
   return HeapAccess<>::load_at(loader, _loader_data_offset);
 }
 
+ClassLoaderData* java_lang_ClassLoader::loader_data_raw(oop loader) {
+  assert(loader != NULL && oopDesc::is_oop(loader), "loader must be oop");
+  return RawAccess<>::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);
--- a/src/hotspot/share/classfile/javaClasses.hpp	Fri Aug 24 09:38:11 2018 +0200
+++ b/src/hotspot/share/classfile/javaClasses.hpp	Fri Jul 06 16:04:19 2018 +0200
@@ -277,6 +277,7 @@
 
   // Conversion
   static Klass* as_Klass(oop java_class);
+  static Klass* as_Klass_raw(oop java_class);
   static void set_klass(oop java_class, Klass* klass);
   static BasicType as_BasicType(oop java_class, Klass** reference_klass = NULL);
   static Symbol* as_signature(oop java_class, bool intern_if_not_found, TRAPS);
@@ -310,8 +311,10 @@
   static oop module(oop java_class);
 
   static int oop_size(oop java_class);
+  static int oop_size_raw(oop java_class);
   static void set_oop_size(HeapWord* java_class, int size);
   static int static_oop_field_count(oop java_class);
+  static int static_oop_field_count_raw(oop java_class);
   static void set_static_oop_field_count(oop java_class, int size);
 
   static GrowableArray<Klass*>* fixup_mirror_list() {
@@ -1320,6 +1323,7 @@
   static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
 
   static ClassLoaderData* loader_data(oop loader);
+  static ClassLoaderData* loader_data_raw(oop loader);
   static ClassLoaderData* cmpxchg_loader_data(ClassLoaderData* new_data, oop loader, ClassLoaderData* expected_data);
 
   static oop parent(oop loader);
--- a/src/hotspot/share/oops/instanceClassLoaderKlass.inline.hpp	Fri Aug 24 09:38:11 2018 +0200
+++ b/src/hotspot/share/oops/instanceClassLoaderKlass.inline.hpp	Fri Jul 06 16:04:19 2018 +0200
@@ -39,7 +39,7 @@
   InstanceKlass::oop_oop_iterate<T>(obj, closure);
 
   if (Devirtualizer::do_metadata(closure)) {
-    ClassLoaderData* cld = java_lang_ClassLoader::loader_data(obj);
+    ClassLoaderData* cld = java_lang_ClassLoader::loader_data_raw(obj);
     // cld can be null if we have a non-registered class loader.
     if (cld != NULL) {
       Devirtualizer::do_cld(closure, cld);
@@ -61,7 +61,7 @@
 
   if (Devirtualizer::do_metadata(closure)) {
     if (mr.contains(obj)) {
-      ClassLoaderData* cld = java_lang_ClassLoader::loader_data(obj);
+      ClassLoaderData* cld = java_lang_ClassLoader::loader_data_raw(obj);
       // cld can be null if we have a non-registered class loader.
       if (cld != NULL) {
         Devirtualizer::do_cld(closure, cld);
--- a/src/hotspot/share/oops/instanceMirrorKlass.cpp	Fri Aug 24 09:38:11 2018 +0200
+++ b/src/hotspot/share/oops/instanceMirrorKlass.cpp	Fri Jul 06 16:04:19 2018 +0200
@@ -56,7 +56,7 @@
 }
 
 int InstanceMirrorKlass::oop_size(oop obj) const {
-  return java_lang_Class::oop_size(obj);
+  return java_lang_Class::oop_size_raw(obj);
 }
 
 int InstanceMirrorKlass::compute_static_oop_field_count(oop obj) {
--- a/src/hotspot/share/oops/instanceMirrorKlass.inline.hpp	Fri Aug 24 09:38:11 2018 +0200
+++ b/src/hotspot/share/oops/instanceMirrorKlass.inline.hpp	Fri Jul 06 16:04:19 2018 +0200
@@ -36,7 +36,7 @@
 template <typename T, class OopClosureType>
 void InstanceMirrorKlass::oop_oop_iterate_statics(oop obj, OopClosureType* closure) {
   T* p         = (T*)start_of_static_fields(obj);
-  T* const end = p + java_lang_Class::static_oop_field_count(obj);
+  T* const end = p + java_lang_Class::static_oop_field_count_raw(obj);
 
   for (; p < end; ++p) {
     Devirtualizer::do_oop(closure, p);
@@ -48,7 +48,7 @@
   InstanceKlass::oop_oop_iterate<T>(obj, closure);
 
   if (Devirtualizer::do_metadata(closure)) {
-    Klass* klass = java_lang_Class::as_Klass(obj);
+    Klass* klass = java_lang_Class::as_Klass_raw(obj);
     // We'll get NULL for primitive mirrors.
     if (klass != NULL) {
       if (klass->is_instance_klass() &&
@@ -90,7 +90,7 @@
                                                           OopClosureType* closure,
                                                           MemRegion mr) {
   T* p   = (T*)start_of_static_fields(obj);
-  T* end = p + java_lang_Class::static_oop_field_count(obj);
+  T* end = p + java_lang_Class::static_oop_field_count_raw(obj);
 
   T* const l   = (T*)mr.start();
   T* const h   = (T*)mr.end();
@@ -116,7 +116,7 @@
 
   if (Devirtualizer::do_metadata(closure)) {
     if (mr.contains(obj)) {
-      Klass* klass = java_lang_Class::as_Klass(obj);
+      Klass* klass = java_lang_Class::as_Klass_raw(obj);
       // We'll get NULL for primitive mirrors.
       if (klass != NULL) {
         Devirtualizer::do_klass(closure, klass);
--- a/src/hotspot/share/oops/instanceRefKlass.inline.hpp	Fri Aug 24 09:38:11 2018 +0200
+++ b/src/hotspot/share/oops/instanceRefKlass.inline.hpp	Fri Jul 06 16:04:19 2018 +0200
@@ -183,8 +183,13 @@
   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,
-      p2i(referent_addr), p2i((oop)HeapAccess<ON_UNKNOWN_OOP_REF | AS_NO_KEEPALIVE>::oop_load_at(obj, java_lang_ref_Reference::referent_offset)));
+  if (java_lang_ref_Reference::is_phantom(obj)) {
+    log_develop_trace(gc, ref)("     referent_addr/* " PTR_FORMAT " / " PTR_FORMAT,
+                               p2i(referent_addr), p2i((oop)HeapAccess<ON_PHANTOM_OOP_REF | AS_NO_KEEPALIVE>::oop_load(referent_addr)));
+  } else {
+    log_develop_trace(gc, ref)("     referent_addr/* " PTR_FORMAT " / " PTR_FORMAT,
+                               p2i(referent_addr), p2i((oop)HeapAccess<ON_WEAK_OOP_REF | AS_NO_KEEPALIVE>::oop_load(referent_addr)));
+  }
   log_develop_trace(gc, ref)("     discovered_addr/* " PTR_FORMAT " / " PTR_FORMAT,
       p2i(discovered_addr), p2i((oop)HeapAccess<AS_NO_KEEPALIVE>::oop_load(discovered_addr)));
 }
--- a/src/hotspot/share/oops/oop.cpp	Fri Aug 24 09:38:11 2018 +0200
+++ b/src/hotspot/share/oops/oop.cpp	Fri Jul 06 16:04:19 2018 +0200
@@ -177,6 +177,7 @@
 void oopDesc::release_address_field_put(int offset, address value)    { HeapAccess<MO_RELEASE>::store_at(as_oop(), offset, value); }
 
 Metadata* oopDesc::metadata_field(int offset) const                   { return HeapAccess<>::load_at(as_oop(), offset); }
+Metadata* oopDesc::metadata_field_raw(int offset) const               { return RawAccess<>::load_at(as_oop(), offset); }
 void oopDesc::metadata_field_put(int offset, Metadata* value)         { HeapAccess<>::store_at(as_oop(), offset, value); }
 
 Metadata* oopDesc::metadata_field_acquire(int offset) const           { return HeapAccess<MO_ACQUIRE>::load_at(as_oop(), offset); }
--- a/src/hotspot/share/oops/oop.hpp	Fri Aug 24 09:38:11 2018 +0200
+++ b/src/hotspot/share/oops/oop.hpp	Fri Jul 06 16:04:19 2018 +0200
@@ -163,6 +163,7 @@
   void obj_field_put_volatile(int offset, oop value);
 
   Metadata* metadata_field(int offset) const;
+  Metadata* metadata_field_raw(int offset) const;
   void metadata_field_put(int offset, Metadata* value);
 
   Metadata* metadata_field_acquire(int offset) const;
@@ -178,6 +179,7 @@
   void bool_field_put(int offset, jboolean contents);
 
   jint int_field(int offset) const;
+  jint int_field_raw(int offset) const;
   void int_field_put(int offset, jint contents);
 
   jshort short_field(int offset) const;
--- a/src/hotspot/share/oops/oop.inline.hpp	Fri Aug 24 09:38:11 2018 +0200
+++ b/src/hotspot/share/oops/oop.inline.hpp	Fri Jul 06 16:04:19 2018 +0200
@@ -306,6 +306,7 @@
 inline void   oopDesc::short_field_put(int offset, jshort value)    { HeapAccess<>::store_at(as_oop(), offset, value); }
 
 inline jint oopDesc::int_field(int offset) const                    { return HeapAccess<>::load_at(as_oop(), offset);  }
+inline jint oopDesc::int_field_raw(int offset) const                { return RawAccess<>::load_at(as_oop(), offset);   }
 inline void oopDesc::int_field_put(int offset, jint value)          { HeapAccess<>::store_at(as_oop(), offset, value); }
 
 inline jlong oopDesc::long_field(int offset) const                  { return HeapAccess<>::load_at(as_oop(), offset);  }