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: #include "precompiled.hpp" aoqi@0: #include "ci/ciConstant.hpp" aoqi@0: #include "ci/ciField.hpp" aoqi@0: #include "ci/ciInstance.hpp" aoqi@0: #include "ci/ciInstanceKlass.hpp" aoqi@0: #include "ci/ciUtilities.hpp" aoqi@0: #include "classfile/systemDictionary.hpp" aoqi@0: #include "oops/oop.inline.hpp" aoqi@0: aoqi@0: // ciInstance aoqi@0: // aoqi@0: // This class represents an instanceOop in the HotSpot virtual aoqi@0: // machine. aoqi@0: aoqi@0: // ------------------------------------------------------------------ aoqi@0: // ciObject::java_mirror_type aoqi@0: ciType* ciInstance::java_mirror_type() { aoqi@0: VM_ENTRY_MARK; aoqi@0: oop m = get_oop(); aoqi@0: // Return NULL if it is not java.lang.Class. aoqi@0: if (m == NULL || m->klass() != SystemDictionary::Class_klass()) { aoqi@0: return NULL; aoqi@0: } aoqi@0: // Return either a primitive type or a klass. aoqi@0: if (java_lang_Class::is_primitive(m)) { aoqi@0: return ciType::make(java_lang_Class::primitive_type(m)); aoqi@0: } else { aoqi@0: Klass* k = java_lang_Class::as_Klass(m); aoqi@0: assert(k != NULL, ""); aoqi@0: return CURRENT_THREAD_ENV->get_klass(k); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: // ------------------------------------------------------------------ aoqi@0: // ciInstance::field_value aoqi@0: // aoqi@0: // Constant value of a field. aoqi@0: ciConstant ciInstance::field_value(ciField* field) { aoqi@0: assert(is_loaded(), "invalid access - must be loaded"); aoqi@0: assert(field->holder()->is_loaded(), "invalid access - holder must be loaded"); aoqi@0: assert(klass()->is_subclass_of(field->holder()), "invalid access - must be subclass"); aoqi@0: aoqi@0: VM_ENTRY_MARK; aoqi@0: ciConstant result; aoqi@0: Handle obj = get_oop(); aoqi@0: assert(!obj.is_null(), "bad oop"); aoqi@0: BasicType field_btype = field->type()->basic_type(); aoqi@0: int offset = field->offset(); aoqi@0: aoqi@0: switch(field_btype) { aoqi@0: case T_BYTE: aoqi@0: return ciConstant(field_btype, obj->byte_field(offset)); aoqi@0: break; aoqi@0: case T_CHAR: aoqi@0: return ciConstant(field_btype, obj->char_field(offset)); aoqi@0: break; aoqi@0: case T_SHORT: aoqi@0: return ciConstant(field_btype, obj->short_field(offset)); aoqi@0: break; aoqi@0: case T_BOOLEAN: aoqi@0: return ciConstant(field_btype, obj->bool_field(offset)); aoqi@0: break; aoqi@0: case T_INT: aoqi@0: return ciConstant(field_btype, obj->int_field(offset)); aoqi@0: break; aoqi@0: case T_FLOAT: aoqi@0: return ciConstant(obj->float_field(offset)); aoqi@0: break; aoqi@0: case T_DOUBLE: aoqi@0: return ciConstant(obj->double_field(offset)); aoqi@0: break; aoqi@0: case T_LONG: aoqi@0: return ciConstant(obj->long_field(offset)); aoqi@0: break; aoqi@0: case T_OBJECT: aoqi@0: case T_ARRAY: aoqi@0: { aoqi@0: oop o = obj->obj_field(offset); aoqi@0: aoqi@0: // A field will be "constant" if it is known always to be aoqi@0: // a non-null reference to an instance of a particular class, aoqi@0: // or to a particular array. This can happen even if the instance aoqi@0: // or array is not perm. In such a case, an "unloaded" ciArray aoqi@0: // or ciInstance is created. The compiler may be able to use aoqi@0: // information about the object's class (which is exact) or length. aoqi@0: aoqi@0: if (o == NULL) { aoqi@0: return ciConstant(field_btype, ciNullObject::make()); aoqi@0: } else { aoqi@0: return ciConstant(field_btype, CURRENT_ENV->get_object(o)); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: ShouldNotReachHere(); aoqi@0: // to shut up the compiler aoqi@0: return ciConstant(); aoqi@0: } aoqi@0: aoqi@0: // ------------------------------------------------------------------ aoqi@0: // ciInstance::field_value_by_offset aoqi@0: // aoqi@0: // Constant value of a field at the specified offset. aoqi@0: ciConstant ciInstance::field_value_by_offset(int field_offset) { aoqi@0: ciInstanceKlass* ik = klass()->as_instance_klass(); aoqi@0: ciField* field = ik->get_field_by_offset(field_offset, false); aoqi@0: if (field == NULL) aoqi@0: return ciConstant(); // T_ILLEGAL aoqi@0: return field_value(field); aoqi@0: } aoqi@0: aoqi@0: // ------------------------------------------------------------------ aoqi@0: // ciInstance::print_impl aoqi@0: // aoqi@0: // Implementation of the print method. aoqi@0: void ciInstance::print_impl(outputStream* st) { aoqi@0: st->print(" type="); aoqi@0: klass()->print(st); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: ciKlass* ciInstance::java_lang_Class_klass() { aoqi@0: VM_ENTRY_MARK; aoqi@0: return CURRENT_ENV->get_metadata(java_lang_Class::as_Klass(get_oop()))->as_klass(); aoqi@0: }