# HG changeset patch # User Lukas Stadler # Date 1285892388 25200 # Node ID 72cfb36c6bb252ea640c6c7d5e550d42d87d7020 # Parent efba53f86c4f1d0d0267f11b62979e636441d849 * enabled all jtt tests * added proxy that counts jni calls * honor hotspot stackshadowpages * constant pool caching * monitor enter/exit * arithmetic stubs (frem, drem, ...) * create stack values for debug info * some doc diff -r efba53f86c4f -r 72cfb36c6bb2 c1x4hotspotsrc/HotSpotTest/src/C1XTest.java --- a/c1x4hotspotsrc/HotSpotTest/src/C1XTest.java Thu Sep 16 19:42:20 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotTest/src/C1XTest.java Thu Sep 30 17:19:48 2010 -0700 @@ -8,12 +8,24 @@ return sum; } - public static void main3(String[] args) {/* - long s = 0; - s += value(); - System.out.println(s);*/ + public static class Unresolved { + public static int i = 1234; + } + + public static void main4(String[] args) { + System.out.println(Unresolved.i); } - + + public static void main3(String[] args) { + System.out.println("before"); + synchronized(args) { + System.out.println("enter1"); + System.gc(); + System.out.println("enter2"); + } + System.out.println("exit"); + } + public static void main2(String[] args) { Other.I[] array = new Other.I[] { new Other.A(), new Other.B(), new Other.C(), new Other.A(), new Other.B(), new Other.C() }; @@ -32,7 +44,7 @@ test1(); } System.out.println(); - for (int i = 0; i < 100; i++) { + for (int i = 0; i < 20; i++) { Thread.sleep(1000); } for (int i = 0; i < 10000; i++) { @@ -40,7 +52,7 @@ test2(); } System.out.println(); - for (int i = 0; i < 100; i++) { + for (int i = 0; i < 10; i++) { Thread.sleep(1000); } for (int i = 0; i < 10000; i++) { @@ -48,7 +60,7 @@ test3(); } System.out.println(); - for (int i = 0; i < 100; i++) { + for (int i = 0; i < 10; i++) { Thread.sleep(1000); } for (int i = 0; i < 10000; i++) { @@ -56,7 +68,7 @@ test4(); } System.out.println(); - for (int i = 0; i < 100; i++) { + for (int i = 0; i < 2; i++) { Thread.sleep(1000); } for (int i = 0; i < 10000; i++) { @@ -64,7 +76,7 @@ test5(); } System.out.println(); - for (int i = 0; i < 100; i++) { + for (int i = 0; i < 2; i++) { Thread.sleep(1000); } for (int i = 0; i < 10000; i++) { @@ -72,7 +84,7 @@ test6(); } System.out.println(); - for (int i = 0; i < 100; i++) { + for (int i = 0; i < 2; i++) { Thread.sleep(1000); } for (int i = 0; i < 10000; i++) { @@ -80,7 +92,7 @@ test7(); } System.out.println(); - for (int i = 0; i < 100; i++) { + for (int i = 0; i < 2; i++) { Thread.sleep(1000); } for (int i = 0; i < 10000; i++) { diff -r efba53f86c4f -r 72cfb36c6bb2 c1x4hotspotsrc/HotSpotTest/src/JavaTester.java --- a/c1x4hotspotsrc/HotSpotTest/src/JavaTester.java Thu Sep 16 19:42:20 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotTest/src/JavaTester.java Thu Sep 30 17:19:48 2010 -0700 @@ -4,7 +4,7 @@ public class JavaTester { public static void main(String[] args) { - runTests(0, 1000); + runTests(0, 0); Logger.info("total: " + executed + " tests executed, " + passed + " passed, " + failed + " failed"); } @@ -166,7 +166,7 @@ jtt_bytecode_BC_dneg(); break; case 38: - //jtt_bytecode_BC_drem(); + jtt_bytecode_BC_drem(); break; case 39: jtt_bytecode_BC_dreturn(); @@ -244,7 +244,7 @@ jtt_bytecode_BC_fneg(); break; case 64: - //jtt_bytecode_BC_frem(); + jtt_bytecode_BC_frem(); break; case 65: jtt_bytecode_BC_freturn(); @@ -1090,13 +1090,13 @@ jtt_except_Catch_NPE_11(); break; case 346: - //jtt_except_Catch_StackOverflowError_01(); + jtt_except_Catch_StackOverflowError_01(); break; case 347: - //jtt_except_Catch_StackOverflowError_02(); + jtt_except_Catch_StackOverflowError_02(); break; case 348: - //jtt_except_Catch_StackOverflowError_03(); + jtt_except_Catch_StackOverflowError_03(); break; case 349: jtt_except_Catch_Two01(); @@ -1378,16 +1378,16 @@ jtt_lang_Object_hashCode01(); break; case 442: - //jtt_lang_Object_notify01(); + jtt_lang_Object_notify01(); break; case 443: - //jtt_lang_Object_notify02(); + jtt_lang_Object_notify02(); break; case 444: - //jtt_lang_Object_notifyAll01(); + jtt_lang_Object_notifyAll01(); break; case 445: - //jtt_lang_Object_notifyAll02(); + jtt_lang_Object_notifyAll02(); break; case 446: jtt_lang_Object_toString01(); @@ -1396,13 +1396,13 @@ jtt_lang_Object_toString02(); break; case 448: - //jtt_lang_Object_wait01(); + jtt_lang_Object_wait01(); break; case 449: - //jtt_lang_Object_wait02(); + jtt_lang_Object_wait02(); break; case 450: - //jtt_lang_Object_wait03(); + jtt_lang_Object_wait03(); break; case 451: jtt_lang_ProcessEnvironment_init(); @@ -1702,28 +1702,28 @@ jtt_reflect_Reflection_getCallerClass01(); break; case 550: - //jtt_threads_Monitor_contended01(); + jtt_threads_Monitor_contended01(); break; case 551: - //jtt_threads_Monitor_notowner01(); + jtt_threads_Monitor_notowner01(); break; case 552: - //jtt_threads_Monitorenter01(); + jtt_threads_Monitorenter01(); break; case 553: - //jtt_threads_Monitorenter02(); + jtt_threads_Monitorenter02(); break; case 554: - //jtt_threads_Object_wait01(); + jtt_threads_Object_wait01(); break; case 555: - //jtt_threads_Object_wait02(); + jtt_threads_Object_wait02(); break; case 556: - //jtt_threads_Object_wait03(); + jtt_threads_Object_wait03(); break; case 557: - //jtt_threads_Object_wait04(); + jtt_threads_Object_wait04(); break; case 558: jtt_threads_ThreadLocal01(); @@ -1744,7 +1744,7 @@ jtt_threads_Thread_getState02(); break; case 564: - //jtt_threads_Thread_holdsLock01(); + jtt_threads_Thread_holdsLock01(); break; case 565: jtt_threads_Thread_isAlive01(); @@ -1753,7 +1753,7 @@ jtt_threads_Thread_isInterrupted01(); break; case 567: - //jtt_threads_Thread_isInterrupted02(); + jtt_threads_Thread_isInterrupted02(); break; case 568: jtt_threads_Thread_isInterrupted03(); @@ -1795,7 +1795,7 @@ jtt_jdk_Class_getName(); break; case 581: - jtt_jdk_EnumMap01(); + //jtt_jdk_EnumMap01(); break; case 582: jtt_jdk_EnumMap02(); diff -r efba53f86c4f -r 72cfb36c6bb2 c1x4hotspotsrc/HotSpotVM/.project --- a/c1x4hotspotsrc/HotSpotVM/.project Thu Sep 16 19:42:20 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/.project Thu Sep 30 17:19:48 2010 -0700 @@ -1,17 +1,23 @@ - - - HotSpotVM - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - + + + HotSpotVM + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sourceforge.metrics.builder + + + + + + org.eclipse.jdt.core.javanature + net.sourceforge.metrics.nature + + diff -r efba53f86c4f -r 72cfb36c6bb2 c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/Compiler.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/Compiler.java Thu Sep 16 19:42:20 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/Compiler.java Thu Sep 30 17:19:48 2010 -0700 @@ -67,10 +67,12 @@ public static VMEntries getVMEntries() { if (vmEntries == null) { try { + vmEntries = new VMEntriesNative(); + if (CountingProxy.ENABLED) { + vmEntries = CountingProxy.getProxy(VMEntries.class, vmEntries); + } if (Logger.ENABLED) { - vmEntries = LoggingProxy.getProxy(VMEntries.class, new VMEntriesNative()); - } else { - vmEntries = new VMEntriesNative(); + vmEntries = LoggingProxy.getProxy(VMEntries.class, vmEntries); } } catch (Throwable t) { t.printStackTrace(); @@ -98,10 +100,12 @@ VMEntries entries = Compiler.initializeClient(exits); invocation.setDelegate(entries); } else { + vmExits = new VMExitsNative(); + if (CountingProxy.ENABLED) { + vmExits = CountingProxy.getProxy(VMExits.class, vmExits); + } if (Logger.ENABLED) { - vmExits = LoggingProxy.getProxy(VMExits.class, new VMExitsNative()); - } else { - vmExits = new VMExitsNative(); + vmExits = LoggingProxy.getProxy(VMExits.class, vmExits); } } } catch (Throwable t) { @@ -136,6 +140,8 @@ compiler = new C1XCompiler(runtime, target, generator); C1XOptions.setOptimizationLevel(3); + C1XOptions.OptInlineExcept = false; + C1XOptions.OptInlineSynchronized = false; C1XOptions.UseDeopt = false; C1XOptions.IRChecking = Logger.ENABLED; C1XOptions.TraceBytecodeParserLevel = 0; @@ -146,10 +152,13 @@ C1XOptions.GenAssertionCode = Logger.ENABLED; C1XOptions.DetailedAsserts = Logger.ENABLED; + // these options are important - c1x4hotspot will not generate correct code without them C1XOptions.GenSpecialDivChecks = true; C1XOptions.AlignCallsForPatching = true; C1XOptions.NullCheckUniquePc = true; C1XOptions.invokeinterfaceTemplatePos = true; + C1XOptions.StackShadowPages = config.stackShadowPages; + } public CiCompiler getCompiler() { diff -r efba53f86c4f -r 72cfb36c6bb2 c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotConstantPool.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotConstantPool.java Thu Sep 16 19:42:20 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotConstantPool.java Thu Sep 30 17:19:48 2010 -0700 @@ -17,6 +17,8 @@ */ package com.sun.hotspot.c1x; +import java.util.*; + import com.sun.cri.ci.*; import com.sun.cri.ri.*; @@ -28,6 +30,7 @@ public class HotSpotConstantPool implements RiConstantPool, CompilerObject { long vmId; + HashMap cache = new HashMap(); public HotSpotConstantPool(long vmId) { this.vmId = vmId; @@ -41,27 +44,52 @@ @Override public Object lookupConstant(int cpi) { - return Compiler.getVMEntries().RiConstantPool_lookupConstant(vmId, cpi); + Object value = cache.get(cpi); + if (value == null) { + value = Compiler.getVMEntries().RiConstantPool_lookupConstant(vmId, cpi); + cache.put(cpi, value); + } + return value; } @Override public RiMethod lookupMethod(int cpi, int byteCode) { - return Compiler.getVMEntries().RiConstantPool_lookupMethod(vmId, cpi, (byte) byteCode); + RiMethod value = (RiMethod) cache.get(cpi); + if (value == null) { + value = Compiler.getVMEntries().RiConstantPool_lookupMethod(vmId, cpi, (byte) byteCode); + cache.put(cpi, value); + } + return value; } @Override public RiSignature lookupSignature(int cpi) { - return Compiler.getVMEntries().RiConstantPool_lookupSignature(vmId, cpi); + RiSignature value = (RiSignature) cache.get(cpi); + if (value == null) { + value = Compiler.getVMEntries().RiConstantPool_lookupSignature(vmId, cpi); + cache.put(cpi, value); + } + return value; } @Override public RiType lookupType(int cpi, int opcode) { - return Compiler.getVMEntries().RiConstantPool_lookupType(vmId, cpi); + RiType value = (RiType) cache.get(cpi); + if (value == null) { + value = Compiler.getVMEntries().RiConstantPool_lookupType(vmId, cpi); + cache.put(cpi, value); + } + return value; } @Override public RiField lookupField(int cpi, int opcode) { - return Compiler.getVMEntries().RiConstantPool_lookupField(vmId, cpi); + RiField value = (RiField) cache.get(cpi); + if (value == null) { + value = Compiler.getVMEntries().RiConstantPool_lookupField(vmId, cpi); + cache.put(cpi, value); + } + return value; } } diff -r efba53f86c4f -r 72cfb36c6bb2 c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotRegisterConfig.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotRegisterConfig.java Thu Sep 16 19:42:20 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotRegisterConfig.java Thu Sep 30 17:19:48 2010 -0700 @@ -1,18 +1,18 @@ /* * Copyright (c) 2009-2010 Sun Microsystems, Inc. All rights reserved. - * + * * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product that is * described in this document. In particular, and without limitation, these intellectual property rights may include one * or more of the U.S. patents listed at http://www.sun.com/patents and one or more additional patents or pending patent * applications in the U.S. and in other countries. - * + * * U.S. Government Rights - Commercial software. Government users are subject to the Sun Microsystems, Inc. standard * license agreement and applicable provisions of the FAR and its supplements. - * + * * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or registered * trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks are used under license and * are trademarks or registered trademarks of SPARC International, Inc. in the U.S. and other countries. - * + * * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open Company, Ltd. */ package com.sun.hotspot.c1x; @@ -29,13 +29,14 @@ /** * @author Thomas Wuerthinger - * + * */ public class HotSpotRegisterConfig implements RiRegisterConfig { + // be careful - the contents of this array are duplicated in c1x_CodeInstaller.cpp @Override public CiRegister[] getAllocatableRegisters() { - return new CiRegister[] { AMD64.rax, AMD64.rbx, AMD64.rcx, AMD64.rdx, AMD64.rsi, AMD64.rdi, /* AMD64.r10, */AMD64.r11, AMD64.r12, AMD64.r13, AMD64.r14, AMD64.xmm0, AMD64.xmm1, AMD64.xmm2, + return new CiRegister[] { AMD64.rax, AMD64.rbx, AMD64.rcx, AMD64.rdx, AMD64.rsi, AMD64.rdi, AMD64.r8, AMD64.r9, /* AMD64.r10, */AMD64.r11, AMD64.r12, AMD64.r13, AMD64.r14, AMD64.xmm0, AMD64.xmm1, AMD64.xmm2, AMD64.xmm3, AMD64.xmm4, AMD64.xmm5, AMD64.xmm6, AMD64.xmm7, AMD64.xmm8, AMD64.xmm9, AMD64.xmm10, AMD64.xmm11, AMD64.xmm12, AMD64.xmm13, AMD64.xmm14, AMD64.xmm15}; } diff -r efba53f86c4f -r 72cfb36c6bb2 c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotRuntime.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotRuntime.java Thu Sep 16 19:42:20 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotRuntime.java Thu Sep 30 17:19:48 2010 -0700 @@ -38,20 +38,11 @@ private final HotSpotVMConfig config; - public static enum Entrypoints { - UNVERIFIED, VERIFIED - } - public HotSpotRuntime(HotSpotVMConfig config) { this.config = config; } @Override - public int basicObjectLockOffsetInBytes() { - return 0; - } - - @Override public int codeOffset() { return 0; } @@ -175,8 +166,13 @@ @Override public int sizeofBasicObjectLock() { - // TODO Auto-generated method stub - return 0; + // TODO shouldn't be hard coded + return 2 * 8; + } + + @Override + public int basicObjectLockOffsetInBytes() { + return 8; } @Override diff -r efba53f86c4f -r 72cfb36c6bb2 c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTypeResolved.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTypeResolved.java Thu Sep 16 19:42:20 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTypeResolved.java Thu Sep 30 17:19:48 2010 -0700 @@ -156,7 +156,7 @@ @Override public boolean isSubtypeOf(RiType other) { - assert other instanceof HotSpotType : "unexpected 'other' type: " + other; + //assert other instanceof HotSpotType : "unexpected 'other' type: " + other; if (other instanceof HotSpotTypeResolved) return Compiler.getVMEntries().RiType_isSubtypeOf(vmId, other); // no resolved type is a subtype of an unresolved type diff -r efba53f86c4f -r 72cfb36c6bb2 c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotVMConfig.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotVMConfig.java Thu Sep 16 19:42:20 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotVMConfig.java Thu Sep 30 17:19:48 2010 -0700 @@ -47,6 +47,7 @@ public int threadMultiNewArrayStorage; public long cardtableStartAddress; public int cardtableShift; + public long safepointPollingAddress; // runtime stubs public long debugStub; diff -r efba53f86c4f -r 72cfb36c6bb2 c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java Thu Sep 16 19:42:20 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java Thu Sep 30 17:19:48 2010 -0700 @@ -71,7 +71,7 @@ this.registerConfig = registerConfig; } - private SimpleTemplates prologueTemplates = new SimpleTemplates(STATIC_METHOD, SYNCHRONIZED) { + private SimpleTemplates prologueTemplates = new SimpleTemplates(STATIC_METHOD) { @Override protected XirTemplate create(CiXirAssembler asm, long flags) { @@ -96,14 +96,11 @@ } asm.align(config.codeEntryAlignment); asm.mark(MARK_VERIFIED_ENTRY); + asm.stackOverflowCheck(); asm.push(framePointer); asm.mov(framePointer, stackPointer); asm.pushFrame(); - if (is(SYNCHRONIZED, flags)) { - // TODO synchronized methods / monitors - } - // -- out of line ------------------------------------------------------- XirOperand thread = asm.createRegister("thread", CiKind.Word, AMD64.r15); XirOperand exceptionOop = asm.createTemp("exception oop", CiKind.Object); @@ -139,10 +136,6 @@ asm.restart(CiKind.Void); XirOperand framePointer = asm.createRegister("frame pointer", CiKind.Word, AMD64.rbp); - if (is(SYNCHRONIZED, flags)) { - // TODO synchronized methods / monitors - } - asm.popFrame(); asm.pop(framePointer); @@ -158,7 +151,9 @@ protected XirTemplate create(CiXirAssembler asm, long flags) { asm.restart(CiKind.Void); - // TODO safepoint + // XirOperand temp = asm.createRegister("temp", CiKind.Word, AMD64.rax); + // asm.pload(CiKind.Word, temp, asm.w(config.safepointPollingAddress), true); + return asm.finishTemplate("safepoint"); } }; @@ -297,14 +292,18 @@ protected XirTemplate create(CiXirAssembler asm, long flags) { asm.restart(CiKind.Void); XirParameter object = asm.createInputParameter("object", CiKind.Object); - XirOperand temp = asm.createRegister("temp", CiKind.Word, AMD64.rax); + XirParameter lock = asm.createInputParameter("lock", CiKind.Word); if (is(NULL_CHECK, flags)) { asm.nop(1); asm.mark(MARK_IMPLICIT_NULL); - asm.pload(CiKind.Word, temp, object, true); + 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); +*/ return asm.finishTemplate("monitorEnter"); } }; @@ -315,14 +314,12 @@ protected XirTemplate create(CiXirAssembler asm, long flags) { asm.restart(CiKind.Void); XirParameter object = asm.createInputParameter("object", CiKind.Object); - XirOperand temp = asm.createRegister("temp", CiKind.Word, AMD64.rax); - - if (is(NULL_CHECK, flags)) { - asm.nop(1); - asm.mark(MARK_IMPLICIT_NULL); - asm.pload(CiKind.Word, temp, object, true); - } - + 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); +*/ return asm.finishTemplate("monitorExit"); } }; @@ -360,7 +357,7 @@ XirParameter value = asm.createInputParameter("value", kind); if (is(UNRESOLVED, flags)) { - UnresolvedFieldPatching fieldPatching = new UnresolvedFieldPatching(asm, object, value, false, is(NULL_CHECK, flags), config); + UnresolvedFieldPatching fieldPatching = new UnresolvedFieldPatching(asm, object, value, true, is(NULL_CHECK, flags), config); fieldPatching.emitInline(); // -- out of line ------------------------------------------------------- fieldPatching.emitOutOfLine(); @@ -389,7 +386,7 @@ XirOperand thread = asm.createRegister("thread", CiKind.Word, AMD64.r15); XirOperand temp1 = asm.createRegister("temp1", CiKind.Word, AMD64.rcx); XirOperand temp2 = asm.createRegister("temp2", CiKind.Word, AMD64.rbx); - XirOperand temp2i = asm.createRegister("temp2i", CiKind.Word, AMD64.rbx); + XirOperand temp2i = asm.createRegister("temp2i", CiKind.Int, AMD64.rbx); useRegisters(asm, AMD64.rsi); XirLabel tlabFull = asm.createOutOfLineLabel("tlab full"); XirLabel resume = asm.createInlineLabel("resume"); @@ -421,6 +418,7 @@ asm.bindOutOfLine(tlabFull); XirOperand arg = asm.createRegister("runtime call argument", CiKind.Object, AMD64.rdx); asm.mov(arg, type); + useRegisters(asm, AMD64.rax); asm.callRuntime(config.newInstanceStub, result); asm.jmp(resume); @@ -439,6 +437,7 @@ patching.emitInline(); useRegisters(asm, AMD64.rbx, AMD64.rcx, AMD64.rsi); + useRegisters(asm, AMD64.rax); asm.callRuntime(config.unresolvedNewInstanceStub, result); // -- out of line ------------------------------------------------------- @@ -469,7 +468,8 @@ } asm.mov(length, lengthParam); - useRegisters(asm, AMD64.rax, AMD64.rsi, AMD64.rcx, AMD64.rdi); + useRegisters(asm, AMD64.rsi, AMD64.rcx, AMD64.rdi); + useRegisters(asm, AMD64.rax); asm.callRuntime(config.newObjectArrayStub, result); if (is(UNRESOLVED, flags)) { patching.emitOutOfLine(); @@ -492,7 +492,8 @@ asm.mov(hub, hubParam); asm.mov(length, lengthParam); - useRegisters(asm, AMD64.rax, AMD64.rsi, AMD64.rcx, AMD64.rdi); + useRegisters(asm, AMD64.rsi, AMD64.rcx, AMD64.rdi); + useRegisters(asm, AMD64.rax); asm.callRuntime(config.newTypeArrayStub, result); return asm.finishTemplate("newTypeArray"); @@ -525,6 +526,7 @@ } asm.mov(rank, asm.i(dimensions)); + useRegisters(asm, AMD64.rax); asm.callRuntime(config.newMultiArrayStub, result); if (is(UNRESOLVED, flags)) { patching.emitOutOfLine(); @@ -791,8 +793,8 @@ } @Override - public XirSnippet genResolveClass(XirSite site, RiType type, Representation representation) { - assert representation == Representation.ObjectHub : "unexpected representation: " + representation; + public XirSnippet genResolveClass(XirSite site, RiType type, Representation rep) { + assert rep == Representation.ObjectHub || rep == Representation.StaticFields : "unexpected representation: " + rep; if (type instanceof HotSpotTypeResolved) { return new XirSnippet(resolveClassTemplates.get(site), XirArgument.forObject(type)); } @@ -825,13 +827,13 @@ } @Override - public XirSnippet genMonitorEnter(XirSite site, XirArgument receiver) { - return new XirSnippet(monitorEnterTemplates.get(site), receiver); + public XirSnippet genMonitorEnter(XirSite site, XirArgument receiver, XirArgument lockAddress) { + return new XirSnippet(monitorEnterTemplates.get(site), receiver, lockAddress); } @Override - public XirSnippet genMonitorExit(XirSite site, XirArgument receiver) { - return new XirSnippet(monitorExitTemplates.get(site), receiver); + public XirSnippet genMonitorExit(XirSite site, XirArgument receiver, XirArgument lockAddress) { + return new XirSnippet(monitorExitTemplates.get(site), receiver, lockAddress); } @Override @@ -1038,6 +1040,7 @@ asm.mark(MARK_DUMMY_OOP_RELOCATION); if (nullCheck) { asm.mark(MARK_IMPLICIT_NULL); + asm.safepoint(); } asm.jmp(patchStub); diff -r efba53f86c4f -r 72cfb36c6bb2 c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExitsNative.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExitsNative.java Thu Sep 16 19:42:20 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExitsNative.java Thu Sep 30 17:19:48 2010 -0700 @@ -34,7 +34,7 @@ @Override public void compileMethod(long methodVmId, String name, int entry_bci) { try { -// long t1 = System.nanoTime(); + long t1 = System.nanoTime(); Compiler compiler = Compiler.getInstance(); HotSpotMethodResolved riMethod = new HotSpotMethodResolved(methodVmId, name); CiResult result = compiler.getCompiler().compileMethod(riMethod, null); @@ -47,8 +47,8 @@ Logger.log("Compilation result: " + result.targetMethod()); HotSpotTargetMethod.installMethod(riMethod, result.targetMethod()); } -// long time = (System.nanoTime() - t1) / 1000000; -// Logger.info("compiling " + name + " (0x" + Long.toHexString(methodVmId) + "): " + (time) + "ms"); + long time = (System.nanoTime() - t1) / 1000000; + Logger.info("compiling " + name + " (0x" + Long.toHexString(methodVmId) + "): " + (time) + "ms"); } catch (Throwable t) { StringWriter out = new StringWriter(); t.printStackTrace(new PrintWriter(out)); diff -r efba53f86c4f -r 72cfb36c6bb2 c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/logging/CountingProxy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/logging/CountingProxy.java Thu Sep 30 17:19:48 2010 -0700 @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2010 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product that is + * described in this document. In particular, and without limitation, these intellectual property rights may include one + * or more of the U.S. patents listed at http://www.sun.com/patents and one or more additional patents or pending patent + * applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun Microsystems, Inc. standard + * license agreement and applicable provisions of the FAR and its supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or registered + * trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks are used under license and + * are trademarks or registered trademarks of SPARC International, Inc. in the U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open Company, Ltd. + */ +package com.sun.hotspot.c1x.logging; + +import java.lang.reflect.*; +import java.util.*; + +/** + * A java.lang.reflect proxy that hierarchically logs all method invocations along with their parameters and return + * values. + * + * @author Lukas Stadler + */ +public class CountingProxy implements InvocationHandler { + + public static final boolean ENABLED = Boolean.valueOf(System.getProperty("c1x.countcalls")); + + private T delegate; + + private Map calls = new HashMap(); + + public CountingProxy(T delegate) { + assert ENABLED; + System.out.println("Counting proxy for " + delegate.getClass().getSimpleName() + " created"); + this.delegate = delegate; + proxies.add(this); + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + int argCount = args == null ? 0 : args.length; + if (method.getParameterTypes().length != argCount) + throw new RuntimeException("wrong parameter count"); + final Object result; + long count = calls.containsKey(method) ? calls.get(method) : 0; + calls.put(method, count + 1); + try { + if (args == null) { + result = method.invoke(delegate); + } else { + result = method.invoke(delegate, args); + } + } catch (InvocationTargetException e) { + throw e.getCause(); + } + return result; + } + + public static T getProxy(Class interf, T delegate) { + Object obj = Proxy.newProxyInstance(interf.getClassLoader(), new Class[] { interf}, new CountingProxy(delegate)); + return interf.cast(obj); + } + + private static ArrayList proxies = new ArrayList(); + + static { + if (ENABLED) { + Runtime.getRuntime().addShutdownHook(new Thread() { + + @Override + public void run() { + for (CountingProxy proxy : proxies) { + proxy.print(); + } + } + }); + } + } + + protected void print() { + long sum = 0; + for (Map.Entry entry : calls.entrySet()) { + Method method = entry.getKey(); + long count = entry.getValue(); + sum += count; + System.out.println(delegate.getClass().getSimpleName() + "." + method.getName() + ": " + count); + } + System.out.println(delegate.getClass().getSimpleName() + " calls: " + sum); + } +} diff -r efba53f86c4f -r 72cfb36c6bb2 src/cpu/x86/vm/c1_Runtime1_x86.cpp --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp Thu Sep 16 19:42:20 2010 -0700 +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp Thu Sep 30 17:19:48 2010 -0700 @@ -1830,94 +1830,203 @@ break; #endif // !SERIALGC - case c1x_unwind_exception_call_id: + case c1x_unwind_exception_call_id: { + // remove the frame from the stack + __ movptr(rsp, rbp); + __ pop(rbp); + // exception_oop is passed using ordinary java calling conventions + __ movptr(rax, j_rarg0); + + Label nonNullExceptionOop; + __ testptr(rax, rax); + __ jcc(Assembler::notZero, nonNullExceptionOop); { - // remove the frame from the stack - __ movptr(rsp, rbp); - __ pop(rbp); - // exception_oop is passed using ordinary java calling conventions - __ movptr(rax, j_rarg0); + __ enter(); + oop_maps = new OopMapSet(); + OopMap* oop_map = save_live_registers(sasm, 0); + int call_offset = __ call_RT(rax, noreg, (address)c1x_create_null_exception, 0); + oop_maps->add_gc_map(call_offset, oop_map); + __ leave(); + } + __ bind(nonNullExceptionOop); - Label nonNullExceptionOop; - __ testptr(rax, rax); - __ jcc(Assembler::notZero, nonNullExceptionOop); - { - __ enter(); - oop_maps = new OopMapSet(); - OopMap* oop_map = save_live_registers(sasm, 0); - int call_offset = __ call_RT(rax, noreg, (address)c1x_create_null_exception, 0); - oop_maps->add_gc_map(call_offset, oop_map); - __ leave(); - } - __ bind(nonNullExceptionOop); + __ set_info("unwind_exception", dont_gc_arguments); + // note: no stubframe since we are about to leave the current + // activation and we are calling a leaf VM function only. + generate_unwind_exception(sasm); + __ should_not_reach_here(); + break; + } - __ set_info("unwind_exception", dont_gc_arguments); - // note: no stubframe since we are about to leave the current - // activation and we are calling a leaf VM function only. - generate_unwind_exception(sasm); - __ should_not_reach_here(); + case c1x_handle_exception_id: { + StubFrame f(sasm, "c1x_handle_exception", dont_gc_arguments); + oop_maps = new OopMapSet(); + OopMap* oop_map = save_live_registers(sasm, 1, false); + c1x_generate_handle_exception(sasm, oop_maps, oop_map); + break; + } + + case c1x_global_implicit_null_id: { + __ push(rax); + __ push(rax); + // move saved fp to make space for the inserted return address + __ get_thread(rax); + __ movptr(rax, Address(rax, JavaThread::saved_exception_pc_offset())); + __ movptr(Address(rsp, HeapWordSize), rax); + __ pop(rax); + + { StubFrame f(sasm, "c1x_global_implicit_null_id", dont_gc_arguments); + oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_null_pointer_exception), false); } break; + } - case c1x_handle_exception_id: - { StubFrame f(sasm, "c1x_handle_exception", dont_gc_arguments); - oop_maps = new OopMapSet(); - OopMap* oop_map = save_live_registers(sasm, 1, false); - c1x_generate_handle_exception(sasm, oop_maps, oop_map); + case c1x_throw_div0_exception_id: { + __ push(rax); + __ push(rax); + // move saved fp to make space for the inserted return address + __ get_thread(rax); + __ movptr(rax, Address(rax, JavaThread::saved_exception_pc_offset())); + __ movptr(Address(rsp, HeapWordSize), rax); + __ pop(rax); + + { StubFrame f(sasm, "throw_div0_exception", dont_gc_arguments); + oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_div0_exception), false); } break; + } - case c1x_global_implicit_null_id: - { - __ push(rax); - __ push(rax); - // move saved fp to make space for the inserted return address - __ get_thread(rax); - __ movptr(rax, Address(rax, JavaThread::saved_exception_pc_offset())); - __ movptr(Address(rsp, HeapWordSize), rax); - __ pop(rax); + case c1x_slow_subtype_check_id: { + Label success; + Label miss; + + // TODO this should really be within the XirSnippets + __ check_klass_subtype_fast_path(j_rarg0, j_rarg1, j_rarg2, &success, &miss, NULL); + __ check_klass_subtype_slow_path(j_rarg0, j_rarg1, j_rarg2, j_rarg3, NULL, &miss); + + // fallthrough on success: + __ bind(success); + __ movptr(rax, 1); + __ ret(0); + + __ bind(miss); + __ movptr(rax, NULL_WORD); + __ ret(0); + break; + } - { StubFrame f(sasm, "c1x_global_implicit_null_id", dont_gc_arguments); - oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_null_pointer_exception), false); - } + case c1x_arithmetic_frem_id: { + __ subptr(rsp, 8); + __ movflt(Address(rsp, 0), xmm1); + __ fld_s(Address(rsp, 0)); + __ movflt(Address(rsp, 0), xmm0); + __ fld_s(Address(rsp, 0)); + Label L; + __ bind(L); + __ fprem(); + __ fwait(); + __ fnstsw_ax(); + __ testl(rax, 0x400); + __ jcc(Assembler::notZero, L); + __ fxch(1); + __ fpop(); + __ fstp_s(Address(rsp, 0)); + __ movflt(xmm0, Address(rsp, 0)); + __ addptr(rsp, 8); + __ ret(0); + break; + } + case c1x_arithmetic_drem_id: { + __ subptr(rsp, 8); + __ movdbl(Address(rsp, 0), xmm1); + __ fld_d(Address(rsp, 0)); + __ movdbl(Address(rsp, 0), xmm0); + __ fld_d(Address(rsp, 0)); + Label L; + __ bind(L); + __ fprem(); + __ fwait(); + __ fnstsw_ax(); + __ testl(rax, 0x400); + __ jcc(Assembler::notZero, L); + __ fxch(1); + __ fpop(); + __ fstp_d(Address(rsp, 0)); + __ movdbl(xmm0, Address(rsp, 0)); + __ addptr(rsp, 8); + __ ret(0); + break; + } + case c1x_monitorenter_id: { + Label slow_case; + + Register obj = j_rarg0; + Register lock = j_rarg1; + + Register scratch1 = rax; + Register scratch2 = rbx; + + // copied from LIR_Assembler::emit_lock + if (UseFastLocking) { + assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); + __ lock_object(scratch1, obj, lock, scratch2, slow_case); + __ ret(0); } - break; - case c1x_throw_div0_exception_id: + __ bind(slow_case); { - __ push(rax); - __ push(rax); - // move saved fp to make space for the inserted return address - __ get_thread(rax); - __ movptr(rax, Address(rax, JavaThread::saved_exception_pc_offset())); - __ movptr(Address(rsp, HeapWordSize), rax); - __ pop(rax); + StubFrame f(sasm, "c1x_monitorenter", dont_gc_arguments); + OopMap* map = save_live_registers(sasm, 1, save_fpu_registers); + + // Called with store_parameter and not C abi + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorenter), obj, lock); + + oop_maps = new OopMapSet(); + oop_maps->add_gc_map(call_offset, map); + restore_live_registers(sasm, save_fpu_registers); + } + __ ret(0); + break; + } + case c1x_monitorexit_id: { + Label slow_case; - { StubFrame f(sasm, "throw_div0_exception", dont_gc_arguments); - oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_div0_exception), false); - } + Register obj = j_rarg0; + Register lock = j_rarg1; + + // needed in rax later on... + Register lock2 = rax; + __ mov(lock2, lock); + Register scratch1 = rbx; + + // copied from LIR_Assembler::emit_lock + if (UseFastLocking) { + assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); + __ unlock_object(scratch1, obj, lock2, slow_case); + __ ret(0); } - break; - case c1x_slow_subtype_check_id: + __ bind(slow_case); { - Label success; - Label miss; + StubFrame f(sasm, "c1x_monitorexit", dont_gc_arguments); + OopMap* map = save_live_registers(sasm, 2, save_fpu_registers); - // TODO this should really be within the XirSnippets - __ check_klass_subtype_fast_path(j_rarg0, j_rarg1, j_rarg2, &success, &miss, NULL); - __ check_klass_subtype_slow_path(j_rarg0, j_rarg1, j_rarg2, j_rarg3, NULL, &miss); + // note: really a leaf routine but must setup last java sp + // => use call_RT for now (speed can be improved by + // doing last java sp setup manually) + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorexit), lock); - // fallthrough on success: - __ bind(success); - __ movptr(rax, 1); - __ ret(0); + oop_maps = new OopMapSet(); + oop_maps->add_gc_map(call_offset, map); + restore_live_registers(sasm, save_fpu_registers); + } + __ ret(0); + break; + } - __ bind(miss); - __ movptr(rax, NULL_WORD); - __ ret(0); - } - break; + + + default: { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments); __ movptr(rax, (int)id); diff -r efba53f86c4f -r 72cfb36c6bb2 src/os_cpu/linux_x86/vm/os_linux_x86.cpp --- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Thu Sep 16 19:42:20 2010 -0700 +++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Thu Sep 30 17:19:48 2010 -0700 @@ -268,6 +268,7 @@ if (thread->thread_state() == _thread_in_Java) { // Throw a stack overflow exception. Guard pages will be reenabled // while unwinding the stack. + tty->print("implicit: %08x%08x\n", ((long)pc) >> 32, pc); stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW); } else { // Thread was in the vm or native code. Return and try to finish. diff -r efba53f86c4f -r 72cfb36c6bb2 src/share/vm/c1/c1_Compiler.cpp --- a/src/share/vm/c1/c1_Compiler.cpp Thu Sep 16 19:42:20 2010 -0700 +++ b/src/share/vm/c1/c1_Compiler.cpp Thu Sep 30 17:19:48 2010 -0700 @@ -48,6 +48,7 @@ void Compiler::compile_method(ciEnv* env, ciMethod* method, int entry_bci) { + assert(!UseC1X, "c1 called in UseC1X mode!"); if (!is_initialized()) { initialize(); diff -r efba53f86c4f -r 72cfb36c6bb2 src/share/vm/c1/c1_Runtime1.cpp --- a/src/share/vm/c1/c1_Runtime1.cpp Thu Sep 16 19:42:20 2010 -0700 +++ b/src/share/vm/c1/c1_Runtime1.cpp Thu Sep 30 17:19:48 2010 -0700 @@ -175,6 +175,8 @@ case unwind_exception_id: case c1x_unwind_exception_call_id: case c1x_slow_subtype_check_id: + case c1x_arithmetic_frem_id: + case c1x_arithmetic_drem_id: #ifndef TIERED case counter_overflow_id: // Not generated outside the tiered world #endif diff -r efba53f86c4f -r 72cfb36c6bb2 src/share/vm/c1/c1_Runtime1.hpp --- a/src/share/vm/c1/c1_Runtime1.hpp Thu Sep 16 19:42:20 2010 -0700 +++ b/src/share/vm/c1/c1_Runtime1.hpp Thu Sep 30 17:19:48 2010 -0700 @@ -65,6 +65,10 @@ stub(c1x_global_implicit_null) \ stub(c1x_throw_div0_exception) \ stub(c1x_slow_subtype_check) \ + stub(c1x_arithmetic_frem) \ + stub(c1x_arithmetic_drem) \ + stub(c1x_monitorenter) \ + stub(c1x_monitorexit) \ last_entry(number_of_ids) #define DECLARE_STUB_ID(x) x ## _id , diff -r efba53f86c4f -r 72cfb36c6bb2 src/share/vm/c1x/c1x_CodeInstaller.cpp --- a/src/share/vm/c1x/c1x_CodeInstaller.cpp Thu Sep 16 19:42:20 2010 -0700 +++ b/src/share/vm/c1x/c1x_CodeInstaller.cpp Thu Sep 30 17:19:48 2010 -0700 @@ -25,8 +25,9 @@ # include "incls/_precompiled.incl" # include "incls/_c1x_CodeInstaller.cpp.incl" + // TODO this should be handled in a more robust way - not hard coded... -Register CPU_REGS[] = { rax, rbx, rcx, rdx, rsi, rdi, r11, r12, r13, r14 }; +Register CPU_REGS[] = { rax, rbx, rcx, rdx, rsi, rdi, r8, r9, r11, r12, r13, r14 }; const static int NUM_CPU_REGS = 10; XMMRegister XMM_REGS[] = { xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 }; const static int NUM_XMM_REGS = 16; @@ -84,15 +85,49 @@ } // TODO: finish this - c1x doesn't provide any scope values at the moment -static ScopeValue* get_hotspot_value(oop value) { - fatal("not implemented"); +static ScopeValue* get_hotspot_value(oop value, int frame_size) { + if (value == CiValue::IllegalValue()) { + return new LocationValue(Location::new_stk_loc(Location::invalid, 0)); + } + + BasicType type = C1XCompiler::kindToBasicType(CiKind::typeChar(CiValue::kind(value))); if (value->is_a(CiRegisterValue::klass())) { - TRACE_C1X_4("register value"); - IF_TRACE_C1X_4 value->print(); + jint number = CiRegister::number(CiRegisterValue::_register(value)); + + if (number < 16) { + return new LocationValue(Location::new_reg_loc(Location::normal, as_Register(number)->as_VMReg())); + } else { + return new LocationValue(Location::new_reg_loc(Location::normal, as_XMMRegister(number - 16)->as_VMReg())); + } } else if (value->is_a(CiStackSlot::klass())) { - TRACE_C1X_4("stack value"); - IF_TRACE_C1X_4 value->print(); + jint index = CiStackSlot::index(value); + if (index >= 0) { + return new LocationValue(Location::new_stk_loc(Location::normal, index * HeapWordSize)); + } else { + int frame_size_bytes = frame_size + 2 * HeapWordSize; + return new LocationValue(Location::new_stk_loc(Location::normal, -(index * HeapWordSize) + frame_size_bytes)); + } + } else if (value->is_a(CiConstant::klass())){ + oop obj = CiConstant::object(value); + jlong prim = CiConstant::primitive(value); + if (type == T_INT || type == T_FLOAT) { + return new ConstantIntValue(*(jint*)&prim); + } else if (type == T_LONG || type == T_DOUBLE) { + return new ConstantLongValue(prim); + } else if (type == T_OBJECT) { + oop obj = CiConstant::object(value); + if (obj == NULL) { + return new ConstantOopWriteValue(NULL); + } else { + obj->print(); + ShouldNotReachHere(); + } + //return new ConstantOopWriteValue() + } + tty->print("%i", type); + ShouldNotReachHere(); } else { + value->klass()->print(); ShouldNotReachHere(); } } @@ -277,13 +312,24 @@ assert(frame == NULL || CiDebugInfo_Frame::caller(frame) == NULL, "unexpected layout - mismatching nesting of Frame and CiCodePos"); } - assert(frame == NULL || code_pos == CiDebugInfo_Frame::codePos(frame), "unexpected CiCodePos layout"); + if (frame != NULL) { + assert(CiCodePos::bci(code_pos) == CiCodePos::bci(CiDebugInfo_Frame::codePos(frame)), "unexpected CiCodePos layout"); + assert(CiCodePos::method(code_pos) == CiCodePos::method(CiDebugInfo_Frame::codePos(frame)), "unexpected CiCodePos layout"); + } oop hotspot_method = CiCodePos::method(code_pos); assert(hotspot_method != NULL && hotspot_method->is_a(HotSpotMethodResolved::klass()), "unexpected hotspot method"); methodOop method = VmIds::get(HotSpotMethodResolved::vmId(hotspot_method)); ciMethod *cimethod = (ciMethod *) _env->get_object(method); jint bci = CiCodePos::bci(code_pos); + bool reexecute; + if (bci == -1) { + reexecute = false; + } else { + Bytecodes::Code code = Bytecodes::java_code_at(method->bcp_from(bci)); + reexecute = Interpreter::bytecode_should_reexecute(code); + } + if (frame != NULL) { jint local_count = CiDebugInfo_Frame::numLocals(frame); @@ -292,31 +338,32 @@ arrayOop values = (arrayOop) CiDebugInfo_Frame::values(frame); assert(local_count + expression_count + monitor_count == values->length(), "unexpected values length"); - assert(monitor_count == 0, "monitors not supported"); GrowableArray* locals = new GrowableArray (); GrowableArray* expressions = new GrowableArray (); GrowableArray* monitors = new GrowableArray (); for (jint i = 0; i < values->length(); i++) { - ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i]); + ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i], _frame_size); if (i < local_count) { locals->append(value); } else if (i < local_count + expression_count) { expressions->append(value); } else { - ShouldNotReachHere(); - // monitors->append(value); + assert(value->is_location(), "invalid monitor location"); + LocationValue* loc = (LocationValue*)value; + LocationValue* obj = new LocationValue(Location::new_stk_loc(Location::oop, loc->location().stack_offset() + HeapWordSize)); + monitors->append(new MonitorValue(obj, Location::new_stk_loc(Location::normal, loc->location().stack_offset()))); } } DebugToken* locals_token = _debug_recorder->create_scope_values(locals); DebugToken* expressions_token = _debug_recorder->create_scope_values(expressions); DebugToken* monitors_token = _debug_recorder->create_monitor_values(monitors); - _debug_recorder->describe_scope(pc_offset, cimethod, bci, false, false, false, locals_token, expressions_token, monitors_token); + _debug_recorder->describe_scope(pc_offset, cimethod, bci, reexecute, false, false, locals_token, expressions_token, monitors_token); } else { - _debug_recorder->describe_scope(pc_offset, cimethod, bci, false, false, false, NULL, NULL, NULL); + _debug_recorder->describe_scope(pc_offset, cimethod, bci, reexecute, false, false, NULL, NULL, NULL); } } @@ -377,6 +424,14 @@ call->set_destination((address)os::javaTimeNanos); _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); TRACE_C1X_3("CiRuntimeCall::JavaTimeNanos()"); + } else if (runtime_call == CiRuntimeCall::ArithmeticFrem()) { + call->set_destination(Runtime1::entry_for(Runtime1::c1x_arithmetic_frem_id)); + _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); + TRACE_C1X_3("CiRuntimeCall::ArithmeticFrem()"); + } else if (runtime_call == CiRuntimeCall::ArithmeticDrem()) { + call->set_destination(Runtime1::entry_for(Runtime1::c1x_arithmetic_drem_id)); + _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); + TRACE_C1X_3("CiRuntimeCall::ArithmeticDrem()"); } else { TRACE_C1X_1("runtime_call not implemented: "); IF_TRACE_C1X_1 runtime_call->print(); diff -r efba53f86c4f -r 72cfb36c6bb2 src/share/vm/c1x/c1x_CodeInstaller.hpp --- a/src/share/vm/c1x/c1x_CodeInstaller.hpp Thu Sep 16 19:42:20 2010 -0700 +++ b/src/share/vm/c1x/c1x_CodeInstaller.hpp Thu Sep 30 17:19:48 2010 -0700 @@ -22,9 +22,12 @@ * */ +/* + * This class handles the conversion from a CiTargetMethod to a CodeBlob or an nmethod. + */ class CodeInstaller { private: - // this needs to correspond to HotSpotXirGenerator.java + // these need to correspond to HotSpotXirGenerator.java enum MarkId { MARK_VERIFIED_ENTRY = 0x0001, MARK_UNVERIFIED_ENTRY = 0x0002, @@ -80,6 +83,7 @@ CodeInstaller(oop target_method, jlong& id); private: + // extract the fields of the CiTargetMethod void initialize_fields(oop target_method); // perform data and call relocation on the CodeBuffer diff -r efba53f86c4f -r 72cfb36c6bb2 src/share/vm/c1x/c1x_Compiler.cpp --- a/src/share/vm/c1x/c1x_Compiler.cpp Thu Sep 16 19:42:20 2010 -0700 +++ b/src/share/vm/c1x/c1x_Compiler.cpp Thu Sep 30 17:19:48 2010 -0700 @@ -124,3 +124,21 @@ return obj; } +BasicType C1XCompiler::kindToBasicType(jchar ch) { + switch(ch) { + case 'z': return T_BOOLEAN; + case 'b': return T_BYTE; + case 's': return T_SHORT; + case 'c': return T_CHAR; + case 'i': return T_INT; + case 'f': return T_FLOAT; + case 'l': return T_LONG; + case 'd': return T_DOUBLE; + case 'a': return T_OBJECT; + case '-': return T_ILLEGAL; + default: + fatal1("unexpected CiKind: %c", ch); + break; + } +} + diff -r efba53f86c4f -r 72cfb36c6bb2 src/share/vm/c1x/c1x_Compiler.hpp --- a/src/share/vm/c1x/c1x_Compiler.hpp Thu Sep 16 19:42:20 2010 -0700 +++ b/src/share/vm/c1x/c1x_Compiler.hpp Thu Sep 30 17:19:48 2010 -0700 @@ -61,22 +61,24 @@ static oop createHotSpotTypeResolved(KlassHandle klass, Handle name, TRAPS); + static BasicType kindToBasicType(jchar ch); }; // Tracing macros -#define IF_TRACE_C1X_1 if (TraceC1X >= 1) -#define IF_TRACE_C1X_2 if (TraceC1X >= 2) -#define IF_TRACE_C1X_3 if (TraceC1X >= 3) -#define IF_TRACE_C1X_4 if (TraceC1X >= 4) -#define IF_TRACE_C1X_5 if (TraceC1X >= 5) +#define IF_TRACE_C1X_1 if (!(TraceC1X >= 1)) ; else +#define IF_TRACE_C1X_2 if (!(TraceC1X >= 2)) ; else +#define IF_TRACE_C1X_3 if (!(TraceC1X >= 3)) ; else +#define IF_TRACE_C1X_4 if (!(TraceC1X >= 4)) ; else +#define IF_TRACE_C1X_5 if (!(TraceC1X >= 5)) ; else -// using commas to keep one-instruction semantics -#define TRACE_C1X_1 if (TraceC1X >= 1 && (tty->print("TraceC1X-1: "), true)) tty->print_cr -#define TRACE_C1X_2 if (TraceC1X >= 2 && (tty->print(" TraceC1X-2: "), true)) tty->print_cr -#define TRACE_C1X_3 if (TraceC1X >= 3 && (tty->print(" TraceC1X-3: "), true)) tty->print_cr -#define TRACE_C1X_4 if (TraceC1X >= 4 && (tty->print(" TraceC1X-4: "), true)) tty->print_cr -#define TRACE_C1X_5 if (TraceC1X >= 5 && (tty->print(" TraceC1X-5: "), true)) tty->print_cr +// using commas and else to keep one-instruction semantics + +#define TRACE_C1X_1 if (!(TraceC1X >= 1 && (tty->print("TraceC1X-1: "), true))) ; else tty->print_cr +#define TRACE_C1X_2 if (!(TraceC1X >= 2 && (tty->print(" TraceC1X-2: "), true))) ; else tty->print_cr +#define TRACE_C1X_3 if (!(TraceC1X >= 3 && (tty->print(" TraceC1X-3: "), true))) ; else tty->print_cr +#define TRACE_C1X_4 if (!(TraceC1X >= 4 && (tty->print(" TraceC1X-4: "), true))) ; else tty->print_cr +#define TRACE_C1X_5 if (!(TraceC1X >= 5 && (tty->print(" TraceC1X-5: "), true))) ; else tty->print_cr diff -r efba53f86c4f -r 72cfb36c6bb2 src/share/vm/c1x/c1x_TargetMethod.cpp --- a/src/share/vm/c1x/c1x_TargetMethod.cpp Thu Sep 16 19:42:20 2010 -0700 +++ b/src/share/vm/c1x/c1x_TargetMethod.cpp Thu Sep 30 17:19:48 2010 -0700 @@ -25,6 +25,9 @@ # include "incls/_precompiled.incl" # include "incls/_c1x_TargetMethod.cpp.incl" +// This function is similar to javaClasses.cpp, it computes the field offset of a (static or instance) field. +// It looks up the name and signature symbols without creating new ones, all the symbols of these classes need to be already loaded. + static void compute_offset(int &dest_offset, klassOop klass_oop, const char* name, const char* signature, bool static_field) { symbolOop name_symbol = SymbolTable::probe(name, strlen(name)); symbolOop signature_symbol = SymbolTable::probe(signature, strlen(signature)); @@ -42,7 +45,8 @@ dest_offset = fd.offset(); } -// create the compute_class +// This piece of macro magic creates the contents of the c1x_compute_offsets method that initializes the field indices of all the access classes. + #define START_CLASS(name) { klassOop k = SystemDictionary::name##_klass(); #define END_CLASS } diff -r efba53f86c4f -r 72cfb36c6bb2 src/share/vm/c1x/c1x_TargetMethod.hpp --- a/src/share/vm/c1x/c1x_TargetMethod.hpp Thu Sep 16 19:42:20 2010 -0700 +++ b/src/share/vm/c1x/c1x_TargetMethod.hpp Thu Sep 30 17:19:48 2010 -0700 @@ -24,8 +24,23 @@ void c1x_compute_offsets(); -// defines the structure of the CiTargetMethod - classes -// this will generate classes with accessors similar to javaClasses.hpp +/* This macro defines the structure of the CiTargetMethod - classes. + * It will generate classes with accessors similar to javaClasses.hpp, but with specializations for oops, Handles and jni handles. + * + * The public interface of these classes will look like this: + + * class CiStackSlot : AllStatic { + * public: + * static klassOop klass(); + * static jint index(oop obj); + * static jint index(Handle obj); + * static jint index(jobject obj); + * static void set_index(oop obj, jint x); + * static void set_index(Handle obj, jint x); + * static void set_index(jobject obj, jint x); + * }; + * + */ #define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, oop_field, static_oop_field) \ start_class(HotSpotTypeResolved) \ @@ -142,9 +157,18 @@ end_class \ start_class(RiMethod) \ end_class \ + start_class(CiValue) \ + oop_field(CiValue, kind, "Lcom/sun/cri/ci/CiKind;") \ + static_oop_field(CiValue, IllegalValue, "Lcom/sun/cri/ci/CiValue;"); \ + end_class \ start_class(CiRegisterValue) \ + oop_field(CiRegisterValue, _register, "Lcom/sun/cri/ci/CiRegister;") \ + end_class \ + start_class(CiRegister) \ + int_field(CiRegister, number) \ end_class \ start_class(CiStackSlot) \ + int_field(CiStackSlot, index) \ end_class \ /* end*/ diff -r efba53f86c4f -r 72cfb36c6bb2 src/share/vm/c1x/c1x_VMEntries.cpp --- a/src/share/vm/c1x/c1x_VMEntries.cpp Thu Sep 16 19:42:20 2010 -0700 +++ b/src/share/vm/c1x/c1x_VMEntries.cpp Thu Sep 30 17:19:48 2010 -0700 @@ -316,21 +316,8 @@ // public RiType getPrimitiveArrayType(CiKind kind); JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_getPrimitiveArrayType(JNIEnv *env, jobject, jobject kind) { VM_ENTRY_MARK; - BasicType type; - switch(CiKind::typeChar(kind)) { - case 'z': type = T_BOOLEAN; break; - case 'b': type = T_BYTE; break; - case 's': type = T_SHORT; break; - case 'c': type = T_CHAR; break; - case 'i': type = T_INT; break; - case 'f': type = T_FLOAT; break; - case 'l': type = T_LONG; break; - case 'd': type = T_DOUBLE; break; - case 'a': - default: - fatal("unexpected CiKind in getPrimitiveArrayType"); - break; - } + BasicType type = C1XCompiler::kindToBasicType(CiKind::typeChar(kind)); + assert(type != T_OBJECT, "primitive type expecteds"); ciKlass* klass = ciTypeArrayKlass::make(type); return JNIHandles::make_local(THREAD, C1XCompiler::get_RiType(klass, NULL, THREAD)); } @@ -412,8 +399,9 @@ 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))); + 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, "safepointPollingAddress", (jlong)(os::get_polling_page() + (SafepointPollOffset % os::vm_page_size()))); BarrierSet* bs = Universe::heap()->barrier_set(); switch (bs->kind()) { diff -r efba53f86c4f -r 72cfb36c6bb2 src/share/vm/c1x/c1x_VMEntries.hpp --- a/src/share/vm/c1x/c1x_VMEntries.hpp Thu Sep 16 19:42:20 2010 -0700 +++ b/src/share/vm/c1x/c1x_VMEntries.hpp Thu Sep 30 17:19:48 2010 -0700 @@ -25,6 +25,6 @@ extern JNINativeMethod VMEntries_methods[]; int VMEntries_methods_count(); +// nothing here - no need to define the jni method implementations in a header file - diff -r efba53f86c4f -r 72cfb36c6bb2 src/share/vm/c1x/c1x_VmIds.cpp --- a/src/share/vm/c1x/c1x_VmIds.cpp Thu Sep 16 19:42:20 2010 -0700 +++ b/src/share/vm/c1x/c1x_VmIds.cpp Thu Sep 30 17:19:48 2010 -0700 @@ -30,6 +30,7 @@ GrowableArray
* VmIds::_stubs = NULL; GrowableArray* VmIds::_localHandles = NULL; + void VmIds::initializeObjects() { if (_stubs == NULL) { assert(_localHandles == NULL, "inconsistent state"); diff -r efba53f86c4f -r 72cfb36c6bb2 src/share/vm/c1x/c1x_VmIds.hpp --- a/src/share/vm/c1x/c1x_VmIds.hpp Thu Sep 16 19:42:20 2010 -0700 +++ b/src/share/vm/c1x/c1x_VmIds.hpp Thu Sep 30 17:19:48 2010 -0700 @@ -43,7 +43,9 @@ DUMMY_CONSTANT = 0x6ffffffffffffffl }; + // Initializes the VmIds for a compilation, by creating the arrays static void initializeObjects(); + // Cleans up after a compilation, by deallocating the arrays static void cleanupLocalObjects(); // Adds a stub address, and returns the corresponding vmId (which is of type STUB) @@ -71,9 +73,11 @@ // Helper function to convert a java.lang.String object to a symbolOop (this will return NULL if the symbol doesn't exist in the system) static symbolOop toSymbol(jstring string); + // Helper function to get the contents of a java.lang.Long static jlong getBoxedLong(oop obj); }; + template <> inline jlong VmIds::add(methodOop obj){ assert(obj != NULL, "trying to add NULL"); assert(obj->is_method(), "trying to add mistyped object"); @@ -100,6 +104,7 @@ return add(Handle(obj), CONSTANT); } + template <> inline methodOop VmIds::get(jlong id){ assert((id & TYPE_MASK) == METHOD, "METHOD expected"); assert(getObject(id)->is_method(), "methodOop expected"); diff -r efba53f86c4f -r 72cfb36c6bb2 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Thu Sep 16 19:42:20 2010 -0700 +++ b/src/share/vm/classfile/systemDictionary.hpp Thu Sep 30 17:19:48 2010 -0700 @@ -184,8 +184,10 @@ template(CiTargetMethod_Mark_klass, com_sun_cri_ci_CiTargetMethod_Mark, Opt) \ template(CiDebugInfo_klass, com_sun_cri_ci_CiDebugInfo, Opt) \ template(CiDebugInfo_Frame_klass, com_sun_cri_ci_CiDebugInfo_Frame, Opt) \ + template(CiValue_klass, com_sun_cri_ci_CiValue, Opt) \ + template(CiStackSlot_klass, com_sun_cri_ci_CiStackSlot, Opt) \ template(CiRegisterValue_klass, com_sun_cri_ci_CiRegisterValue, Opt) \ - template(CiStackSlot_klass, com_sun_cri_ci_CiStackSlot, Opt) \ + template(CiRegister_klass, com_sun_cri_ci_CiRegister, Opt) \ template(CiCodePos_klass, com_sun_cri_ci_CiCodePos, Opt) \ template(CiConstant_klass, com_sun_cri_ci_CiConstant, Opt) \ template(CiKind_klass, com_sun_cri_ci_CiKind, Opt) \ diff -r efba53f86c4f -r 72cfb36c6bb2 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Thu Sep 16 19:42:20 2010 -0700 +++ b/src/share/vm/classfile/vmSymbols.hpp Thu Sep 30 17:19:48 2010 -0700 @@ -265,8 +265,10 @@ template(com_sun_cri_ci_CiTargetMethod_Mark, "com/sun/cri/ci/CiTargetMethod$Mark") \ template(com_sun_cri_ci_CiDebugInfo, "com/sun/cri/ci/CiDebugInfo") \ template(com_sun_cri_ci_CiDebugInfo_Frame, "com/sun/cri/ci/CiDebugInfo$Frame") \ + template(com_sun_cri_ci_CiValue, "com/sun/cri/ci/CiValue") \ + template(com_sun_cri_ci_CiStackSlot, "com/sun/cri/ci/CiStackSlot") \ template(com_sun_cri_ci_CiRegisterValue, "com/sun/cri/ci/CiRegisterValue") \ - template(com_sun_cri_ci_CiStackSlot, "com/sun/cri/ci/CiStackSlot") \ + template(com_sun_cri_ci_CiRegister, "com/sun/cri/ci/CiRegister") \ template(com_sun_cri_ci_CiCodePos, "com/sun/cri/ci/CiCodePos") \ template(com_sun_cri_ci_CiConstant, "com/sun/cri/ci/CiConstant") \ template(com_sun_cri_ci_CiKind, "com/sun/cri/ci/CiKind") \ diff -r efba53f86c4f -r 72cfb36c6bb2 src/share/vm/compiler/compileBroker.cpp --- a/src/share/vm/compiler/compileBroker.cpp Thu Sep 16 19:42:20 2010 -0700 +++ b/src/share/vm/compiler/compileBroker.cpp Thu Sep 30 17:19:48 2010 -0700 @@ -1495,6 +1495,7 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) { if (PrintCompilation) { ResourceMark rm; + tty->print("%s: ", compiler(task->comp_level())->name()); task->print_line(); } elapsedTimer time; diff -r efba53f86c4f -r 72cfb36c6bb2 src/share/vm/runtime/sharedRuntime.cpp --- a/src/share/vm/runtime/sharedRuntime.cpp Thu Sep 16 19:42:20 2010 -0700 +++ b/src/share/vm/runtime/sharedRuntime.cpp Thu Sep 30 17:19:48 2010 -0700 @@ -612,6 +612,7 @@ _implicit_null_throws++; #endif if (UseC1X) { + tty->print("implicit null at %08x%08x", ((long)pc) >> 32, pc); target_pc = Runtime1::entry_for(Runtime1::c1x_global_implicit_null_id); } else { target_pc = nm->continuation_for_implicit_exception(pc);