# HG changeset patch # User Thomas Wuerthinger # Date 1321404505 -3600 # Node ID ff6a991c6e3c4485b26c97e34948c985d66708b1 # Parent c7d4198a9bce04a7cdf08d8de5673c6093828f51 Use GraalEnv to look up types. diff -r c7d4198a9bce -r ff6a991c6e3c src/share/vm/graal/graalCompiler.cpp --- a/src/share/vm/graal/graalCompiler.cpp Tue Nov 15 22:06:02 2011 +0100 +++ b/src/share/vm/graal/graalCompiler.cpp Wed Nov 16 01:48:25 2011 +0100 @@ -27,6 +27,7 @@ #include "graal/graalVMExits.hpp" #include "graal/graalVMEntries.hpp" #include "graal/graalVmIds.hpp" +#include "graal/graalEnv.hpp" #include "c1/c1_Runtime1.hpp" #include "runtime/arguments.hpp" @@ -124,33 +125,62 @@ TRACE_graal_1("GraalCompiler::print_timers"); } -oop GraalCompiler::get_RiType(KlassHandle klass, KlassHandle accessor, TRAPS) { - if (klass->oop_is_instance_slow()) { - assert(instanceKlass::cast(klass())->is_initialized(), "unexpected unresolved klass"); - } else if (klass->oop_is_javaArray_slow()){ +oop GraalCompiler::get_RiType(Symbol* klass_name, TRAPS) { + return VMExits::createRiTypeUnresolved(VmIds::toString(klass_name, THREAD), THREAD); +} + +oop GraalCompiler::get_RiTypeFromSignature(constantPoolHandle cp, int index, KlassHandle loading_klass, TRAPS) { + + Symbol* signature = cp->symbol_at(index); + BasicType field_type = FieldType::basic_type(signature); + // If the field is a pointer type, get the klass of the + // field. + if (field_type == T_OBJECT || field_type == T_ARRAY) { + KlassHandle handle = GraalEnv::get_klass_by_name(loading_klass, signature, false); + if (handle.is_null()) { + return get_RiType(signature, CHECK_NULL); + } else { + return get_RiType(handle, CHECK_NULL); + } } else { - klass()->print(); - assert(false, "unexpected klass"); + return VMExits::createRiTypePrimitive(field_type, CHECK_NULL); } +} + +oop GraalCompiler::get_RiType(constantPoolHandle cp, int index, KlassHandle loading_klass, TRAPS) { + bool is_accessible = false; + + KlassHandle klass = GraalEnv::get_klass_by_index(cp, index, is_accessible, loading_klass); + oop catch_class = NULL; + if (klass.is_null()) { + // We have to lock the cpool to keep the oop from being resolved + // while we are accessing it. + ObjectLocker ol(cp, THREAD); + + Symbol* klass_name = NULL; + constantTag tag = cp->tag_at(index); + if (tag.is_klass()) { + // The klass has been inserted into the constant pool + // very recently. + return GraalCompiler::get_RiType(cp->resolved_klass_at(index), CHECK_NULL); + } else if (tag.is_symbol()) { + klass_name = cp->symbol_at(index); + } else { + assert(cp->tag_at(index).is_unresolved_klass(), "wrong tag"); + klass_name = cp->unresolved_klass_at(index); + } + return GraalCompiler::get_RiType(klass_name, CHECK_NULL); + } else { + return GraalCompiler::get_RiType(klass, CHECK_NULL); + } +} + +oop GraalCompiler::get_RiType(KlassHandle klass, TRAPS) { Handle name = VmIds::toString(klass->name(), THREAD); return createHotSpotTypeResolved(klass, name, CHECK_NULL); } - oop GraalCompiler::get_RiType(ciType *type, KlassHandle accessor, TRAPS) { - if (type->is_loaded()) { - if (type->is_primitive_type()) { - return VMExits::createRiTypePrimitive((int) type->basic_type(), THREAD); - } - KlassHandle klass = (klassOop) type->get_oop(); - Handle name = VmIds::toString(klass->name(), THREAD); - return createHotSpotTypeResolved(klass, name, CHECK_NULL); - } else { - Symbol* name = ((ciKlass *) type)->name()->get_symbol(); - return VMExits::createRiTypeUnresolved(VmIds::toString(name, THREAD), THREAD); - } -} - -oop GraalCompiler::get_RiField(ciField *field, ciInstanceKlass* accessor_klass, KlassHandle accessor, Bytecodes::Code byteCode, TRAPS) { +oop GraalCompiler::get_RiField(ciField *field, ciInstanceKlass* accessor_klass, Handle field_holder, Handle field_type, Bytecodes::Code byteCode, TRAPS) { int offset; if (byteCode != Bytecodes::_illegal) { bool will_link = field->will_link_from_vm(accessor_klass, byteCode); @@ -159,8 +189,6 @@ offset = field->offset(); } Handle field_name = VmIds::toString(field->name()->get_symbol(), CHECK_0); - Handle field_holder = get_RiType(field->holder(), accessor, CHECK_0); - Handle field_type = get_RiType(field->type(), accessor, CHECK_0); int flags = field->flags().as_int(); return VMExits::createRiField(field_holder, field_name, field_type, offset, flags, THREAD); } diff -r c7d4198a9bce -r ff6a991c6e3c src/share/vm/graal/graalCompiler.hpp --- a/src/share/vm/graal/graalCompiler.hpp Tue Nov 15 22:06:02 2011 +0100 +++ b/src/share/vm/graal/graalCompiler.hpp Wed Nov 16 01:48:25 2011 +0100 @@ -56,10 +56,12 @@ // Print compilation timers and statistics virtual void print_timers(); - - static oop get_RiType(KlassHandle klass, KlassHandle accessor, TRAPS); - static oop get_RiType(ciType *klass, KlassHandle accessor, TRAPS); - static oop get_RiField(ciField *ciField, ciInstanceKlass* accessor_klass, KlassHandle accessor, Bytecodes::Code byteCode, TRAPS); + + static oop get_RiTypeFromSignature(constantPoolHandle cp, int index, KlassHandle accessor, TRAPS); + static oop get_RiType(constantPoolHandle cp, int index, KlassHandle accessor, TRAPS); + static oop get_RiType(Symbol* klass_name, TRAPS); + static oop get_RiType(KlassHandle klass, TRAPS); + static oop get_RiField(ciField *field, ciInstanceKlass* accessor_klass, Handle field_holder, Handle field_type, Bytecodes::Code byteCode, TRAPS); static oop createHotSpotTypeResolved(KlassHandle klass, Handle name, TRAPS); static oop createHotSpotMethodResolved(methodHandle method, TRAPS); diff -r c7d4198a9bce -r ff6a991c6e3c src/share/vm/graal/graalVMEntries.cpp --- a/src/share/vm/graal/graalVMEntries.cpp Tue Nov 15 22:06:02 2011 +0100 +++ b/src/share/vm/graal/graalVMEntries.cpp Wed Nov 16 01:48:25 2011 +0100 @@ -22,11 +22,13 @@ */ #include "precompiled.hpp" +#include "runtime/fieldDescriptor.hpp" #include "c1/c1_Runtime1.hpp" #include "ci/ciMethodData.hpp" #include "compiler/compileBroker.hpp" #include "graal/graalVMEntries.hpp" #include "graal/graalCompiler.hpp" +#include "graal/graalEnv.hpp" #include "graal/graalJavaAccess.hpp" #include "graal/graalCodeInstaller.hpp" #include "graal/graalVMExits.hpp" @@ -120,11 +122,8 @@ HotSpotExceptionHandler::set_catchClass(entry, NULL); } else { constantPoolOop cp = instanceKlass::cast(method->method_holder())->constants(); - ciInstanceKlass* loading_klass = (ciInstanceKlass *) CURRENT_ENV->get_object(method->method_holder()); - bool is_accessible = false; - ciKlass *klass = CURRENT_ENV->get_klass_by_index(cp, catch_class_index, is_accessible, loading_klass); - oop catch_class = GraalCompiler::get_RiType(klass, method->method_holder(), CHECK_NULL); - + KlassHandle loading_klass = method->method_holder(); + oop catch_class = GraalCompiler::get_RiType(cp, catch_class_index, loading_klass, CHECK_NULL); HotSpotExceptionHandler::set_catchClass(entry, catch_class); } array->obj_at_put(i, entry()); @@ -308,7 +307,7 @@ if (receiver.is_null()) continue; float prob = recv->receiver_count(i) / (float) total_count; - oop type = GraalCompiler::get_RiType(receiver, KlassHandle(), CHECK_NULL); + oop type = GraalCompiler::get_RiType(receiver, CHECK_NULL); probabilities->float_at_put(pos, prob); types->obj_at_put(pos, type); @@ -512,9 +511,8 @@ result = VMExits::createCiConstantObject(string, CHECK_0); } else if (tag.is_klass() || tag.is_unresolved_klass()) { bool ignore; - ciInstanceKlass* accessor = (ciInstanceKlass*) ciEnv::current()->get_object(cp->pool_holder()); - ciKlass* klass = ciEnv::current()->get_klass_by_index(cp, index, ignore, accessor); - result = GraalCompiler::get_RiType(klass, cp->pool_holder(), CHECK_NULL); + KlassHandle klass = GraalEnv::get_klass_by_index(cp, index, ignore, cp->pool_holder()); + result = GraalCompiler::get_RiType(klass, CHECK_NULL); } else if (tag.is_object()) { oop obj = cp->object_at(index); assert(obj->is_instance(), "must be an instance"); @@ -531,7 +529,7 @@ TRACE_graal_3("VMEntries::RiConstantPool_lookupMethod"); VM_ENTRY_MARK; index = GraalCompiler::to_cp_index_u2(index); - constantPoolOop cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type)))->constants(); + constantPoolHandle cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type)))->constants(); Bytecodes::Code bc = (Bytecodes::Code) (((int) byteCode) & 0xFF); ciInstanceKlass* loading_klass = (ciInstanceKlass *) CURRENT_ENV->get_object(cp->pool_holder()); @@ -541,10 +539,12 @@ oop ret = GraalCompiler::createHotSpotMethodResolved(method, CHECK_NULL); return JNIHandles::make_local(THREAD, ret); } else { - Handle name = VmIds::toString(cimethod->name()->get_symbol(), CHECK_NULL); - Handle signature = VmIds::toString(cimethod->signature()->as_symbol()->get_symbol(), CHECK_NULL); - Handle holder = GraalCompiler::get_RiType(cimethod->holder(), cp->klass(), THREAD); - return JNIHandles::make_local(THREAD, VMExits::createRiMethodUnresolved(name, signature, holder, THREAD)); + // Get the method's name and signature. + Handle name = VmIds::toString(cp->name_ref_at(index), CHECK_NULL); + Handle signature = VmIds::toString(cp->signature_ref_at(index), CHECK_NULL); + int holder_index = cp->klass_ref_index_at(index); + Handle type = GraalCompiler::get_RiType(cp, holder_index, cp->pool_holder(), CHECK_NULL); + return JNIHandles::make_local(THREAD, VMExits::createRiMethodUnresolved(name, signature, type, THREAD)); } } @@ -554,11 +554,8 @@ VM_ENTRY_MARK; constantPoolOop cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type)))->constants(); - - ciInstanceKlass* loading_klass = (ciInstanceKlass *) CURRENT_ENV->get_object(cp->pool_holder()); - bool is_accessible = false; - ciKlass *klass = CURRENT_ENV->get_klass_by_index(cp, index, is_accessible, loading_klass); - return JNIHandles::make_local(THREAD, GraalCompiler::get_RiType(klass, cp->klass(), THREAD)); + oop result = GraalCompiler::get_RiType(cp, index, cp->pool_holder(), CHECK_NULL); + return JNIHandles::make_local(THREAD, result); } // public void RiConstantPool_loadReferencedType(long vmId, int cpi); @@ -586,18 +583,37 @@ } // public RiField RiConstantPool_lookupField(long vmId, int cpi); -JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_VMEntries_RiConstantPool_1lookupField(JNIEnv *env, jobject, jobject type, jint index, jbyte byteCode) { +JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_VMEntries_RiConstantPool_1lookupField(JNIEnv *env, jobject, jobject constantPoolHolder, jint index, jbyte byteCode) { TRACE_graal_3("VMEntries::RiConstantPool_lookupField"); VM_ENTRY_MARK; index = GraalCompiler::to_cp_index_u2(index); - constantPoolOop cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type)))->constants(); + constantPoolHandle cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(constantPoolHolder)))->constants(); ciInstanceKlass* loading_klass = (ciInstanceKlass *) CURRENT_ENV->get_object(cp->pool_holder()); ciField *field = CURRENT_ENV->get_field_by_index(loading_klass, index); + int nt_index = cp->name_and_type_ref_index_at(index); + int sig_index = cp->signature_ref_index_at(nt_index); + Symbol* signature = cp->symbol_at(sig_index); + int holder_index = cp->klass_ref_index_at(index); + Handle holder = GraalCompiler::get_RiType(cp, holder_index, cp->pool_holder(), CHECK_NULL); + Bytecodes::Code code = (Bytecodes::Code)(((int) byteCode) & 0xFF); - Handle field_handle = GraalCompiler::get_RiField(field, loading_klass, cp->pool_holder(), code, THREAD); + if (holder->klass() == SystemDictionary::HotSpotTypeResolved_klass()) { + FieldAccessInfo result; + LinkResolver::resolve_field(result, cp, index, + Bytecodes::java_code(code), + true, false, Thread::current()); + if (HAS_PENDING_EXCEPTION) { + CLEAR_PENDING_EXCEPTION; + } + //result.field_offset(); + holder = GraalCompiler::get_RiType(result.klass(), CHECK_NULL); + } + + Handle type = GraalCompiler::get_RiTypeFromSignature(cp, sig_index, cp->pool_holder(), CHECK_NULL); + Handle field_handle = GraalCompiler::get_RiField(field, loading_klass, holder, type, code, THREAD); bool is_constant = field->is_constant(); if (is_constant && field->is_static()) { ciConstant constant = field->constant_value(); @@ -692,17 +708,12 @@ // public RiType RiType_componentType(HotSpotResolvedType klass); JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_VMEntries_RiType_1componentType(JNIEnv *, jobject, jobject klass) { TRACE_graal_3("VMEntries::RiType_componentType"); - ciArrayKlass* array_klass; - { - VM_ENTRY_MARK; - assert(JNIHandles::resolve(klass) != NULL, ""); - array_klass = (ciArrayKlass *) CURRENT_ENV->get_object(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass))); - } - ciType* element_type = array_klass->element_type(); - VM_ENTRY_MARK; + KlassHandle array_klass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass)); + assert(array_klass->oop_is_objArray(), "just checking"); + klassOop element_type = objArrayKlass::cast(array_klass())->element_klass(); assert(JNIHandles::resolve(klass) != NULL, ""); - return JNIHandles::make_local(GraalCompiler::get_RiType(element_type, java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass)), THREAD)); + return JNIHandles::make_local(GraalCompiler::get_RiType(element_type, THREAD)); } // public RiType RiType_superType(HotSpotResolvedType klass); @@ -710,18 +721,17 @@ TRACE_graal_3("VMEntries::RiType_superType"); VM_ENTRY_MARK; KlassHandle klass_handle(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass))); - ciInstanceKlass* k = NULL; + klassOop k; if (klass_handle->oop_is_array()) { - k = (ciInstanceKlass *) CURRENT_ENV->get_object(SystemDictionary::Object_klass()); + k = SystemDictionary::Object_klass(); } else { guarantee(klass_handle->oop_is_instance(), "must be instance klass"); - k = (ciInstanceKlass *) CURRENT_ENV->get_object(klass_handle()); - k = k->super(); + k = klass_handle->super(); } if (k != NULL) { - return JNIHandles::make_local(GraalCompiler::get_RiType(k, klass_handle, THREAD)); + return JNIHandles::make_local(GraalCompiler::get_RiType(k, THREAD)); } else { return NULL; } @@ -730,25 +740,12 @@ // public RiType RiType_uniqueConcreteSubtype(HotSpotResolvedType klass); JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_VMEntries_RiType_1uniqueConcreteSubtype(JNIEnv *, jobject, jobject klass) { TRACE_graal_3("VMEntries::RiType_uniqueConcreteSubtype"); - Thread* THREAD = Thread::current(); + VM_ENTRY_MARK; KlassHandle klass_handle(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass))); - ciInstanceKlass* k = NULL; - { - VM_ENTRY_MARK; - k = (ciInstanceKlass *) CURRENT_ENV->get_object(klass_handle()); + Klass *up_cast = klass_handle->up_cast_abstract(); + if (up_cast->is_leaf_class()) { + return JNIHandles::make_local(GraalCompiler::get_RiType(up_cast, THREAD)); } - - if (k->is_abstract()) { - ciInstanceKlass* sub = k->unique_concrete_subklass(); - if (sub != NULL && sub->is_leaf_type()) { - VM_ENTRY_MARK; - return JNIHandles::make_local(GraalCompiler::get_RiType(sub, klass_handle, THREAD)); - } - } else if (k->is_leaf_type()) { - assert(!k->is_interface(), ""); - return klass; - } - return NULL; } @@ -774,39 +771,32 @@ // public RiField[] RiType_fields(HotSpotTypeResolved klass); JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_VMEntries_RiType_1fields(JNIEnv *, jobject, jobject klass) { TRACE_graal_3("VMEntries::RiType_fields"); - KlassHandle klass_handle; - ciInstanceKlass* instance_klass; - objArrayHandle fieldsArray; - HandleMark hm; - { - VM_ENTRY_MARK; - klass_handle = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass)); - instance_klass = (ciInstanceKlass *) CURRENT_ENV->get_object(klass_handle()); - } - GrowableArray* fields = instance_klass->non_static_fields(); - { - VM_ENTRY_MARK; + VM_ENTRY_MARK; + + instanceKlassHandle k = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass)); + objArrayHandle field_array = oopFactory::new_objArray(SystemDictionary::RiField_klass(), k->fields()->length() / instanceKlass::next_offset, CHECK_NULL); + class MyFieldClosure : public FieldClosure { + public: + instanceKlassHandle _holder; + Handle _resolved_type_holder; + objArrayHandle _field_array; + int _current; + + MyFieldClosure(instanceKlassHandle& holder, Handle resolved_type_holder, objArrayHandle field_array) : _holder(holder), _resolved_type_holder(resolved_type_holder), _field_array(field_array), _current(0) { } - int count = 0; - for (int i = 0; i < fields->length(); i++) { - ciField* field = fields->at(i); - if (field->holder() == instance_klass) { - count++; + virtual void do_field(fieldDescriptor* fd) { + if (!Thread::current()->has_pending_exception()) { + if (fd->field_holder() == _holder()) { + Handle type = GraalCompiler::get_RiTypeFromSignature(fd->constants(), fd->signature_index(), fd->field_holder(), Thread::current()); + Handle field = VMExits::createRiField(_resolved_type_holder, VmIds::toString(fd->name(), Thread::current()), type, fd->offset(), fd->access_flags().as_int(), Thread::current()); + _field_array->obj_at_put(_current++, field()); + } } } - - fieldsArray = oopFactory::new_objArray(SystemDictionary::RiField_klass(), count, CHECK_NULL); - int z = 0; - for (int i = 0; i < fields->length(); i++) { - ciField* field = fields->at(i); - if (field->holder() == instance_klass) { - Handle field_handle = GraalCompiler::get_RiField(field, instance_klass, klass_handle, Bytecodes::_illegal, CHECK_NULL); - fieldsArray->obj_at_put(z, field_handle()); - z++; - } - } - } - return JNIHandles::make_local(fieldsArray()); + }; + MyFieldClosure closure(k, JNIHandles::resolve(klass), field_array); + k->do_nonstatic_fields(&closure); + return JNIHandles::make_local(field_array()); } // public RiType getPrimitiveArrayType(CiKind kind); @@ -815,8 +805,7 @@ VM_ENTRY_MARK; BasicType type = GraalCompiler::kindToBasicType(CiKind::typeChar(kind)); assert(type != T_OBJECT, "primitive type expecteds"); - ciKlass* klass = ciTypeArrayKlass::make(type); - return JNIHandles::make_local(THREAD, GraalCompiler::get_RiType(klass, KlassHandle(), THREAD)); + return JNIHandles::make_local(THREAD, GraalCompiler::get_RiType(Universe::typeArrayKlassObj(type), THREAD)); } // public long getMaxCallTargetOffset(CiRuntimeCall rtcall); diff -r c7d4198a9bce -r ff6a991c6e3c src/share/vm/oops/instanceKlass.hpp --- a/src/share/vm/oops/instanceKlass.hpp Tue Nov 15 22:06:02 2011 +0100 +++ b/src/share/vm/oops/instanceKlass.hpp Wed Nov 16 01:48:25 2011 +0100 @@ -634,7 +634,7 @@ void process_interfaces(Thread *thread); // virtual operations from Klass - bool is_leaf_class() const { return _subklass == NULL; } + bool is_leaf_class() const { return _subklass == NULL && _nof_implementors == 0; } objArrayOop compute_secondary_supers(int num_extra_slots, TRAPS); bool compute_is_subtype_of(klassOop k); bool can_be_primary_super_slow() const; diff -r c7d4198a9bce -r ff6a991c6e3c src/share/vm/runtime/fieldDescriptor.hpp --- a/src/share/vm/runtime/fieldDescriptor.hpp Tue Nov 15 22:06:02 2011 +0100 +++ b/src/share/vm/runtime/fieldDescriptor.hpp Wed Nov 16 01:48:25 2011 +0100 @@ -49,6 +49,8 @@ constantPoolHandle _cp; public: + int name_index() const { return _name_index; } + int signature_index() const { return _signature_index; } Symbol* name() const { return _cp->symbol_at(_name_index); } Symbol* signature() const { return _cp->symbol_at(_signature_index); } klassOop field_holder() const { return _cp->pool_holder(); }