# HG changeset patch # User Lukas Stadler # Date 1283318010 25200 # Node ID abc670a709dc37bd41cc5f918072c2b745819109 # Parent 695451afc619e2d37ccbf3d6f77f83609d33b8ca * -XX:TraceC1X=0...5 controls the native c1x tracing * -Dc1x.debug=true turns on the logging proxies and lots of log output on the java side * provide more information about types to the compiler (type hierarchy, etc) * provide exception handler tables to the compiler * add exception handlers to the nmethod * correct implementation of ExceptionObject * exception handling/unwinding entry points * modified versions of handle/unwind exception stubs using standard calling conventions * exception throwing * implicit null pointer exception, implicit div by 0 exception * arraystore/classcast/arrayindex exceptions * checkcast implementation * newarray, anewarray, multinewarray implementation * correct new instance initialization * access to java class mirrors (for ldc) * unresolved methods * class resolving - class patching (asssembly prototype copying) diff -r 695451afc619 -r abc670a709dc .cproject --- a/.cproject Thu Aug 19 14:34:52 2010 -0700 +++ b/.cproject Tue Aug 31 22:13:30 2010 -0700 @@ -23,7 +23,7 @@ - + diff -r 695451afc619 -r abc670a709dc .project --- a/.project Thu Aug 19 14:34:52 2010 -0700 +++ b/.project Tue Aug 31 22:13:30 2010 -0700 @@ -88,7 +88,7 @@ client 2 - /home/ls/source/jre1.7.0/lib/amd64/client + PARENT-1-PROJECT_LOC/jre1.7.0/lib/amd64/client diff -r 695451afc619 -r abc670a709dc c1x4hotspotsrc/HotSpotTest/src/jttTests.java --- a/c1x4hotspotsrc/HotSpotTest/src/jttTests.java Thu Aug 19 14:34:52 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotTest/src/jttTests.java Tue Aug 31 22:13:30 2010 -0700 @@ -4,7 +4,7 @@ public class jttTests { public static void main(String[] args) { - runTests(0, 200); + runTests(0, 1000); Logger.info("total: " + executed + " tests executed, " + passed + " passed, " + failed + " failed"); } @@ -82,7 +82,7 @@ jtt_bytecode_BC_arraylength(); break; case 10: - //jtt_bytecode_BC_athrow(); + jtt_bytecode_BC_athrow(); break; case 11: jtt_bytecode_BC_baload(); @@ -97,25 +97,25 @@ jtt_bytecode_BC_castore(); break; case 15: - //jtt_bytecode_BC_checkcast01(); + jtt_bytecode_BC_checkcast01(); break; case 16: - //jtt_bytecode_BC_checkcast02(); + jtt_bytecode_BC_checkcast02(); break; case 17: jtt_bytecode_BC_d2f(); break; case 18: - //jtt_bytecode_BC_d2i01(); + jtt_bytecode_BC_d2i01(); break; case 19: - //jtt_bytecode_BC_d2i02(); + jtt_bytecode_BC_d2i02(); break; case 20: - //jtt_bytecode_BC_d2l01(); + jtt_bytecode_BC_d2l01(); break; case 21: - //jtt_bytecode_BC_d2l02(); + jtt_bytecode_BC_d2l02(); break; case 22: jtt_bytecode_BC_dadd(); @@ -580,10 +580,10 @@ jtt_bytecode_BC_lxor(); break; case 176: - jtt_bytecode_BC_monitorenter(); + // jtt_bytecode_BC_monitorenter(); break; case 177: - jtt_bytecode_BC_monitorenter02(); + // jtt_bytecode_BC_monitorenter02(); break; case 178: jtt_bytecode_BC_multianewarray01(); @@ -1024,7 +1024,7 @@ jtt_except_BC_lrem(); break; case 324: - jtt_except_BC_monitorenter(); + //jtt_except_BC_monitorenter(); break; case 325: jtt_except_BC_multianewarray(); @@ -1108,19 +1108,19 @@ jtt_except_Catch_Two03(); break; case 352: - jtt_except_Except_Synchronized01(); + //jtt_except_Except_Synchronized01(); break; case 353: - jtt_except_Except_Synchronized02(); + //jtt_except_Except_Synchronized02(); break; case 354: - jtt_except_Except_Synchronized03(); + //jtt_except_Except_Synchronized03(); break; case 355: - jtt_except_Except_Synchronized04(); + //jtt_except_Except_Synchronized04(); break; case 356: - jtt_except_Except_Synchronized05(); + //jtt_except_Except_Synchronized05(); break; case 357: jtt_except_Finally01(); @@ -1159,19 +1159,19 @@ jtt_except_Throw_NPE_01(); break; case 369: - jtt_except_Throw_Synchronized01(); + //jtt_except_Throw_Synchronized01(); break; case 370: - jtt_except_Throw_Synchronized02(); + //jtt_except_Throw_Synchronized02(); break; case 371: - jtt_except_Throw_Synchronized03(); + //jtt_except_Throw_Synchronized03(); break; case 372: - jtt_except_Throw_Synchronized04(); + //jtt_except_Throw_Synchronized04(); break; case 373: - jtt_except_Throw_Synchronized05(); + //jtt_except_Throw_Synchronized05(); break; case 374: jtt_lang_Boxed_TYPE_01(); @@ -1213,7 +1213,7 @@ jtt_lang_Class_getComponentType01(); break; case 387: - jtt_lang_Class_getInterfaces01(); + //jtt_lang_Class_getInterfaces01(); break; case 388: jtt_lang_Class_getName01(); @@ -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(); @@ -1453,7 +1453,7 @@ jtt_micro_BigIntParams02(); break; case 467: - jtt_micro_BigInterfaceParams01(); + //jtt_micro_BigInterfaceParams01(); break; case 468: jtt_micro_BigLongParams02(); @@ -1471,7 +1471,7 @@ jtt_micro_BigObjectParams01(); break; case 473: - jtt_micro_BigObjectParams02(); + //jtt_micro_BigObjectParams02(); break; case 474: jtt_micro_BigParamsAlignment(); @@ -1480,7 +1480,7 @@ jtt_micro_BigShortParams01(); break; case 476: - jtt_micro_BigVirtualParams01(); + //jtt_micro_BigVirtualParams01(); break; case 477: jtt_micro_Bubblesort(); @@ -1501,7 +1501,7 @@ jtt_micro_StrangeFrames(); break; case 483: - jtt_micro_String_format01(); + //jtt_micro_String_format01(); break; case 484: jtt_micro_String_format02(); @@ -1630,13 +1630,13 @@ jtt_reflect_Class_getField01(); break; case 526: - jtt_reflect_Class_getField02(); + //jtt_reflect_Class_getField02(); break; case 527: jtt_reflect_Class_getMethod01(); break; case 528: - jtt_reflect_Class_getMethod02(); + //jtt_reflect_Class_getMethod02(); break; case 529: jtt_reflect_Class_newInstance01(); @@ -1681,19 +1681,19 @@ jtt_reflect_Invoke_except01(); break; case 543: - jtt_reflect_Invoke_main01(); + //jtt_reflect_Invoke_main01(); break; case 544: - jtt_reflect_Invoke_main02(); + //jtt_reflect_Invoke_main02(); break; case 545: - jtt_reflect_Invoke_main03(); + //jtt_reflect_Invoke_main03(); break; case 546: - jtt_reflect_Invoke_virtual01(); + //jtt_reflect_Invoke_virtual01(); break; case 547: - jtt_reflect_Method_getParameterTypes01(); + //jtt_reflect_Method_getParameterTypes01(); break; case 548: jtt_reflect_Method_getReturnType01(); @@ -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(); @@ -1732,19 +1732,19 @@ jtt_threads_ThreadLocal02(); break; case 560: - jtt_threads_ThreadLocal03(); + //jtt_threads_ThreadLocal03(); break; case 561: jtt_threads_Thread_currentThread01(); break; case 562: - jtt_threads_Thread_getState01(); + //jtt_threads_Thread_getState01(); break; case 563: - jtt_threads_Thread_getState02(); + //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,10 +1795,10 @@ jtt_jdk_Class_getName(); break; case 581: - jtt_jdk_EnumMap01(); + //jtt_jdk_EnumMap01(); break; case 582: - jtt_jdk_EnumMap02(); + //jtt_jdk_EnumMap02(); break; case 583: jtt_jdk_System_currentTimeMillis01(); diff -r 695451afc619 -r abc670a709dc c1x4hotspotsrc/HotSpotVM/.settings/org.eclipse.jdt.core.prefs --- a/c1x4hotspotsrc/HotSpotVM/.settings/org.eclipse.jdt.core.prefs Thu Aug 19 14:34:52 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/.settings/org.eclipse.jdt.core.prefs Tue Aug 31 22:13:30 2010 -0700 @@ -1,4 +1,4 @@ -#Tue Aug 10 16:59:56 PDT 2010 +#Mon Aug 23 15:50:20 PDT 2010 eclipse.preferences.version=1 org.eclipse.jdt.core.builder.cleanOutputFolder=clean org.eclipse.jdt.core.builder.duplicateResourceTask=warning @@ -376,7 +376,7 @@ org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true org.eclipse.jdt.core.formatter.tabulation.char=space org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=false +org.eclipse.jdt.core.formatter.use_on_off_tags=true org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false org.eclipse.jdt.core.formatter.wrap_before_binary_operator=false org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true diff -r 695451afc619 -r abc670a709dc c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/Compiler.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/Compiler.java Thu Aug 19 14:34:52 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/Compiler.java Tue Aug 31 22:13:30 2010 -0700 @@ -62,8 +62,10 @@ public static VMEntries getVMEntries() { if (vmEntries == null) { try { - vmEntries = LoggingProxy.getProxy(VMEntries.class, new VMEntriesNative()); - // vmEntries = new VMEntriesNative(); + if (Logger.ENABLED) + vmEntries = LoggingProxy.getProxy(VMEntries.class, new VMEntriesNative()); + else + vmEntries = new VMEntriesNative(); } catch (Throwable t) { t.printStackTrace(); } @@ -86,12 +88,14 @@ ReplacingInputStream input = new ReplacingInputStream(socket.getInputStream()); InvocationSocket invocation = new InvocationSocket(output, input); - VMExits exits = (VMExits)Proxy.newProxyInstance(VMExits.class.getClassLoader(), new Class[] {VMExits.class}, invocation); + VMExits exits = (VMExits) Proxy.newProxyInstance(VMExits.class.getClassLoader(), new Class[] { VMExits.class}, invocation); VMEntries entries = Compiler.initializeClient(exits); invocation.setDelegate(entries); } else { - vmExits = LoggingProxy.getProxy(VMExits.class, new VMExitsNative()); - // vmExits = new VMExitsNative(); + if (Logger.ENABLED) + vmExits = LoggingProxy.getProxy(VMExits.class, new VMExitsNative()); + else + vmExits = new VMExitsNative(); } } catch (Throwable t) { t.printStackTrace(); @@ -120,13 +124,14 @@ compiler = new C1XCompiler(runtime, target, generator); C1XOptions.setOptimizationLevel(3); - C1XOptions.TraceBytecodeParserLevel = 4; + C1XOptions.TraceBytecodeParserLevel = Logger.ENABLED ? 4 : 0; C1XOptions.PrintCFGToFile = false; C1XOptions.PrintAssembly = false;// true; - C1XOptions.PrintCompilation = true; + C1XOptions.PrintCompilation = Logger.ENABLED; C1XOptions.GenAssertionCode = true; C1XOptions.DetailedAsserts = true; C1XOptions.GenSpecialDivChecks = true; + C1XOptions.AlignCallsForPatching = true; } public CiCompiler getCompiler() { diff -r 695451afc619 -r abc670a709dc c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotExceptionHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotExceptionHandler.java Tue Aug 31 22:13:30 2010 -0700 @@ -0,0 +1,43 @@ +package com.sun.hotspot.c1x; + +import com.sun.cri.ri.*; + + +public class HotSpotExceptionHandler implements RiExceptionHandler, CompilerObject { + private int startBci; + private int endBci; + private int handlerBci; + private int catchClassIndex; + private RiType catchClass; + + @Override + public int startBCI() { + return startBci; + } + + @Override + public int endBCI() { + return endBci; + } + + @Override + public int handlerBCI() { + return handlerBci; + } + + @Override + public int catchClassIndex() { + return catchClassIndex; + } + + @Override + public boolean isCatchAll() { + return catchClassIndex == 0; + } + + @Override + public RiType catchKlass() { + return catchClass; + } + +} diff -r 695451afc619 -r abc670a709dc c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotMethod.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotMethod.java Thu Aug 19 14:34:52 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotMethod.java Tue Aug 31 22:13:30 2010 -0700 @@ -1,169 +1,25 @@ -/* - * 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; - -import com.sun.cri.ri.*; - -/** - * Implementation of RiMethod for HotSpot methods. - * - * @author Thomas Wuerthinger, Lukas Stadler - */ -public class HotSpotMethod implements RiMethod, CompilerObject { - - private final long vmId; - private final String name; - - // cached values - private byte[] code; - private int accessFlags = -1; - private int maxLocals = -1; - private int maxStackSize = -1; - private RiSignature signature; - private RiType holder; - - public HotSpotMethod(long vmId, String name) { - this.vmId = vmId; - this.name = name; - } - - @Override - public int accessFlags() { - if (accessFlags == -1) { - accessFlags = Compiler.getVMEntries().RiMethod_accessFlags(vmId); - } - return accessFlags; - } - - @Override - public boolean canBeStaticallyBound() { - // TODO Auto-generated method stub - return false; - } - - @Override - public byte[] code() { - if (code == null) { - code = Compiler.getVMEntries().RiMethod_code(vmId); - } - return code; - } - - @Override - public RiExceptionHandler[] exceptionHandlers() { - // TODO: Add support for exception handlers - return new RiExceptionHandler[0]; - } - - @Override - public boolean hasBalancedMonitors() { - // TODO Auto-generated method stub - return false; - } - - @Override - public RiType holder() { - if (holder == null ) { - holder = Compiler.getVMEntries().RiMethod_holder(vmId); - } - return holder; - } - - @Override - public boolean isClassInitializer() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isConstructor() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isLeafMethod() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isOverridden() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isResolved() { - // TODO Auto-generated method stub - return false; - } - - @Override - public String jniSymbol() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Object liveness(int bci) { - // TODO Auto-generated method stub - return null; - } - - @Override - public int maxLocals() { - if (maxLocals == -1) { - maxLocals = Compiler.getVMEntries().RiMethod_maxLocals(vmId); - } - return maxLocals; - } - - @Override - public int maxStackSize() { - if (maxStackSize == -1) { - maxStackSize = Compiler.getVMEntries().RiMethod_maxStackSize(vmId); - } - return maxStackSize; - } - - @Override - public RiMethodProfile methodData() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String name() { - return name; - } - - @Override - public RiSignature signature() { - if (signature == null) { - signature = new HotSpotSignature(Compiler.getVMEntries().RiMethod_signature(vmId)); - } - return signature; - } - - @Override - public String toString() { - return "HotSpotMethod<" + name + ">"; - } - -} +/* + * 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; + +import com.sun.cri.ri.*; + + +public interface HotSpotMethod extends RiMethod, CompilerObject { + +} diff -r 695451afc619 -r abc670a709dc c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotMethodResolved.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotMethodResolved.java Tue Aug 31 22:13:30 2010 -0700 @@ -0,0 +1,169 @@ +/* + * 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; + +import com.sun.cri.ri.*; + +/** + * Implementation of RiMethod for resolved HotSpot methods. + * + * @author Thomas Wuerthinger, Lukas Stadler + */ +public class HotSpotMethodResolved implements HotSpotMethod { + + private final long vmId; + private final String name; + + // cached values + private byte[] code; + private int accessFlags = -1; + private int maxLocals = -1; + private int maxStackSize = -1; + private RiExceptionHandler[] exceptionHandlers; + private RiSignature signature; + private RiType holder; + + public HotSpotMethodResolved(long vmId, String name) { + this.vmId = vmId; + this.name = name; + } + + @Override + public int accessFlags() { + if (accessFlags == -1) { + accessFlags = Compiler.getVMEntries().RiMethod_accessFlags(vmId); + } + return accessFlags; + } + + @Override + public boolean canBeStaticallyBound() { + // TODO Auto-generated method stub + return false; + } + + @Override + public byte[] code() { + if (code == null) { + code = Compiler.getVMEntries().RiMethod_code(vmId); + } + return code; + } + + @Override + public RiExceptionHandler[] exceptionHandlers() { + if (exceptionHandlers == null) { + exceptionHandlers = Compiler.getVMEntries().RiMethod_exceptionHandlers(vmId); + } + return exceptionHandlers; + } + + @Override + public boolean hasBalancedMonitors() { + // TODO Auto-generated method stub + return false; + } + + @Override + public RiType holder() { + if (holder == null ) { + holder = Compiler.getVMEntries().RiMethod_holder(vmId); + } + return holder; + } + + @Override + public boolean isClassInitializer() { + return "".equals(name); + } + + @Override + public boolean isConstructor() { + return "".equals(name); + } + + @Override + public boolean isLeafMethod() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isOverridden() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isResolved() { + return true; + } + + @Override + public String jniSymbol() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object liveness(int bci) { + // TODO Auto-generated method stub + return null; + } + + @Override + public int maxLocals() { + if (maxLocals == -1) { + maxLocals = Compiler.getVMEntries().RiMethod_maxLocals(vmId); + } + return maxLocals; + } + + @Override + public int maxStackSize() { + if (maxStackSize == -1) { + maxStackSize = Compiler.getVMEntries().RiMethod_maxStackSize(vmId); + } + return maxStackSize; + } + + @Override + public RiMethodProfile methodData() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String name() { + return name; + } + + @Override + public RiSignature signature() { + if (signature == null) { + signature = new HotSpotSignature(Compiler.getVMEntries().RiMethod_signature(vmId)); + } + return signature; + } + + @Override + public String toString() { + return "HotSpotMethod<" + name + ">"; + } + +} diff -r 695451afc619 -r abc670a709dc c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotMethodUnresolved.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotMethodUnresolved.java Tue Aug 31 22:13:30 2010 -0700 @@ -0,0 +1,133 @@ +/* + * 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; + +import com.sun.cri.ci.*; +import com.sun.cri.ri.*; + +/** + * Implementation of RiMethod for unresolved HotSpot methods. + * + * @author Lukas Stadler + */ +public class HotSpotMethodUnresolved implements HotSpotMethod { + private final String name; + private final RiType holder; + private final RiSignature signature; + + public HotSpotMethodUnresolved(String name, String signature, RiType holder) { + this.name = name; + this.holder = holder; + this.signature = new HotSpotSignature(signature); + } + + @Override + public String name() { + return name; + } + + @Override + public RiType holder() { + return holder; + } + + @Override + public RiSignature signature() { + return signature; + } + + @Override + public boolean isResolved() { + return false; + } + + @Override + public byte[] code() { + throw unresolved("code"); + } + + @Override + public RiMethodProfile methodData() { + throw unresolved("methodData"); + } + + @Override + public String jniSymbol() { + throw unresolved("jniSymbol"); + } + + @Override + public int maxLocals() { + throw unresolved("maxLocals"); + } + + @Override + public int maxStackSize() { + throw unresolved("maxStackSize"); + } + + @Override + public boolean hasBalancedMonitors() { + throw unresolved("hasBalancedMonitors"); + } + + @Override + public int accessFlags() { + throw unresolved("accessFlags"); + } + + @Override + public boolean isLeafMethod() { + throw unresolved("isLeafMethod"); + } + + @Override + public boolean isClassInitializer() { + return "".equals(name); + } + + @Override + public boolean isConstructor() { + return "".equals(name); + } + + @Override + public boolean isOverridden() { + throw unresolved("isOverridden"); + } + + @Override + public Object liveness(int bci) { + throw unresolved("liveness"); + } + + @Override + public boolean canBeStaticallyBound() { + throw unresolved("canBeStaticallyBound"); + } + + @Override + public RiExceptionHandler[] exceptionHandlers() { + throw unresolved("exceptionHandlers"); + } + + private CiUnresolvedException unresolved(String operation) { + return new CiUnresolvedException(operation + " not defined for unresolved method " + name); + } + +} diff -r 695451afc619 -r abc670a709dc c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotRegisterConfig.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotRegisterConfig.java Thu Aug 19 14:34:52 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotRegisterConfig.java Tue Aug 31 22:13:30 2010 -0700 @@ -35,7 +35,7 @@ @Override public CiRegister[] getAllocatableRegisters() { - return new CiRegister[] { AMD64.rax, AMD64.rbx, AMD64.rcx, AMD64.rdx, AMD64.rsi, AMD64.rdi, /*AMD64.r10, */AMD64.r11, AMD64.xmm0, AMD64.xmm1, AMD64.xmm2, AMD64.xmm3, AMD64.xmm4, AMD64.xmm5, + 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, 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 695451afc619 -r abc670a709dc c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTargetMethod.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTargetMethod.java Thu Aug 19 14:34:52 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTargetMethod.java Tue Aug 31 22:13:30 2010 -0700 @@ -21,6 +21,7 @@ import com.sun.cri.ci.*; import com.sun.cri.ci.CiTargetMethod.*; +import com.sun.hotspot.c1x.logging.*; /** * CiTargetMethod augmented with HotSpot-specific information. @@ -30,17 +31,23 @@ public class HotSpotTargetMethod implements CompilerObject { public final CiTargetMethod targetMethod; - public final HotSpotMethod method; // used only for methods - public final String name; // used only for stubs + public final HotSpotMethodResolved method; // used only for methods + public final String name; // used only for stubs public final Site[] sites; + public final ExceptionHandler[] exceptionHandlers; - private HotSpotTargetMethod(HotSpotMethod method, CiTargetMethod targetMethod) { + private HotSpotTargetMethod(HotSpotMethodResolved method, CiTargetMethod targetMethod) { this.method = method; this.targetMethod = targetMethod; this.name = null; sites = getSortedSites(targetMethod); + if (targetMethod.exceptionHandlers == null) { + exceptionHandlers = null; + } else { + exceptionHandlers = targetMethod.exceptionHandlers.toArray(new ExceptionHandler[targetMethod.exceptionHandlers.size()]); + } } private HotSpotTargetMethod(CiTargetMethod targetMethod, String name) { @@ -49,10 +56,12 @@ this.name = name; sites = getSortedSites(targetMethod); + assert targetMethod.exceptionHandlers == null || targetMethod.exceptionHandlers.size() == 0; + exceptionHandlers = null; } private Site[] getSortedSites(CiTargetMethod target) { - List[] lists = new List[] {target.directCalls, target.indirectCalls, target.safepoints, target.dataReferences, target.exceptionHandlers, target.marks}; + List[] lists = new List[] { target.directCalls, target.indirectCalls, target.safepoints, target.dataReferences, target.marks}; int count = 0; for (List list : lists) { count += list.size(); @@ -73,12 +82,13 @@ return s1.pcOffset - s2.pcOffset; } }); - for(Site site : result) - System.out.println(site.pcOffset + ": " + site); + if (Logger.ENABLED) + for (Site site : result) + Logger.log(site.pcOffset + ": " + site); return result; } - public static void installMethod(HotSpotMethod method, CiTargetMethod targetMethod) { + public static void installMethod(HotSpotMethodResolved method, CiTargetMethod targetMethod) { Compiler.getVMEntries().installMethod(new HotSpotTargetMethod(method, targetMethod)); } diff -r 695451afc619 -r abc670a709dc c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTypePrimitive.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTypePrimitive.java Thu Aug 19 14:34:52 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTypePrimitive.java Tue Aug 31 22:13:30 2010 -0700 @@ -47,7 +47,6 @@ @Override public RiType componentType() { - // TODO Auto-generated method stub return null; } @@ -71,61 +70,51 @@ @Override public boolean hasFinalizableSubclass() { - // TODO Auto-generated method stub return false; } @Override public boolean hasFinalizer() { - // TODO Auto-generated method stub return false; } @Override public boolean hasSubclass() { - // TODO Auto-generated method stub return false; } @Override public boolean isArrayClass() { - // TODO Auto-generated method stub return false; } @Override public boolean isInitialized() { - // TODO Auto-generated method stub - return false; + return true; } @Override public boolean isInstance(Object obj) { - // TODO Auto-generated method stub return false; } @Override public boolean isInstanceClass() { - // TODO Auto-generated method stub return false; } @Override public boolean isInterface() { - // TODO Auto-generated method stub return false; } @Override public boolean isResolved() { - // TODO Auto-generated method stub return true; } @Override public boolean isSubtypeOf(RiType other) { - // TODO Auto-generated method stub return false; } diff -r 695451afc619 -r abc670a709dc c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTypeResolved.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTypeResolved.java Thu Aug 19 14:34:52 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTypeResolved.java Tue Aug 31 22:13:30 2010 -0700 @@ -28,48 +28,68 @@ public class HotSpotTypeResolved implements HotSpotType { private final long vmId; - + private final long javaMirrorVmId; private final String name; + private final int accessFlags; + private final boolean hasFinalizer; + private final boolean hasSubclass; + private final boolean hasFinalizableSubclass; + private final boolean isInitialized; + private final boolean isArrayClass; + private final boolean isInstanceClass; + private final boolean isInterface; + private final int instanceSize; - // cached values - private Boolean isArrayClass; - private Boolean isInstanceClass; - private Boolean isInterface; - private long instanceSize; - - public HotSpotTypeResolved(long vmId, String name) { + public HotSpotTypeResolved(long vmId, long javaMirrorVmId, String name, int accessFlags, boolean hasFinalizer, boolean hasSubclass, boolean hasFinalizableSubclass, boolean isInitialized, + boolean isArrayClass, boolean isInstanceClass, boolean isInterface, int instanceSize) { this.vmId = vmId; + this.javaMirrorVmId = javaMirrorVmId; this.name = name; + this.accessFlags = accessFlags; + this.hasFinalizer = hasFinalizer; + this.hasSubclass = hasSubclass; + this.hasFinalizableSubclass = hasFinalizableSubclass; + this.isInitialized = isInitialized; + this.isArrayClass = isArrayClass; + this.isInstanceClass = isInstanceClass; + this.isInterface = isInterface; + this.instanceSize = instanceSize; } @Override public int accessFlags() { - // TODO Auto-generated method stub - return 0; + return accessFlags; } @Override public RiType arrayOf() { - // TODO Auto-generated method stub return null; } @Override public RiType componentType() { - // TODO Auto-generated method stub return null; } @Override public RiType exactType() { - // TODO Auto-generated method stub return null; } @Override public CiConstant getEncoding(Representation r) { - // TODO Auto-generated method stub - return null; + switch (r) { + case JavaClass: + return CiConstant.forObject((Long) javaMirrorVmId); + case ObjectHub: + return CiConstant.forObject(this); + case StaticFields: + return CiConstant.forObject(this); + case TypeInfo: + return CiConstant.forObject(this); + default: + return null; + } } @Override @@ -79,52 +99,42 @@ @Override public boolean hasFinalizableSubclass() { - // TODO Auto-generated method stub - return false; + return hasFinalizableSubclass; } @Override public boolean hasFinalizer() { - // TODO Auto-generated method stub - return false; + return hasFinalizer; } @Override public boolean hasSubclass() { - // TODO Auto-generated method stub - return false; + return hasSubclass; } @Override public boolean isArrayClass() { - if (isArrayClass == null) - isArrayClass = Compiler.getVMEntries().RiType_isArrayClass(vmId); return isArrayClass; } @Override public boolean isInitialized() { - // TODO Auto-generated method stub - return false; + return isInitialized; } @Override public boolean isInstance(Object obj) { - // TODO Auto-generated method stub + return false; } @Override public boolean isInstanceClass() { - if (isInstanceClass == null) - isInstanceClass = Compiler.getVMEntries().RiType_isInstanceClass(vmId); return isInstanceClass; } @Override public boolean isInterface() { - if (isInterface == null) - isInterface = Compiler.getVMEntries().RiType_isInterface(vmId); return isInterface; } @@ -135,7 +145,10 @@ @Override public boolean isSubtypeOf(RiType other) { - // TODO Auto-generated method stub + assert other instanceof HotSpotType; + if (other instanceof HotSpotTypeResolved) + return Compiler.getVMEntries().RiType_isSubtypeOf(vmId, other); + // no resolved type is a subtype of an unresolved type return false; } @@ -151,18 +164,18 @@ @Override public String name() { - return name; + return "L" + name + ";"; } @Override public RiMethod resolveMethodImpl(RiMethod method) { - // TODO Auto-generated method stub - return null; + assert method instanceof HotSpotMethod; + return Compiler.getVMEntries().RiType_resolveMethodImpl(vmId, method.name(), method.signature().asString()); } @Override public String toString() { - return "HotSpotType<" + name + ">"; + return "HotSpotType<" + name + ", resolved>"; } public RiConstantPool constantPool() { @@ -173,10 +186,7 @@ return vmId; } - public long instanceSize() { - if (instanceSize == 0) { - instanceSize = Compiler.getVMEntries().RiType_instanceSize(vmId); - } + public int instanceSize() { return instanceSize; } diff -r 695451afc619 -r abc670a709dc c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTypeUnresolved.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTypeUnresolved.java Thu Aug 19 14:34:52 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTypeUnresolved.java Tue Aug 31 22:13:30 2010 -0700 @@ -147,7 +147,7 @@ @Override public String toString() { - return "HotSpotTypeUnresolved<" + name + ">"; + return "HotSpotType<" + name + ", unresolved>"; } @Override diff -r 695451afc619 -r abc670a709dc c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotVMConfig.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotVMConfig.java Thu Aug 19 14:34:52 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotVMConfig.java Tue Aug 31 22:13:30 2010 -0700 @@ -40,13 +40,24 @@ public int threadTlabTopOffset; public int threadTlabEndOffset; public int instanceHeaderPrototypeOffset; + public int threadExceptionOopOffset; + public int threadExceptionPcOffset; + public int threadMultiNewArrayStorage; // runtime stubs + public long debugStub; public long instanceofStub; - public long debugStub; + public long newInstanceStub; + public long newTypeArrayStub; + public long newObjectArrayStub; + public long newMultiArrayStub; + public long loadKlassStub; public long resolveStaticCallStub; - public long newInstanceStub; - public long throwImplicitNullStub; + public long unwindExceptionStub; + public long handleExceptionStub; + public long throwClassCastException; + public long throwArrayStoreException; + public long throwArrayIndexException; public void check() { assert vmPageSize >= 16; diff -r 695451afc619 -r abc670a709dc c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java Thu Aug 19 14:34:52 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java Tue Aug 31 22:13:30 2010 -0700 @@ -19,6 +19,7 @@ import java.lang.reflect.*; import java.util.*; +import java.util.concurrent.*; import com.sun.c1x.target.amd64.*; import com.sun.cri.ci.CiAddress.Scale; @@ -36,16 +37,26 @@ public class HotSpotXirGenerator implements RiXirGenerator { // this needs to correspond to c1x_CodeInstaller.hpp - private static final Integer MARK_VERIFIED_ENTRY = 0x0001; - private static final Integer MARK_UNVERIFIED_ENTRY = 0x0002; - private static final Integer MARK_OSR_ENTRY = 0x0003; - private static final Integer MARK_STATIC_CALL_STUB = 0x1000; - private static final Integer MARK_INVOKE_INVALID = 0x2000; - private static final Integer MARK_INVOKEINTERFACE = 0x2001; - private static final Integer MARK_INVOKESTATIC = 0x2002; - private static final Integer MARK_INVOKESPECIAL = 0x2003; - private static final Integer MARK_INVOKEVIRTUAL = 0x2004; - private static final Integer MARK_IMPLICIT_NULL_EXCEPTION_TARGET = 0x3000; + // @formatter:off + private static final Integer MARK_VERIFIED_ENTRY = 0x0001; + private static final Integer MARK_UNVERIFIED_ENTRY = 0x0002; + private static final Integer MARK_OSR_ENTRY = 0x0003; + private static final Integer MARK_UNWIND_ENTRY = 0x0004; + private static final Integer MARK_EXCEPTION_HANDLER_ENTRY = 0x0005; + + private static final Integer MARK_STATIC_CALL_STUB = 0x1000; + + private static final Integer MARK_INVOKE_INVALID = 0x2000; + private static final Integer MARK_INVOKEINTERFACE = 0x2001; + private static final Integer MARK_INVOKESTATIC = 0x2002; + private static final Integer MARK_INVOKESPECIAL = 0x2003; + private static final Integer MARK_INVOKEVIRTUAL = 0x2004; + + private static final Integer MARK_IMPLICIT_NULL = 0x3000; + + private static final Integer MARK_KLASS_PATCHING = 0x4000; + private static final Integer MARK_DUMMY_OOP_RELOCATION = 0x4001; + // @formatter:on private final HotSpotVMConfig config; private final CiTarget target; @@ -56,16 +67,24 @@ private XirTemplate[] emptyTemplates = new XirTemplate[CiKind.values().length]; private XirTemplate[] arrayLoadTemplates = new XirTemplate[CiKind.values().length]; private XirTemplate[] arrayStoreTemplates = new XirTemplate[CiKind.values().length]; + private XirTemplate[] arrayLoadTemplatesWithLength = new XirTemplate[CiKind.values().length]; + private XirTemplate[] arrayStoreTemplatesWithLength = new XirTemplate[CiKind.values().length]; private XirTemplate prologueTemplate; private XirTemplate staticPrologueTemplate; private XirTemplate epilogueTemplate; private XirTemplate arrayLengthTemplate; + private XirTemplate safepointTemplate; private XirTemplate exceptionObjectTemplate; private XirTemplate invokeStaticTemplate; private XirTemplate invokeSpecialTemplate; private XirTemplate invokeInterfaceTemplate; private XirTemplate invokeVirtualTemplate; - private XirTemplate newInstanceTemplate; + + private XirTemplate newInstanceUnresolvedTemplate; + private XirPair newObjectArrayTemplate; + private XirTemplate newTypeArrayTemplate; + private XirPair resolveClassTemplate; + private XirPair checkCastTemplate; static class XirPair { @@ -80,8 +99,8 @@ private XirPair[] putFieldTemplates = new XirPair[CiKind.values().length]; private XirPair[] getFieldTemplates = new XirPair[CiKind.values().length]; - private XirPair[] putStaticFieldTemplates = new XirPair[CiKind.values().length]; - private XirPair[] getStaticFieldTemplates = new XirPair[CiKind.values().length]; + private XirPair[] putStaticTemplates = new XirPair[CiKind.values().length]; + private XirPair[] getStaticTemplates = new XirPair[CiKind.values().length]; private XirPair instanceofTemplate; private XirPair instanceofTemplateNonnull; @@ -107,12 +126,14 @@ XirOperand result = asm.createTemp("result", kind); emptyTemplates[index] = asm.finishTemplate(result, "empty-" + kind); - putFieldTemplates[index] = buildPutFieldTemplate(kind, kind == CiKind.Object, false); - getFieldTemplates[index] = buildGetFieldTemplate(kind, false); - putStaticFieldTemplates[index] = buildPutFieldTemplate(kind, kind == CiKind.Object, true); - getStaticFieldTemplates[index] = buildGetFieldTemplate(kind, true); - arrayLoadTemplates[index] = buildArrayLoad(kind, asm, true); - arrayStoreTemplates[index] = buildArrayStore(kind, asm, true, kind == CiKind.Object, kind == CiKind.Object); + putFieldTemplates[index] = buildPutFieldTemplate(kind, kind == CiKind.Object); + getFieldTemplates[index] = buildGetFieldTemplate(kind); + putStaticTemplates[index] = buildPutStaticTemplate(kind, kind == CiKind.Object); + getStaticTemplates[index] = buildGetStaticTemplate(kind); + arrayLoadTemplates[index] = buildArrayLoad(kind, asm, true, false); + arrayStoreTemplates[index] = buildArrayStore(kind, asm, true, kind == CiKind.Object, kind == CiKind.Object, false); + arrayLoadTemplatesWithLength[index] = buildArrayLoad(kind, asm, true, true); + arrayStoreTemplatesWithLength[index] = buildArrayStore(kind, asm, true, kind == CiKind.Object, kind == CiKind.Object, true); // newArrayTemplates[index] = buildNewArray(kind); } // templates.add(emptyTemplates[index]); @@ -127,21 +148,43 @@ epilogueTemplate = buildEpilogue(); arrayLengthTemplate = buildArrayLength(); exceptionObjectTemplate = buildExceptionObject(); + safepointTemplate = buildSafepoint(); instanceofTemplate = buildInstanceof(false); instanceofTemplateNonnull = buildInstanceof(true); invokeStaticTemplate = buildInvokeStatic(); invokeSpecialTemplate = buildInvokeSpecial(); invokeInterfaceTemplate = buildInvokeInterface(); invokeVirtualTemplate = buildInvokeVirtual(); - newInstanceTemplate = buildNewInstance(); + newInstanceUnresolvedTemplate = buildNewInstanceUnresolved(); + newObjectArrayTemplate = new XirPair(buildNewObjectArray(true), buildNewObjectArray(false)); + newTypeArrayTemplate = buildNewTypeArray(); + resolveClassTemplate = new XirPair(buildResolveClass(true), buildResolveClass(false)); + checkCastTemplate = buildCheckCast(); return templates; } + private final OndemandTemplates newInstanceTemplates = new OndemandTemplates() { + + @Override + protected XirTemplate create(CiXirAssembler asm, int size) { + return buildNewInstance(asm, size); + } + }; + + private final OndemandTemplates multiNewArrayTemplate = new OndemandTemplates() { + + @Override + protected XirPair create(CiXirAssembler asm, int dimensions) { + return new XirPair(buildMultiNewArray(dimensions, true), buildMultiNewArray(dimensions, false)); + } + }; + private XirTemplate buildPrologue(boolean staticMethod) { asm.restart(CiKind.Void); XirOperand temp = asm.createRegister("temp (rax)", CiKind.Int, AMD64.rax); - XirOperand frame_pointer = asm.createRegister("frame pointer", CiKind.Word, AMD64.rbp); + XirOperand framePointer = asm.createRegister("frame pointer", CiKind.Word, AMD64.rbp); + XirOperand stackPointer = asm.createRegister("stack pointer", CiKind.Word, AMD64.rsp); asm.align(config.codeEntryAlignment); asm.mark(MARK_OSR_ENTRY); @@ -155,35 +198,75 @@ asm.align(config.codeEntryAlignment); } asm.mark(MARK_VERIFIED_ENTRY); - asm.push(frame_pointer); + asm.push(framePointer); + asm.mov(framePointer, stackPointer); asm.pushFrame(); + // -- out of line ------------------------------------------------------- + XirOperand thread = asm.createRegister("thread", CiKind.Word, AMD64.r15); + XirOperand exceptionOop = asm.createTemp("exception oop", CiKind.Object); + XirLabel unwind = asm.createOutOfLineLabel("unwind"); + asm.bindOutOfLine(unwind); + + asm.mark(MARK_UNWIND_ENTRY); + //asm.popFrame(); + //asm.pop(framePointer); + + // TODO synchronized methods / monitors + + asm.pload(CiKind.Object, exceptionOop, thread, asm.i(config.threadExceptionOopOffset), false); + asm.pstore(CiKind.Object, thread, asm.i(config.threadExceptionOopOffset), asm.createConstant(CiConstant.NULL_OBJECT), false); + asm.pstore(CiKind.Long, thread, asm.i(config.threadExceptionPcOffset), asm.l(0), false); + + asm.callRuntime(config.unwindExceptionStub, null, exceptionOop); + asm.shouldNotReachHere(); + + asm.mark(MARK_EXCEPTION_HANDLER_ENTRY); + asm.callRuntime(config.handleExceptionStub, null); + asm.shouldNotReachHere(); + return asm.finishTemplate(staticMethod ? "static prologue" : "prologue"); } private XirTemplate buildEpilogue() { asm.restart(CiKind.Void); - XirOperand frame_pointer = asm.createRegister("frame pointer", CiKind.Word, AMD64.rbp); + XirOperand framePointer = asm.createRegister("frame pointer", CiKind.Word, AMD64.rbp); + asm.popFrame(); - asm.pop(frame_pointer); + asm.pop(framePointer); // TODO safepoint check + return asm.finishTemplate("epilogue"); } private XirTemplate buildArrayLength() { XirOperand result = asm.restart(CiKind.Int); XirParameter object = asm.createInputParameter("object", CiKind.Object); + asm.mark(MARK_IMPLICIT_NULL); asm.pload(CiKind.Int, result, object, asm.i(config.arrayLengthOffset), true); return asm.finishTemplate("arrayLength"); } private XirTemplate buildExceptionObject() { - asm.restart(); - XirOperand temp = asm.createRegister("temp (rax)", CiKind.Object, AMD64.rax); - return asm.finishTemplate(temp, "exception object"); + XirOperand result = asm.restart(CiKind.Object); + XirOperand thread = asm.createRegister("thread", CiKind.Word, AMD64.r15); + + asm.pload(CiKind.Object, result, thread, asm.i(config.threadExceptionOopOffset), false); + asm.pstore(CiKind.Object, thread, asm.i(config.threadExceptionOopOffset), asm.o(null), false); + asm.pstore(CiKind.Long, thread, asm.i(config.threadExceptionPcOffset), asm.l(0), false); + + return asm.finishTemplate("exception object"); } - private XirPair buildGetFieldTemplate(CiKind kind, boolean isStatic) { + private XirTemplate buildSafepoint() { + asm.restart(CiKind.Void); + + // TODO safepoint + + return asm.finishTemplate("safepoint"); + } + + private XirPair buildGetFieldTemplate(CiKind kind) { final XirTemplate resolved; final XirTemplate unresolved; { @@ -191,31 +274,52 @@ XirOperand result = asm.restart(kind); XirParameter object = asm.createInputParameter("object", CiKind.Object); XirParameter fieldOffset = asm.createConstantInputParameter("fieldOffset", CiKind.Int); + asm.mark(MARK_IMPLICIT_NULL); asm.pload(kind, result, object, fieldOffset, true); resolved = asm.finishTemplate("getfield<" + kind + ">"); } - if (isStatic) { - asm.restart(kind); - asm.shouldNotReachHere(); - -// XirParameter object = asm.createInputParameter("object", CiKind.Object); -// XirParameter guard = asm.createInputParameter("guard", CiKind.Object); -// XirOperand fieldOffset = asm.createTemp("fieldOffset", CiKind.Int); -// if (isStatic) { -// callRuntimeThroughStub(asm, "resolveGetStatic", fieldOffset, guard); -// } else { -// callRuntimeThroughStub(asm, "resolveGetField", fieldOffset, guard); -// } -// asm.pload(kind, result, object, fieldOffset, true); - - unresolved = asm.finishTemplate("getfield<" + kind + ">-unresolved"); - } else { - unresolved = null; - } + unresolved = null; return new XirPair(resolved, unresolved); } - private XirPair buildPutFieldTemplate(CiKind kind, boolean genWriteBarrier, boolean isStatic) { + private XirPair buildPutFieldTemplate(CiKind kind, boolean genWriteBarrier) { + final XirTemplate resolved; + final XirTemplate unresolved; + { + // resolved case + asm.restart(CiKind.Void); + XirParameter object = asm.createInputParameter("object", CiKind.Object); + XirParameter value = asm.createInputParameter("value", kind); + XirParameter fieldOffset = asm.createConstantInputParameter("fieldOffset", CiKind.Int); + asm.mark(MARK_IMPLICIT_NULL); + asm.pstore(kind, object, fieldOffset, value, true); + if (genWriteBarrier) { + // TODO write barrier + // addWriteBarrier(asm, object, value); + } + resolved = asm.finishTemplate("putfield<" + kind + ", " + genWriteBarrier + ">"); + } + unresolved = null; + return new XirPair(resolved, unresolved); + } + + private XirPair buildGetStaticTemplate(CiKind kind) { + final XirTemplate resolved; + final XirTemplate unresolved; + { + // resolved case + XirOperand result = asm.restart(kind); + XirParameter object = asm.createInputParameter("object", CiKind.Object); + XirParameter fieldOffset = asm.createConstantInputParameter("fieldOffset", CiKind.Int); + asm.mark(MARK_IMPLICIT_NULL); + asm.pload(kind, result, object, fieldOffset, true); + resolved = asm.finishTemplate("getfield<" + kind + ">"); + } + unresolved = null; + return new XirPair(resolved, unresolved); + } + + private XirPair buildPutStaticTemplate(CiKind kind, boolean genWriteBarrier) { final XirTemplate resolved; final XirTemplate unresolved; { @@ -224,6 +328,7 @@ XirParameter object = asm.createInputParameter("object", CiKind.Object); XirParameter value = asm.createInputParameter("value", kind); XirParameter fieldOffset = asm.createConstantInputParameter("fieldOffset", CiKind.Int); + asm.mark(MARK_IMPLICIT_NULL); asm.pstore(kind, object, fieldOffset, value, true); if (genWriteBarrier) { // TODO write barrier @@ -231,147 +336,251 @@ } resolved = asm.finishTemplate("putfield<" + kind + ", " + genWriteBarrier + ">"); } - if (isStatic) { - // unresolved case - asm.restart(CiKind.Void); - asm.shouldNotReachHere(); - -// XirParameter object = asm.createInputParameter("object", CiKind.Object); -// XirParameter value = asm.createInputParameter("value", kind); -// XirParameter guard = asm.createInputParameter("guard", CiKind.Object); -// XirOperand fieldOffset = asm.createTemp("fieldOffset", CiKind.Int); -// if (isStatic) { -// callRuntimeThroughStub(asm, "resolvePutStatic", fieldOffset, guard); -// } else { -// callRuntimeThroughStub(asm, "resolvePutField", fieldOffset, guard); -// } -// asm.pstore(kind, object, fieldOffset, value, true); -// if (genWriteBarrier) { -// addWriteBarrier(asm, object, value); -// } - - unresolved = asm.finishTemplate("putfield<" + kind + ", " + genWriteBarrier + ">-unresolved"); - } else { - unresolved = null; - } + unresolved = null; return new XirPair(resolved, unresolved); } private XirPair buildInstanceof(boolean nonnull) { - XirTemplate resolved; - XirTemplate unresolved; + final XirTemplate resolved; + final XirTemplate unresolved; { XirOperand result = asm.restart(CiKind.Boolean); XirParameter object = asm.createInputParameter("object", CiKind.Object); XirParameter hub = asm.createConstantInputParameter("hub", CiKind.Object); - XirOperand temp = asm.createTemp("temp", CiKind.Object); + XirOperand objHub = asm.createTemp("objHub", CiKind.Object); + XirLabel end = asm.createInlineLabel("end"); XirLabel slow_path = asm.createOutOfLineLabel("slow path"); - asm.mov(result, asm.b(false)); if (!nonnull) { - // first check for null + // null isn't "instanceof" anything + asm.mov(result, asm.b(false)); asm.jeq(end, object, asm.o(null)); } - asm.pload(CiKind.Object, temp, object, asm.i(config.hubOffset), !nonnull); + asm.pload(CiKind.Object, objHub, object, asm.i(config.hubOffset), false); + // if we get an exact match: succeed immediately asm.mov(result, asm.b(true)); - asm.jneq(slow_path, temp, hub); - + asm.jneq(slow_path, objHub, hub); asm.bindInline(end); + // -- out of line ------------------------------------------------------- asm.bindOutOfLine(slow_path); - asm.push(temp); - asm.push(hub); - asm.callRuntime(config.instanceofStub, result); - asm.pop(hub); - asm.pop(result); + checkSubtype(result, objHub, hub); asm.jmp(end); + resolved = asm.finishTemplate("instanceof-leaf<" + nonnull + ">"); } - {/* - * // unresolved instanceof unresolved = buildUnresolvedInstanceOf(nonnull); - */ - asm.restart(CiKind.Boolean); + { + XirOperand result = asm.restart(CiKind.Boolean); + XirParameter object = asm.createInputParameter("object", CiKind.Object); - System.out.println(object); - asm.shouldNotReachHere(); + XirOperand hub = asm.createTemp("hub", CiKind.Object); + XirOperand objHub = asm.createTemp("objHub", CiKind.Object); + + XirLabel end = asm.createInlineLabel("end"); + XirLabel slow_path = asm.createOutOfLineLabel("slow path"); + + // insert the patching code for class resolving - the hub will end up in "hub" + UnresolvedClassPatching patching = new UnresolvedClassPatching(asm, hub, config); + patching.emitInline(); + + if (!nonnull) { + // null isn't "instanceof" anything + asm.mov(result, asm.b(false)); + asm.jeq(end, object, asm.o(null)); + } + asm.pload(CiKind.Object, objHub, object, asm.i(config.hubOffset), false); + // if we get an exact match: succeed immediately + asm.mov(result, asm.b(true)); + asm.jneq(slow_path, objHub, hub); + asm.bindInline(end); + + // -- out of line ------------------------------------------------------- + asm.bindOutOfLine(slow_path); + checkSubtype(result, objHub, hub); + asm.jmp(end); + + patching.emitOutOfLine(); + unresolved = asm.finishTemplate("instanceof-leaf<" + nonnull + ">"); } return new XirPair(resolved, unresolved); } - private XirTemplate buildArrayStore(CiKind kind, CiXirAssembler asm, boolean genBoundsCheck, boolean genStoreCheck, boolean genWriteBarrier) { + private XirPair buildCheckCast() { + final XirTemplate resolved; + final XirTemplate unresolved; + { + asm.restart(); + + XirParameter object = asm.createInputParameter("object", CiKind.Object); + XirParameter hub = asm.createConstantInputParameter("hub", CiKind.Object); + XirOperand objHub = asm.createTemp("objHub", CiKind.Object); + + XirLabel end = asm.createInlineLabel("end"); + XirLabel slow_path = asm.createOutOfLineLabel("slow path"); + + // null can be cast to anything + asm.jeq(end, object, asm.o(null)); + + asm.pload(CiKind.Object, objHub, object, asm.i(config.hubOffset), false); + // if we get an exact match: succeed immediately + asm.jneq(slow_path, objHub, hub); + asm.bindInline(end); + + // -- out of line ------------------------------------------------------- + asm.bindOutOfLine(slow_path); + checkSubtype(objHub, objHub, hub); + asm.jneq(end, objHub, asm.o(null)); + XirOperand scratch = asm.createRegister("scratch", CiKind.Object, AMD64.r10); + asm.mov(scratch, object); + asm.callRuntime(config.throwClassCastException, null); + asm.shouldNotReachHere(); + + resolved = asm.finishTemplate(object, "check cast"); + } + { + asm.restart(); + + XirParameter object = asm.createInputParameter("object", CiKind.Object); + XirOperand hub = asm.createTemp("hub", CiKind.Object); + XirOperand objHub = asm.createTemp("objHub", CiKind.Object); + + XirLabel end = asm.createInlineLabel("end"); + XirLabel slow_path = asm.createOutOfLineLabel("slow path"); + + // insert the patching code for class resolving - the hub will end up in "hub" + UnresolvedClassPatching patching = new UnresolvedClassPatching(asm, hub, config); + patching.emitInline(); + + // null can be cast to anything + asm.jeq(end, object, asm.o(null)); + + asm.pload(CiKind.Object, objHub, object, asm.i(config.hubOffset), false); + // if we get an exact match: succeed immediately + asm.jneq(slow_path, objHub, hub); + asm.bindInline(end); + + // -- out of line ------------------------------------------------------- + asm.bindOutOfLine(slow_path); + checkSubtype(objHub, objHub, hub); + asm.jneq(end, objHub, asm.o(null)); + XirOperand scratch = asm.createRegister("scratch", CiKind.Object, AMD64.r10); + asm.mov(scratch, object); + asm.callRuntime(config.throwClassCastException, null); + asm.shouldNotReachHere(); + + patching.emitOutOfLine(); + + unresolved = asm.finishTemplate(object, "check cast"); + } + return new XirPair(resolved, unresolved); + } + + private XirTemplate buildArrayStore(CiKind kind, CiXirAssembler asm, boolean genBoundsCheck, boolean genStoreCheck, boolean genWriteBarrier, boolean withLength) { asm.restart(CiKind.Void); XirParameter array = asm.createInputParameter("array", CiKind.Object); XirParameter index = asm.createInputParameter("index", CiKind.Int); XirParameter value = asm.createInputParameter("value", kind); - XirOperand length = asm.createTemp("length", CiKind.Int); XirOperand temp = asm.createTemp("temp", CiKind.Word); XirOperand valueHub = null; XirOperand compHub = null; XirLabel store = asm.createInlineLabel("store"); XirLabel failBoundsCheck = null; XirLabel slowStoreCheck = null; + // if the length is known the array cannot be null + boolean implicitNullException = !withLength; + if (genBoundsCheck) { // load the array length and check the index failBoundsCheck = asm.createOutOfLineLabel("failBoundsCheck"); - asm.pload(CiKind.Int, length, array, asm.i(config.arrayLengthOffset), true); + XirOperand length; + if (withLength) { + length = asm.createInputParameter("length", CiKind.Int); + } else { + length = asm.createTemp("length", CiKind.Int); + asm.mark(MARK_IMPLICIT_NULL); + asm.pload(CiKind.Int, length, array, asm.i(config.arrayLengthOffset), true); + implicitNullException = false; + } asm.jugteq(failBoundsCheck, index, length); + } if (genStoreCheck) { slowStoreCheck = asm.createOutOfLineLabel("slowStoreCheck"); asm.jeq(store, value, asm.o(null)); // first check if value is null valueHub = asm.createTemp("valueHub", CiKind.Object); compHub = asm.createTemp("compHub", CiKind.Object); - asm.pload(CiKind.Object, compHub, array, asm.i(config.hubOffset), !genBoundsCheck); + if (implicitNullException) { + asm.mark(MARK_IMPLICIT_NULL); + } + asm.pload(CiKind.Object, compHub, array, asm.i(config.hubOffset), implicitNullException); asm.pload(CiKind.Object, compHub, compHub, asm.i(config.arrayClassElementOffset), false); asm.pload(CiKind.Object, valueHub, value, asm.i(config.hubOffset), false); asm.jneq(slowStoreCheck, compHub, valueHub); // then check component hub matches value hub + + implicitNullException = false; } asm.bindInline(store); int elemSize = target.sizeInBytes(kind); - asm.pstore(kind, array, index, value, config.getArrayOffset(kind), Scale.fromInt(elemSize), !genBoundsCheck && !genStoreCheck); + + if (implicitNullException) { + asm.mark(MARK_IMPLICIT_NULL); + } + asm.pstore(kind, array, index, value, config.getArrayOffset(kind), Scale.fromInt(elemSize), implicitNullException); if (genWriteBarrier) { // addWriteBarrier(asm, array, value); } + + // -- out of line ------------------------------------------------------- if (genBoundsCheck) { asm.bindOutOfLine(failBoundsCheck); + asm.callRuntime(config.throwArrayIndexException, null); asm.shouldNotReachHere(); - // callRuntimeThroughStub(asm, "throwArrayIndexOutOfBoundsException", null, array, index); } if (genStoreCheck) { asm.bindOutOfLine(slowStoreCheck); - asm.push(valueHub); - asm.push(compHub); - asm.callRuntime(config.instanceofStub, null); - asm.pop(temp); - asm.pop(temp); + checkSubtype(temp, valueHub, compHub); asm.jneq(store, temp, asm.w(0)); - asm.shouldNotReachHere(); + asm.callRuntime(config.throwArrayStoreException, null); asm.jmp(store); } return asm.finishTemplate("arraystore<" + kind + ">"); } - private XirTemplate buildArrayLoad(CiKind kind, CiXirAssembler asm, boolean genBoundsCheck) { + private XirTemplate buildArrayLoad(CiKind kind, CiXirAssembler asm, boolean genBoundsCheck, boolean withLength) { XirOperand result = asm.restart(kind); XirParameter array = asm.createInputParameter("array", CiKind.Object); XirParameter index = asm.createInputParameter("index", CiKind.Int); - XirOperand length = asm.createTemp("length", CiKind.Int); - XirLabel fail = null; + XirLabel failBoundsCheck = null; + // if the length is known the array cannot be null + boolean implicitNullException = !withLength; + if (genBoundsCheck) { // load the array length and check the index - fail = asm.createOutOfLineLabel("fail"); - asm.pload(CiKind.Int, length, array, asm.i(config.arrayLengthOffset), true); - asm.jugteq(fail, index, length); + failBoundsCheck = asm.createOutOfLineLabel("failBoundsCheck"); + XirOperand length; + if (withLength) { + length = asm.createInputParameter("length", CiKind.Int); + } else { + length = asm.createTemp("length", CiKind.Int); + asm.mark(MARK_IMPLICIT_NULL); + asm.pload(CiKind.Int, length, array, asm.i(config.arrayLengthOffset), true); + implicitNullException = false; + } + asm.jugteq(failBoundsCheck, index, length); + implicitNullException = false; } int elemSize = target.sizeInBytes(kind); - asm.pload(kind, result, array, index, config.getArrayOffset(kind), Scale.fromInt(elemSize), !genBoundsCheck); + if (implicitNullException) { + asm.mark(MARK_IMPLICIT_NULL); + } + asm.pload(kind, result, array, index, config.getArrayOffset(kind), Scale.fromInt(elemSize), implicitNullException); if (genBoundsCheck) { - asm.bindOutOfLine(fail); + asm.bindOutOfLine(failBoundsCheck); + asm.callRuntime(config.throwArrayIndexException, null); asm.shouldNotReachHere(); - // callRuntimeThroughStub(asm, "throwArrayIndexOutOfBoundsException", null, array, index); } return asm.finishTemplate("arrayload<" + kind + ">"); } @@ -383,6 +592,7 @@ XirLabel stub = asm.createOutOfLineLabel("call stub"); asm.mark(MARK_INVOKESTATIC); + // -- out of line ------------------------------------------------------- asm.bindOutOfLine(stub); XirOperand method = asm.createRegister("method", CiKind.Word, AMD64.rbx); asm.mark(MARK_STATIC_CALL_STUB, XirMark.CALLSITE); @@ -396,11 +606,16 @@ private XirTemplate buildInvokeSpecial() { asm.restart(); + XirParameter receiver = asm.createInputParameter("receiver", CiKind.Object); XirParameter addr = asm.createConstantInputParameter("addr", CiKind.Word); + XirOperand temp = asm.createRegister("temp", CiKind.Word, AMD64.rax); + XirLabel stub = asm.createOutOfLineLabel("call stub"); - XirLabel stub = asm.createOutOfLineLabel("call stub"); + asm.mark(MARK_IMPLICIT_NULL); + asm.pload(CiKind.Word, temp, receiver, true); asm.mark(MARK_INVOKESPECIAL); + // -- out of line ------------------------------------------------------- asm.bindOutOfLine(stub); XirOperand method = asm.createRegister("method", CiKind.Word, AMD64.rbx); asm.mark(MARK_STATIC_CALL_STUB, XirMark.CALLSITE); @@ -414,13 +629,18 @@ private XirTemplate buildInvokeInterface() { asm.restart(); + XirParameter receiver = asm.createInputParameter("receiver", CiKind.Object); XirParameter addr = asm.createConstantInputParameter("addr", CiKind.Word); XirOperand method = asm.createRegister("method", CiKind.Object, AMD64.rbx); + XirOperand temp = asm.createRegister("temp", CiKind.Word, AMD64.rax); + XirLabel stub = asm.createOutOfLineLabel("call stub"); - XirLabel stub = asm.createOutOfLineLabel("call stub"); + asm.mark(MARK_IMPLICIT_NULL); + asm.pload(CiKind.Word, temp, receiver, true); asm.mark(MARK_INVOKEINTERFACE); asm.mov(method, asm.createConstant(CiConstant.forObject(HotSpotProxy.DUMMY_CONSTANT_OBJ))); + // -- out of line ------------------------------------------------------- asm.bindOutOfLine(stub); asm.mark(MARK_STATIC_CALL_STUB, XirMark.CALLSITE); asm.mov(method, asm.w(0l)); @@ -433,13 +653,18 @@ private XirTemplate buildInvokeVirtual() { asm.restart(); + XirParameter receiver = asm.createInputParameter("receiver", CiKind.Object); XirParameter addr = asm.createConstantInputParameter("addr", CiKind.Word); XirOperand method = asm.createRegister("method", CiKind.Object, AMD64.rbx); + XirOperand temp = asm.createRegister("temp", CiKind.Word, AMD64.rax); + XirLabel stub = asm.createOutOfLineLabel("call stub"); - XirLabel stub = asm.createOutOfLineLabel("call stub"); + asm.mark(MARK_IMPLICIT_NULL); + asm.pload(CiKind.Word, temp, receiver, true); asm.mark(MARK_INVOKEVIRTUAL); asm.mov(method, asm.createConstant(CiConstant.forObject(HotSpotProxy.DUMMY_CONSTANT_OBJ))); + // -- out of line ------------------------------------------------------- asm.bindOutOfLine(stub); asm.mark(MARK_STATIC_CALL_STUB, XirMark.CALLSITE); asm.mov(method, asm.w(0l)); @@ -447,25 +672,22 @@ asm.jmp(dummy); asm.bindOutOfLine(dummy); - asm.mark(MARK_IMPLICIT_NULL_EXCEPTION_TARGET, XirMark.CALLSITE); - asm.callRuntime(config.throwImplicitNullStub, null); - return asm.finishTemplate(addr, "invokespecial"); } - private XirTemplate buildNewInstance() { + private XirTemplate buildNewInstance(CiXirAssembler asm, int size) { XirOperand result = asm.restart(CiKind.Word); XirOperand type = asm.createInputParameter("type", CiKind.Object); - XirOperand instanceSize = asm.createConstantInputParameter("instance size", CiKind.Word); XirOperand thread = asm.createRegister("thread", CiKind.Word, AMD64.r15); - XirOperand temp1 = asm.createTemp("temp1", CiKind.Word); - XirOperand temp2 = asm.createTemp("temp2", CiKind.Word); + XirOperand temp1 = asm.createRegister("temp1", CiKind.Word, AMD64.rcx); + XirOperand temp2 = asm.createRegister("temp2", CiKind.Word, AMD64.rbx); + useRegisters(asm, AMD64.rsi); XirLabel tlabFull = asm.createOutOfLineLabel("tlab full"); XirLabel resume = asm.createInlineLabel("resume"); asm.pload(CiKind.Word, result, thread, asm.i(config.threadTlabTopOffset), false); - asm.add(temp1, result, instanceSize); + asm.add(temp1, result, asm.w(size)); asm.pload(CiKind.Word, temp2, thread, asm.i(config.threadTlabEndOffset), false); asm.jgt(tlabFull, temp1, temp2); @@ -476,6 +698,14 @@ asm.pstore(CiKind.Word, result, temp1, false); asm.pstore(CiKind.Object, result, asm.i(config.hubOffset), type, false); + if (size > 2 * target.wordSize) { + asm.mov(temp1, asm.w(0)); + for (int offset = 2 * target.wordSize; offset < size; offset += target.wordSize) { + asm.pstore(CiKind.Word, result, asm.i(offset), temp1, false); + } + } + + // -- out of line ------------------------------------------------------- asm.bindOutOfLine(tlabFull); XirOperand arg = asm.createRegister("runtime call argument", CiKind.Object, AMD64.rdx); asm.mov(arg, type); @@ -485,6 +715,110 @@ return asm.finishTemplate("new instance"); } + private XirTemplate buildNewInstanceUnresolved() { + XirOperand result = asm.restart(CiKind.Word); + XirOperand arg = asm.createRegister("runtime call argument", CiKind.Object, AMD64.rdx); + + UnresolvedClassPatching patching = new UnresolvedClassPatching(asm, arg, config); + + patching.emitInline(); + useRegisters(AMD64.rbx, AMD64.rcx, AMD64.rsi); + asm.callRuntime(config.newInstanceStub, result); + + // -- out of line ------------------------------------------------------- + patching.emitOutOfLine(); + + return asm.finishTemplate("new instance"); + } + + private XirTemplate buildNewObjectArray(boolean resolved) { + XirOperand result = asm.restart(CiKind.Object); + + XirParameter lengthParam = asm.createInputParameter("length", CiKind.Int); + + XirOperand length = asm.createRegister("length", CiKind.Int, AMD64.rbx); + XirOperand hub = asm.createRegister("hub", CiKind.Object, AMD64.rdx); + + UnresolvedClassPatching patching = null; + if (resolved) { + asm.mov(hub, asm.createConstantInputParameter("hub", CiKind.Object)); + } else { + // insert the patching code for class resolving - the hub will end up in "hub" + patching = new UnresolvedClassPatching(asm, hub, config); + patching.emitInline(); + } + + asm.mov(length, lengthParam); + useRegisters(AMD64.rsi, AMD64.rcx, AMD64.rdi); + asm.callRuntime(config.newObjectArrayStub, result); + if (!resolved) { + patching.emitOutOfLine(); + } + return asm.finishTemplate(resolved ? "newObjectArray" : "newObjectArray (unresolved)"); + } + + private XirTemplate buildMultiNewArray(int dimensions, boolean resolved) { + XirOperand result = asm.restart(CiKind.Object); + + XirOperand hub = asm.createRegister("hub", CiKind.Object, AMD64.rax); + XirOperand rank = asm.createRegister("rank", CiKind.Int, AMD64.rbx); + XirOperand sizes = asm.createRegister("sizes", CiKind.Long, AMD64.rcx); + XirOperand thread = asm.createRegister("thread", CiKind.Long, AMD64.r15); + asm.add(sizes, thread, asm.l(config.threadMultiNewArrayStorage)); + for (int i = 0; i < dimensions; i++) { + XirParameter length = asm.createInputParameter("length" + i, CiKind.Int); + asm.pstore(CiKind.Int, sizes, asm.i(i * target.sizeInBytes(CiKind.Int)), length, false); + } + + UnresolvedClassPatching patching = null; + if (resolved) { + asm.mov(hub, asm.createConstantInputParameter("hub", CiKind.Object)); + } else { + // insert the patching code for class resolving - the hub will end up in "hub" + patching = new UnresolvedClassPatching(asm, hub, config); + patching.emitInline(); + } + + asm.mov(rank, asm.i(dimensions)); + asm.callRuntime(config.newMultiArrayStub, result); + if (!resolved) { + patching.emitOutOfLine(); + } + return asm.finishTemplate(resolved ? "multiNewArray" + dimensions : "multiNewArray" + dimensions + " (unresolved)"); + } + + private XirTemplate buildNewTypeArray() { + XirOperand result = asm.restart(CiKind.Object); + + XirParameter lengthParam = asm.createInputParameter("length", CiKind.Int); + XirParameter hubParam = asm.createConstantInputParameter("hub", CiKind.Object); + + XirOperand length = asm.createRegister("length", CiKind.Int, AMD64.rbx); + XirOperand hub = asm.createRegister("hub", CiKind.Object, AMD64.rdx); + + asm.mov(hub, hubParam); + asm.mov(length, lengthParam); + useRegisters(AMD64.rsi, AMD64.rcx, AMD64.rdi); + asm.callRuntime(config.newTypeArrayStub, result); + + return asm.finishTemplate("newObjectArray"); + } + + private XirTemplate buildResolveClass(boolean resolved) { + XirOperand result = asm.restart(CiKind.Word); + if (resolved) { + XirOperand type = asm.createConstantInputParameter("type", CiKind.Object); + + asm.mov(result, type); + } else { + UnresolvedClassPatching patching = new UnresolvedClassPatching(asm, result, config); + patching.emitInline(); + // -- out of line ------------------------------------------------------- + patching.emitOutOfLine(); + } + return asm.finishTemplate(resolved ? "resolve class" : "resolve class (unresolved)"); + } + @Override public XirSnippet genArrayLength(XirSite site, XirArgument array) { return new XirSnippet(arrayLengthTemplate, array); @@ -492,19 +826,26 @@ @Override public XirSnippet genArrayLoad(XirSite site, XirArgument array, XirArgument index, XirArgument length, CiKind elementKind, RiType elementType) { - // TODO: emit different template if length is present - return new XirSnippet(arrayLoadTemplates[elementKind.ordinal()], array, index); + if (length == null) { + return new XirSnippet(arrayLoadTemplates[elementKind.ordinal()], array, index); + } + return new XirSnippet(arrayLoadTemplatesWithLength[elementKind.ordinal()], array, index, length); } @Override public XirSnippet genArrayStore(XirSite site, XirArgument array, XirArgument index, XirArgument length, XirArgument value, CiKind elementKind, RiType elementType) { - // TODO: emit different template if length is present - return new XirSnippet(arrayStoreTemplates[elementKind.ordinal()], array, index, value); + if (length == null) { + return new XirSnippet(arrayStoreTemplates[elementKind.ordinal()], array, index, value); + } + return new XirSnippet(arrayStoreTemplatesWithLength[elementKind.ordinal()], array, index, value, length); } @Override public XirSnippet genCheckCast(XirSite site, XirArgument receiver, XirArgument hub, RiType type) { - return new XirSnippet(emptyTemplates[CiKind.Object.ordinal()]); + if (type.isResolved()) { + return new XirSnippet(checkCastTemplate.resolved, receiver, hub); + } + return new XirSnippet(checkCastTemplate.unresolved, receiver); } @Override @@ -520,18 +861,18 @@ @Override public XirSnippet genGetField(XirSite site, XirArgument receiver, RiField field) { - XirPair pair = getStaticFieldTemplates[field.kind().ordinal()]; - assert field.isResolved() : "getfield doesn't expect unresolved fields"; - XirArgument offset = XirArgument.forInt(((HotSpotField) field).offset()); - return new XirSnippet(pair.resolved, receiver, offset); + XirPair pair = getFieldTemplates[field.kind().ordinal()]; + if (field.isResolved()) { + return new XirSnippet(pair.resolved, receiver, XirArgument.forInt(((HotSpotField) field).offset())); + } + return new XirSnippet(pair.unresolved, receiver); } @Override public XirSnippet genGetStatic(XirSite site, XirArgument staticTuple, RiField field) { - XirPair pair = getStaticFieldTemplates[field.kind().ordinal()]; + XirPair pair = getStaticTemplates[field.kind().ordinal()]; if (field.isResolved()) { - XirArgument offset = XirArgument.forInt(((HotSpotField) field).offset()); - return new XirSnippet(pair.resolved, staticTuple, offset); + return new XirSnippet(pair.resolved, staticTuple, XirArgument.forInt(((HotSpotField) field).offset())); } return new XirSnippet(pair.unresolved, staticTuple, null); } @@ -539,17 +880,17 @@ @Override public XirSnippet genPutField(XirSite site, XirArgument receiver, RiField field, XirArgument value) { XirPair pair = putFieldTemplates[field.kind().ordinal()]; - assert field.isResolved() : "putfield doesn't expect unresolved fields"; - XirArgument offset = XirArgument.forInt(((HotSpotField) field).offset()); - return new XirSnippet(pair.resolved, receiver, value, offset); + if (field.isResolved()) { + return new XirSnippet(pair.resolved, receiver, value, XirArgument.forInt(((HotSpotField) field).offset())); + } + return new XirSnippet(pair.unresolved, receiver, value); } @Override public XirSnippet genPutStatic(XirSite site, XirArgument staticTuple, RiField field, XirArgument value) { - XirPair pair = putFieldTemplates[field.kind().ordinal()]; + XirPair pair = putStaticTemplates[field.kind().ordinal()]; if (field.isResolved()) { - XirArgument offset = XirArgument.forInt(((HotSpotField) field).offset()); - return new XirSnippet(pair.resolved, staticTuple, value, offset); + return new XirSnippet(pair.resolved, staticTuple, value, XirArgument.forInt(((HotSpotField) field).offset())); } return new XirSnippet(pair.unresolved, staticTuple, value); } @@ -559,7 +900,6 @@ if (type.isResolved()) { return new XirSnippet(instanceofTemplate.resolved, receiver, hub); } - // XirArgument guard = guardFor(type, ResolveClass.SNIPPET); return new XirSnippet(instanceofTemplate.unresolved, receiver); } @@ -570,12 +910,12 @@ @Override public XirSnippet genInvokeInterface(XirSite site, XirArgument receiver, RiMethod method) { - return new XirSnippet(invokeInterfaceTemplate, XirArgument.forWord(0)); + return new XirSnippet(invokeInterfaceTemplate, receiver, XirArgument.forWord(0)); } @Override public XirSnippet genInvokeSpecial(XirSite site, XirArgument receiver, RiMethod method) { - return new XirSnippet(invokeSpecialTemplate, XirArgument.forWord(0)); + return new XirSnippet(invokeSpecialTemplate, receiver, XirArgument.forWord(0)); } @Override @@ -585,7 +925,7 @@ @Override public XirSnippet genInvokeVirtual(XirSite site, XirArgument receiver, RiMethod method) { - return new XirSnippet(invokeVirtualTemplate, XirArgument.forWord(0)); + return new XirSnippet(invokeVirtualTemplate, receiver, XirArgument.forWord(0)); } @Override @@ -600,36 +940,48 @@ @Override public XirSnippet genNewArray(XirSite site, XirArgument length, CiKind elementKind, RiType componentType, RiType arrayType) { - return new XirSnippet(emptyTemplates[CiKind.Object.ordinal()]); + if (elementKind == CiKind.Object) { + if (arrayType instanceof HotSpotTypeResolved) { + return new XirSnippet(newObjectArrayTemplate.resolved, length, XirArgument.forObject(arrayType)); + } + return new XirSnippet(newObjectArrayTemplate.unresolved, length); + } + assert arrayType == null; + arrayType = Compiler.getVMEntries().getPrimitiveArrayType(elementKind); + return new XirSnippet(newTypeArrayTemplate, length, XirArgument.forObject(arrayType)); } @Override public XirSnippet genNewInstance(XirSite site, RiType type) { - assert type instanceof HotSpotTypeResolved; - HotSpotTypeResolved resolved = (HotSpotTypeResolved) type; - return new XirSnippet(newInstanceTemplate, XirArgument.forObject(type), XirArgument.forWord(resolved.instanceSize())); + if (type instanceof HotSpotTypeResolved) { + int instanceSize = ((HotSpotTypeResolved) type).instanceSize(); + return new XirSnippet(newInstanceTemplates.get(instanceSize), XirArgument.forObject(type)); + } + return new XirSnippet(newInstanceUnresolvedTemplate); } @Override public XirSnippet genNewMultiArray(XirSite site, XirArgument[] lengths, RiType type) { - return new XirSnippet(emptyTemplates[CiKind.Object.ordinal()]); + if (type instanceof HotSpotTypeResolved) { + XirArgument[] params = Arrays.copyOf(lengths, lengths.length + 1); + params[lengths.length] = XirArgument.forObject(type); + return new XirSnippet(multiNewArrayTemplate.get(lengths.length).resolved, params); + } + return new XirSnippet(multiNewArrayTemplate.get(lengths.length).unresolved, lengths); } @Override public XirSnippet genResolveClass(XirSite site, RiType type, Representation representation) { - XirOperand result = asm.restart(CiKind.Object); - if (type.isResolved()) { - asm.mov(result, asm.o(type)); - return new XirSnippet(asm.finishTemplate("resolve class")); + assert representation == Representation.ObjectHub; + if (type instanceof HotSpotTypeResolved) { + return new XirSnippet(resolveClassTemplate.resolved, XirArgument.forObject(type)); } - asm.shouldNotReachHere(); - return new XirSnippet(asm.finishTemplate("resolve class")); - + return new XirSnippet(resolveClassTemplate.unresolved); } @Override public XirSnippet genSafepoint(XirSite site) { - return new XirSnippet(emptyTemplates[CiKind.Void.ordinal()]); + return new XirSnippet(safepointTemplate); } @Override @@ -637,4 +989,95 @@ return new XirSnippet(exceptionObjectTemplate); } + private static class UnresolvedClassPatching { + + private final XirLabel patchSite; + private final XirLabel replacement; + private final XirLabel patchStub; + private final CiXirAssembler asm; + private final HotSpotVMConfig config; + private final XirOperand arg; + private State state; + + private enum State { + New, Inline, Finished + } + + public UnresolvedClassPatching(CiXirAssembler asm, XirOperand arg, HotSpotVMConfig config) { + this.asm = asm; + this.arg = arg; + this.config = config; + patchSite = asm.createInlineLabel("patch site"); + replacement = asm.createOutOfLineLabel("replacement"); + patchStub = asm.createOutOfLineLabel("patch stub"); + + state = State.New; + } + + public void emitInline() { + assert state == State.New; + + asm.bindInline(patchSite); + asm.mark(MARK_DUMMY_OOP_RELOCATION); + asm.jmp(patchStub); + + // TODO: make this more generic & safe - this is needed to create space for patching + asm.nop(5); + + state = State.Inline; + } + + public void emitOutOfLine() { + assert state == State.Inline; + + asm.bindOutOfLine(replacement); + XirMark begin = asm.mark(null); + asm.mov(arg, asm.createConstant(CiConstant.forObject(null))); + XirMark end = asm.mark(null); + // make this piece of data look like an instruction + asm.rawBytes(new byte[] { (byte) 0xb8, 0, 0, 0x05, 0}); + asm.mark(MARK_KLASS_PATCHING, begin, end); + asm.bindOutOfLine(patchStub); + asm.callRuntime(config.loadKlassStub, null); + asm.jmp(patchSite); + + state = State.Finished; + } + } + + private void checkSubtype(XirOperand result, XirOperand objHub, XirOperand hub) { + asm.push(objHub); + asm.push(hub); + asm.callRuntime(config.instanceofStub, null); + asm.pop(result); + asm.pop(result); + } + + private void useRegisters(CiXirAssembler asm, CiRegister... registers) { + if (registers != null) { + for (CiRegister register : registers) { + asm.createRegister("reg", CiKind.Illegal, register); + } + } + } + + private void useRegisters(CiRegister... registers) { + useRegisters(asm, registers); + } + + private abstract class OndemandTemplates { + + private ConcurrentHashMap templates = new ConcurrentHashMap(); + + protected abstract T create(CiXirAssembler asm, int index); + + public T get(int index) { + T template = templates.get(index); + if (template == null) { + template = create(asm.copy(), index); + templates.put(index, template); + } + return template; + } + } } diff -r 695451afc619 -r abc670a709dc c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMEntries.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMEntries.java Thu Aug 19 14:34:52 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMEntries.java Tue Aug 31 22:13:30 2010 -0700 @@ -42,7 +42,7 @@ public RiType RiSignature_lookupType(String returnType, long accessingClassVmId); - public CiConstant RiConstantPool_lookupConstant(long vmId, int cpi); + public Object RiConstantPool_lookupConstant(long vmId, int cpi); public RiMethod RiConstantPool_lookupMethod(long vmId, int cpi, byte byteCode); @@ -52,14 +52,6 @@ public RiField RiConstantPool_lookupField(long vmId, int cpi); - public boolean RiType_isArrayClass(long vmId); - - public boolean RiType_isInstanceClass(long vmId); - - public boolean RiType_isInterface(long vmId); - - public long RiType_instanceSize(long vmId); - public RiConstantPool RiType_constantPool(long vmId); public void installMethod(HotSpotTargetMethod targetMethod); @@ -68,4 +60,12 @@ public HotSpotVMConfig getConfiguration(); + public RiExceptionHandler[] RiMethod_exceptionHandlers(long vmId); + + public RiMethod RiType_resolveMethodImpl(long vmId, String name, String signature); + + public boolean RiType_isSubtypeOf(long vmId, RiType other); + + public RiType getPrimitiveArrayType(CiKind kind); + } \ No newline at end of file diff -r 695451afc619 -r abc670a709dc c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMEntriesNative.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMEntriesNative.java Thu Aug 19 14:34:52 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMEntriesNative.java Tue Aug 31 22:13:30 2010 -0700 @@ -50,7 +50,7 @@ public native RiType RiSignature_lookupType(String returnType, long accessingClassVmId); @Override - public native CiConstant RiConstantPool_lookupConstant(long vmId, int cpi); + public native Object RiConstantPool_lookupConstant(long vmId, int cpi); @Override public native RiMethod RiConstantPool_lookupMethod(long vmId, int cpi, byte byteCode); @@ -65,18 +65,6 @@ public native RiField RiConstantPool_lookupField(long vmId, int cpi); @Override - public native boolean RiType_isArrayClass(long vmId); - - @Override - public native boolean RiType_isInstanceClass(long vmId); - - @Override - public native boolean RiType_isInterface(long vmId); - - @Override - public native long RiType_instanceSize(long vmId); - - @Override public native RiConstantPool RiType_constantPool(long vmId); @Override @@ -88,4 +76,16 @@ @Override public native HotSpotVMConfig getConfiguration(); + @Override + public native RiExceptionHandler[] RiMethod_exceptionHandlers(long vmId); + + @Override + public native RiMethod RiType_resolveMethodImpl(long vmId, String name, String signature); + + @Override + public native boolean RiType_isSubtypeOf(long vmId, RiType other); + + @Override + public native RiType getPrimitiveArrayType(CiKind kind); + } diff -r 695451afc619 -r abc670a709dc c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExits.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExits.java Thu Aug 19 14:34:52 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExits.java Tue Aug 31 22:13:30 2010 -0700 @@ -30,7 +30,9 @@ public abstract void compileMethod(long methodVmId, String name, int entry_bci); - public abstract RiMethod createRiMethod(long vmId, String name); + public abstract RiMethod createRiMethodResolved(long vmId, String name); + + public abstract RiMethod createRiMethodUnresolved(String name, String signature, RiType holder); public abstract RiSignature createRiSignature(String signature); diff -r 695451afc619 -r abc670a709dc c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExitsNative.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExitsNative.java Thu Aug 19 14:34:52 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExitsNative.java Tue Aug 31 22:13:30 2010 -0700 @@ -34,9 +34,9 @@ @Override public void compileMethod(long methodVmId, String name, int entry_bci) { try { - Logger.info("compiling " + name + " (" + methodVmId + ")"); + Logger.info("compiling " + name + " (0x" + Long.toHexString(methodVmId) + ")"); Compiler compiler = Compiler.getInstance(); - HotSpotMethod riMethod = new HotSpotMethod(methodVmId, name); + HotSpotMethodResolved riMethod = new HotSpotMethodResolved(methodVmId, name); CiResult result = compiler.getCompiler().compileMethod(riMethod, null); if (result.bailout() != null) { @@ -55,9 +55,13 @@ } @Override - public RiMethod createRiMethod(long vmId, String name) { - RiMethod m = new HotSpotMethod(vmId, name); - return m; + public RiMethod createRiMethodResolved(long vmId, String name) { + return new HotSpotMethodResolved(vmId, name); + } + + @Override + public RiMethod createRiMethodUnresolved(String name, String signature, RiType holder) { + return new HotSpotMethodUnresolved(name, signature, holder); } @Override @@ -72,7 +76,7 @@ @Override public RiType createRiType(long vmId, String name) { - return new HotSpotTypeResolved(vmId, name); + throw new RuntimeException("not implemented"); } @Override diff -r 695451afc619 -r abc670a709dc c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/logging/Logger.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/logging/Logger.java Thu Aug 19 14:34:52 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/logging/Logger.java Tue Aug 31 22:13:30 2010 -0700 @@ -20,6 +20,7 @@ import java.io.*; import java.lang.reflect.*; import java.util.*; + /** * Scoped logging class used to display the call hierarchy of VMEntries/VMExits calls * @@ -27,7 +28,7 @@ */ public class Logger { - private static final boolean ENABLED = true; + public static final boolean ENABLED = Boolean.valueOf(System.getProperty("c1x.debug")); private static final int SPACING = 4; private static Deque openStack = new LinkedList(); private static boolean open = false; @@ -36,21 +37,30 @@ private final static PrintStream out; static { - PrintStream ps; - try { - ps = new PrintStream(new FileOutputStream("output.txt")); - } catch (FileNotFoundException e) { - e.printStackTrace(); - ps = null; + PrintStream ps = null; + String filename = System.getProperty("c1x.info_file"); + if (filename != null && !"".equals(filename)) { + try { + ps = new PrintStream(new FileOutputStream(filename)); + } catch (FileNotFoundException e) { + e.printStackTrace(); + ps = null; + } } out = ps; - out.println("start: " + new Date()); + if (out != null) + out.println("start: " + new Date()); } public static void info(String message) { - log(message); - out.println(message); - out.flush(); + if (ENABLED) + log(message); + else + System.out.println(message); + if (out != null) { + out.println(message); + out.flush(); + } } public static void log(String message) { diff -r 695451afc619 -r abc670a709dc src/cpu/x86/vm/c1_Runtime1_x86.cpp --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp Thu Aug 19 14:34:52 2010 -0700 +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp Tue Aug 31 22:13:30 2010 -0700 @@ -599,30 +599,50 @@ // has_argument: true if the exception needs an argument (passed on stack because registers must be preserved) OopMapSet* Runtime1::generate_exception_throw(StubAssembler* sasm, address target, bool has_argument) { - // preserve all registers - int num_rt_args = has_argument ? 2 : 1; - OopMap* oop_map = save_live_registers(sasm, num_rt_args); + OopMapSet* oop_maps = new OopMapSet(); + if (UseC1X) { + // c1x passes the argument in r10 + OopMap* oop_map = save_live_registers(sasm, 1); + + // now all registers are saved and can be used freely + // verify that no old value is used accidentally + __ invalidate_registers(true, true, true, true, true, true); - // now all registers are saved and can be used freely - // verify that no old value is used accidentally - __ invalidate_registers(true, true, true, true, true, true); + // registers used by this stub + const Register temp_reg = rbx; - // registers used by this stub - const Register temp_reg = rbx; + // load argument for exception that is passed as an argument into the stub + if (has_argument) { + __ movptr(c_rarg1, r10); + } + int call_offset = __ call_RT(noreg, noreg, target, has_argument ? 1 : 0); - // load argument for exception that is passed as an argument into the stub - if (has_argument) { -#ifdef _LP64 - __ movptr(c_rarg1, Address(rbp, 2*BytesPerWord)); -#else - __ movptr(temp_reg, Address(rbp, 2*BytesPerWord)); - __ push(temp_reg); -#endif // _LP64 + oop_maps->add_gc_map(call_offset, oop_map); + } else { + // preserve all registers + int num_rt_args = has_argument ? 2 : 1; + OopMap* oop_map = save_live_registers(sasm, num_rt_args); + + // now all registers are saved and can be used freely + // verify that no old value is used accidentally + __ invalidate_registers(true, true, true, true, true, true); + + // registers used by this stub + const Register temp_reg = rbx; + + // load argument for exception that is passed as an argument into the stub + if (has_argument) { + #ifdef _LP64 + __ movptr(c_rarg1, Address(rbp, 2*BytesPerWord)); + #else + __ movptr(temp_reg, Address(rbp, 2*BytesPerWord)); + __ push(temp_reg); + #endif // _LP64 + } + int call_offset = __ call_RT(noreg, noreg, target, num_rt_args - 1); + + oop_maps->add_gc_map(call_offset, oop_map); } - int call_offset = __ call_RT(noreg, noreg, target, num_rt_args - 1); - - OopMapSet* oop_maps = new OopMapSet(); - oop_maps->add_gc_map(call_offset, oop_map); __ stop("should not reach here"); @@ -717,6 +737,74 @@ } +void Runtime1::c1x_generate_handle_exception(StubAssembler *sasm, OopMapSet* oop_maps, OopMap* oop_map) { + NOT_LP64(fatal("64 bit only")); + // incoming parameters + const Register exception_oop = j_rarg0; + // other registers used in this stub + const Register exception_pc = j_rarg1; + const Register thread = r15_thread; + + __ block_comment("c1x_generate_handle_exception"); + + // verify that rax, contains a valid exception + __ verify_not_null_oop(exception_oop); + +#ifdef ASSERT + // check that fields in JavaThread for exception oop and issuing pc are + // empty before writing to them + Label oop_empty; + __ cmpptr(Address(thread, JavaThread::exception_oop_offset()), (int32_t) NULL_WORD); + __ jcc(Assembler::equal, oop_empty); + __ stop("exception oop already set"); + __ bind(oop_empty); + + Label pc_empty; + __ cmpptr(Address(thread, JavaThread::exception_pc_offset()), 0); + __ jcc(Assembler::equal, pc_empty); + __ stop("exception pc already set"); + __ bind(pc_empty); +#endif + + // save exception oop and issuing pc into JavaThread + // (exception handler will load it from here) + __ movptr(Address(thread, JavaThread::exception_oop_offset()), exception_oop); + __ movptr(exception_pc, Address(rbp, 1*BytesPerWord)); + __ movptr(Address(thread, JavaThread::exception_pc_offset()), exception_pc); + + // compute the exception handler. + // the exception oop and the throwing pc are read from the fields in JavaThread + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc)); + oop_maps->add_gc_map(call_offset, oop_map); + + // rax,: handler address + // will be the deopt blob if nmethod was deoptimized while we looked up + // handler regardless of whether handler existed in the nmethod. + + // only rax, is valid at this time, all other registers have been destroyed by the runtime call + __ invalidate_registers(false, true, true, true, true, true); + +#ifdef ASSERT + // Do we have an exception handler in the nmethod? + Label done; + __ testptr(rax, rax); + __ jcc(Assembler::notZero, done); + __ stop("no handler found"); + __ bind(done); +#endif + + // exception handler found + // patch the return address -> the stub will directly return to the exception handler + __ movptr(Address(rbp, 1*BytesPerWord), rax); + + // restore registers + restore_live_registers(sasm, false); + + // return to exception handler + __ leave(); + __ ret(0); +} + void Runtime1::generate_unwind_exception(StubAssembler *sasm) { // incoming parameters @@ -925,6 +1013,12 @@ } +JRT_ENTRY(void, c1x_create_null_exception(JavaThread* thread)) + thread->set_vm_result(Exceptions::new_exception(thread, vmSymbols::java_lang_NullPointerException(), NULL)()); +JRT_END + + + OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { @@ -1307,7 +1401,8 @@ break; case unwind_exception_id: - { __ set_info("unwind_exception", dont_gc_arguments); + { + __ 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); @@ -1735,6 +1830,94 @@ break; #endif // !SERIALGC + 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); + { + __ 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; + + 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_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_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; default: { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments); __ movptr(rax, (int)id); diff -r 695451afc619 -r abc670a709dc src/share/vm/c1/c1_Runtime1.cpp --- a/src/share/vm/c1/c1_Runtime1.cpp Thu Aug 19 14:34:52 2010 -0700 +++ b/src/share/vm/c1/c1_Runtime1.cpp Tue Aug 31 22:13:30 2010 -0700 @@ -173,6 +173,8 @@ case slow_subtype_check_id: case fpu2long_stub_id: case unwind_exception_id: + case c1x_unwind_exception_call_id: + case c1x_slow_subtype_check_id: #ifndef TIERED case counter_overflow_id: // Not generated outside the tiered world #endif @@ -411,6 +413,9 @@ JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* thread, oopDesc* ex, address pc, nmethod*& nm)) Handle exception(thread, ex); + if (UseC1X && exception.is_null()) { + exception = Exceptions::new_exception(thread, vmSymbols::java_lang_NullPointerException(), NULL); + } nm = CodeCache::find_nmethod(pc); assert(nm != NULL, "this is not an nmethod"); // Adjust the pc as needed/ diff -r 695451afc619 -r abc670a709dc src/share/vm/c1/c1_Runtime1.hpp --- a/src/share/vm/c1/c1_Runtime1.hpp Thu Aug 19 14:34:52 2010 -0700 +++ b/src/share/vm/c1/c1_Runtime1.hpp Tue Aug 31 22:13:30 2010 -0700 @@ -60,6 +60,11 @@ stub(g1_post_barrier_slow) \ stub(fpu2long_stub) \ stub(counter_overflow) \ + stub(c1x_unwind_exception_call) \ + stub(c1x_handle_exception) \ + stub(c1x_global_implicit_null) \ + stub(c1x_throw_div0_exception) \ + stub(c1x_slow_subtype_check) \ last_entry(number_of_ids) #define DECLARE_STUB_ID(x) x ## _id , @@ -124,6 +129,7 @@ static OopMapSet* generate_code_for(StubID id, StubAssembler* masm); static OopMapSet* generate_exception_throw(StubAssembler* sasm, address target, bool has_argument); static void generate_handle_exception(StubAssembler *sasm, OopMapSet* oop_maps, OopMap* oop_map, bool ignore_fpu_registers = false); + static void c1x_generate_handle_exception(StubAssembler *sasm, OopMapSet* oop_maps, OopMap* oop_map); static void generate_unwind_exception(StubAssembler *sasm); static OopMapSet* generate_patching(StubAssembler* sasm, address target); diff -r 695451afc619 -r abc670a709dc src/share/vm/c1x/c1x_CodeInstaller.cpp --- a/src/share/vm/c1x/c1x_CodeInstaller.cpp Thu Aug 19 14:34:52 2010 -0700 +++ b/src/share/vm/c1x/c1x_CodeInstaller.cpp Tue Aug 31 22:13:30 2010 -0700 @@ -26,7 +26,6 @@ # include "incls/_precompiled.incl" # include "incls/_c1x_CodeInstaller.cpp.incl" - #define C1X_REGISTER_COUNT 32 VMReg get_hotspot_reg(jint c1x_reg) { @@ -76,11 +75,11 @@ static ScopeValue* get_hotspot_value(oop value) { fatal("not implemented"); if (value->is_a(CiRegisterValue::klass())) { - tty->print("register value"); - value->print(); + TRACE_C1X_4("register value"); + IF_TRACE_C1X_4 value->print(); } else if (value->is_a(CiStackSlot::klass())) { - tty->print("stack value"); - value->print(); + TRACE_C1X_4("stack value"); + IF_TRACE_C1X_4 value->print(); } else { ShouldNotReachHere(); } @@ -94,24 +93,35 @@ initialize_fields(target_method); assert(_hotspot_method != NULL && _name == NULL, "installMethod needs NON-NULL method and NULL name"); - + assert(_hotspot_method->is_a(HotSpotMethodResolved::klass()), "installMethod needs a HotSpotMethodResolved"); // TODO: This is a hack.. Produce correct entries. _offsets.set_value(CodeOffsets::Exceptions, 0); _offsets.set_value(CodeOffsets::Deopt, 0); - methodOop method = VmIds::get(HotSpotMethod::vmId(_hotspot_method)); + methodOop method = VmIds::get(HotSpotMethodResolved::vmId(_hotspot_method)); ciMethod *ciMethodObject = (ciMethod *)_env->get_object(method); _parameter_count = method->size_of_parameters(); // (very) conservative estimate: each site needs a relocation CodeBuffer buffer("temp c1x method", _total_size, _sites->length() * relocInfo::length_limit); initialize_buffer(buffer); - ExceptionHandlerTable handler_table; - ImplicitExceptionTable inc_table; + process_exception_handlers(); { ThreadToNativeFromVM t((JavaThread*)THREAD); - _env->register_method(ciMethodObject, -1, &_offsets, 0, &buffer, _frame_size, _debug_recorder->_oopmaps, &handler_table, &inc_table, NULL, _env->comp_level(), false, false); + _env->register_method(ciMethodObject, + -1, + &_offsets, + 0, + &buffer, + (_frame_size / HeapWordSize) + 2, // conversion to words, need to add two slots for ret address and frame pointer + _debug_recorder->_oopmaps, + &_exception_handler_table, + &_implicit_exception_table, + C1XCompiler::instance(), + _env->comp_level(), + false, + false); } } @@ -129,7 +139,7 @@ const char* cname = java_lang_String::as_utf8_string(_name); BufferBlob* blob = BufferBlob::create(strdup(cname), &buffer); // this is leaking strings... but only a limited number of stubs will be created - Disassembler::decode((CodeBlob*)blob); + IF_TRACE_C1X_3 Disassembler::decode((CodeBlob*)blob); id = VmIds::addStub(blob->instructions_begin()); } @@ -138,6 +148,7 @@ _hotspot_method = HotSpotTargetMethod::method(target_method); _name = HotSpotTargetMethod::name(target_method); _sites = (arrayOop)HotSpotTargetMethod::sites(target_method); + _exception_handlers = (arrayOop)HotSpotTargetMethod::exceptionHandlers(target_method); _code = (arrayOop)CiTargetMethod::targetCode(_citarget_method); _code_size = CiTargetMethod::targetCodeSize(_citarget_method); @@ -150,7 +161,110 @@ _next_call_type = MARK_INVOKE_INVALID; } -void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) { +// perform data and call relocation on the CodeBuffer +void CodeInstaller::initialize_buffer(CodeBuffer& buffer) { + _oop_recorder = new OopRecorder(_env->arena()); + _env->set_oop_recorder(_oop_recorder); + _debug_recorder = new DebugInformationRecorder(_env->oop_recorder()); + _debug_recorder->set_oopmaps(new OopMapSet()); + _dependencies = new Dependencies(_env); + + _env->set_oop_recorder(_oop_recorder); + _env->set_debug_info(_debug_recorder); + _env->set_dependencies(_dependencies); + buffer.initialize_oop_recorder(_oop_recorder); + + buffer.initialize_consts_size(_constants_size); + _instructions = buffer.insts(); + _constants = buffer.consts(); + + // copy the code into the newly created CodeBuffer + memcpy(_instructions->start(), _code->base(T_BYTE), _code_size); + _instructions->set_end(_instructions->start() + _code_size); + + oop* sites = (oop*)_sites->base(T_OBJECT); + for (int i=0; i<_sites->length(); i++) { + oop site = sites[i]; + jint pc_offset = CiTargetMethod_Site::pcOffset(site); + + if (site->is_a(CiTargetMethod_Safepoint::klass())) { + TRACE_C1X_4("safepoint at %i", pc_offset); + site_Safepoint(buffer, pc_offset, site); + } else if (site->is_a(CiTargetMethod_Call::klass())) { + TRACE_C1X_4("call at %i", pc_offset); + site_Call(buffer, pc_offset, site); + } else if (site->is_a(CiTargetMethod_DataPatch::klass())) { + TRACE_C1X_4("datapatch at %i", pc_offset); + site_DataPatch(buffer, pc_offset, site); + } else if (site->is_a(CiTargetMethod_Mark::klass())) { + TRACE_C1X_4("mark at %i", pc_offset); + site_Mark(buffer, pc_offset, site); + } else { + fatal("unexpected Site subclass"); + } + } +} + +void CodeInstaller::process_exception_handlers() { + // allocate some arrays for use by the collection code. + const int num_handlers = 5; + GrowableArray* bcis = new GrowableArray(num_handlers); + GrowableArray* scope_depths = new GrowableArray(num_handlers); + GrowableArray* pcos = new GrowableArray(num_handlers); + + if (_exception_handlers != NULL) { + oop* exception_handlers = (oop*)_exception_handlers->base(T_OBJECT); + for (int i=0; i<_exception_handlers->length(); i++) { + jint pc_offset = CiTargetMethod_Site::pcOffset(exception_handlers[i]); + int start = i; + while ((i + 1)<_exception_handlers->length() && CiTargetMethod_Site::pcOffset(exception_handlers[i + 1]) == pc_offset) + i ++; + + // empty the arrays + bcis->trunc_to(0); + scope_depths->trunc_to(0); + pcos->trunc_to(0); + + for (int j = start; j <= i; j++) { + oop exc = exception_handlers[j]; + jint handler_offset = CiTargetMethod_ExceptionHandler::handlerPos(exc); + jint handler_bci = CiTargetMethod_ExceptionHandler::handlerBci(exc); + jint bci = CiTargetMethod_ExceptionHandler::bci(exc); + jint scope_level = CiTargetMethod_ExceptionHandler::scopeLevel(exc); + Handle handler_type = CiTargetMethod_ExceptionHandler::exceptionType(exc); + + assert(handler_offset != -1, "must have been generated"); + + int e = bcis->find(handler_bci); + if (e >= 0 && scope_depths->at(e) == scope_level) { + // two different handlers are declared to dispatch to the same + // catch bci. During parsing we created edges for each + // handler but we really only need one. The exception handler + // table will also get unhappy if we try to declare both since + // it's nonsensical. Just skip this handler. + continue; + } + + bcis->append(handler_bci); + if (handler_bci == -1) { + // insert a wildcard handler at scope depth 0 so that the + // exception lookup logic with find it. + scope_depths->append(0); + } else { + scope_depths->append(scope_level); + } + pcos->append(handler_offset); + + // stop processing once we hit a catch any +// if (handler->is_catch_all()) { +// assert(i == handlers->length() - 1, "catch all must be last handler"); +// } + + } + _exception_handler_table.add_subtable(pc_offset, bcis, scope_depths, pcos); + } + } + } @@ -160,13 +274,14 @@ oop caller_frame = CiDebugInfo_Frame::caller(frame); record_frame(pc_offset, caller_pos, caller_frame); } else { - assert(frame == NULL || CiDebugInfo_Frame::caller(frame) == NULL, "unexpected layout - different nesting of Frame and CiCodePos"); + 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"); oop hotspot_method = CiCodePos::method(code_pos); - methodOop method = VmIds::get(HotSpotMethod::vmId(hotspot_method)); + 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); @@ -205,6 +320,22 @@ } } + +void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) { + oop debug_info = CiTargetMethod_Safepoint::debugInfo(site); + assert(debug_info != NULL, "debug info expected"); + +// address instruction = _instructions->start() + pc_offset; +// jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start(); + _debug_recorder->add_safepoint(pc_offset, create_oop_map(_frame_size, _parameter_count, debug_info)); + + oop code_pos = CiDebugInfo::codePos(debug_info); + oop frame = CiDebugInfo::frame(debug_info); + record_frame(pc_offset, code_pos, frame); + + _debug_recorder->end_safepoint(pc_offset); +} + void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, oop site) { oop runtime_call = CiTargetMethod_Call::runtimeCall(site); oop hotspot_method = CiTargetMethod_Call::method(site); @@ -217,75 +348,71 @@ assert((runtime_call ? 1 : 0) + (hotspot_method ? 1 : 0) + (symbol ? 1 : 0) + (global_stub ? 1 : 0) == 1, "Call site needs exactly one type"); - address instruction = _instructions->start() + pc_offset; - address operand = Assembler::locate_operand(instruction, Assembler::call32_operand); - address next_instruction = Assembler::locate_next_instruction(instruction); - - if (runtime_call != NULL) { - if (runtime_call == CiRuntimeCall::Debug()) { - tty->print_cr("CiRuntimeCall::Debug()"); - } else { - runtime_call->print(); - } - tty->print_cr("runtime_call"); - } else if (global_stub != NULL) { - assert(java_lang_boxing_object::is_instance(global_stub, T_LONG), "global_stub needs to be of type Long"); + NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); + jint next_pc_offset = pc_offset + NativeCall::instruction_size; - jlong stub_id = global_stub->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG)); - address dest = VmIds::getStub(stub_id); - long disp = dest - next_instruction; - assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); - *((jint*)operand) = (jint)disp; - - _instructions->relocate(instruction, runtime_call_Relocation::spec(), Assembler::call32_operand); - tty->print_cr("relocating (stub) %016x/%016x", instruction, operand); - } else if (symbol != NULL) { - tty->print_cr("symbol"); - } else { // method != NULL - assert(hotspot_method->is_a(SystemDictionary::HotSpotMethod_klass()), "unexpected RiMethod subclass"); - methodOop method = VmIds::get(HotSpotMethod::vmId(hotspot_method)); - - jint next_pc_offset = next_instruction - _instructions->start(); - - assert(debug_info != NULL, "debug info expected"); + if (debug_info != NULL) { _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(_frame_size, _parameter_count, debug_info)); oop code_pos = CiDebugInfo::codePos(debug_info); oop frame = CiDebugInfo::frame(debug_info); record_frame(next_pc_offset, code_pos, frame); + } + if (runtime_call != NULL) { + if (runtime_call == CiRuntimeCall::Debug()) { + TRACE_C1X_3("CiRuntimeCall::Debug()"); + } else if (runtime_call == CiRuntimeCall::UnwindException()) { + call->set_destination(Runtime1::entry_for(Runtime1::c1x_unwind_exception_call_id)); + _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); + TRACE_C1X_3("CiRuntimeCall::UnwindException()"); + } else if (runtime_call == CiRuntimeCall::HandleException()) { + call->set_destination(Runtime1::entry_for(Runtime1::c1x_handle_exception_id)); + _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); + TRACE_C1X_3("CiRuntimeCall::HandleException()"); + } else { + TRACE_C1X_1("runtime_call not implemented: "); + IF_TRACE_C1X_1 runtime_call->print(); + } + } else if (global_stub != NULL) { + assert(java_lang_boxing_object::is_instance(global_stub, T_LONG), "global_stub needs to be of type Long"); + + call->set_destination(VmIds::getStub(global_stub)); + _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); + TRACE_C1X_3("relocating (stub) at %016x", call->instruction_address()); + } else if (symbol != NULL) { + fatal("symbol"); + } else { // method != NULL + assert(hotspot_method != NULL, "unexpected RiMethod"); + assert(debug_info != NULL, "debug info expected"); + + methodOop method = NULL; + if (hotspot_method->is_a(HotSpotMethodResolved::klass())) + method = VmIds::get(HotSpotMethodResolved::vmId(hotspot_method)); + + assert(debug_info != NULL, "debug info expected"); + + TRACE_C1X_3("method call"); switch(_next_call_type) { case MARK_INVOKEVIRTUAL: case MARK_INVOKEINTERFACE: { - assert(!method->is_static(), "cannot call static method with invokeinterface"); + assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface"); - address dest = SharedRuntime::get_resolve_virtual_call_stub(); - long disp = dest - next_instruction; - assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); - *((jint*)operand) = (jint)disp; - - _instructions->relocate(instruction, virtual_call_Relocation::spec(_invoke_mark_pc), Assembler::call32_operand); + call->set_destination(SharedRuntime::get_resolve_virtual_call_stub()); + _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc), Assembler::call32_operand); break; } case MARK_INVOKESTATIC: { - assert(method->is_static(), "cannot call non-static method with invokestatic"); + assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic"); - address dest = SharedRuntime::get_resolve_static_call_stub(); - long disp = dest - next_instruction; - assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); - *((jint*)operand) = (jint)disp; - - _instructions->relocate(instruction, relocInfo::static_call_type, Assembler::call32_operand); + call->set_destination(SharedRuntime::get_resolve_static_call_stub()); + _instructions->relocate(call->instruction_address(), relocInfo::static_call_type, Assembler::call32_operand); break; } case MARK_INVOKESPECIAL: { - assert(!method->is_static(), "cannot call static method with invokespecial"); + assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial"); - address dest = SharedRuntime::get_resolve_opt_virtual_call_stub(); - long disp = dest - next_instruction; - assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); - *((jint*)operand) = (jint)disp; - - _instructions->relocate(instruction, relocInfo::opt_virtual_call_type, Assembler::call32_operand); + call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub()); + _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type, Assembler::call32_operand); break; } case MARK_INVOKE_INVALID: @@ -293,8 +420,10 @@ ShouldNotReachHere(); break; } - _next_call_type = MARK_INVOKE_INVALID; - _debug_recorder->end_safepoint(pc_offset); + } + _next_call_type = MARK_INVOKE_INVALID; + if (debug_info != NULL) { + _debug_recorder->end_safepoint(next_pc_offset); } } @@ -327,7 +456,7 @@ *((jint*)operand) = (jint)disp; _instructions->relocate(instruction, section_word_Relocation::spec((address)dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); - tty->print_cr("relocating (Float/Long/Double) at %016x/%016x", instruction, operand); + TRACE_C1X_3("relocating (Float/Long/Double) at %016x/%016x", instruction, operand); break; } case 'a': { @@ -337,7 +466,7 @@ if (obj->is_a(HotSpotTypeResolved::klass())) { *((jobject*)operand) = JNIHandles::make_local(VmIds::get(HotSpotTypeResolved::vmId(obj))); _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); - tty->print_cr("relocating (HotSpotType) at %016x/%016x", instruction, operand); + TRACE_C1X_3("relocating (HotSpotType) at %016x/%016x", instruction, operand); } else { assert(java_lang_boxing_object::is_instance(obj, T_LONG), "unexpected DataPatch object type"); jlong id = obj->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG)); @@ -352,7 +481,7 @@ *((jobject*)operand) = JNIHandles::make_local(VmIds::get(id)); } _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); - tty->print_cr("relocating (oop constant) at %016x/%016x", instruction, operand); + TRACE_C1X_3("relocating (oop constant) at %016x/%016x", instruction, operand); } break; } @@ -362,10 +491,6 @@ } } -void CodeInstaller::site_ExceptionHandler(CodeBuffer& buffer, jint pc_offset, oop site) { - -} - void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) { oop id_obj = CiTargetMethod_Mark::id(site); arrayOop references = (arrayOop)CiTargetMethod_Mark::references(site); @@ -386,6 +511,12 @@ case MARK_OSR_ENTRY: _offsets.set_value(CodeOffsets::OSR_Entry, pc_offset); break; + case MARK_UNWIND_ENTRY: + _offsets.set_value(CodeOffsets::UnwindHandler, pc_offset); + break; + case MARK_EXCEPTION_HANDLER_ENTRY: + _offsets.set_value(CodeOffsets::Exceptions, pc_offset); + break; case MARK_STATIC_CALL_STUB: { assert(references->length() == 1, "static call stub needs one reference"); oop ref = ((oop*)references->base(T_OBJECT))[0]; @@ -401,8 +532,33 @@ _next_call_type = (MarkId)id; _invoke_mark_pc = instruction; break; - case MARK_IMPLICIT_NULL_EXCEPTION_TARGET: + case MARK_IMPLICIT_NULL: + _implicit_exception_table.append(pc_offset, pc_offset); break; + case MARK_KLASS_PATCHING: { + unsigned char* byte_count = (unsigned char*) (instruction - 1); + unsigned char* byte_skip = (unsigned char*) (instruction - 2); + unsigned char* being_initialized_entry_offset = (unsigned char*) (instruction - 3); + + assert(*byte_skip == 5, "unexpected byte_skip"); + + assert(references->length() == 2, "MARK_KLASS_PATCHING needs 2 references"); + oop ref1 = ((oop*)references->base(T_OBJECT))[0]; + oop ref2 = ((oop*)references->base(T_OBJECT))[1]; + int i_byte_count = CiTargetMethod_Site::pcOffset(ref2) - CiTargetMethod_Site::pcOffset(ref1); + assert(i_byte_count == (unsigned char)i_byte_count, "invalid offset"); + *byte_count = i_byte_count; + *being_initialized_entry_offset = *byte_count + *byte_skip; + + break; + } + case MARK_DUMMY_OOP_RELOCATION: { + _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); + + RelocIterator iter(_instructions, (address)instruction, (address)(instruction + 1)); + relocInfo::change_reloc_info_for_address(&iter, (address) instruction, relocInfo::oop_type, relocInfo::none); + break; + } default: ShouldNotReachHere(); break; @@ -410,51 +566,7 @@ } } -// perform data and call relocation on the CodeBuffer -void CodeInstaller::initialize_buffer(CodeBuffer& buffer) { - _oop_recorder = new OopRecorder(_env->arena()); - _env->set_oop_recorder(_oop_recorder); - _debug_recorder = new DebugInformationRecorder(_env->oop_recorder()); - _debug_recorder->set_oopmaps(new OopMapSet()); - _dependencies = new Dependencies(_env); - _env->set_oop_recorder(_oop_recorder); - _env->set_debug_info(_debug_recorder); - _env->set_dependencies(_dependencies); - buffer.initialize_oop_recorder(_oop_recorder); - - buffer.initialize_consts_size(_constants_size); - _instructions = buffer.insts(); - _constants = buffer.consts(); - - // copy the code into the newly created CodeBuffer - memcpy(_instructions->start(), _code->base(T_BYTE), _code_size); - _instructions->set_end(_instructions->start() + _code_size); - - oop* sites = (oop*)_sites->base(T_OBJECT); - for (int i=0; i<_sites->length(); i++) { - oop site = sites[i]; - jint pc_offset = CiTargetMethod_Site::pcOffset(site); - - if (site->is_a(CiTargetMethod_Safepoint::klass())) { - tty->print_cr("safepoint at %i", pc_offset); - site_Safepoint(buffer, pc_offset, site); - } else if (site->is_a(CiTargetMethod_Call::klass())) { - tty->print_cr("call at %i", pc_offset); - site_Call(buffer, pc_offset, site); - } else if (site->is_a(CiTargetMethod_DataPatch::klass())) { - tty->print_cr("datapatch at %i", pc_offset); - site_DataPatch(buffer, pc_offset, site); - } else if (site->is_a(CiTargetMethod_ExceptionHandler::klass())) { - tty->print_cr("exception handler at %i", pc_offset); - site_ExceptionHandler(buffer, pc_offset, site); - } else if (site->is_a(CiTargetMethod_Mark::klass())) { - tty->print_cr("mark at %i", pc_offset); - site_Mark(buffer, pc_offset, site); - } else { - ShouldNotReachHere(); - } - } /* if (_relocation_count > 0) { @@ -524,5 +636,4 @@ } } }*/ -} diff -r 695451afc619 -r abc670a709dc src/share/vm/c1x/c1x_CodeInstaller.hpp --- a/src/share/vm/c1x/c1x_CodeInstaller.hpp Thu Aug 19 14:34:52 2010 -0700 +++ b/src/share/vm/c1x/c1x_CodeInstaller.hpp Tue Aug 31 22:13:30 2010 -0700 @@ -26,16 +26,20 @@ private: // this needs to correspond to HotSpotXirGenerator.java enum MarkId { - MARK_VERIFIED_ENTRY = 0x0001, - MARK_UNVERIFIED_ENTRY = 0x0002, - MARK_OSR_ENTRY = 0x0003, - MARK_STATIC_CALL_STUB = 0x1000, - MARK_INVOKE_INVALID = 0x2000, - MARK_INVOKEINTERFACE = 0x2001, - MARK_INVOKESTATIC = 0x2002, - MARK_INVOKESPECIAL = 0x2003, - MARK_INVOKEVIRTUAL = 0x2004, - MARK_IMPLICIT_NULL_EXCEPTION_TARGET = 0x3000 + MARK_VERIFIED_ENTRY = 0x0001, + MARK_UNVERIFIED_ENTRY = 0x0002, + MARK_OSR_ENTRY = 0x0003, + MARK_UNWIND_ENTRY = 0x0004, + MARK_EXCEPTION_HANDLER_ENTRY = 0x0005, + MARK_STATIC_CALL_STUB = 0x1000, + MARK_INVOKE_INVALID = 0x2000, + MARK_INVOKEINTERFACE = 0x2001, + MARK_INVOKESTATIC = 0x2002, + MARK_INVOKESPECIAL = 0x2003, + MARK_INVOKEVIRTUAL = 0x2004, + MARK_IMPLICIT_NULL = 0x3000, + MARK_KLASS_PATCHING = 0x4000, + MARK_DUMMY_OOP_RELOCATION = 0x4001 }; ciEnv* _env; @@ -44,6 +48,7 @@ oop _hotspot_method; oop _name; arrayOop _sites; + arrayOop _exception_handlers; CodeOffsets _offsets; arrayOop _code; @@ -59,9 +64,11 @@ CodeSection* _instructions; CodeSection* _constants; - OopRecorder* _oop_recorder; + OopRecorder* _oop_recorder; DebugInformationRecorder* _debug_recorder; - Dependencies* _dependencies; + Dependencies* _dependencies; + ExceptionHandlerTable _exception_handler_table; + ImplicitExceptionTable _implicit_exception_table; public: @@ -80,9 +87,10 @@ void site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site); void site_Call(CodeBuffer& buffer, jint pc_offset, oop site); void site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site); - void site_ExceptionHandler(CodeBuffer& buffer, jint pc_offset, oop site); void site_Mark(CodeBuffer& buffer, jint pc_offset, oop site); void record_frame(jint pc_offset, oop code_pos, oop frame); + void process_exception_handlers(); + }; diff -r 695451afc619 -r abc670a709dc src/share/vm/c1x/c1x_Compiler.cpp --- a/src/share/vm/c1x/c1x_Compiler.cpp Thu Aug 19 14:34:52 2010 -0700 +++ b/src/share/vm/c1x/c1x_Compiler.cpp Tue Aug 31 22:13:30 2010 -0700 @@ -26,12 +26,22 @@ # include "incls/_precompiled.incl" # include "incls/_c1x_Compiler.cpp.incl" +C1XCompiler* C1XCompiler::_instance = NULL; + + +C1XCompiler::C1XCompiler() { + _initialized = false; + assert(_instance == NULL, "only one instance allowed"); + _instance = this; +} + + // Initialization void C1XCompiler::initialize() { if (_initialized) return; _initialized = true; - TRACE_C1X_1("initialize"); + TRACE_C1X_1("C1XCompiler::initialize"); JNIEnv *env = ((JavaThread *)Thread::current())->jni_environment(); jclass klass = env->FindClass("com/sun/hotspot/c1x/VMEntriesNative"); @@ -63,7 +73,7 @@ // Print compilation timers and statistics void C1XCompiler::print_timers() { - TRACE_C1X_1("print_timers"); + TRACE_C1X_1("C1XCompiler::print_timers"); } oop C1XCompiler::get_RiType(ciType *type, klassOop accessor, TRAPS) { @@ -71,8 +81,9 @@ if (type->is_primitive_type()) { return VMExits::createRiTypePrimitive((int)type->basic_type(), THREAD); } - klassOop klass = (klassOop)type->get_oop(); - return VMExits::createRiType(VmIds::add(klass), VmIds::toString(klass->klass_part()->name(), THREAD), THREAD); + KlassHandle klass = (klassOop)type->get_oop(); + Handle name = VmIds::toString(klass->name(), THREAD); + return createHotSpotTypeResolved(klass, name, CHECK_NULL); } else { symbolOop name = ((ciKlass *)type)->name()->get_symbolOop(); return VMExits::createRiTypeUnresolved(VmIds::toString(name, THREAD), VmIds::add(accessor), THREAD); @@ -89,3 +100,33 @@ return VMExits::createRiField(field_holder, field_name, field_type, offset, THREAD); } + +oop C1XCompiler::createHotSpotTypeResolved(KlassHandle klass, Handle name, TRAPS) { + instanceKlass::cast(HotSpotTypeResolved::klass())->initialize(CHECK_NULL); + oop obj = instanceKlass::cast(HotSpotTypeResolved::klass())->allocate_instance(CHECK_NULL); + + HotSpotTypeResolved::set_vmId(obj, VmIds::add(klass, VmIds::CLASS)); + HotSpotTypeResolved::set_javaMirrorVmId(obj, VmIds::add(klass->java_mirror(), VmIds::CONSTANT)); + HotSpotTypeResolved::set_name(obj, name()); + HotSpotTypeResolved::set_accessFlags(obj, klass->access_flags().as_int()); + HotSpotTypeResolved::set_isInterface(obj, klass->is_interface()); + HotSpotTypeResolved::set_isInstanceClass(obj, klass->oop_is_instance()); + + if (klass->oop_is_javaArray()) { + HotSpotTypeResolved::set_isArrayClass(obj, true); + } else { + HotSpotTypeResolved::set_isArrayClass(obj, false); + HotSpotTypeResolved::set_isInitialized(obj, instanceKlass::cast(klass())->is_initialized()); + HotSpotTypeResolved::set_instanceSize(obj, instanceKlass::cast(klass())->size_helper() * HeapWordSize); + HotSpotTypeResolved::set_hasFinalizer(obj, klass->has_finalizer()); + } + + // TODO replace these with correct values + HotSpotTypeResolved::set_hasSubclass(obj, false); + HotSpotTypeResolved::set_hasFinalizableSubclass(obj, false); + + return obj; +} + + + diff -r 695451afc619 -r abc670a709dc src/share/vm/c1x/c1x_Compiler.hpp --- a/src/share/vm/c1x/c1x_Compiler.hpp Thu Aug 19 14:34:52 2010 -0700 +++ b/src/share/vm/c1x/c1x_Compiler.hpp Tue Aug 31 22:13:30 2010 -0700 @@ -26,11 +26,16 @@ private: - bool _initialized; + bool _initialized; + + static C1XCompiler* _instance; public: - C1XCompiler() { _initialized = false; } + C1XCompiler(); + + static C1XCompiler* instance() { return _instance; } + virtual const char* name() { return "C1X"; } @@ -54,13 +59,8 @@ static oop get_RiType(ciType *klass, klassOop accessor, TRAPS); static oop get_RiField(ciField *ciField, TRAPS); -/* - static oop get_RiMethod(ciMethod *ciMethod, TRAPS); - static oop get_RiType(klassOop klass, TRAPS); - static oop get_RiMethod(methodOop method, TRAPS); - static oop get_unresolved_RiType(oop klass, klassOop accessingType, TRAPS); - static oop get_RiConstantPool(constantPoolOop cpOop, TRAPS); -*/ + static oop createHotSpotTypeResolved(KlassHandle klass, Handle name, TRAPS); + }; // Tracing macros @@ -71,11 +71,12 @@ #define IF_TRACE_C1X_4 if (TraceC1X >= 4) #define IF_TRACE_C1X_5 if (TraceC1X >= 5) -#define TRACE_C1X_1 if (TraceC1X >= 1) tty->print("TraceC1X-1: "); if (TraceC1X >= 1) tty->print_cr -#define TRACE_C1X_2 if (TraceC1X >= 2) tty->print(" TraceC1X-2: "); if (TraceC1X >= 2) tty->print_cr -#define TRACE_C1X_3 if (TraceC1X >= 3) tty->print(" TraceC1X-3: "); if (TraceC1X >= 3) tty->print_cr -#define TRACE_C1X_4 if (TraceC1X >= 4) tty->print(" TraceC1X-4: "); if (TraceC1X >= 4) tty->print_cr -#define TRACE_C1X_5 if (TraceC1X >= 5) tty->print(" TraceC1X-5: "); if (TraceC1X >= 5) tty->print_cr +// 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 diff -r 695451afc619 -r abc670a709dc src/share/vm/c1x/c1x_TargetMethod.cpp --- a/src/share/vm/c1x/c1x_TargetMethod.cpp Thu Aug 19 14:34:52 2010 -0700 +++ b/src/share/vm/c1x/c1x_TargetMethod.cpp Tue Aug 31 22:13:30 2010 -0700 @@ -51,13 +51,14 @@ #define FIELD(klass, name, signature, static_field) compute_offset(klass::_##name##_offset, k, #name, signature, static_field); #define CHAR_FIELD(klass, name) FIELD(klass, name, "C", false) #define INT_FIELD(klass, name) FIELD(klass, name, "I", false) +#define BOOLEAN_FIELD(klass, name) FIELD(klass, name, "Z", false) #define LONG_FIELD(klass, name) FIELD(klass, name, "J", false) #define OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, false) #define STATIC_OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, true) void c1x_compute_offsets() { - COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, LONG_FIELD, OOP_FIELD, STATIC_OOP_FIELD) + COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, OOP_FIELD, STATIC_OOP_FIELD) } #define EMPTY0 @@ -66,7 +67,7 @@ #define FIELD2(klass, name) int klass::_##name##_offset = 0; #define FIELD3(klass, name, sig) FIELD2(klass, name) -COMPILER_CLASSES_DO(EMPTY1, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3) +COMPILER_CLASSES_DO(EMPTY1, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3) diff -r 695451afc619 -r abc670a709dc src/share/vm/c1x/c1x_TargetMethod.hpp --- a/src/share/vm/c1x/c1x_TargetMethod.hpp Thu Aug 19 14:34:52 2010 -0700 +++ b/src/share/vm/c1x/c1x_TargetMethod.hpp Tue Aug 31 22:13:30 2010 -0700 @@ -27,18 +27,37 @@ // defines the structure of the CiTargetMethod - classes // this will generate classes with accessors similar to javaClasses.hpp -#define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, long_field, oop_field, static_oop_field) \ +#define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, oop_field, static_oop_field) \ start_class(HotSpotTypeResolved) \ long_field(HotSpotTypeResolved, vmId) \ + long_field(HotSpotTypeResolved, javaMirrorVmId) \ + oop_field(HotSpotTypeResolved, name, "Ljava/lang/String;") \ + int_field(HotSpotTypeResolved, accessFlags) \ + boolean_field(HotSpotTypeResolved, hasFinalizer) \ + boolean_field(HotSpotTypeResolved, hasSubclass) \ + boolean_field(HotSpotTypeResolved, hasFinalizableSubclass) \ + boolean_field(HotSpotTypeResolved, isInitialized) \ + boolean_field(HotSpotTypeResolved, isArrayClass) \ + boolean_field(HotSpotTypeResolved, isInstanceClass) \ + boolean_field(HotSpotTypeResolved, isInterface) \ + int_field(HotSpotTypeResolved, instanceSize) \ end_class \ - start_class(HotSpotMethod) \ - long_field(HotSpotMethod, vmId) \ + start_class(HotSpotMethodResolved) \ + long_field(HotSpotMethodResolved, vmId) \ end_class \ start_class(HotSpotTargetMethod) \ oop_field(HotSpotTargetMethod, targetMethod, "Lcom/sun/cri/ci/CiTargetMethod;") \ - oop_field(HotSpotTargetMethod, method, "Lcom/sun/hotspot/c1x/HotSpotMethod;") \ + oop_field(HotSpotTargetMethod, method, "Lcom/sun/hotspot/c1x/HotSpotMethodResolved;")\ oop_field(HotSpotTargetMethod, name, "Ljava/lang/String;") \ oop_field(HotSpotTargetMethod, sites, "[Lcom/sun/cri/ci/CiTargetMethod$Site;") \ + oop_field(HotSpotTargetMethod, exceptionHandlers, "[Lcom/sun/cri/ci/CiTargetMethod$ExceptionHandler;") \ + end_class \ + start_class(HotSpotExceptionHandler) \ + int_field(HotSpotExceptionHandler, startBci) \ + int_field(HotSpotExceptionHandler, endBci) \ + int_field(HotSpotExceptionHandler, handlerBci) \ + int_field(HotSpotExceptionHandler, catchClassIndex) \ + oop_field(HotSpotExceptionHandler, catchClass, "Lcom/sun/cri/ri/RiType;") \ end_class \ start_class(CiTargetMethod) \ int_field(CiTargetMethod, frameSize) \ @@ -66,6 +85,9 @@ end_class \ start_class(CiTargetMethod_ExceptionHandler) \ int_field(CiTargetMethod_ExceptionHandler, handlerPos) \ + int_field(CiTargetMethod_ExceptionHandler, handlerBci) \ + int_field(CiTargetMethod_ExceptionHandler, bci) \ + int_field(CiTargetMethod_ExceptionHandler, scopeLevel) \ oop_field(CiTargetMethod_ExceptionHandler, exceptionType, "Lcom/sun/cri/ri/RiType;")\ end_class \ start_class(CiTargetMethod_Mark) \ @@ -100,7 +122,22 @@ char_field(CiKind, typeChar) \ end_class \ start_class(CiRuntimeCall) \ + static_oop_field(CiRuntimeCall, UnwindException, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, RegisterFinalizer, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, HandleException, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, OSRMigrationEnd, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, JavaTimeMillis, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, JavaTimeNanos, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ static_oop_field(CiRuntimeCall, Debug, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, ArithmethicLrem, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, ArithmeticLdiv, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, ArithmeticFrem, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, ArithmeticDrem, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, ArithmeticCos, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, ArithmeticTan, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, ArithmeticLog, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, ArithmeticLog10, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ + static_oop_field(CiRuntimeCall, ArithmeticSin, "Lcom/sun/cri/ci/CiRuntimeCall;"); \ end_class \ start_class(RiMethod) \ end_class \ @@ -110,6 +147,9 @@ end_class \ /* end*/ + + + #define START_CLASS(name) \ class name : AllStatic { \ private: \ @@ -124,12 +164,15 @@ #define FIELD(name, type, accessor) \ static int _##name##_offset; \ static type name(oop obj) { check(obj); return obj->accessor(_##name##_offset); } \ + static type name(Handle obj) { check(obj()); return obj->accessor(_##name##_offset); } \ static type name(jobject obj) { check(JNIHandles::resolve(obj)); return JNIHandles::resolve(obj)->accessor(_##name##_offset); } \ static void set_##name(oop obj, type x) { check(obj); obj->accessor##_put(_##name##_offset, x); } \ + static void set_##name(Handle obj, type x) { check(obj()); obj->accessor##_put(_##name##_offset, x); } \ static void set_##name(jobject obj, type x) { check(JNIHandles::resolve(obj)); JNIHandles::resolve(obj)->accessor##_put(_##name##_offset, x); } #define CHAR_FIELD(klass, name) FIELD(name, jchar, char_field) #define INT_FIELD(klass, name) FIELD(name, jint, int_field) +#define BOOLEAN_FIELD(klass, name) FIELD(name, jboolean, bool_field) #define LONG_FIELD(klass, name) FIELD(name, jlong, long_field) #define OOP_FIELD(klass, name, signature) FIELD(name, oop, obj_field) #define STATIC_OOP_FIELD(klassName, name, signature) \ @@ -137,12 +180,13 @@ static oop name() { return klassName::klass()->obj_field(_##name##_offset); } \ static void set_##name(oop x) { klassName::klass()->obj_field_put(_##name##_offset, x); } -COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, LONG_FIELD, OOP_FIELD, STATIC_OOP_FIELD) +COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, OOP_FIELD, STATIC_OOP_FIELD) #undef START_CLASS #undef END_CLASS #undef FIELD #undef CHAR_FIELD #undef INT_FIELD +#undef BOOLEAN_FIELD #undef LONG_FIELD #undef OOP_FIELD #undef STATIC_OOP_FIELD diff -r 695451afc619 -r abc670a709dc src/share/vm/c1x/c1x_VMEntries.cpp --- a/src/share/vm/c1x/c1x_VMEntries.cpp Thu Aug 19 14:34:52 2010 -0700 +++ b/src/share/vm/c1x/c1x_VMEntries.cpp Tue Aug 31 22:13:30 2010 -0700 @@ -51,10 +51,9 @@ // public RiType RiMethod_holder(long vmId); JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1holder(JNIEnv *, jobject, jlong vmId) { VM_ENTRY_MARK - klassOop klass = VmIds::get(vmId)->method_holder(); - jlong klassVmId = VmIds::add(klass); - Handle name = VmIds::toString(klass->klass_part()->name(), CHECK_NULL); - oop holder = VMExits::createRiType(klassVmId, name, THREAD); + KlassHandle klass = VmIds::get(vmId)->method_holder(); + Handle name = VmIds::toString(klass->name(), CHECK_NULL); + oop holder = C1XCompiler::createHotSpotTypeResolved(klass, name, CHECK_NULL); return JNIHandles::make_local(THREAD, holder); } @@ -62,6 +61,7 @@ JNIEXPORT jstring JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1signature(JNIEnv *env, jobject, jlong vmId) { VM_ENTRY_MARK methodOop method = VmIds::get(vmId); + method->constMethod()->exception_table(); return VmIds::toString(method->signature(), THREAD); } @@ -70,8 +70,45 @@ return VmIds::get(vmId)->access_flags().as_int(); } +// public RiExceptionHandler[] RiMethod_exceptionHandlers(long vmId); +JNIEXPORT jobjectArray JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1exceptionHandlers(JNIEnv *, jobject, jlong vmId) { + VM_ENTRY_MARK + methodHandle method = VmIds::get(vmId); + typeArrayHandle handlers = method->exception_table(); + int handler_count = handlers.is_null() ? 0 : handlers->length() / 4; + + instanceKlass::cast(HotSpotExceptionHandler::klass())->initialize(CHECK_NULL); + objArrayHandle array = oopFactory::new_objArray(SystemDictionary::RiExceptionHandler_klass(), handler_count, CHECK_NULL); + + for (int i=0; iallocate_instance(CHECK_NULL); + HotSpotExceptionHandler::set_startBci(entry, handlers->int_at(base + 0)); + HotSpotExceptionHandler::set_endBci(entry, handlers->int_at(base + 1)); + HotSpotExceptionHandler::set_handlerBci(entry, handlers->int_at(base + 2)); + int catch_class_index = handlers->int_at(base + 3); + HotSpotExceptionHandler::set_catchClassIndex(entry, catch_class_index); + + if (catch_class_index == 0) { + 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 = C1XCompiler::get_RiType(klass, method->method_holder(), CHECK_NULL); + + HotSpotExceptionHandler::set_catchClass(entry, catch_class); + } + array->obj_at_put(i, entry()); + } + + return (jobjectArray)JNIHandles::make_local(array()); +} + // public RiType RiSignature_lookupType(String returnType, long accessingClassVmId); -JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiSignature_1lookupType(JNIEnv *, jobject, jstring jname, jlong accessingClassVmId) { +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiSignature_1lookupType(JNIEnv *env, jobject, jstring jname, jlong accessingClassVmId) { VM_ENTRY_MARK; symbolOop nameSymbol = VmIds::toSymbol(jname); @@ -103,7 +140,7 @@ } klassOop resolved_type = SystemDictionary::resolve_or_null(nameSymbol, classloader, protectionDomain, THREAD); if (resolved_type != NULL) { - result = VMExits::createRiType(VmIds::add(resolved_type), name, THREAD); + result = C1XCompiler::createHotSpotTypeResolved(resolved_type, name, CHECK_NULL); } else { result = VMExits::createRiTypeUnresolved(name, accessingClassVmId, THREAD); } @@ -143,24 +180,14 @@ } result = VMExits::createCiConstantObject(VmIds::add(string), CHECK_0); } else if (tag.is_klass() || tag.is_unresolved_klass()) { - - // TODO: Return RiType object - ShouldNotReachHere(); - // 4881222: allow ldc to take a class type - //bool ignore; - //ciKlass* klass = get_klass_by_index_impl(cpool, index, ignore, accessor); - //if (HAS_PENDING_EXCEPTION) { - // CLEAR_PENDING_EXCEPTION; - // record_out_of_memory_failure(); - // return ciConstant(); - //} - //assert (klass->is_instance_klass() || klass->is_array_klass(), - // "must be an instance or array klass "); - //return ciConstant(T_OBJECT, 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 = C1XCompiler::get_RiType(klass, cp->pool_holder(), CHECK_NULL); } else if (tag.is_object()) { oop obj = cp->object_at(index); assert(obj->is_instance(), "must be an instance"); - result = VMExits::createCiConstantObject(VmIds::add(obj), CHECK_0); + result = VMExits::createCiConstantObject(VmIds::add(obj), CHECK_NULL); } else { ShouldNotReachHere(); } @@ -172,14 +199,21 @@ JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupMethod(JNIEnv *env, jobject, jlong vmId, jint index, jbyte byteCode) { VM_ENTRY_MARK; - constantPoolOop cp = VmIds::get(vmId); + constantPoolHandle cp = VmIds::get(vmId); Bytecodes::Code bc = (Bytecodes::Code)(((int)byteCode) & 0xFF); ciInstanceKlass* loading_klass = (ciInstanceKlass *)CURRENT_ENV->get_object(cp->pool_holder()); ciMethod *cimethod = CURRENT_ENV->get_method_by_index(cp, index, bc, loading_klass); - methodOop method = (methodOop)cimethod->get_oop(); - Handle name = VmIds::toString(method->name(), CHECK_NULL); - return JNIHandles::make_local(THREAD, VMExits::createRiMethod(VmIds::add(method), name, THREAD)); + if (cimethod->is_loaded()) { + methodOop method = (methodOop)cimethod->get_oop(); + Handle name = VmIds::toString(method->name(), CHECK_NULL); + return JNIHandles::make_local(THREAD, VMExits::createRiMethodResolved(VmIds::add(method), name, THREAD)); + } else { + Handle name = VmIds::toString((symbolOop)cimethod->name()->get_oop(), CHECK_NULL); + Handle signature = VmIds::toString((symbolOop)cimethod->signature()->as_symbol()->get_oop(), CHECK_NULL); + Handle holder = C1XCompiler::get_RiType(cimethod->holder(), cp->klass(), THREAD); + return JNIHandles::make_local(THREAD, VMExits::createRiMethodUnresolved(name, signature, holder, THREAD)); + } } // public RiSignature RiConstantPool_lookupSignature(long vmId, int cpi); @@ -198,7 +232,6 @@ bool is_accessible = false; ciKlass *klass = CURRENT_ENV->get_klass_by_index(cp, index, is_accessible, loading_klass); return JNIHandles::make_local(THREAD, C1XCompiler::get_RiType(klass, cp->klass(), THREAD)); - } // public RiField RiConstantPool_lookupField(long vmId, int cpi); @@ -220,37 +253,57 @@ return JNIHandles::make_local(VMExits::createRiConstantPool(VmIds::add(constantPool), THREAD)); } -// public boolean RiType_isArrayClass(long vmId); -JNIEXPORT jboolean JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1isArrayClass(JNIEnv *, jobject, jlong vmId) { - return VmIds::get(vmId)->klass_part()->oop_is_javaArray(); -} +// public RiMethod RiType_resolveMethodImpl(long vmId, String name, String signature); +JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_3resolveMethodImpl(JNIEnv *, jobject, jlong vmId, jstring name, jstring signature) { + VM_ENTRY_MARK; -// public boolean RiType_isInstanceClass(long vmId); -JNIEXPORT jboolean JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1isInstanceClass(JNIEnv *, jobject, jlong vmId) { - return VmIds::get(vmId)->klass_part()->oop_is_instance(); + klassOop klass = VmIds::get(vmId); + methodOop method = klass->klass_part()->lookup_method(VmIds::toSymbol(name), VmIds::toSymbol(signature)); + return JNIHandles::make_local(THREAD, VMExits::createRiMethodResolved(VmIds::add(method), Handle(JNIHandles::resolve(name)), THREAD)); } -// public boolean RiType_isInterface(long vmId); -JNIEXPORT jboolean JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1isInterface(JNIEnv *, jobject, jlong vmId) { - return VmIds::get(vmId)->klass_part()->is_interface(); +// public boolean RiType_isSubtypeOf(long vmId, RiType other); +JNIEXPORT jboolean JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_2isSubtypeOf(JNIEnv *, jobject, jlong vmId, jobject jother) { + oop other = JNIHandles::resolve(jother); + assert(other->is_a(HotSpotTypeResolved::klass()), "resolved hotspot type expected"); + klassOop thisKlass = VmIds::get(vmId); + klassOop otherKlass = VmIds::get(HotSpotTypeResolved::vmId(other)); + return instanceKlass::cast(thisKlass)->is_subtype_of(otherKlass); } -// public long RiType_instanceSize(long vmId); -JNIEXPORT jlong JNICALL Java_com_sun_hotspot_c1x_VMEntries_RiType_1instanceSize(JNIEnv *, jobject, jlong vmId) { - return align_object_size(instanceKlass::cast(VmIds::get(vmId))->size_helper() * HeapWordSize); -} - - // 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) { - tty->print_cr("field not found: %s (%s)", name, sig); - assert(id != NULL, "field not found"); + TRACE_C1X_1("field not found: %s (%s)", name, sig); + fatal("field not found"); } return id; } +// 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; + } + ciKlass* klass = ciTypeArrayKlass::make(type); + return JNIHandles::make_local(THREAD, C1XCompiler::get_RiType(klass, NULL, THREAD)); +} + + 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); } void set_long(JNIEnv* env, jobject obj, const char* name, long value) { env->SetLongField(obj, getFieldID(env, obj, name, "J"), value); } @@ -269,7 +322,6 @@ // public HotSpotVMConfig getConfiguration(); JNIEXPORT jobject JNICALL Java_com_sun_hotspot_c1x_VMEntries_getConfiguration(JNIEnv *env, jobject) { - tty->print_cr("Java_com_sun_hotspot_c1x_VMEntries_getConfiguration"); jclass klass = env->FindClass("com/sun/hotspot/c1x/HotSpotVMConfig"); assert(klass != NULL, "HotSpot vm config class not found"); jobject config = env->AllocObject(klass); @@ -286,12 +338,23 @@ 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()); + set_int(env, config, "threadExceptionOopOffset", in_bytes(JavaThread::exception_oop_offset())); + set_int(env, config, "threadExceptionPcOffset", in_bytes(JavaThread::exception_pc_offset())); + set_int(env, config, "threadMultiNewArrayStorage", in_bytes(JavaThread::c1x_multinewarray_storage_offset())); - set_long(env, config, "instanceofStub", VmIds::addStub(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); 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, "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, "resolveStaticCallStub", VmIds::addStub(SharedRuntime::get_resolve_static_call_stub())); - set_long(env, config, "newInstanceStub", VmIds::addStub(Runtime1::entry_for(Runtime1::fast_new_instance_id))); - set_long(env, config, "throwImplicitNullStub", VmIds::addStub(Runtime1::entry_for(Runtime1::throw_null_pointer_exception_id))); + 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))); jintArray arrayOffsets = env->NewIntArray(basicTypeCount); for (int i=0; i static jlong add(T obj); + + // Returns the stub address with the given vmId static address getStub(jlong id); + // Returns the stub address with the given vmId taken from a java.lang.Long + static address getStub(oop id); + + // Returns the object with the given id, the return type is defined by the template parameter (which must correspond to the actual type of the vmId) template static T get(jlong id); + + // Helper function to convert a symbolOop to a java.lang.String object template static T toString(symbolOop symbol, TRAPS); + + // 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); + + static jlong getBoxedLong(oop obj); }; template <> inline jlong VmIds::add(methodOop obj){ - assert(obj != NULL && obj->is_method(), "trying to add NULL or mistyped object"); + assert(obj != NULL, "trying to add NULL"); + assert(obj->is_method(), "trying to add mistyped object"); return add(Handle(obj), METHOD); } template <> inline jlong VmIds::add(klassOop obj) { - assert(obj != NULL && obj->is_klass(), "trying to add NULL or mistyped object"); + assert(obj != NULL, "trying to add NULL"); + assert(obj->is_klass(), "trying to add mistyped object"); return add(Handle(obj), CLASS); } template <> inline jlong VmIds::add(symbolOop obj) { - assert(obj != NULL && obj->is_symbol(), "trying to add NULL or mistyped object"); + assert(obj != NULL, "trying to add NULL"); + assert(obj->is_symbol(), "trying to add mistyped object"); return add(Handle(obj), SYMBOL); } template <> inline jlong VmIds::add(constantPoolOop obj) { - assert(obj != NULL && obj->is_constantPool(), "trying to add NULL or mistyped object"); + assert(obj != NULL, "trying to add NULL"); + assert(obj->is_constantPool(), "trying to add mistyped object"); return add(Handle(obj), CONSTANT_POOL); } template <> inline jlong VmIds::add(oop obj) { - assert(obj != NULL && obj->is_oop(), "trying to add NULL or mistyped object"); + assert(obj != NULL, "trying to add NULL"); + assert(obj->is_oop(), "trying to add mistyped object"); return add(Handle(obj), CONSTANT); } @@ -104,6 +126,10 @@ return (oop)getObject(id); } +inline address VmIds::getStub(oop obj) { + return getStub(getBoxedLong(obj)); +} + template <> inline Handle VmIds::toString(symbolOop symbol, TRAPS) { return java_lang_String::create_from_symbol(symbol, THREAD); } @@ -121,3 +147,7 @@ return java_lang_String::as_symbol_or_null(JNIHandles::resolve(string)); } +inline jlong VmIds::getBoxedLong(oop obj) { + assert(obj->is_oop(true), "cannot unbox null or non-oop"); + return obj->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG)); +} diff -r 695451afc619 -r abc670a709dc src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Thu Aug 19 14:34:52 2010 -0700 +++ b/src/share/vm/classfile/systemDictionary.hpp Tue Aug 31 22:13:30 2010 -0700 @@ -172,8 +172,9 @@ template(Long_klass, java_lang_Long, Pre) \ \ template(HotSpotTypeResolved_klass, com_sun_hotspot_c1x_HotSpotTypeResolved, Pre) \ - template(HotSpotMethod_klass, com_sun_hotspot_c1x_HotSpotMethod, Pre) \ + template(HotSpotMethodResolved_klass, com_sun_hotspot_c1x_HotSpotMethodResolved, Pre) \ template(HotSpotTargetMethod_klass, com_sun_hotspot_c1x_HotSpotTargetMethod, Pre) \ + template(HotSpotExceptionHandler_klass,com_sun_hotspot_c1x_HotSpotExceptionHandler, Pre) \ template(CiTargetMethod_klass, com_sun_cri_ci_CiTargetMethod, Pre) \ template(CiTargetMethod_Site_klass, com_sun_cri_ci_CiTargetMethod_Site, Pre) \ template(CiTargetMethod_Call_klass, com_sun_cri_ci_CiTargetMethod_Call, Pre) \ @@ -190,6 +191,7 @@ template(CiKind_klass, com_sun_cri_ci_CiKind, Pre) \ template(CiRuntimeCall_klass, com_sun_cri_ci_CiRuntimeCall, Pre) \ template(RiMethod_klass, com_sun_cri_ri_RiMethod, Pre) \ + template(RiExceptionHandler_klass, com_sun_cri_ri_RiExceptionHandler, Pre) \ /*end*/ diff -r 695451afc619 -r abc670a709dc src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Thu Aug 19 14:34:52 2010 -0700 +++ b/src/share/vm/classfile/vmSymbols.hpp Tue Aug 31 22:13:30 2010 -0700 @@ -246,14 +246,16 @@ \ /* support for C1X */ \ template(com_sun_hotspot_c1x_VMExits, "com/sun/hotspot/c1x/VMExits") \ - template(com_sun_hotspot_c1x_HotSpotMethod, "com/sun/hotspot/c1x/HotSpotMethod") \ + template(com_sun_hotspot_c1x_HotSpotMethodResolved, "com/sun/hotspot/c1x/HotSpotMethodResolved") \ template(com_sun_hotspot_c1x_HotSpotTargetMethod, "com/sun/hotspot/c1x/HotSpotTargetMethod") \ template(com_sun_hotspot_c1x_HotSpotTypeResolved, "com/sun/hotspot/c1x/HotSpotTypeResolved") \ + template(com_sun_hotspot_c1x_HotSpotExceptionHandler,"com/sun/hotspot/c1x/HotSpotExceptionHandler") \ template(com_sun_hotspot_c1x_Compiler, "com/sun/hotspot/c1x/Compiler") \ template(com_sun_cri_ri_RiMethod, "com/sun/cri/ri/RiMethod") \ template(com_sun_cri_ri_RiField, "com/sun/cri/ri/RiField") \ template(com_sun_cri_ri_RiType, "com/sun/cri/ri/RiType") \ template(com_sun_cri_ri_RiConstantPool, "com/sun/cri/ri/RiConstantPool") \ + template(com_sun_cri_ri_RiExceptionHandler, "com/sun/cri/ri/RiExceptionHandler") \ template(com_sun_cri_ci_CiTargetMethod, "com/sun/cri/ci/CiTargetMethod") \ template(com_sun_cri_ci_CiTargetMethod_Site, "com/sun/cri/ci/CiTargetMethod$Site") \ template(com_sun_cri_ci_CiTargetMethod_Call, "com/sun/cri/ci/CiTargetMethod$Call") \ @@ -271,8 +273,10 @@ template(com_sun_cri_ci_CiRuntimeCall, "com/sun/cri/ci/CiRuntimeCall") \ template(compileMethod_name, "compileMethod") \ template(compileMethod_signature, "(JLjava/lang/String;I)V") \ - template(createRiMethod_name, "createRiMethod") \ - template(createRiMethod_signature, "(JLjava/lang/String;)Lcom/sun/cri/ri/RiMethod;") \ + template(createRiMethodResolved_name, "createRiMethodResolved") \ + template(createRiMethodResolved_signature, "(JLjava/lang/String;)Lcom/sun/cri/ri/RiMethod;") \ + template(createRiMethodUnresolved_name, "createRiMethodUnresolved") \ + template(createRiMethodUnresolved_signature, "(Ljava/lang/String;Ljava/lang/String;Lcom/sun/cri/ri/RiType;)Lcom/sun/cri/ri/RiMethod;") \ template(createRiSignature_name, "createRiSignature") \ template(createRiSignature_signature, "(Ljava/lang/String;)Lcom/sun/cri/ri/RiSignature;") \ template(createRiField_name, "createRiField") \ diff -r 695451afc619 -r abc670a709dc src/share/vm/code/nmethod.cpp --- a/src/share/vm/code/nmethod.cpp Thu Aug 19 14:34:52 2010 -0700 +++ b/src/share/vm/code/nmethod.cpp Tue Aug 31 22:13:30 2010 -0700 @@ -796,9 +796,16 @@ _stub_offset = instructions_offset() + code_buffer->total_offset_of(code_buffer->stubs()->start()); // Exception handler and deopt handler are in the stub section - _exception_offset = _stub_offset + offsets->value(CodeOffsets::Exceptions); - _deoptimize_offset = _stub_offset + offsets->value(CodeOffsets::Deopt); - _deoptimize_mh_offset = _stub_offset + offsets->value(CodeOffsets::DeoptMH); + if (UseC1X) { + // c1x produces no stub section + _exception_offset = instructions_offset() + offsets->value(CodeOffsets::Exceptions); + _deoptimize_offset = instructions_offset() + offsets->value(CodeOffsets::Deopt); + _deoptimize_mh_offset = instructions_offset() + offsets->value(CodeOffsets::DeoptMH); + } else { + _exception_offset = _stub_offset + offsets->value(CodeOffsets::Exceptions); + _deoptimize_offset = _stub_offset + offsets->value(CodeOffsets::Deopt); + _deoptimize_mh_offset = _stub_offset + offsets->value(CodeOffsets::DeoptMH); + } if (offsets->value(CodeOffsets::UnwindHandler) != -1) { _unwind_handler_offset = instructions_offset() + offsets->value(CodeOffsets::UnwindHandler); } else { @@ -2442,6 +2449,7 @@ if (block_begin == entry_point()) stream->print_cr("[Entry Point]"); if (block_begin == verified_entry_point()) stream->print_cr("[Verified Entry Point]"); if (block_begin == exception_begin()) stream->print_cr("[Exception Handler]"); + if (block_begin == unwind_handler_begin()) stream->print_cr("[Unwind Handler]"); if (block_begin == stub_begin()) stream->print_cr("[Stub Code]"); if (block_begin == deopt_handler_begin()) stream->print_cr("[Deopt Handler Code]"); if (block_begin == deopt_mh_handler_begin()) stream->print_cr("[Deopt MH Handler Code]"); diff -r 695451afc619 -r abc670a709dc src/share/vm/runtime/sharedRuntime.cpp --- a/src/share/vm/runtime/sharedRuntime.cpp Thu Aug 19 14:34:52 2010 -0700 +++ b/src/share/vm/runtime/sharedRuntime.cpp Tue Aug 31 22:13:30 2010 -0700 @@ -611,7 +611,11 @@ #ifndef PRODUCT _implicit_null_throws++; #endif - target_pc = nm->continuation_for_implicit_exception(pc); + if (UseC1X) { + target_pc = Runtime1::entry_for(Runtime1::c1x_global_implicit_null_id); + } else { + target_pc = nm->continuation_for_implicit_exception(pc); + } // If there's an unexpected fault, target_pc might be NULL, // in which case we want to fall through into the normal // error handling code. @@ -627,7 +631,11 @@ #ifndef PRODUCT _implicit_div0_throws++; #endif - target_pc = nm->continuation_for_implicit_exception(pc); + if (UseC1X) { + target_pc = Runtime1::entry_for(Runtime1::c1x_throw_div0_exception_id); + } else { + target_pc = nm->continuation_for_implicit_exception(pc); + } // If there's an unexpected fault, target_pc might be NULL, // in which case we want to fall through into the normal // error handling code. diff -r 695451afc619 -r abc670a709dc src/share/vm/runtime/thread.hpp --- a/src/share/vm/runtime/thread.hpp Thu Aug 19 14:34:52 2010 -0700 +++ b/src/share/vm/runtime/thread.hpp Tue Aug 31 22:13:30 2010 -0700 @@ -763,6 +763,9 @@ private: + // c1x needs some place to put the dimensions + jint c1x_multinewarray_storage[256]; + StackGuardState _stack_guard_state; // Compiler exception handling (NOTE: The _exception_oop is *NOT* the same as _pending_exception. It is @@ -1191,6 +1194,7 @@ static ByteSize is_method_handle_return_offset() { return byte_offset_of(JavaThread, _is_method_handle_return); } static ByteSize stack_guard_state_offset() { return byte_offset_of(JavaThread, _stack_guard_state ); } static ByteSize suspend_flags_offset() { return byte_offset_of(JavaThread, _suspend_flags ); } + static ByteSize c1x_multinewarray_storage_offset() { return byte_offset_of(JavaThread, c1x_multinewarray_storage); } static ByteSize do_not_unlock_if_synchronized_offset() { return byte_offset_of(JavaThread, _do_not_unlock_if_synchronized); } static ByteSize should_post_on_exceptions_flag_offset() { diff -r 695451afc619 -r abc670a709dc src/share/vm/utilities/globalDefinitions.hpp --- a/src/share/vm/utilities/globalDefinitions.hpp Thu Aug 19 14:34:52 2010 -0700 +++ b/src/share/vm/utilities/globalDefinitions.hpp Tue Aug 31 22:13:30 2010 -0700 @@ -84,9 +84,9 @@ // log2_intptr(sizeof(class JavaThread)) - log2_intptr(64); // see os::set_memory_serialize_page() #ifdef _LP64 -const int SerializePageShiftCount = 4; +const int SerializePageShiftCount = 5; #else -const int SerializePageShiftCount = 3; +const int SerializePageShiftCount = 4; #endif // An opaque struct of heap-word width, so that HeapWord* can be a generic