hotspot/src/share/vm/classfile/packageEntry.hpp
changeset 38940 7de797f32b5f
parent 38733 2b65f4db449e
child 39290 0cc9f5028562
--- a/hotspot/src/share/vm/classfile/packageEntry.hpp	Thu Jun 02 09:44:41 2016 +0200
+++ b/hotspot/src/share/vm/classfile/packageEntry.hpp	Fri Jun 03 11:53:55 2016 -0400
@@ -34,16 +34,32 @@
 // A PackageEntry basically represents a Java package.  It contains:
 //   - Symbol* containing the package's name.
 //   - ModuleEntry* for this package's containing module.
-//   - a flag indicating if package is exported, either qualifiedly or
-//     unqualifiedly.
+//   - a flag indicating if package is exported unqualifiedly
 //   - a flag indicating if this package is exported to all unnamed modules.
 //   - a growable array containing other module entries that this
 //     package is exported to.
 //
-// Packages that are:
-//   - not exported:        _qualified_exports = NULL  && _is_exported is false
-//   - qualified exports:   (_qualified_exports != NULL || _is_exported_allUnnamed is true) && _is_exported is true
-//   - unqualified exports: (_qualified_exports = NULL && _is_exported_allUnnamed is false) && _is_exported is true
+// Packages can be exported in the following 3 ways:
+//   - not exported:        the package has not been explicitly qualified to a
+//                            particular module nor has it been specified to be
+//                            unqualifiedly exported to all modules. If all states
+//                            of exportedness are false, the package is considered
+//                            not exported.
+//   - qualified exports:   the package has been explicitly qualified to at least
+//                            one particular module or has been qualifiedly exported
+//                            to all unnamed modules.
+//                            Note: _is_exported_allUnnamed is a form of a qualified
+//                            export. It is equivalent to the package being
+//                            explicitly exported to all current and future unnamed modules.
+//   - unqualified exports: the package is exported to all modules.
+//
+// A package can transition from:
+//   - being not exported, to being exported either in a qualified or unqualified manner
+//   - being qualifiedly exported, to unqualifiedly exported. Its exported scope is widened.
+//
+// A package cannot transition from:
+//   - being unqualifiedly exported, to exported qualifiedly to a specific module.
+//       This transition attempt is silently ignored in set_exported.
 //
 // The Mutex Module_lock is shared between ModuleEntry and PackageEntry, to lock either
 // data structure.
@@ -55,7 +71,7 @@
   // loaded by the boot loader from -Xbootclasspath/a in an unnamed module, it
   // indicates from which class path entry.
   s2 _classpath_index;
-  bool _is_exported;
+  bool _is_exported_unqualified;
   bool _is_exported_allUnnamed;
   GrowableArray<ModuleEntry*>* _exported_pending_delete; // transitioned from qualified to unqualified, delete at safepoint
   GrowableArray<ModuleEntry*>* _qualified_exports;
@@ -68,7 +84,7 @@
   void init() {
     _module = NULL;
     _classpath_index = -1;
-    _is_exported = false;
+    _is_exported_unqualified = false;
     _is_exported_allUnnamed = false;
     _exported_pending_delete = NULL;
     _qualified_exports = NULL;
@@ -83,34 +99,41 @@
   void               set_module(ModuleEntry* m) { _module = m; }
 
   // package's export state
-  bool is_exported() const { return _is_exported; } // qualifiedly or unqualifiedly exported
+  bool is_exported() const { // qualifiedly or unqualifiedly exported
+      return (is_unqual_exported() || has_qual_exports_list() || is_exported_allUnnamed());
+  }
+  // Returns true if the package has any explicit qualified exports or is exported to all unnamed
   bool is_qual_exported() const {
-    return (_is_exported && (_qualified_exports != NULL || _is_exported_allUnnamed));
+    return (has_qual_exports_list() || is_exported_allUnnamed());
+  }
+  // Returns true if there are any explicit qualified exports
+  bool has_qual_exports_list() const {
+    assert(!(_qualified_exports != NULL && _is_exported_unqualified),
+           "_qualified_exports set at same time as _is_exported_unqualified");
+    return (_qualified_exports != NULL);
+  }
+  bool is_exported_allUnnamed() const {
+    assert(!(_is_exported_allUnnamed && _is_exported_unqualified),
+           "_is_exported_allUnnamed set at same time as _is_exported_unqualified");
+    return _is_exported_allUnnamed;
   }
   bool is_unqual_exported() const {
-    return (_is_exported && (_qualified_exports == NULL && !_is_exported_allUnnamed));
+    assert(!(_qualified_exports != NULL && _is_exported_unqualified),
+           "_qualified_exports set at same time as _is_exported_unqualified");
+    assert(!(_is_exported_allUnnamed && _is_exported_unqualified),
+           "_is_exported_allUnnamed set at same time as _is_exported_unqualified");
+    return _is_exported_unqualified;
   }
   void set_unqual_exported() {
-    _is_exported = true;
+    _is_exported_unqualified = true;
     _is_exported_allUnnamed = false;
     _qualified_exports = NULL;
   }
   bool exported_pending_delete() const     { return (_exported_pending_delete != NULL); }
 
-  void set_exported(bool e)                { _is_exported = e; }
   void set_exported(ModuleEntry* m);
 
-  void set_is_exported_allUnnamed() {
-    if (!is_unqual_exported()) {
-     _is_exported_allUnnamed = true;
-     _is_exported = true;
-    }
-  }
-  bool is_exported_allUnnamed() const {
-    assert(_is_exported || !_is_exported_allUnnamed,
-           "is_allUnnamed set without is_exported being set");
-    return _is_exported_allUnnamed;
-  }
+  void set_is_exported_allUnnamed();
 
   void set_classpath_index(s2 classpath_index) {
     _classpath_index = classpath_index;
@@ -122,7 +145,7 @@
   // returns true if the package is defined in the unnamed module
   bool in_unnamed_module() const  { return !_module->is_named(); }
 
-  // returns true if the package specifies m as a qualified export
+  // returns true if the package specifies m as a qualified export, including through an unnamed export
   bool is_qexported_to(ModuleEntry* m) const;
 
   // add the module to the package's qualified exports