32 #include "utilities/ostream.hpp" |
32 #include "utilities/ostream.hpp" |
33 |
33 |
34 // A PackageEntry basically represents a Java package. It contains: |
34 // A PackageEntry basically represents a Java package. It contains: |
35 // - Symbol* containing the package's name. |
35 // - Symbol* containing the package's name. |
36 // - ModuleEntry* for this package's containing module. |
36 // - ModuleEntry* for this package's containing module. |
37 // - a flag indicating if package is exported unqualifiedly |
37 // - a field indicating if the package is exported unqualifiedly or to all |
38 // - a flag indicating if this package is exported to all unnamed modules. |
38 // unnamed modules. |
39 // - a growable array containing other module entries that this |
39 // - a growable array containing other module entries that this |
40 // package is exported to. |
40 // package is exported to. |
41 // |
41 // |
42 // Packages can be exported in the following 3 ways: |
42 // Packages can be exported in the following 3 ways: |
43 // - not exported: the package does not have qualified or unqualified exports. |
43 // - not exported: the package does not have qualified or unqualified exports. |
44 // - qualified exports: the package has been explicitly qualified to at least |
44 // - qualified exports: the package has been explicitly qualified to at least |
45 // one particular module or has been qualifiedly exported |
45 // one particular module or has been qualifiedly exported |
46 // to all unnamed modules. |
46 // to all unnamed modules. |
47 // Note: _is_exported_allUnnamed is a form of a qualified |
47 // Note: being exported to all unnamed is a form of a qualified |
48 // export. It is equivalent to the package being |
48 // export. It is equivalent to the package being explicitly |
49 // explicitly exported to all current and future unnamed modules. |
49 // exported to all current and future unnamed modules. |
50 // - unqualified exports: the package is exported to all modules. |
50 // - unqualified exports: the package is exported to all modules. |
51 // |
51 // |
52 // A package can transition from: |
52 // A package can transition from: |
53 // - being not exported, to being exported either in a qualified or unqualified manner |
53 // - being not exported, to being exported either in a qualified or unqualified manner |
54 // - being qualifiedly exported, to unqualifiedly exported. Its exported scope is widened. |
54 // - being qualifiedly exported, to unqualifiedly exported. Its exported scope is widened. |
55 // |
55 // |
56 // A package cannot transition from: |
56 // A package cannot transition from: |
57 // - being unqualifiedly exported, to exported qualifiedly to a specific module. |
57 // - being unqualifiedly exported, to exported qualifiedly to a specific module. |
58 // This transition attempt is silently ignored in set_exported. |
58 // This transition attempt is silently ignored in set_exported. |
|
59 // - being qualifiedly exported to not exported. |
|
60 // Because transitions are only allowed from less exposure to greater exposure, |
|
61 // the transition from qualifiedly exported to not exported would be considered |
|
62 // a backward direction. Therefore the implementation considers a package as |
|
63 // qualifiedly exported even if its export-list exists but is empty. |
59 // |
64 // |
60 // The Mutex Module_lock is shared between ModuleEntry and PackageEntry, to lock either |
65 // The Mutex Module_lock is shared between ModuleEntry and PackageEntry, to lock either |
61 // data structure. |
66 // data structure. |
|
67 |
|
68 // PKG_EXP_UNQUALIFIED and PKG_EXP_ALLUNNAMED indicate whether the package is |
|
69 // exported unqualifiedly or exported to all unnamed modules. They are used to |
|
70 // set the value of _export_flags. Field _export_flags and the _qualified_exports |
|
71 // list are used to determine a package's export state. |
|
72 // Valid states are: |
|
73 // |
|
74 // 1. Package is not exported |
|
75 // _export_flags is zero and _qualified_exports is null |
|
76 // 2. Package is unqualifiedly exported |
|
77 // _export_flags is set to PKG_EXP_UNQUALIFIED |
|
78 // _qualified_exports may or may not be null depending on whether the package |
|
79 // transitioned from qualifiedly exported to unqualifiedly exported. |
|
80 // 3. Package is qualifiedly exported |
|
81 // _export_flags may be set to PKG_EXP_ALLUNNAMED if the package is also |
|
82 // exported to all unnamed modules |
|
83 // _qualified_exports will be non-null |
|
84 // 4. Package is exported to all unnamed modules |
|
85 // _export_flags is set to PKG_EXP_ALLUNNAMED |
|
86 // _qualified_exports may or may not be null depending on whether the package |
|
87 // is also qualifiedly exported to one or more named modules. |
|
88 #define PKG_EXP_UNQUALIFIED 0x0001 |
|
89 #define PKG_EXP_ALLUNNAMED 0x0002 |
|
90 #define PKG_EXP_UNQUALIFIED_OR_ALL_UNAMED (PKG_EXP_UNQUALIFIED | PKG_EXP_ALLUNNAMED) |
|
91 |
62 class PackageEntry : public HashtableEntry<Symbol*, mtModule> { |
92 class PackageEntry : public HashtableEntry<Symbol*, mtModule> { |
63 private: |
93 private: |
64 ModuleEntry* _module; |
94 ModuleEntry* _module; |
|
95 // Indicates if package is exported unqualifiedly or to all unnamed. Access to |
|
96 // this field is protected by the Module_lock. |
|
97 int _export_flags; |
65 // Used to indicate for packages with classes loaded by the boot loader that |
98 // Used to indicate for packages with classes loaded by the boot loader that |
66 // a class in that package has been loaded. And, for packages with classes |
99 // a class in that package has been loaded. And, for packages with classes |
67 // loaded by the boot loader from -Xbootclasspath/a in an unnamed module, it |
100 // loaded by the boot loader from -Xbootclasspath/a in an unnamed module, it |
68 // indicates from which class path entry. |
101 // indicates from which class path entry. |
69 s2 _classpath_index; |
102 s2 _classpath_index; |
70 bool _is_exported_unqualified; |
|
71 bool _is_exported_allUnnamed; |
|
72 bool _must_walk_exports; |
103 bool _must_walk_exports; |
73 GrowableArray<ModuleEntry*>* _exported_pending_delete; // transitioned from qualified to unqualified, delete at safepoint |
104 // Contains list of modules this package is qualifiedly exported to. Access |
|
105 // to this list is protected by the Module_lock. |
74 GrowableArray<ModuleEntry*>* _qualified_exports; |
106 GrowableArray<ModuleEntry*>* _qualified_exports; |
75 TRACE_DEFINE_TRACE_ID_FIELD; |
107 TRACE_DEFINE_TRACE_ID_FIELD; |
76 |
108 |
77 // Initial size of a package entry's list of qualified exports. |
109 // Initial size of a package entry's list of qualified exports. |
78 enum {QUAL_EXP_SIZE = 43}; |
110 enum {QUAL_EXP_SIZE = 43}; |
79 |
111 |
80 public: |
112 public: |
81 void init() { |
113 void init() { |
82 _module = NULL; |
114 _module = NULL; |
|
115 _export_flags = 0; |
83 _classpath_index = -1; |
116 _classpath_index = -1; |
84 _is_exported_unqualified = false; |
|
85 _is_exported_allUnnamed = false; |
|
86 _must_walk_exports = false; |
117 _must_walk_exports = false; |
87 _exported_pending_delete = NULL; |
|
88 _qualified_exports = NULL; |
118 _qualified_exports = NULL; |
89 } |
119 } |
90 |
120 |
91 // package name |
121 // package name |
92 Symbol* name() const { return literal(); } |
122 Symbol* name() const { return literal(); } |
93 void set_name(Symbol* n) { set_literal(n); } |
|
94 |
123 |
95 // the module containing the package definition |
124 // the module containing the package definition |
96 ModuleEntry* module() const { return _module; } |
125 ModuleEntry* module() const { return _module; } |
97 void set_module(ModuleEntry* m) { _module = m; } |
126 void set_module(ModuleEntry* m) { _module = m; } |
98 |
127 |
99 // package's export state |
128 // package's export state |
100 bool is_exported() const { // qualifiedly or unqualifiedly exported |
129 bool is_exported() const { // qualifiedly or unqualifiedly exported |
101 return (is_unqual_exported() || has_qual_exports_list() || is_exported_allUnnamed()); |
130 assert_locked_or_safepoint(Module_lock); |
|
131 return ((_export_flags & PKG_EXP_UNQUALIFIED_OR_ALL_UNAMED) != 0) || has_qual_exports_list(); |
102 } |
132 } |
103 // Returns true if the package has any explicit qualified exports or is exported to all unnamed |
133 // Returns true if the package has any explicit qualified exports or is exported to all unnamed |
104 bool is_qual_exported() const { |
134 bool is_qual_exported() const { |
|
135 assert_locked_or_safepoint(Module_lock); |
105 return (has_qual_exports_list() || is_exported_allUnnamed()); |
136 return (has_qual_exports_list() || is_exported_allUnnamed()); |
106 } |
137 } |
107 // Returns true if there are any explicit qualified exports |
138 // Returns true if there are any explicit qualified exports. Note that even |
|
139 // if the _qualified_exports list is now empty (because the modules that were |
|
140 // on the list got gc-ed and deleted from the list) this method may still |
|
141 // return true. |
108 bool has_qual_exports_list() const { |
142 bool has_qual_exports_list() const { |
109 assert(!(_qualified_exports != NULL && _is_exported_unqualified), |
143 assert_locked_or_safepoint(Module_lock); |
110 "_qualified_exports set at same time as _is_exported_unqualified"); |
144 return (!is_unqual_exported() && _qualified_exports != NULL); |
111 return (_qualified_exports != NULL); |
|
112 } |
145 } |
113 bool is_exported_allUnnamed() const { |
146 bool is_exported_allUnnamed() const { |
114 assert(!(_is_exported_allUnnamed && _is_exported_unqualified), |
147 assert_locked_or_safepoint(Module_lock); |
115 "_is_exported_allUnnamed set at same time as _is_exported_unqualified"); |
148 return (_export_flags == PKG_EXP_ALLUNNAMED); |
116 return _is_exported_allUnnamed; |
|
117 } |
149 } |
118 bool is_unqual_exported() const { |
150 bool is_unqual_exported() const { |
119 assert(!(_qualified_exports != NULL && _is_exported_unqualified), |
151 assert_locked_or_safepoint(Module_lock); |
120 "_qualified_exports set at same time as _is_exported_unqualified"); |
152 return (_export_flags == PKG_EXP_UNQUALIFIED); |
121 assert(!(_is_exported_allUnnamed && _is_exported_unqualified), |
153 } |
122 "_is_exported_allUnnamed set at same time as _is_exported_unqualified"); |
154 |
123 return _is_exported_unqualified; |
155 // Explicitly set _export_flags to PKG_EXP_UNQUALIFIED and clear |
124 } |
156 // PKG_EXP_ALLUNNAMED, if it was set. |
125 void set_unqual_exported() { |
157 void set_unqual_exported() { |
126 assert(Module_lock->owned_by_self(), "should have the Module_lock"); |
158 assert(Module_lock->owned_by_self(), "should have the Module_lock"); |
127 _is_exported_unqualified = true; |
159 _export_flags = PKG_EXP_UNQUALIFIED; |
128 _is_exported_allUnnamed = false; |
160 } |
129 _qualified_exports = NULL; |
161 |
130 } |
162 bool exported_pending_delete() const; |
131 bool exported_pending_delete() const { return (_exported_pending_delete != NULL); } |
|
132 |
163 |
133 void set_exported(ModuleEntry* m); |
164 void set_exported(ModuleEntry* m); |
134 |
165 |
135 void set_is_exported_allUnnamed(); |
166 void set_is_exported_allUnnamed(); |
136 |
167 |