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