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/_ciObject.cpp.incl" duke@435: duke@435: // ciObject duke@435: // duke@435: // This class represents an oop in the HotSpot virtual machine. duke@435: // Its subclasses are structured in a hierarchy which mirrors duke@435: // an aggregate of the VM's oop and klass hierarchies (see duke@435: // oopHierarchy.hpp). Each instance of ciObject holds a handle duke@435: // to a corresponding oop on the VM side and provides routines duke@435: // for accessing the information in its oop. By using the ciObject duke@435: // hierarchy for accessing oops in the VM, the compiler ensures duke@435: // that it is safe with respect to garbage collection; that is, duke@435: // GC and compilation can proceed independently without duke@435: // interference. duke@435: // duke@435: // Within the VM, the oop and klass hierarchies are separate. duke@435: // The compiler interface does not preserve this separation -- duke@435: // the distinction between `klassOop' and `Klass' are not duke@435: // reflected in the interface and instead the Klass hierarchy duke@435: // is directly modeled as the subclasses of ciKlass. duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciObject::ciObject duke@435: ciObject::ciObject(oop o) { duke@435: ASSERT_IN_VM; duke@435: if (ciObjectFactory::is_initialized()) { duke@435: _handle = JNIHandles::make_local(o); duke@435: } else { duke@435: _handle = JNIHandles::make_global(o); duke@435: } duke@435: _klass = NULL; duke@435: _ident = 0; jrose@1424: init_flags_from(o); duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciObject::ciObject duke@435: // duke@435: ciObject::ciObject(Handle h) { duke@435: ASSERT_IN_VM; duke@435: if (ciObjectFactory::is_initialized()) { duke@435: _handle = JNIHandles::make_local(h()); duke@435: } else { duke@435: _handle = JNIHandles::make_global(h); duke@435: } duke@435: _klass = NULL; duke@435: _ident = 0; jrose@1424: init_flags_from(h()); duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciObject::ciObject duke@435: // duke@435: // Unloaded klass/method variant. `klass' is the klass of the unloaded duke@435: // klass/method, if that makes sense. duke@435: ciObject::ciObject(ciKlass* klass) { duke@435: ASSERT_IN_VM; duke@435: assert(klass != NULL, "must supply klass"); duke@435: _handle = NULL; duke@435: _klass = klass; duke@435: _ident = 0; duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciObject::ciObject duke@435: // duke@435: // NULL variant. Used only by ciNullObject. duke@435: ciObject::ciObject() { duke@435: ASSERT_IN_VM; duke@435: _handle = NULL; duke@435: _klass = NULL; duke@435: _ident = 0; duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciObject::klass duke@435: // duke@435: // Get the ciKlass of this ciObject. duke@435: ciKlass* ciObject::klass() { duke@435: if (_klass == NULL) { duke@435: if (_handle == NULL) { duke@435: // When both _klass and _handle are NULL, we are dealing duke@435: // with the distinguished instance of ciNullObject. duke@435: // No one should ask it for its klass. duke@435: assert(is_null_object(), "must be null object"); duke@435: ShouldNotReachHere(); duke@435: return NULL; duke@435: } duke@435: duke@435: GUARDED_VM_ENTRY( duke@435: oop o = get_oop(); duke@435: _klass = CURRENT_ENV->get_object(o->klass())->as_klass(); duke@435: ); duke@435: } duke@435: return _klass; duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciObject::set_ident duke@435: // duke@435: // Set the unique identity number of a ciObject. duke@435: void ciObject::set_ident(uint id) { duke@435: assert((_ident >> FLAG_BITS) == 0, "must only initialize once"); duke@435: assert( id < ((uint)1 << (BitsPerInt-FLAG_BITS)), "id too big"); duke@435: _ident = _ident + (id << FLAG_BITS); duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciObject::ident duke@435: // duke@435: // Report the unique identity number of a ciObject. duke@435: uint ciObject::ident() { duke@435: uint id = _ident >> FLAG_BITS; duke@435: assert(id != 0, "must be initialized"); duke@435: return id; duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciObject::equals duke@435: // duke@435: // Are two ciObjects equal? duke@435: bool ciObject::equals(ciObject* obj) { duke@435: return (this == obj); duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciObject::hash duke@435: // duke@435: // A hash value for the convenience of compilers. duke@435: // duke@435: // Implementation note: we use the address of the ciObject as the duke@435: // basis for the hash. Use the _ident field, which is well-behaved. duke@435: int ciObject::hash() { duke@435: return ident() * 31; duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ jrose@1424: // ciObject::constant_encoding duke@435: // duke@435: // The address which the compiler should embed into the duke@435: // generated code to represent this oop. This address duke@435: // is not the true address of the oop -- it will get patched duke@435: // during nmethod creation. duke@435: // duke@435: // duke@435: // duke@435: // Implementation note: we use the handle as the encoding. The duke@435: // nmethod constructor resolves the handle and patches in the oop. duke@435: // duke@435: // This method should be changed to return an generified address duke@435: // to discourage use of the JNI handle. jrose@1424: jobject ciObject::constant_encoding() { duke@435: assert(is_null_object() || handle() != NULL, "cannot embed null pointer"); jrose@1424: assert(can_be_constant(), "oop must be NULL or perm"); duke@435: return handle(); duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ jrose@1424: // ciObject::can_be_constant jrose@1424: bool ciObject::can_be_constant() { jrose@1424: if (ScavengeRootsInCode >= 1) return true; // now everybody can encode as a constant jrose@1424: return handle() == NULL || !is_scavengable(); jrose@1424: } jrose@1424: jrose@1424: // ------------------------------------------------------------------ jrose@1424: // ciObject::should_be_constant() jrose@1424: bool ciObject::should_be_constant() { jrose@1424: if (ScavengeRootsInCode >= 2) return true; // force everybody to be a constant jrose@1424: return handle() == NULL || !is_scavengable(); duke@435: } duke@435: duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciObject::print duke@435: // duke@435: // Print debugging output about this ciObject. duke@435: // duke@435: // Implementation note: dispatch to the virtual print_impl behavior duke@435: // for this ciObject. duke@435: void ciObject::print(outputStream* st) { duke@435: st->print("<%s", type_string()); duke@435: GUARDED_VM_ENTRY(print_impl(st);) jrose@1424: st->print(" ident=%d %s%s address=0x%x>", ident(), duke@435: is_perm() ? "PERM" : "", jrose@1424: is_scavengable() ? "SCAVENGABLE" : "", duke@435: (address)this); duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciObject::print_oop duke@435: // duke@435: // Print debugging output about the oop this ciObject represents. duke@435: void ciObject::print_oop(outputStream* st) { duke@435: if (is_null_object()) { duke@435: st->print_cr("NULL"); duke@435: } else if (!is_loaded()) { duke@435: st->print_cr("UNLOADED"); duke@435: } else { duke@435: GUARDED_VM_ENTRY(get_oop()->print_on(st);) duke@435: } duke@435: }