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: #include "incls/_precompiled.incl" duke@435: #include "incls/_ciKlass.cpp.incl" duke@435: duke@435: // ciKlass duke@435: // duke@435: // This class represents a klassOop in the HotSpot virtual duke@435: // machine. duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciKlass::ciKlass duke@435: ciKlass::ciKlass(KlassHandle h_k) : ciType(h_k) { duke@435: assert(get_oop()->is_klass(), "wrong type"); duke@435: Klass* k = get_Klass(); duke@435: _layout_helper = k->layout_helper(); duke@435: symbolOop klass_name = k->name(); duke@435: assert(klass_name != NULL, "wrong ciKlass constructor"); duke@435: _name = CURRENT_ENV->get_object(klass_name)->as_symbol(); duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciKlass::ciKlass duke@435: // duke@435: // Nameless klass variant. duke@435: ciKlass::ciKlass(KlassHandle h_k, ciSymbol* name) : ciType(h_k) { duke@435: assert(get_oop()->is_klass(), "wrong type"); duke@435: _name = name; duke@435: _layout_helper = Klass::_lh_neutral_value; duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciKlass::ciKlass duke@435: // duke@435: // Unloaded klass variant. duke@435: ciKlass::ciKlass(ciSymbol* name, ciKlass* klass) : ciType(klass) { duke@435: _name = name; duke@435: _layout_helper = Klass::_lh_neutral_value; duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciKlass::is_subtype_of duke@435: bool ciKlass::is_subtype_of(ciKlass* that) { duke@435: assert(is_loaded() && that->is_loaded(), "must be loaded"); duke@435: assert(is_java_klass() && that->is_java_klass(), "must be java klasses"); duke@435: // Check to see if the klasses are identical. duke@435: if (this == that) { duke@435: return true; duke@435: } duke@435: duke@435: VM_ENTRY_MARK; duke@435: Klass* this_klass = get_Klass(); duke@435: klassOop that_klass = that->get_klassOop(); duke@435: bool result = this_klass->is_subtype_of(that_klass); duke@435: duke@435: return result; duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciKlass::is_subclass_of duke@435: bool ciKlass::is_subclass_of(ciKlass* that) { duke@435: assert(is_loaded() && that->is_loaded(), "must be loaded"); duke@435: assert(is_java_klass() && that->is_java_klass(), "must be java klasses"); duke@435: // Check to see if the klasses are identical. duke@435: duke@435: VM_ENTRY_MARK; duke@435: Klass* this_klass = get_Klass(); duke@435: klassOop that_klass = that->get_klassOop(); duke@435: bool result = this_klass->is_subclass_of(that_klass); duke@435: duke@435: return result; duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciKlass::super_depth duke@435: juint ciKlass::super_depth() { duke@435: assert(is_loaded(), "must be loaded"); duke@435: assert(is_java_klass(), "must be java klasses"); duke@435: duke@435: VM_ENTRY_MARK; duke@435: Klass* this_klass = get_Klass(); duke@435: return this_klass->super_depth(); duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciKlass::super_check_offset duke@435: juint ciKlass::super_check_offset() { duke@435: assert(is_loaded(), "must be loaded"); duke@435: assert(is_java_klass(), "must be java klasses"); duke@435: duke@435: VM_ENTRY_MARK; duke@435: Klass* this_klass = get_Klass(); duke@435: return this_klass->super_check_offset(); duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciKlass::super_of_depth duke@435: ciKlass* ciKlass::super_of_depth(juint i) { duke@435: assert(is_loaded(), "must be loaded"); duke@435: assert(is_java_klass(), "must be java klasses"); duke@435: duke@435: VM_ENTRY_MARK; duke@435: Klass* this_klass = get_Klass(); duke@435: klassOop super = this_klass->primary_super_of_depth(i); duke@435: return (super != NULL) ? CURRENT_THREAD_ENV->get_object(super)->as_klass() : NULL; duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciKlass::can_be_primary_super duke@435: bool ciKlass::can_be_primary_super() { duke@435: assert(is_loaded(), "must be loaded"); duke@435: assert(is_java_klass(), "must be java klasses"); duke@435: duke@435: VM_ENTRY_MARK; duke@435: Klass* this_klass = get_Klass(); duke@435: return this_klass->can_be_primary_super(); duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciKlass::least_common_ancestor duke@435: // duke@435: // Get the shared parent of two klasses. duke@435: // duke@435: // Implementation note: this method currently goes "over the wall" duke@435: // and does all of the work on the VM side. It could be rewritten duke@435: // to use the super() method and do all of the work (aside from the duke@435: // lazy computation of super()) in native mode. This may be duke@435: // worthwhile if the compiler is repeatedly requesting the same lca duke@435: // computation or possibly if most of the superklasses have already duke@435: // been created as ciObjects anyway. Something to think about... duke@435: ciKlass* duke@435: ciKlass::least_common_ancestor(ciKlass* that) { duke@435: assert(is_loaded() && that->is_loaded(), "must be loaded"); duke@435: assert(is_java_klass() && that->is_java_klass(), "must be java klasses"); duke@435: // Check to see if the klasses are identical. duke@435: if (this == that) { duke@435: return this; duke@435: } duke@435: duke@435: VM_ENTRY_MARK; duke@435: Klass* this_klass = get_Klass(); duke@435: Klass* that_klass = that->get_Klass(); duke@435: Klass* lca = this_klass->LCA(that_klass); duke@435: duke@435: // Many times the LCA will be either this_klass or that_klass. duke@435: // Treat these as special cases. duke@435: if (lca == that_klass) { duke@435: return that; duke@435: } duke@435: if (this_klass == lca) { duke@435: return this; duke@435: } duke@435: duke@435: // Create the ciInstanceKlass for the lca. duke@435: ciKlass* result = duke@435: CURRENT_THREAD_ENV->get_object(lca->as_klassOop())->as_klass(); duke@435: duke@435: return result; duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciKlass::find_klass duke@435: // duke@435: // Find a klass using this klass's class loader. duke@435: ciKlass* ciKlass::find_klass(ciSymbol* klass_name) { duke@435: assert(is_loaded(), "cannot find_klass through an unloaded klass"); duke@435: return CURRENT_ENV->get_klass_by_name(this, duke@435: klass_name, false); duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciKlass::java_mirror duke@435: ciInstance* ciKlass::java_mirror() { duke@435: GUARDED_VM_ENTRY( duke@435: oop java_mirror = get_Klass()->java_mirror(); duke@435: return CURRENT_ENV->get_object(java_mirror)->as_instance(); duke@435: ) duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciKlass::modifier_flags duke@435: jint ciKlass::modifier_flags() { duke@435: assert(is_loaded(), "not loaded"); duke@435: GUARDED_VM_ENTRY( duke@435: return get_Klass()->modifier_flags(); duke@435: ) duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciKlass::access_flags duke@435: jint ciKlass::access_flags() { duke@435: assert(is_loaded(), "not loaded"); duke@435: GUARDED_VM_ENTRY( duke@435: return get_Klass()->access_flags().as_int(); duke@435: ) duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciKlass::print_impl duke@435: // duke@435: // Implementation of the print method duke@435: void ciKlass::print_impl(outputStream* st) { duke@435: st->print(" name="); duke@435: print_name_on(st); duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciKlass::print_name duke@435: // duke@435: // Print the name of this klass duke@435: void ciKlass::print_name_on(outputStream* st) { duke@435: name()->print_symbol_on(st); duke@435: }