1 | /* |
2 | * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
5 | * This code is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 only, as |
7 | * published by the Free Software Foundation. |
8 | * |
9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
12 | * version 2 for more details (a copy is included in the LICENSE file that |
13 | * accompanied this code). |
14 | * |
15 | * You should have received a copy of the GNU General Public License version |
16 | * 2 along with this work; if not, write to the Free Software Foundation, |
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
18 | * |
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 | * or visit www.oracle.com if you need additional information or have any |
21 | * questions. |
22 | * |
23 | */ |
24 | |
25 | #ifndef SHARE_CI_CIINSTANCEKLASS_HPP |
26 | #define SHARE_CI_CIINSTANCEKLASS_HPP |
27 | |
28 | #include "ci/ciConstantPoolCache.hpp" |
29 | #include "ci/ciFlags.hpp" |
30 | #include "ci/ciKlass.hpp" |
31 | #include "ci/ciSymbol.hpp" |
32 | |
33 | // ciInstanceKlass |
34 | // |
35 | // This class represents a Klass* in the HotSpot virtual machine |
36 | // whose Klass part is an InstanceKlass. It may or may not |
37 | // be loaded. |
38 | class ciInstanceKlass : public ciKlass { |
39 | CI_PACKAGE_ACCESS |
40 | friend class ciBytecodeStream; |
41 | friend class ciEnv; |
42 | friend class ciExceptionHandler; |
43 | friend class ciMethod; |
44 | friend class ciField; |
45 | |
46 | private: |
47 | enum SubklassValue { subklass_unknown, subklass_false, subklass_true }; |
48 | |
49 | jobject _loader; |
50 | jobject _protection_domain; |
51 | |
52 | InstanceKlass::ClassState _init_state; // state of class |
53 | bool _is_shared; |
54 | bool _has_finalizer; |
55 | SubklassValue _has_subklass; |
56 | bool _has_nonstatic_fields; |
57 | bool _has_nonstatic_concrete_methods; |
58 | bool _is_unsafe_anonymous; |
59 | |
60 | ciFlags _flags; |
61 | jint _nonstatic_field_size; |
62 | jint _nonstatic_oop_map_size; |
63 | |
64 | // Lazy fields get filled in only upon request. |
65 | ciInstanceKlass* _super; |
66 | ciInstance* _java_mirror; |
67 | |
68 | ciConstantPoolCache* _field_cache; // cached map index->field |
69 | GrowableArray<ciField*>* _nonstatic_fields; |
70 | int _has_injected_fields; // any non static injected fields? lazily initialized. |
71 | |
72 | // The possible values of the _implementor fall into following three cases: |
73 | // NULL: no implementor. |
74 | // A ciInstanceKlass that's not itself: one implementor. |
75 | // Itself: more than one implementor. |
76 | ciInstanceKlass* _implementor; |
77 | |
78 | void compute_injected_fields(); |
79 | bool compute_injected_fields_helper(); |
80 | |
81 | protected: |
82 | ciInstanceKlass(Klass* k); |
83 | ciInstanceKlass(ciSymbol* name, jobject loader, jobject protection_domain); |
84 | |
85 | InstanceKlass* get_instanceKlass() const { |
86 | return InstanceKlass::cast(get_Klass()); |
87 | } |
88 | |
89 | oop loader(); |
90 | jobject loader_handle(); |
91 | |
92 | oop protection_domain(); |
93 | jobject protection_domain_handle(); |
94 | |
95 | const char* type_string() { return "ciInstanceKlass" ; } |
96 | |
97 | bool is_in_package_impl(const char* packagename, int len); |
98 | |
99 | void print_impl(outputStream* st); |
100 | |
101 | ciConstantPoolCache* field_cache(); |
102 | |
103 | bool is_shared() { return _is_shared; } |
104 | |
105 | void compute_shared_init_state(); |
106 | bool compute_shared_has_subklass(); |
107 | int compute_nonstatic_fields(); |
108 | GrowableArray<ciField*>* compute_nonstatic_fields_impl(GrowableArray<ciField*>* super_fields); |
109 | |
110 | // Update the init_state for shared klasses |
111 | void update_if_shared(InstanceKlass::ClassState expected) { |
112 | if (_is_shared && _init_state != expected) { |
113 | if (is_loaded()) compute_shared_init_state(); |
114 | } |
115 | } |
116 | |
117 | public: |
118 | // Has this klass been initialized? |
119 | bool is_initialized() { |
120 | update_if_shared(InstanceKlass::fully_initialized); |
121 | return _init_state == InstanceKlass::fully_initialized; |
122 | } |
123 | bool is_not_initialized() { |
124 | update_if_shared(InstanceKlass::fully_initialized); |
125 | return _init_state < InstanceKlass::being_initialized; |
126 | } |
127 | // Is this klass being initialized? |
128 | bool is_being_initialized() { |
129 | update_if_shared(InstanceKlass::being_initialized); |
130 | return _init_state == InstanceKlass::being_initialized; |
131 | } |
132 | // Has this klass been linked? |
133 | bool is_linked() { |
134 | update_if_shared(InstanceKlass::linked); |
135 | return _init_state >= InstanceKlass::linked; |
136 | } |
137 | // Is this klass in error state? |
138 | bool is_in_error_state() { |
139 | update_if_shared(InstanceKlass::initialization_error); |
140 | return _init_state == InstanceKlass::initialization_error; |
141 | } |
142 | |
143 | // General klass information. |
144 | ciFlags flags() { |
145 | assert(is_loaded(), "must be loaded" ); |
146 | return _flags; |
147 | } |
148 | bool has_finalizer() { |
149 | assert(is_loaded(), "must be loaded" ); |
150 | return _has_finalizer; } |
151 | bool has_subklass() { |
152 | assert(is_loaded(), "must be loaded" ); |
153 | if (_has_subklass == subklass_unknown || |
154 | (_is_shared && _has_subklass == subklass_false)) { |
155 | if (flags().is_final()) { |
156 | return false; |
157 | } else { |
158 | return compute_shared_has_subklass(); |
159 | } |
160 | } |
161 | return _has_subklass == subklass_true; |
162 | } |
163 | jint size_helper() { |
164 | return (Klass::layout_helper_size_in_bytes(layout_helper()) |
165 | >> LogHeapWordSize); |
166 | } |
167 | jint nonstatic_field_size() { |
168 | assert(is_loaded(), "must be loaded" ); |
169 | return _nonstatic_field_size; } |
170 | jint has_nonstatic_fields() { |
171 | assert(is_loaded(), "must be loaded" ); |
172 | return _has_nonstatic_fields; } |
173 | jint nonstatic_oop_map_size() { |
174 | assert(is_loaded(), "must be loaded" ); |
175 | return _nonstatic_oop_map_size; } |
176 | ciInstanceKlass* super(); |
177 | jint nof_implementors() { |
178 | ciInstanceKlass* impl; |
179 | assert(is_loaded(), "must be loaded" ); |
180 | impl = implementor(); |
181 | if (impl == NULL) { |
182 | return 0; |
183 | } else if (impl != this) { |
184 | return 1; |
185 | } else { |
186 | return 2; |
187 | } |
188 | } |
189 | bool has_nonstatic_concrete_methods() { |
190 | assert(is_loaded(), "must be loaded" ); |
191 | return _has_nonstatic_concrete_methods; |
192 | } |
193 | |
194 | bool is_unsafe_anonymous() { |
195 | return _is_unsafe_anonymous; |
196 | } |
197 | |
198 | ciInstanceKlass* get_canonical_holder(int offset); |
199 | ciField* get_field_by_offset(int field_offset, bool is_static); |
200 | ciField* get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static); |
201 | |
202 | // total number of nonstatic fields (including inherited): |
203 | int nof_nonstatic_fields() { |
204 | if (_nonstatic_fields == NULL) |
205 | return compute_nonstatic_fields(); |
206 | else |
207 | return _nonstatic_fields->length(); |
208 | } |
209 | |
210 | bool has_injected_fields() { |
211 | if (_has_injected_fields == -1) { |
212 | compute_injected_fields(); |
213 | } |
214 | return _has_injected_fields > 0 ? true : false; |
215 | } |
216 | |
217 | bool has_object_fields() const; |
218 | |
219 | // nth nonstatic field (presented by ascending address) |
220 | ciField* nonstatic_field_at(int i) { |
221 | assert(_nonstatic_fields != NULL, "" ); |
222 | return _nonstatic_fields->at(i); |
223 | } |
224 | |
225 | ciInstanceKlass* unique_concrete_subklass(); |
226 | bool has_finalizable_subclass(); |
227 | |
228 | bool contains_field_offset(int offset) { |
229 | return instanceOopDesc::contains_field_offset(offset, nonstatic_field_size()); |
230 | } |
231 | |
232 | // Get the instance of java.lang.Class corresponding to |
233 | // this klass. This instance is used for locking of |
234 | // synchronized static methods of this klass. |
235 | ciInstance* java_mirror(); |
236 | |
237 | // Java access flags |
238 | bool is_public () { return flags().is_public(); } |
239 | bool is_final () { return flags().is_final(); } |
240 | bool is_super () { return flags().is_super(); } |
241 | bool is_interface () { return flags().is_interface(); } |
242 | bool is_abstract () { return flags().is_abstract(); } |
243 | |
244 | ciMethod* find_method(ciSymbol* name, ciSymbol* signature); |
245 | // Note: To find a method from name and type strings, use ciSymbol::make, |
246 | // but consider adding to vmSymbols.hpp instead. |
247 | |
248 | bool is_leaf_type(); |
249 | ciInstanceKlass* implementor(); |
250 | |
251 | // Is the defining class loader of this class the default loader? |
252 | bool uses_default_loader() const; |
253 | |
254 | bool is_java_lang_Object() const; |
255 | |
256 | BasicType box_klass_type() const; |
257 | bool is_box_klass() const; |
258 | bool is_boxed_value_offset(int offset) const; |
259 | |
260 | // Is this klass in the given package? |
261 | bool is_in_package(const char* packagename) { |
262 | return is_in_package(packagename, (int) strlen(packagename)); |
263 | } |
264 | bool is_in_package(const char* packagename, int len); |
265 | |
266 | // What kind of ciObject is this? |
267 | bool is_instance_klass() const { return true; } |
268 | bool is_java_klass() const { return true; } |
269 | |
270 | virtual ciKlass* exact_klass() { |
271 | if (is_loaded() && is_final() && !is_interface()) { |
272 | return this; |
273 | } |
274 | return NULL; |
275 | } |
276 | |
277 | ciInstanceKlass* unsafe_anonymous_host(); |
278 | |
279 | bool can_be_instantiated() { |
280 | assert(is_loaded(), "must be loaded" ); |
281 | return !is_interface() && !is_abstract(); |
282 | } |
283 | |
284 | // Dump the current state of this klass for compilation replay. |
285 | virtual void dump_replay_data(outputStream* out); |
286 | |
287 | #ifdef ASSERT |
288 | bool debug_final_field_at(int offset); |
289 | bool debug_stable_field_at(int offset); |
290 | #endif |
291 | }; |
292 | |
293 | #endif // SHARE_CI_CIINSTANCEKLASS_HPP |
294 | |