duke@435: /* coleenp@4037: * 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: #include "precompiled.hpp" stefank@2314: #include "ci/ciKlass.hpp" stefank@2314: #include "ci/ciSymbol.hpp" stefank@2314: #include "ci/ciUtilities.hpp" stefank@2314: #include "oops/oop.inline.hpp" duke@435: duke@435: // ciKlass duke@435: // coleenp@4037: // This class represents a Klass* 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) { coleenp@4037: assert(get_Klass()->is_klass(), "wrong type"); duke@435: Klass* k = get_Klass(); duke@435: _layout_helper = k->layout_helper(); coleenp@2497: Symbol* klass_name = k->name(); duke@435: assert(klass_name != NULL, "wrong ciKlass constructor"); coleenp@2497: _name = CURRENT_ENV->get_symbol(klass_name); 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) { coleenp@4037: assert(get_Klass()->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. coleenp@4037: ciKlass::ciKlass(ciSymbol* name, BasicType bt) : ciType(bt) { 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: // 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(); coleenp@4037: Klass* that_klass = that->get_Klass(); 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: // Check to see if the klasses are identical. duke@435: duke@435: VM_ENTRY_MARK; duke@435: Klass* this_klass = get_Klass(); coleenp@4037: Klass* that_klass = that->get_Klass(); 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: 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: 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: duke@435: VM_ENTRY_MARK; duke@435: Klass* this_klass = get_Klass(); coleenp@4037: Klass* super = this_klass->primary_super_of_depth(i); coleenp@4037: return (super != NULL) ? CURRENT_THREAD_ENV->get_klass(super) : 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: 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: // 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 = coleenp@4037: CURRENT_THREAD_ENV->get_klass(lca); 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 jrose@1959: // jrose@1959: // Get the instance of java.lang.Class corresponding to this klass. jrose@1959: // If it is an unloaded instance or array klass, return an unloaded jrose@1959: // mirror object of type Class. duke@435: ciInstance* ciKlass::java_mirror() { duke@435: GUARDED_VM_ENTRY( jrose@1959: if (!is_loaded()) jrose@1959: return ciEnv::current()->get_unloaded_klass_mirror(this); duke@435: oop java_mirror = get_Klass()->java_mirror(); coleenp@4037: return CURRENT_ENV->get_instance(java_mirror); 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: }