# HG changeset patch # User Thomas Wuerthinger # Date 1293649601 -3600 # Node ID 00bc9eaf0e24b0b5c1a861b9152ca0831b297740 # Parent 79d04223b8a5b98242edf5e4b0f4bce4286c0e34 Support for -XX:+UseFastLocking flag. Fixed monitor enter XIR template for correct debug info at the runtime call. diff -r 79d04223b8a5 -r 00bc9eaf0e24 c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotVMConfig.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotVMConfig.java Tue Dec 28 18:33:26 2010 +0100 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotVMConfig.java Wed Dec 29 20:06:41 2010 +0100 @@ -33,6 +33,7 @@ public boolean windowsOs; public int codeEntryAlignment; public boolean verifyPointers; + public boolean useFastLocking; // offsets, ... public int vmPageSize; @@ -73,6 +74,8 @@ public long throwArrayIndexException; public long monitorEnterStub; public long monitorExitStub; + public long fastMonitorEnterStub; + public long fastMonitorExitStub; public long verifyPointerStub; public void check() { diff -r 79d04223b8a5 -r 00bc9eaf0e24 c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java Tue Dec 28 18:33:26 2010 +0100 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java Wed Dec 29 20:06:41 2010 +0100 @@ -314,9 +314,20 @@ asm.pload(CiKind.Word, asm.createTemp("temp", CiKind.Word), object, true); } - useRegisters(asm, AMD64.rbx, AMD64.rsi, AMD64.rdx); - useRegisters(asm, AMD64.rax); - asm.callRuntime(config.monitorEnterStub, null, object, lock); + + // (tw) It is important to use for this runtime call the debug info AFTER the monitor enter. Otherwise the monitor object + // is not correctly garbage collected. + final boolean useInfoAfter = true; + + if (config.useFastLocking) { + useRegisters(asm, AMD64.rbx, AMD64.rsi, AMD64.rdx, AMD64.rax); + asm.callRuntime(config.fastMonitorEnterStub, null, useInfoAfter, object, lock); + } else { + asm.reserveOutgoingStack(target.wordSize * 2); + asm.pstore(CiKind.Object, asm.createRegister("rsp", CiKind.Word, AMD64.RSP.asRegister()), asm.i(target.wordSize), object, false); + asm.pstore(CiKind.Word, asm.createRegister("rsp", CiKind.Word, AMD64.RSP.asRegister()), asm.i(0), lock, false); + asm.callRuntime(config.monitorEnterStub, null, useInfoAfter); + } return asm.finishTemplate("monitorEnter"); } @@ -330,9 +341,14 @@ XirParameter object = asm.createInputParameter("object", CiKind.Object); XirParameter lock = asm.createInputParameter("lock", CiKind.Word); - useRegisters(asm, AMD64.rbx, AMD64.rsi, AMD64.rdx); - useRegisters(asm, AMD64.rax); - asm.callRuntime(config.monitorExitStub, null, object, lock); + if (config.useFastLocking) { + useRegisters(asm, AMD64.rbx, AMD64.rsi, AMD64.rdx, AMD64.rax); + asm.callRuntime(config.fastMonitorExitStub, null, object, lock); + } else { + asm.reserveOutgoingStack(target.wordSize); + asm.pstore(CiKind.Word, asm.createRegister("rsp", CiKind.Word, AMD64.RSP.asRegister()), asm.i(0), lock, false); + asm.callRuntime(config.monitorExitStub, null); + } return asm.finishTemplate("monitorExit"); } diff -r 79d04223b8a5 -r 00bc9eaf0e24 c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExitsNative.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExitsNative.java Tue Dec 28 18:33:26 2010 +0100 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExitsNative.java Wed Dec 29 20:06:41 2010 +0100 @@ -51,7 +51,7 @@ C1XOptions.UseDeopt = false; C1XOptions.IRChecking = false; C1XOptions.DetailedAsserts = false; - C1XOptions.CommentedAssembly = true; + C1XOptions.CommentedAssembly = false; C1XOptions.MethodEndBreakpointGuards = 2; } diff -r 79d04223b8a5 -r 00bc9eaf0e24 src/cpu/x86/vm/c1_Runtime1_x86.cpp --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp Tue Dec 28 18:33:26 2010 +0100 +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp Wed Dec 29 20:06:41 2010 +0100 @@ -2010,6 +2010,7 @@ Register scratch1 = rax; Register scratch2 = rbx; + assert_different_registers(obj, lock, scratch1, scratch2); // copied from LIR_Assembler::emit_lock if (UseFastLocking) { @@ -2043,6 +2044,7 @@ Register lock2 = rax; __ mov(lock2, lock); Register scratch1 = rbx; + assert_different_registers(obj, lock, scratch1, lock2); // copied from LIR_Assembler::emit_lock if (UseFastLocking) { diff -r 79d04223b8a5 -r 00bc9eaf0e24 src/os/linux/vm/os_linux.cpp --- a/src/os/linux/vm/os_linux.cpp Tue Dec 28 18:33:26 2010 +0100 +++ b/src/os/linux/vm/os_linux.cpp Wed Dec 29 20:06:41 2010 +0100 @@ -3408,6 +3408,7 @@ void signalHandler(int sig, siginfo_t* info, void* uc) { assert(info != NULL && uc != NULL, "it must be old kernel"); + ResourceMark rm; if (TraceSignals) { tty->print_cr(err_msg("signal received: code=%d errno=%d signo=%d thread=%s address=%x", info->si_code, info->si_errno, info->si_signo, Thread::current()->name(), info->si_addr)); } diff -r 79d04223b8a5 -r 00bc9eaf0e24 src/os_cpu/linux_x86/vm/os_linux_x86.cpp --- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Tue Dec 28 18:33:26 2010 +0100 +++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Wed Dec 29 20:06:41 2010 +0100 @@ -260,7 +260,7 @@ if (cb != NULL && cb->is_nmethod()) { nmethod* nm = (nmethod*)cb; int rel = pc - nm->code_begin(); - tty->print_cr("Implicit exception at %d of method %s", rel, nm->method()->name()->as_C_string()); + tty->print_cr(err_msg("Implicit exception at %d of method %s", rel, nm->method()->name()->as_C_string())); } else { tty->print_cr("No code blob found for %x", pc); } diff -r 79d04223b8a5 -r 00bc9eaf0e24 src/share/vm/c1/c1_Runtime1.cpp --- a/src/share/vm/c1/c1_Runtime1.cpp Tue Dec 28 18:33:26 2010 +0100 +++ b/src/share/vm/c1/c1_Runtime1.cpp Wed Dec 29 20:06:41 2010 +0100 @@ -596,12 +596,22 @@ JRT_ENTRY_NO_ASYNC(void, Runtime1::monitorenter(JavaThread* thread, oopDesc* obj, BasicObjectLock* lock)) NOT_PRODUCT(_monitorenter_slowcase_cnt++;) +#ifdef ASSERT + if (TraceC1X >= 3) { + tty->print_cr("entered locking slow case with obj=" INTPTR_FORMAT " and lock= " INTPTR_FORMAT, obj, lock); + } if (PrintBiasedLockingStatistics) { Atomic::inc(BiasedLocking::slow_path_entry_count_addr()); } +#endif Handle h_obj(thread, obj); assert(h_obj()->is_oop(), "must be NULL or an object"); if (UseBiasedLocking) { + if (UseFastLocking) { + assert(obj == lock->obj(), "must match"); + } else { + lock->set_obj(obj); + } // Retry fast entry if bias is revoked to avoid unnecessary inflation ObjectSynchronizer::fast_enter(h_obj, lock->lock(), true, CHECK); } else { @@ -614,6 +624,14 @@ ObjectSynchronizer::fast_enter(h_obj, lock->lock(), false, THREAD); } } +#ifdef ASSERT + if (TraceC1X >= 3) { + tty->print_cr("exiting locking lock state: obj=" INTPTR_FORMAT, lock->obj()); + lock->lock()->print_on(tty); + tty->print_cr(""); + tty->print_cr("done"); + } +#endif JRT_END @@ -631,7 +649,7 @@ ResetNoHandleMark rhm; nmethod* method = thread->last_frame().cb()->as_nmethod_or_null(); if (method != NULL) { - tty->print_cr("ERROR in monitorexit in method %s", method->name()); + tty->print_cr("ERROR in monitorexit in method %s wrong obj " INTPTR_FORMAT, method->name(), obj); } thread->print_stack_on(tty); assert(false, "invalid lock object pointer dected"); diff -r 79d04223b8a5 -r 00bc9eaf0e24 src/share/vm/c1/c1_globals.hpp --- a/src/share/vm/c1/c1_globals.hpp Tue Dec 28 18:33:26 2010 +0100 +++ b/src/share/vm/c1/c1_globals.hpp Wed Dec 29 20:06:41 2010 +0100 @@ -217,7 +217,7 @@ develop(bool, UseFastNewObjectArray, true, \ "Use fast inlined object array allocation") \ \ - develop(bool, UseFastLocking, true, \ + product(bool, UseFastLocking, true, \ "Use fast inlined locking code") \ \ develop(bool, UseSlowPath, false, \ diff -r 79d04223b8a5 -r 00bc9eaf0e24 src/share/vm/c1x/c1x_CodeInstaller.cpp --- a/src/share/vm/c1x/c1x_CodeInstaller.cpp Tue Dec 28 18:33:26 2010 +0100 +++ b/src/share/vm/c1x/c1x_CodeInstaller.cpp Wed Dec 29 20:06:41 2010 +0100 @@ -559,6 +559,7 @@ Handle obj = CiConstant::object(constant); if (obj->is_a(HotSpotTypeResolved::klass())) { + assert(!obj.is_null(), ""); *((jobject*) operand) = JNIHandles::make_local(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(obj))); _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); TRACE_C1X_3("relocating (HotSpotType) at %016x/%016x", instruction, operand); diff -r 79d04223b8a5 -r 00bc9eaf0e24 src/share/vm/c1x/c1x_Compiler.cpp --- a/src/share/vm/c1x/c1x_Compiler.cpp Tue Dec 28 18:33:26 2010 +0100 +++ b/src/share/vm/c1x/c1x_Compiler.cpp Wed Dec 29 20:06:41 2010 +0100 @@ -139,6 +139,7 @@ instanceKlass::cast(HotSpotTypeResolved::klass())->initialize(CHECK_NULL); oop obj = instanceKlass::cast(HotSpotTypeResolved::klass())->allocate_instance(CHECK_NULL); + assert(obj != NULL, "must succeed in allocating instance"); HotSpotTypeResolved::set_javaMirror(obj, klass->java_mirror()); HotSpotTypeResolved::set_name(obj, name()); diff -r 79d04223b8a5 -r 00bc9eaf0e24 src/share/vm/c1x/c1x_TargetMethod.hpp --- a/src/share/vm/c1x/c1x_TargetMethod.hpp Tue Dec 28 18:33:26 2010 +0100 +++ b/src/share/vm/c1x/c1x_TargetMethod.hpp Wed Dec 29 20:06:41 2010 +0100 @@ -190,7 +190,7 @@ class name : AllStatic { \ private: \ friend class C1XCompiler; \ - static void check(oop obj) { assert(obj != NULL, "NULL field access"); assert(obj->is_a(SystemDictionary::name##_klass()), "wrong class, " #name " expected"); } \ + static void check(oop obj) { assert(obj != NULL, "NULL field access of class " #name); assert(obj->is_a(SystemDictionary::name##_klass()), "wrong class, " #name " expected"); } \ static void compute_offsets(); \ public: \ static klassOop klass() { return SystemDictionary::name##_klass(); } diff -r 79d04223b8a5 -r 00bc9eaf0e24 src/share/vm/c1x/c1x_VMEntries.cpp --- a/src/share/vm/c1x/c1x_VMEntries.cpp Tue Dec 28 18:33:26 2010 +0100 +++ b/src/share/vm/c1x/c1x_VMEntries.cpp Wed Dec 29 20:06:41 2010 +0100 @@ -141,8 +141,12 @@ 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 = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(accessingClass))->klass_part()->class_loader(); - Handle protectionDomain = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(accessingClass))->klass_part()->protection_domain(); + Handle classloader; + Handle protectionDomain; + if (JNIHandles::resolve(accessingClass) != NULL) { + classloader = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(accessingClass))->klass_part()->class_loader(); + protectionDomain = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(accessingClass))->klass_part()->protection_domain(); + } resolved_type = SystemDictionary::resolve_or_null(nameSymbol, classloader, protectionDomain, THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; @@ -310,6 +314,7 @@ JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1constantPool(JNIEnv *, jobject, jobject klass) { VM_ENTRY_MARK; + assert(JNIHandles::resolve(klass) != NULL, ""); constantPoolOop constantPool = ((instanceKlass*)java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass))->klass_part())->constants(); return JNIHandles::make_local(VMExits::createRiConstantPool(VmIds::add(constantPool), THREAD)); } @@ -318,6 +323,7 @@ JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_3resolveMethodImpl(JNIEnv *, jobject, jobject resolved_type, jstring name, jstring signature) { VM_ENTRY_MARK; + assert(JNIHandles::resolve(resolved_type) != NULL, ""); klassOop klass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(resolved_type)); symbolOop name_symbol = VmIds::toSymbol(name); symbolOop signature_symbol = VmIds::toSymbol(signature); @@ -336,6 +342,7 @@ JNIEXPORT jboolean JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_2isSubtypeOf(JNIEnv *, jobject, jobject klass, jobject jother) { oop other = JNIHandles::resolve(jother); assert(other->is_a(HotSpotTypeResolved::klass()), "resolved hotspot type expected"); + assert(JNIHandles::resolve(klass) != NULL, ""); klassOop thisKlass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass)); klassOop otherKlass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(other)); if (thisKlass->klass_part()->oop_is_instance_slow()) { @@ -352,11 +359,13 @@ 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; + assert(JNIHandles::resolve(klass) != NULL, ""); return JNIHandles::make_local(C1XCompiler::get_RiType(element_type, java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass)), THREAD)); } @@ -427,6 +436,7 @@ set_boolean(env, config, "windowsOs", false); #endif set_boolean(env, config, "verifyPointers", VerifyOops); + set_boolean(env, config, "useFastLocking", UseFastLocking); set_int(env, config, "codeEntryAlignment", CodeEntryAlignment); set_int(env, config, "vmPageSize", os::vm_page_size()); set_int(env, config, "stackShadowPages", StackShadowPages); @@ -459,8 +469,10 @@ 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::c1x_monitorenter_id))); - set_long(env, config, "monitorExitStub", VmIds::addStub(Runtime1::entry_for(Runtime1::c1x_monitorexit_id))); + set_long(env, config, "monitorEnterStub", VmIds::addStub(Runtime1::entry_for(Runtime1::monitorenter_id))); + set_long(env, config, "monitorExitStub", VmIds::addStub(Runtime1::entry_for(Runtime1::monitorexit_id))); + set_long(env, config, "fastMonitorEnterStub", VmIds::addStub(Runtime1::entry_for(Runtime1::c1x_monitorenter_id))); + set_long(env, config, "fastMonitorExitStub", VmIds::addStub(Runtime1::entry_for(Runtime1::c1x_monitorexit_id))); set_long(env, config, "safepointPollingAddress", (jlong)(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()))); BarrierSet* bs = Universe::heap()->barrier_set(); diff -r 79d04223b8a5 -r 00bc9eaf0e24 src/share/vm/oops/oop.inline.hpp --- a/src/share/vm/oops/oop.inline.hpp Tue Dec 28 18:33:26 2010 +0100 +++ b/src/share/vm/oops/oop.inline.hpp Wed Dec 29 20:06:41 2010 +0100 @@ -533,8 +533,8 @@ // used only for asserts inline bool oopDesc::is_oop(bool ignore_mark_word) const { oop obj = (oop) this; - if (!check_obj_alignment(obj)) return false; - if (!Universe::heap()->is_in_reserved(obj)) return false; + if (!check_obj_alignment(obj)) { tty->print_cr("unaligned"); return false; } + if (!Universe::heap()->is_in_reserved(obj)) { tty->print_cr("not in reserved"); return false; } // obj is aligned and accessible in heap // try to find metaclass cycle safely without seg faulting on bad input // we should reach klassKlassObj by following klass link at most 3 times diff -r 79d04223b8a5 -r 00bc9eaf0e24 src/share/vm/runtime/sharedRuntime.cpp --- a/src/share/vm/runtime/sharedRuntime.cpp Tue Dec 28 18:33:26 2010 +0100 +++ b/src/share/vm/runtime/sharedRuntime.cpp Wed Dec 29 20:06:41 2010 +0100 @@ -731,7 +731,7 @@ #endif if (UseC1X) { if (TraceSignals) { - tty->print_cr("calling implicit call stub relative pc=%d method name = %s", pc - nm->entry_point(), nm->method()->name()->as_C_string()); + tty->print_cr(err_msg("calling implicit call stub relative pc=%d method name = %s", pc - nm->entry_point(), nm->method()->name()->as_C_string())); } target_pc = Runtime1::entry_for(Runtime1::c1x_global_implicit_null_id); } else { diff -r 79d04223b8a5 -r 00bc9eaf0e24 src/share/vm/runtime/stackValue.cpp --- a/src/share/vm/runtime/stackValue.cpp Tue Dec 28 18:33:26 2010 +0100 +++ b/src/share/vm/runtime/stackValue.cpp Wed Dec 29 20:06:41 2010 +0100 @@ -116,7 +116,15 @@ #endif #ifndef PRODUCT if (val != NULL && !val->is_oop()) { - tty->print_cr("found wrong oop " INTPTR_FORMAT " at location:", val); + ResourceMark rm; + tty->print_cr("found wrong oop " INTPTR_FORMAT " at location " INTPTR_FORMAT " (%d):", val, value_addr, val->is_oop()); + if (fr->cb() != NULL) { + CodeBlob* cb = fr->cb(); + if (cb->is_nmethod()) { + nmethod* nm = (nmethod*)cb; + tty->print_cr("method is %s", nm->method()->name()->as_C_string()); + } + } sv->print(); tty->print_cr(""); tty->print_cr("one less %d; one more %d", (*(((oop *)value_addr) - 1))->is_oop(), (*(((oop *)value_addr) + 1))->is_oop());