duke@435: /* jiangli@3701: * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. duke@435: * duke@435: */ duke@435: stefank@2314: #ifndef SHARE_VM_CI_CIINSTANCEKLASS_HPP stefank@2314: #define SHARE_VM_CI_CIINSTANCEKLASS_HPP stefank@2314: stefank@2314: #include "ci/ciConstantPoolCache.hpp" stefank@2314: #include "ci/ciFlags.hpp" stefank@2314: #include "ci/ciKlass.hpp" stefank@2314: #include "ci/ciSymbol.hpp" stefank@2314: duke@435: // ciInstanceKlass duke@435: // coleenp@4037: // This class represents a Klass* in the HotSpot virtual machine coleenp@4037: // whose Klass part is an InstanceKlass. It may or may not duke@435: // be loaded. duke@435: class ciInstanceKlass : public ciKlass { duke@435: CI_PACKAGE_ACCESS twisti@1573: friend class ciBytecodeStream; duke@435: friend class ciEnv; twisti@1573: friend class ciExceptionHandler; duke@435: friend class ciMethod; duke@435: friend class ciField; duke@435: duke@435: private: duke@435: jobject _loader; duke@435: jobject _protection_domain; duke@435: coleenp@4037: InstanceKlass::ClassState _init_state; // state of class coleenp@548: bool _is_shared; duke@435: bool _has_finalizer; duke@435: bool _has_subklass; coleenp@548: bool _has_nonstatic_fields; coleenp@548: duke@435: ciFlags _flags; duke@435: jint _nonstatic_field_size; kvn@479: jint _nonstatic_oop_map_size; duke@435: duke@435: // Lazy fields get filled in only upon request. duke@435: ciInstanceKlass* _super; duke@435: ciInstance* _java_mirror; duke@435: duke@435: ciConstantPoolCache* _field_cache; // cached map index->field duke@435: GrowableArray* _nonstatic_fields; duke@435: jiangli@3701: // The possible values of the _implementor fall into following three cases: jiangli@3701: // NULL: no implementor. jiangli@3701: // A ciInstanceKlass that's not itself: one implementor. jiangli@3701: // Itsef: more than one implementors. jiangli@3701: ciInstanceKlass* _implementor; duke@435: kvn@479: GrowableArray* _non_static_fields; kvn@479: duke@435: protected: duke@435: ciInstanceKlass(KlassHandle h_k); duke@435: ciInstanceKlass(ciSymbol* name, jobject loader, jobject protection_domain); duke@435: coleenp@4037: InstanceKlass* get_instanceKlass() const { coleenp@4037: return (InstanceKlass*)get_Klass(); duke@435: } duke@435: duke@435: oop loader(); duke@435: jobject loader_handle(); duke@435: duke@435: oop protection_domain(); duke@435: jobject protection_domain_handle(); duke@435: duke@435: const char* type_string() { return "ciInstanceKlass"; } duke@435: twisti@1573: bool is_in_package_impl(const char* packagename, int len); twisti@1573: duke@435: void print_impl(outputStream* st); duke@435: duke@435: ciConstantPoolCache* field_cache(); duke@435: duke@435: bool is_shared() { return _is_shared; } duke@435: never@2000: void compute_shared_init_state(); duke@435: bool compute_shared_has_subklass(); duke@435: int compute_nonstatic_fields(); duke@435: GrowableArray* compute_nonstatic_fields_impl(GrowableArray* super_fields); duke@435: never@2000: // Update the init_state for shared klasses coleenp@4037: void update_if_shared(InstanceKlass::ClassState expected) { never@2000: if (_is_shared && _init_state != expected) { never@2000: if (is_loaded()) compute_shared_init_state(); never@2000: } never@2000: } never@2000: duke@435: public: duke@435: // Has this klass been initialized? duke@435: bool is_initialized() { coleenp@4037: update_if_shared(InstanceKlass::fully_initialized); coleenp@4037: return _init_state == InstanceKlass::fully_initialized; never@2000: } never@2000: // Is this klass being initialized? never@2000: bool is_being_initialized() { coleenp@4037: update_if_shared(InstanceKlass::being_initialized); coleenp@4037: return _init_state == InstanceKlass::being_initialized; duke@435: } duke@435: // Has this klass been linked? duke@435: bool is_linked() { coleenp@4037: update_if_shared(InstanceKlass::linked); coleenp@4037: return _init_state >= InstanceKlass::linked; duke@435: } duke@435: duke@435: // General klass information. duke@435: ciFlags flags() { duke@435: assert(is_loaded(), "must be loaded"); duke@435: return _flags; duke@435: } duke@435: bool has_finalizer() { duke@435: assert(is_loaded(), "must be loaded"); duke@435: return _has_finalizer; } duke@435: bool has_subklass() { duke@435: assert(is_loaded(), "must be loaded"); duke@435: if (_is_shared && !_has_subklass) { duke@435: if (flags().is_final()) { duke@435: return false; duke@435: } else { duke@435: return compute_shared_has_subklass(); duke@435: } duke@435: } duke@435: return _has_subklass; duke@435: } duke@435: jint size_helper() { duke@435: return (Klass::layout_helper_size_in_bytes(layout_helper()) duke@435: >> LogHeapWordSize); duke@435: } duke@435: jint nonstatic_field_size() { duke@435: assert(is_loaded(), "must be loaded"); duke@435: return _nonstatic_field_size; } coleenp@548: jint has_nonstatic_fields() { coleenp@548: assert(is_loaded(), "must be loaded"); coleenp@548: return _has_nonstatic_fields; } kvn@479: jint nonstatic_oop_map_size() { kvn@479: assert(is_loaded(), "must be loaded"); kvn@479: return _nonstatic_oop_map_size; } duke@435: ciInstanceKlass* super(); jiangli@3701: jint nof_implementors() { jiangli@3701: ciInstanceKlass* impl; duke@435: assert(is_loaded(), "must be loaded"); jiangli@3701: impl = implementor(); jiangli@3701: if (impl == NULL) { jiangli@3701: return 0; jiangli@3701: } else if (impl != this) { jiangli@3701: return 1; jiangli@3701: } else { jiangli@3701: return 2; jiangli@3701: } duke@435: } duke@435: duke@435: ciInstanceKlass* get_canonical_holder(int offset); duke@435: ciField* get_field_by_offset(int field_offset, bool is_static); never@1515: ciField* get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static); kvn@479: kvn@479: GrowableArray* non_static_fields(); kvn@479: duke@435: // total number of nonstatic fields (including inherited): duke@435: int nof_nonstatic_fields() { duke@435: if (_nonstatic_fields == NULL) duke@435: return compute_nonstatic_fields(); duke@435: else duke@435: return _nonstatic_fields->length(); duke@435: } duke@435: // nth nonstatic field (presented by ascending address) duke@435: ciField* nonstatic_field_at(int i) { duke@435: assert(_nonstatic_fields != NULL, ""); duke@435: return _nonstatic_fields->at(i); duke@435: } duke@435: duke@435: ciInstanceKlass* unique_concrete_subklass(); duke@435: bool has_finalizable_subclass(); duke@435: duke@435: bool contains_field_offset(int offset) { coleenp@548: return instanceOopDesc::contains_field_offset(offset, nonstatic_field_size()); duke@435: } duke@435: duke@435: // Get the instance of java.lang.Class corresponding to duke@435: // this klass. This instance is used for locking of duke@435: // synchronized static methods of this klass. duke@435: ciInstance* java_mirror(); duke@435: duke@435: // Java access flags duke@435: bool is_public () { return flags().is_public(); } duke@435: bool is_final () { return flags().is_final(); } duke@435: bool is_super () { return flags().is_super(); } duke@435: bool is_interface () { return flags().is_interface(); } duke@435: bool is_abstract () { return flags().is_abstract(); } duke@435: duke@435: ciMethod* find_method(ciSymbol* name, ciSymbol* signature); duke@435: // Note: To find a method from name and type strings, use ciSymbol::make, duke@435: // but consider adding to vmSymbols.hpp instead. duke@435: duke@435: bool is_leaf_type(); jiangli@3701: ciInstanceKlass* implementor(); duke@435: duke@435: // Is the defining class loader of this class the default loader? kvn@5110: bool uses_default_loader() const; duke@435: coleenp@4037: bool is_java_lang_Object() const; duke@435: kvn@5110: BasicType box_klass_type() const; kvn@5110: bool is_box_klass() const; kvn@5110: bool is_boxed_value_offset(int offset) const; kvn@5110: twisti@1573: // Is this klass in the given package? twisti@1573: bool is_in_package(const char* packagename) { twisti@1573: return is_in_package(packagename, (int) strlen(packagename)); twisti@1573: } twisti@1573: bool is_in_package(const char* packagename, int len); twisti@1573: duke@435: // What kind of ciObject is this? coleenp@4037: bool is_instance_klass() const { return true; } coleenp@4037: bool is_java_klass() const { return true; } minqi@4267: minqi@4267: // Dump the current state of this klass for compilation replay. minqi@4267: virtual void dump_replay_data(outputStream* out); duke@435: }; stefank@2314: stefank@2314: #endif // SHARE_VM_CI_CIINSTANCEKLASS_HPP