| 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 | |