duke@435: /* duke@435: * Copyright 1999-2007 Sun Microsystems, Inc. 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: * duke@435: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, duke@435: * CA 95054 USA or visit www.sun.com if you need additional information or duke@435: * have any questions. duke@435: * duke@435: */ duke@435: duke@435: // ciInstanceKlass duke@435: // duke@435: // This class represents a klassOop in the HotSpot virtual machine duke@435: // 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 duke@435: friend class ciEnv; duke@435: friend class ciMethod; duke@435: friend class ciField; duke@435: friend class ciBytecodeStream; duke@435: duke@435: private: duke@435: bool _is_shared; duke@435: duke@435: jobject _loader; duke@435: jobject _protection_domain; duke@435: duke@435: bool _is_initialized; duke@435: bool _is_linked; duke@435: bool _has_finalizer; duke@435: bool _has_subklass; duke@435: ciFlags _flags; duke@435: jint _nonstatic_field_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: duke@435: enum { implementors_limit = instanceKlass::implementors_limit }; duke@435: ciInstanceKlass* _implementors[implementors_limit]; duke@435: jint _nof_implementors; duke@435: duke@435: protected: duke@435: ciInstanceKlass(KlassHandle h_k); duke@435: ciInstanceKlass(ciSymbol* name, jobject loader, jobject protection_domain); duke@435: duke@435: instanceKlass* get_instanceKlass() const { duke@435: 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: 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: duke@435: bool compute_shared_is_initialized(); duke@435: bool compute_shared_is_linked(); duke@435: bool compute_shared_has_subklass(); duke@435: int compute_shared_nof_implementors(); duke@435: int compute_nonstatic_fields(); duke@435: GrowableArray* compute_nonstatic_fields_impl(GrowableArray* super_fields); duke@435: duke@435: public: duke@435: // Has this klass been initialized? duke@435: bool is_initialized() { duke@435: if (_is_shared && !_is_initialized) { duke@435: return is_loaded() && compute_shared_is_initialized(); duke@435: } duke@435: return _is_initialized; duke@435: } duke@435: // Has this klass been linked? duke@435: bool is_linked() { duke@435: if (_is_shared && !_is_linked) { duke@435: return is_loaded() && compute_shared_is_linked(); duke@435: } duke@435: return _is_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; } duke@435: ciInstanceKlass* super(); duke@435: jint nof_implementors() { duke@435: assert(is_loaded(), "must be loaded"); duke@435: if (_is_shared) return compute_shared_nof_implementors(); duke@435: return _nof_implementors; 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); 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) { duke@435: return (offset/wordSize) >= instanceOopDesc::header_size() duke@435: && (offset/wordSize)-instanceOopDesc::header_size() < 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(); duke@435: ciInstanceKlass* implementor(int n); duke@435: duke@435: // Is the defining class loader of this class the default loader? duke@435: bool uses_default_loader(); duke@435: duke@435: bool is_java_lang_Object(); duke@435: duke@435: // What kind of ciObject is this? duke@435: bool is_instance_klass() { return true; } duke@435: bool is_java_klass() { return true; } duke@435: };