changeset 54674:27c8a2e0b0e5

8223177: Data race on JvmtiEnvBase::_tag_map in double-checked locking Summary: Add memory fences on accesses to JvmtiEnvBase::_tag_map Reviewed-by: dholmes, jcbeyler, sspitsyn
author manc
date Tue, 30 Apr 2019 18:44:41 -0700
parents 67b040623a12
children 4a4bf48f76a4
files src/hotspot/share/prims/jvmtiEnvBase.hpp src/hotspot/share/prims/jvmtiTagMap.cpp
diffstat 2 files changed, 12 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/prims/jvmtiEnvBase.hpp	Wed May 01 16:47:26 2019 -0700
+++ b/src/hotspot/share/prims/jvmtiEnvBase.hpp	Tue Apr 30 18:44:41 2019 -0700
@@ -32,6 +32,7 @@
 #include "oops/oopHandle.hpp"
 #include "runtime/fieldDescriptor.hpp"
 #include "runtime/frame.hpp"
+#include "runtime/orderAccess.hpp"
 #include "runtime/thread.hpp"
 #include "runtime/vmOperations.hpp"
 #include "utilities/growableArray.hpp"
@@ -98,7 +99,7 @@
   const void *_env_local_storage;     // per env agent allocated data.
   jvmtiEventCallbacks _event_callbacks;
   jvmtiExtEventCallbacks _ext_event_callbacks;
-  JvmtiTagMap* _tag_map;
+  JvmtiTagMap* volatile _tag_map;
   JvmtiEnvEventEnable _env_event_enable;
   jvmtiCapabilities _current_capabilities;
   jvmtiCapabilities _prohibited_capabilities;
@@ -253,6 +254,13 @@
     return _tag_map;
   }
 
+  JvmtiTagMap* acquire_tag_map() {
+    return OrderAccess::load_acquire(&_tag_map);
+  }
+
+  void release_set_tag_map(JvmtiTagMap* tag_map) {
+    OrderAccess::release_store(&_tag_map, tag_map);
+  }
 
   // return true if event is enabled globally or for any thread
   // True only if there is a callback for it.
--- a/src/hotspot/share/prims/jvmtiTagMap.cpp	Wed May 01 16:47:26 2019 -0700
+++ b/src/hotspot/share/prims/jvmtiTagMap.cpp	Tue Apr 30 18:44:41 2019 -0700
@@ -445,7 +445,7 @@
   _hashmap = new JvmtiTagHashmap();
 
   // finally add us to the environment
-  ((JvmtiEnvBase *)env)->set_tag_map(this);
+  ((JvmtiEnvBase *)env)->release_set_tag_map(this);
 }
 
 
@@ -514,7 +514,7 @@
 // returns the tag map for the given environments. If the tag map
 // doesn't exist then it is created.
 JvmtiTagMap* JvmtiTagMap::tag_map_for(JvmtiEnv* env) {
-  JvmtiTagMap* tag_map = ((JvmtiEnvBase*)env)->tag_map();
+  JvmtiTagMap* tag_map = ((JvmtiEnvBase*)env)->acquire_tag_map();
   if (tag_map == NULL) {
     MutexLocker mu(JvmtiThreadState_lock);
     tag_map = ((JvmtiEnvBase*)env)->tag_map();
@@ -3318,7 +3318,7 @@
   if (JvmtiEnv::environments_might_exist()) {
     JvmtiEnvIterator it;
     for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) {
-      JvmtiTagMap* tag_map = env->tag_map();
+      JvmtiTagMap* tag_map = env->acquire_tag_map();
       if (tag_map != NULL && !tag_map->is_empty()) {
         tag_map->do_weak_oops(is_alive, f);
       }