duke@435: /* drchase@5732: * Copyright (c) 1999, 2013, 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/ciField.hpp" stefank@2314: #include "ci/ciInstanceKlass.hpp" stefank@2314: #include "ci/ciUtilities.hpp" stefank@2314: #include "classfile/systemDictionary.hpp" stefank@2314: #include "gc_interface/collectedHeap.inline.hpp" stefank@2314: #include "interpreter/linkResolver.hpp" stefank@2314: #include "memory/universe.inline.hpp" stefank@2314: #include "oops/oop.inline.hpp" stefank@2314: #include "oops/oop.inline2.hpp" stefank@2314: #include "runtime/fieldDescriptor.hpp" duke@435: duke@435: // ciField duke@435: // duke@435: // This class represents the result of a field lookup in the VM. duke@435: // The lookup may not succeed, in which case the information in duke@435: // the ciField will be incomplete. duke@435: duke@435: // The ciObjectFactory cannot create circular data structures in one query. duke@435: // To avoid vicious circularities, we initialize ciField::_type to NULL duke@435: // for reference types and derive it lazily from the ciField::_signature. duke@435: // Primitive types are eagerly initialized, and basic layout queries duke@435: // can succeed without initialization, using only the BasicType of the field. duke@435: duke@435: // Notes on bootstrapping and shared CI objects: A field is shared if and duke@435: // only if it is (a) non-static and (b) declared by a shared instance klass. duke@435: // This allows non-static field lists to be cached on shared types. duke@435: // Because the _type field is lazily initialized, however, there is a duke@435: // special restriction that a shared field cannot cache an unshared type. duke@435: // This puts a small performance penalty on shared fields with unshared duke@435: // types, such as StackTraceElement[] Throwable.stackTrace. duke@435: // (Throwable is shared because ClassCastException is shared, but duke@435: // StackTraceElement is not presently shared.) duke@435: duke@435: // It is not a vicious circularity for a ciField to recursively create duke@435: // the ciSymbols necessary to represent its name and signature. duke@435: // Therefore, these items are created eagerly, and the name and signature duke@435: // of a shared field are themselves shared symbols. This somewhat duke@435: // pollutes the set of shared CI objects: It grows from 50 to 93 items, duke@435: // with all of the additional 43 being uninteresting shared ciSymbols. duke@435: // This adds at most one step to the binary search, an amount which duke@435: // decreases for complex compilation tasks. duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciField::ciField never@3854: ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) { duke@435: ASSERT_IN_VM; duke@435: CompilerThread *thread = CompilerThread::current(); duke@435: duke@435: assert(ciObjectFactory::is_initialized(), "not a shared field"); duke@435: duke@435: assert(klass->get_instanceKlass()->is_linked(), "must be linked before using its constan-pool"); duke@435: duke@435: constantPoolHandle cpool(thread, klass->get_instanceKlass()->constants()); duke@435: duke@435: // Get the field's name, signature, and type. coleenp@2497: Symbol* name = cpool->name_ref_at(index); coleenp@2497: _name = ciEnv::current(thread)->get_symbol(name); duke@435: duke@435: int nt_index = cpool->name_and_type_ref_index_at(index); duke@435: int sig_index = cpool->signature_ref_index_at(nt_index); coleenp@2497: Symbol* signature = cpool->symbol_at(sig_index); coleenp@2497: _signature = ciEnv::current(thread)->get_symbol(signature); duke@435: coleenp@2497: BasicType field_type = FieldType::basic_type(signature); duke@435: duke@435: // If the field is a pointer type, get the klass of the duke@435: // field. duke@435: if (field_type == T_OBJECT || field_type == T_ARRAY) { duke@435: bool ignore; duke@435: // This is not really a class reference; the index always refers to the duke@435: // field's type signature, as a symbol. Linkage checks do not apply. twisti@1573: _type = ciEnv::current(thread)->get_klass_by_index(cpool, sig_index, ignore, klass); duke@435: } else { duke@435: _type = ciType::make(field_type); duke@435: } duke@435: coleenp@2497: _name = (ciSymbol*)ciEnv::current(thread)->get_symbol(name); duke@435: duke@435: // Get the field's declared holder. duke@435: // duke@435: // Note: we actually create a ciInstanceKlass for this klass, duke@435: // even though we may not need to. duke@435: int holder_index = cpool->klass_ref_index_at(index); duke@435: bool holder_is_accessible; duke@435: ciInstanceKlass* declared_holder = twisti@1573: ciEnv::current(thread)->get_klass_by_index(cpool, holder_index, twisti@1573: holder_is_accessible, twisti@1573: klass)->as_instance_klass(); duke@435: duke@435: // The declared holder of this field may not have been loaded. duke@435: // Bail out with partial field information. duke@435: if (!holder_is_accessible) { drchase@5732: // _type has already been set. duke@435: // The default values for _flags and _constant_value will suffice. duke@435: // We need values for _holder, _offset, and _is_constant, duke@435: _holder = declared_holder; duke@435: _offset = -1; duke@435: _is_constant = false; duke@435: return; duke@435: } duke@435: coleenp@4037: InstanceKlass* loaded_decl_holder = declared_holder->get_instanceKlass(); duke@435: duke@435: // Perform the field lookup. duke@435: fieldDescriptor field_desc; coleenp@4037: Klass* canonical_holder = coleenp@2497: loaded_decl_holder->find_field(name, signature, &field_desc); duke@435: if (canonical_holder == NULL) { duke@435: // Field lookup failed. Will be detected by will_link. duke@435: _holder = declared_holder; duke@435: _offset = -1; duke@435: _is_constant = false; duke@435: return; duke@435: } duke@435: duke@435: assert(canonical_holder == field_desc.field_holder(), "just checking"); duke@435: initialize_from(&field_desc); duke@435: } duke@435: never@3854: ciField::ciField(fieldDescriptor *fd): _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) { duke@435: ASSERT_IN_VM; duke@435: duke@435: // Get the field's name, signature, and type. duke@435: ciEnv* env = CURRENT_ENV; coleenp@2497: _name = env->get_symbol(fd->name()); coleenp@2497: _signature = env->get_symbol(fd->signature()); duke@435: duke@435: BasicType field_type = fd->field_type(); duke@435: duke@435: // If the field is a pointer type, get the klass of the duke@435: // field. duke@435: if (field_type == T_OBJECT || field_type == T_ARRAY) { duke@435: _type = NULL; // must call compute_type on first access duke@435: } else { duke@435: _type = ciType::make(field_type); duke@435: } duke@435: duke@435: initialize_from(fd); duke@435: duke@435: // Either (a) it is marked shared, or else (b) we are done bootstrapping. duke@435: assert(is_shared() || ciObjectFactory::is_initialized(), duke@435: "bootstrap classes must not create & cache unshared fields"); duke@435: } duke@435: jrose@1608: static bool trust_final_non_static_fields(ciInstanceKlass* holder) { jrose@1608: if (holder == NULL) jrose@1608: return false; jrose@1608: if (holder->name() == ciSymbol::java_lang_System()) jrose@1608: // Never trust strangely unstable finals: System.out, etc. jrose@1608: return false; jrose@1608: // Even if general trusting is disabled, trust system-built closures in these packages. jrose@2639: if (holder->is_in_package("java/lang/invoke") || holder->is_in_package("sun/invoke")) jrose@1608: return true; jrose@1608: return TrustFinalNonStaticFields; jrose@1608: } jrose@1608: duke@435: void ciField::initialize_from(fieldDescriptor* fd) { duke@435: // Get the flags, offset, and canonical holder of the field. duke@435: _flags = ciFlags(fd->access_flags()); duke@435: _offset = fd->offset(); coleenp@4037: _holder = CURRENT_ENV->get_instance_klass(fd->field_holder()); duke@435: duke@435: // Check to see if the field is constant. vlivanov@5658: bool is_final = this->is_final(); vlivanov@5658: bool is_stable = FoldStableValues && this->is_stable(); vlivanov@5658: if (_holder->is_initialized() && (is_final || is_stable)) { twisti@1573: if (!this->is_static()) { jrose@2639: // A field can be constant if it's a final static field or if jrose@2639: // it's a final non-static field of a trusted class (classes in jrose@2639: // java.lang.invoke and sun.invoke packages and subpackages). vlivanov@5658: if (is_stable || trust_final_non_static_fields(_holder)) { twisti@1573: _is_constant = true; twisti@1573: return; twisti@1573: } twisti@1573: _is_constant = false; twisti@1573: return; twisti@1573: } twisti@1573: duke@435: // This field just may be constant. The only cases where it will duke@435: // not be constant are: duke@435: // duke@435: // 1. The field holds a non-perm-space oop. The field is, strictly duke@435: // speaking, constant but we cannot embed non-perm-space oops into duke@435: // generated code. For the time being we need to consider the duke@435: // field to be not constant. duke@435: // 2. The field is a *special* static&final field whose value duke@435: // may change. The three examples are java.lang.System.in, duke@435: // java.lang.System.out, and java.lang.System.err. duke@435: coleenp@4037: KlassHandle k = _holder->get_Klass(); never@1577: assert( SystemDictionary::System_klass() != NULL, "Check once per vm"); never@2568: if( k() == SystemDictionary::System_klass() ) { duke@435: // Check offsets for case 2: System.in, System.out, or System.err duke@435: if( _offset == java_lang_System::in_offset_in_bytes() || duke@435: _offset == java_lang_System::out_offset_in_bytes() || duke@435: _offset == java_lang_System::err_offset_in_bytes() ) { duke@435: _is_constant = false; duke@435: return; duke@435: } duke@435: } duke@435: never@2658: Handle mirror = k->java_mirror(); never@2658: duke@435: switch(type()->basic_type()) { duke@435: case T_BYTE: never@2658: _constant_value = ciConstant(type()->basic_type(), mirror->byte_field(_offset)); duke@435: break; duke@435: case T_CHAR: never@2658: _constant_value = ciConstant(type()->basic_type(), mirror->char_field(_offset)); duke@435: break; duke@435: case T_SHORT: never@2658: _constant_value = ciConstant(type()->basic_type(), mirror->short_field(_offset)); duke@435: break; duke@435: case T_BOOLEAN: never@2658: _constant_value = ciConstant(type()->basic_type(), mirror->bool_field(_offset)); duke@435: break; duke@435: case T_INT: never@2658: _constant_value = ciConstant(type()->basic_type(), mirror->int_field(_offset)); duke@435: break; duke@435: case T_FLOAT: never@2658: _constant_value = ciConstant(mirror->float_field(_offset)); duke@435: break; duke@435: case T_DOUBLE: never@2658: _constant_value = ciConstant(mirror->double_field(_offset)); duke@435: break; duke@435: case T_LONG: never@2658: _constant_value = ciConstant(mirror->long_field(_offset)); duke@435: break; duke@435: case T_OBJECT: duke@435: case T_ARRAY: duke@435: { never@2658: oop o = mirror->obj_field(_offset); duke@435: duke@435: // A field will be "constant" if it is known always to be duke@435: // a non-null reference to an instance of a particular class, duke@435: // or to a particular array. This can happen even if the instance duke@435: // or array is not perm. In such a case, an "unloaded" ciArray duke@435: // or ciInstance is created. The compiler may be able to use duke@435: // information about the object's class (which is exact) or length. duke@435: duke@435: if (o == NULL) { duke@435: _constant_value = ciConstant(type()->basic_type(), ciNullObject::make()); duke@435: } else { duke@435: _constant_value = ciConstant(type()->basic_type(), CURRENT_ENV->get_object(o)); duke@435: assert(_constant_value.as_object() == CURRENT_ENV->get_object(o), "check interning"); duke@435: } duke@435: } duke@435: } vlivanov@5658: if (is_stable && _constant_value.is_null_or_zero()) { vlivanov@5658: // It is not a constant after all; treat it as uninitialized. vlivanov@5658: _is_constant = false; vlivanov@5658: } else { vlivanov@5658: _is_constant = true; vlivanov@5658: } duke@435: } else { duke@435: _is_constant = false; duke@435: } duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciField::compute_type duke@435: // duke@435: // Lazily compute the type, if it is an instance klass. duke@435: ciType* ciField::compute_type() { duke@435: GUARDED_VM_ENTRY(return compute_type_impl();) duke@435: } duke@435: duke@435: ciType* ciField::compute_type_impl() { jrose@2982: ciKlass* type = CURRENT_ENV->get_klass_by_name_impl(_holder, constantPoolHandle(), _signature, false); duke@435: if (!type->is_primitive_type() && is_shared()) { duke@435: // We must not cache a pointer to an unshared type, in a shared field. duke@435: bool type_is_also_shared = false; duke@435: if (type->is_type_array_klass()) { duke@435: type_is_also_shared = true; // int[] etc. are explicitly bootstrapped duke@435: } else if (type->is_instance_klass()) { duke@435: type_is_also_shared = type->as_instance_klass()->is_shared(); duke@435: } else { duke@435: // Currently there is no 'shared' query for array types. duke@435: type_is_also_shared = !ciObjectFactory::is_initialized(); duke@435: } duke@435: if (!type_is_also_shared) duke@435: return type; // Bummer. duke@435: } duke@435: _type = type; duke@435: return type; duke@435: } duke@435: duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciField::will_link duke@435: // duke@435: // Can a specific access to this field be made without causing duke@435: // link errors? duke@435: bool ciField::will_link(ciInstanceKlass* accessing_klass, duke@435: Bytecodes::Code bc) { duke@435: VM_ENTRY_MARK; never@3854: assert(bc == Bytecodes::_getstatic || bc == Bytecodes::_putstatic || never@3854: bc == Bytecodes::_getfield || bc == Bytecodes::_putfield, never@3854: "unexpected bytecode"); never@3854: duke@435: if (_offset == -1) { duke@435: // at creation we couldn't link to our holder so we need to duke@435: // maintain that stance, otherwise there's no safe way to use this duke@435: // ciField. duke@435: return false; duke@435: } duke@435: never@3854: // Check for static/nonstatic mismatch never@3854: bool is_static = (bc == Bytecodes::_getstatic || bc == Bytecodes::_putstatic); never@3854: if (is_static != this->is_static()) { never@3854: return false; never@3854: } never@3854: never@3854: // Get and put can have different accessibility rules never@3854: bool is_put = (bc == Bytecodes::_putfield || bc == Bytecodes::_putstatic); never@3854: if (is_put) { never@3854: if (_known_to_link_with_put == accessing_klass) { never@3854: return true; never@3854: } never@3856: } else { never@3854: if (_known_to_link_with_get == accessing_klass) { never@3854: return true; never@3854: } duke@435: } duke@435: drchase@5732: fieldDescriptor result; drchase@5732: LinkResolver::resolve_field(result, _holder->get_instanceKlass(), drchase@5732: _name->get_symbol(), _signature->get_symbol(), drchase@5732: accessing_klass->get_Klass(), bc, true, false, drchase@5732: KILL_COMPILE_ON_FATAL_(false)); duke@435: duke@435: // update the hit-cache, unless there is a problem with memory scoping: never@3854: if (accessing_klass->is_shared() || !is_shared()) { never@3854: if (is_put) { never@3854: _known_to_link_with_put = accessing_klass; never@3854: } else { never@3854: _known_to_link_with_get = accessing_klass; never@3854: } never@3854: } duke@435: duke@435: return true; duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciField::print duke@435: void ciField::print() { roland@4357: tty->print("print_symbol(); roland@4357: tty->print(" signature="); roland@4357: _signature->print_symbol(); duke@435: tty->print(" offset=%d type=", _offset); vlivanov@5658: if (_type != NULL) vlivanov@5658: _type->print_name(); vlivanov@5658: else vlivanov@5658: tty->print("(reference)"); vlivanov@5658: tty->print(" flags=%04x", flags().as_int()); duke@435: tty->print(" is_constant=%s", bool_to_str(_is_constant)); kvn@2037: if (_is_constant && is_static()) { duke@435: tty->print(" constant_value="); duke@435: _constant_value.print(); duke@435: } duke@435: tty->print(">"); duke@435: } duke@435: duke@435: // ------------------------------------------------------------------ duke@435: // ciField::print_name_on duke@435: // duke@435: // Print the name of this field duke@435: void ciField::print_name_on(outputStream* st) { duke@435: name()->print_symbol_on(st); duke@435: }