< prev index next >

src/share/vm/classfile/dictionary.hpp

Print this page

        

@@ -27,10 +27,11 @@
 
 #include "classfile/protectionDomainCache.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/oop.hpp"
+#include "runtime/orderAccess.hpp"
 #include "utilities/hashtable.hpp"
 #include "utilities/ostream.hpp"
 
 class DictionaryEntry;
 class BoolObjectClosure;

@@ -132,11 +133,27 @@
   //
   // The usage of the PD set can be seen in SystemDictionary::validate_protection_domain()
   // It is essentially a cache to avoid repeated Java up-calls to
   // ClassLoader.checkPackageAccess().
   //
-  ProtectionDomainEntry* _pd_set;
+  class ProtectionDomainSet {
+    // Do not access without synchronization
+    ProtectionDomainEntry* volatile _pd_set;
+  public:
+    ProtectionDomainEntry* pd_set_acquire() const {
+      return (ProtectionDomainEntry*)OrderAccess::load_ptr_acquire(&_pd_set);
+    }
+    void release_set_pd_set(ProtectionDomainEntry* new_head) {
+      // Warning: Preserve store ordering.  The SystemDictionary is read
+      //          without locks.  The new ProtectionDomainEntry must be
+      //          complete before other threads can be allowed to see it
+      //          via a store to _pd_set.
+      OrderAccess::release_store_ptr(&_pd_set, new_head);
+    }
+  };
+
+  ProtectionDomainSet _inner;
 
  public:
   // Tells whether a protection is in the approved set.
   bool contains_protection_domain(oop protection_domain) const;
   // Adds a protection domain to the approved set.

@@ -151,12 +168,12 @@
 
   DictionaryEntry** next_addr() {
     return (DictionaryEntry**)HashtableEntry<InstanceKlass*, mtClass>::next_addr();
   }
 
-  ProtectionDomainEntry* pd_set() const { return _pd_set; }
-  void set_pd_set(ProtectionDomainEntry* pd_set) { _pd_set = pd_set; }
+  ProtectionDomainEntry* pd_set() const            { return _inner.pd_set_acquire(); }
+  void set_pd_set(ProtectionDomainEntry* new_head) {  _inner.release_set_pd_set(new_head); }
 
   // Tells whether the initiating class' protection domain can access the klass in this entry
   bool is_valid_protection_domain(Handle protection_domain) {
     if (!ProtectionDomainVerification) return true;
     if (!SystemDictionary::has_checkPackageAccess()) return true;

@@ -165,11 +182,11 @@
          ? true
          : contains_protection_domain(protection_domain());
   }
 
   void verify_protection_domain_set() {
-    for (ProtectionDomainEntry* current = _pd_set;
+    for (ProtectionDomainEntry* current = pd_set();
                                 current != NULL;
                                 current = current->_next) {
       current->_pd_cache->protection_domain()->verify();
     }
   }

@@ -179,11 +196,11 @@
     return (klass->name() == class_name);
   }
 
   void print_count(outputStream *st) {
     int count = 0;
-    for (ProtectionDomainEntry* current = _pd_set;
+    for (ProtectionDomainEntry* current = pd_set();
                                 current != NULL;
                                 current = current->_next) {
       count++;
     }
     st->print_cr("pd set count = #%d", count);
< prev index next >