Mercurial > hg > truffle
diff src/share/vm/c1x/c1x_VMEntries.cpp @ 1433:efba53f86c4f
various fixes and enhancements
* correct refmap->oopmap conversion (register numbering, stack slot numbering)
* fixes for inlining (correct scoping in exception handler lookup, NPE in scope conversion)
* support for "jump to runtime stub" (patching code needs to be aware of jmp instruction)
* provide more information about methods (to allow inlining: has_balanced_monitors, etc.)
* fixes to signature type lookup
* isSubTypeOf: correct handling of array classes
* RiType: componentType/arrayOf
* prologue: inline cache check, icmiss stub
* klass state check (resolved but not initialized) in newinstance
* card table write barriers
* c1x classes are optional (to allow running c1 without them)
* correct for stored frame pointer in calling conventions (methods with arguments on stack)
* getType(Class<?>) for some basic types, used for optimizations and folding
* RiMethod/RiType: throw exception instead of silent failure on unsupported operations
* RiType: resolved/unresolved array type support
* refactoring: new on-demand template generation mechanism
* optimizations: template specialization for no_null_check, given length, etc.
author | Lukas Stadler <lukas.stadler@oracle.com> |
---|---|
date | Thu, 16 Sep 2010 19:42:20 -0700 |
parents | b61a43cd1255 |
children | 72cfb36c6bb2 |
line wrap: on
line diff
--- a/src/share/vm/c1x/c1x_VMEntries.cpp Wed Sep 01 17:13:38 2010 -0700 +++ b/src/share/vm/c1x/c1x_VMEntries.cpp Thu Sep 16 19:42:20 2010 -0700 @@ -103,6 +103,16 @@ return (jobjectArray) JNIHandles::make_local(array()); } +// public boolean RiMethod_hasBalancedMonitors(long vmId); +JNIEXPORT jint JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1hasBalancedMonitors(JNIEnv *, jobject, jlong vmId) { + ciMethod* cimethod; + { + VM_ENTRY_MARK; + cimethod = (ciMethod*)CURRENT_ENV->get_object(VmIds::get<methodOop>(vmId)); + } + return cimethod->has_balanced_monitors(); +} + // public RiType RiSignature_lookupType(String returnType, long accessingClassVmId); JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiSignature_1lookupType(JNIEnv *env, jobject, jstring jname, jlong accessingClassVmId) { VM_ENTRY_MARK; @@ -128,13 +138,17 @@ } else if (nameSymbol == vmSymbols::float_signature()) { result = VMExits::createRiTypePrimitive((int) T_FLOAT, THREAD); } else { - Handle classloader; - Handle protectionDomain; - if (accessingClassVmId != 0) { - classloader = VmIds::get<klassOop>(accessingClassVmId)->klass_part()->class_loader(); - protectionDomain = VmIds::get<klassOop>(accessingClassVmId)->klass_part()->protection_domain(); + klassOop resolved_type = NULL; + // if the name isn't in the symbol table then the class isn't loaded anyway... + if (nameSymbol != NULL) { + Handle classloader; + Handle protectionDomain; + if (accessingClassVmId != 0) { + classloader = VmIds::get<klassOop>(accessingClassVmId)->klass_part()->class_loader(); + protectionDomain = VmIds::get<klassOop>(accessingClassVmId)->klass_part()->protection_domain(); + } + resolved_type = SystemDictionary::resolve_or_null(nameSymbol, classloader, protectionDomain, THREAD); } - klassOop resolved_type = SystemDictionary::resolve_or_null(nameSymbol, classloader, protectionDomain, THREAD); if (resolved_type != NULL) { result = C1XCompiler::createHotSpotTypeResolved(resolved_type, name, CHECK_NULL); } else { @@ -174,7 +188,10 @@ return NULL; } } - result = VMExits::createCiConstantObject(VmIds::add<oop>(string), CHECK_0); + jlong id = VmIds::add<oop>(string); +// tty->print("\n\nstring: 0x%08x%08x\n", string, id>>32, id); +// string->print(); + result = VMExits::createCiConstantObject(id, CHECK_0); } else if (tag.is_klass() || tag.is_unresolved_klass()) { bool ignore; ciInstanceKlass* accessor = (ciInstanceKlass*) ciEnv::current()->get_object(cp->pool_holder()); @@ -238,7 +255,7 @@ ciInstanceKlass* loading_klass = (ciInstanceKlass *) CURRENT_ENV->get_object(cp->pool_holder()); ciField *field = CURRENT_ENV->get_field_by_index(loading_klass, index); - return JNIHandles::make_local(THREAD, C1XCompiler::get_RiField(field, THREAD)); + return JNIHandles::make_local(THREAD, C1XCompiler::get_RiField(field, cp->pool_holder(), THREAD)); } // public RiConstantPool RiType_constantPool(long vmId); @@ -264,17 +281,36 @@ assert(other->is_a(HotSpotTypeResolved::klass()), "resolved hotspot type expected"); klassOop thisKlass = VmIds::get<klassOop>(vmId); klassOop otherKlass = VmIds::get<klassOop>(HotSpotTypeResolved::vmId(other)); - return instanceKlass::cast(thisKlass)->is_subtype_of(otherKlass); + if (thisKlass->klass_part()->oop_is_instance_slow()) { + return instanceKlass::cast(thisKlass)->is_subtype_of(otherKlass); + } else if (thisKlass->klass_part()->oop_is_array()) { + return arrayKlass::cast(thisKlass)->is_subtype_of(otherKlass); + } else { + fatal("unexpected class type"); + } } -// helpers used to set fields in the HotSpotVMConfig object -jfieldID getFieldID(JNIEnv* env, jobject obj, const char* name, const char* sig) { - jfieldID id = env->GetFieldID(env->GetObjectClass(obj), name, sig); - if (id == NULL) { - TRACE_C1X_1("field not found: %s (%s)", name, sig); - fatal("field not found"); +// public RiType RiType_componentType(long vmId); +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1componentType(JNIEnv *, jobject, jlong vmId) { + ciArrayKlass* klass; + { + VM_ENTRY_MARK; + klass = (ciArrayKlass *) CURRENT_ENV->get_object(VmIds::get<klassOop>(vmId)); } - return id; + ciType* element_type = klass->element_type(); + + VM_ENTRY_MARK; + return JNIHandles::make_local(C1XCompiler::get_RiType(element_type, VmIds::get<klassOop>(vmId), THREAD)); +} + +// public RiType RiType_arrayOf(long vmId); +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1arrayOf(JNIEnv *, jobject, jlong vmId) { + VM_ENTRY_MARK; + + instanceKlass* klass = instanceKlass::cast(VmIds::get<klassOop>(vmId)); + KlassHandle array = klass->array_klass(THREAD); + Handle name = array->name(); + return JNIHandles::make_local(THREAD, C1XCompiler::createHotSpotTypeResolved(array, name, THREAD)); } // public RiType getPrimitiveArrayType(CiKind kind); @@ -299,6 +335,26 @@ return JNIHandles::make_local(THREAD, C1XCompiler::get_RiType(klass, NULL, THREAD)); } +// public RiType getType(Class<?> javaClass); +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_getType(JNIEnv *env, jobject, jobject javaClass) { + VM_ENTRY_MARK; + KlassHandle klass = java_lang_Class::as_klassOop(JNIHandles::resolve(javaClass)); + Handle name = java_lang_String::create_from_symbol(klass->name(), CHECK_NULL); + + oop type = C1XCompiler::createHotSpotTypeResolved(klass, name, CHECK_NULL); + return JNIHandles::make_local(THREAD, type); +} + + +// helpers used to set fields in the HotSpotVMConfig object +jfieldID getFieldID(JNIEnv* env, jobject obj, const char* name, const char* sig) { + jfieldID id = env->GetFieldID(env->GetObjectClass(obj), name, sig); + if (id == NULL) { + TRACE_C1X_1("field not found: %s (%s)", name, sig); + fatal("field not found"); + } + return id; +} void set_boolean(JNIEnv* env, jobject obj, const char* name, bool value) { env->SetBooleanField(obj, getFieldID(env, obj, name, "Z"), value); } void set_int(JNIEnv* env, jobject obj, const char* name, int value) { env->SetIntField(obj, getFieldID(env, obj, name, "I"), value); } @@ -331,6 +387,8 @@ set_int(env, config, "stackShadowPages", StackShadowPages); set_int(env, config, "hubOffset", oopDesc::klass_offset_in_bytes()); set_int(env, config, "arrayLengthOffset", arrayOopDesc::length_offset_in_bytes()); + set_int(env, config, "klassStateOffset", instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc)); + set_int(env, config, "klassStateFullyInitialized", (int)instanceKlass::fully_initialized); set_int(env, config, "threadTlabTopOffset", in_bytes(JavaThread::tlab_top_offset())); set_int(env, config, "threadTlabEndOffset", in_bytes(JavaThread::tlab_end_offset())); set_int(env, config, "instanceHeaderPrototypeOffset", Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()); @@ -341,16 +399,45 @@ set_long(env, config, "debugStub", VmIds::addStub((address)warning)); set_long(env, config, "instanceofStub", VmIds::addStub(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); set_long(env, config, "newInstanceStub", VmIds::addStub(Runtime1::entry_for(Runtime1::fast_new_instance_init_check_id))); + set_long(env, config, "unresolvedNewInstanceStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_instance_id))); set_long(env, config, "newTypeArrayStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_type_array_id))); set_long(env, config, "newObjectArrayStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_object_array_id))); set_long(env, config, "newMultiArrayStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_multi_array_id))); set_long(env, config, "loadKlassStub", VmIds::addStub(Runtime1::entry_for(Runtime1::load_klass_patching_id))); + set_long(env, config, "accessFieldStub", VmIds::addStub(Runtime1::entry_for(Runtime1::access_field_patching_id))); set_long(env, config, "resolveStaticCallStub", VmIds::addStub(SharedRuntime::get_resolve_static_call_stub())); + set_long(env, config, "inlineCacheMissStub", VmIds::addStub(SharedRuntime::get_ic_miss_stub())); set_long(env, config, "unwindExceptionStub", VmIds::addStub(Runtime1::entry_for(Runtime1::c1x_unwind_exception_call_id))); set_long(env, config, "handleExceptionStub", VmIds::addStub(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id))); set_long(env, config, "throwClassCastException", VmIds::addStub(Runtime1::entry_for(Runtime1::throw_class_cast_exception_id))); set_long(env, config, "throwArrayStoreException", VmIds::addStub(Runtime1::entry_for(Runtime1::throw_array_store_exception_id))); set_long(env, config, "throwArrayIndexException", VmIds::addStub(Runtime1::entry_for(Runtime1::throw_range_check_failed_id))); + set_long(env, config, "monitorEnterStub", VmIds::addStub(Runtime1::entry_for(Runtime1::monitorenter_nofpu_id))); + set_long(env, config, "monitorExitStub", VmIds::addStub(Runtime1::entry_for(Runtime1::monitorexit_nofpu_id))); + + BarrierSet* bs = Universe::heap()->barrier_set(); + switch (bs->kind()) { + case BarrierSet::CardTableModRef: + case BarrierSet::CardTableExtension: { + jlong base = (jlong)((CardTableModRefBS*)bs)->byte_map_base; + assert(base != 0, "unexpected byte_map_base"); + set_long(env, config, "cardtableStartAddress", base); + set_int(env, config, "cardtableShift", CardTableModRefBS::card_shift); + break; + } + case BarrierSet::ModRef: + case BarrierSet::Other: + set_long(env, config, "cardtableStartAddress", 0); + set_int(env, config, "cardtableShift", 0); + // No post barriers + break; +#ifndef SERIALGC + case BarrierSet::G1SATBCT: + case BarrierSet::G1SATBCTLogging: +#endif // SERIALGC + default: + ShouldNotReachHere(); + } jintArray arrayOffsets = env->NewIntArray(basicTypeCount); for (int i=0; i<basicTypeCount; i++) { @@ -394,6 +481,7 @@ #define CI_KIND "Lcom/sun/cri/ci/CiKind;" #define STRING "Ljava/lang/String;" #define OBJECT "Ljava/lang/Object;" +#define CLASS "Ljava/lang/Class;" JNINativeMethod VMEntries_methods[] = { {CC"RiMethod_code", CC"("PROXY")[B", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1code)}, @@ -403,6 +491,7 @@ {CC"RiMethod_signature", CC"("PROXY")"STRING, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1signature)}, {CC"RiMethod_accessFlags", CC"("PROXY")I", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1accessFlags)}, {CC"RiMethod_exceptionHandlers", CC"("PROXY")"EXCEPTION_HANDLERS, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1exceptionHandlers)}, + {CC"RiMethod_hasBalancedMonitors", CC"("PROXY")Z", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1hasBalancedMonitors)}, {CC"RiSignature_lookupType", CC"("STRING PROXY")"TYPE, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiSignature_1lookupType)}, {CC"RiConstantPool_lookupConstant", CC"("PROXY"I)"OBJECT, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupConstant)}, {CC"RiConstantPool_lookupMethod", CC"("PROXY"IB)"METHOD, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupMethod)}, @@ -412,7 +501,10 @@ {CC"RiType_constantPool", CC"("PROXY")"CONSTANT_POOL, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_1constantPool)}, {CC"RiType_resolveMethodImpl", CC"("PROXY STRING STRING")"METHOD, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_3resolveMethodImpl)}, {CC"RiType_isSubtypeOf", CC"("PROXY TYPE")Z", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_2isSubtypeOf)}, + {CC"RiType_componentType", CC"("PROXY")"TYPE, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_1componentType)}, + {CC"RiType_arrayOf", CC"("PROXY")"TYPE, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_1arrayOf)}, {CC"getPrimitiveArrayType", CC"("CI_KIND")"TYPE, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_getPrimitiveArrayType)}, + {CC"getType", CC"("CLASS")"TYPE, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_getType)}, {CC"getConfiguration", CC"()"CONFIG, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_getConfiguration)}, {CC"installMethod", CC"("TARGET_METHOD")V", FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_installMethod)}, {CC"installStub", CC"("TARGET_METHOD")"PROXY, FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_installStub)}