changeset 1429:abc670a709dc

* -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)
author Lukas Stadler <lukas.stadler@oracle.com>
date Tue, 31 Aug 2010 22:13:30 -0700
parents 695451afc619
children 949ade3f2ff3
files .cproject .project c1x4hotspotsrc/HotSpotTest/src/jttTests.java c1x4hotspotsrc/HotSpotVM/.settings/org.eclipse.jdt.core.prefs c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/Compiler.java c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotExceptionHandler.java c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotMethod.java c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotMethodResolved.java c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotMethodUnresolved.java c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotRegisterConfig.java c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTargetMethod.java c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTypePrimitive.java c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTypeResolved.java c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTypeUnresolved.java c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotVMConfig.java c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMEntries.java c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMEntriesNative.java c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExits.java c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExitsNative.java c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/logging/Logger.java src/cpu/x86/vm/c1_Runtime1_x86.cpp src/share/vm/c1/c1_Runtime1.cpp src/share/vm/c1/c1_Runtime1.hpp src/share/vm/c1x/c1x_CodeInstaller.cpp src/share/vm/c1x/c1x_CodeInstaller.hpp src/share/vm/c1x/c1x_Compiler.cpp src/share/vm/c1x/c1x_Compiler.hpp src/share/vm/c1x/c1x_TargetMethod.cpp src/share/vm/c1x/c1x_TargetMethod.hpp src/share/vm/c1x/c1x_VMEntries.cpp src/share/vm/c1x/c1x_VMExits.cpp src/share/vm/c1x/c1x_VMExits.hpp src/share/vm/c1x/c1x_VmIds.hpp src/share/vm/classfile/systemDictionary.hpp src/share/vm/classfile/vmSymbols.hpp src/share/vm/code/nmethod.cpp src/share/vm/runtime/sharedRuntime.cpp src/share/vm/runtime/thread.hpp src/share/vm/utilities/globalDefinitions.hpp
diffstat 40 files changed, 1982 insertions(+), 760 deletions(-) [+]
line wrap: on
line diff
--- a/.cproject	Thu Aug 19 14:34:52 2010 -0700
+++ b/.cproject	Tue Aug 31 22:13:30 2010 -0700
@@ -23,7 +23,7 @@
 							<builder arguments="${workspace_loc:/c1x4hotspot}/domake" autoBuildTarget="jvmg1" buildPath="${workspace_loc:/c1x4hotspot}/make" cleanBuildTarget="clean" command="bash" enableAutoBuild="true" enableCleanBuild="false" enabledIncrementalBuild="true" id="cdt.managedbuild.target.gnu.builder.base.81453037" incrementalBuildTarget="jvmg1" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelizationNumber="1" superClass="cdt.managedbuild.target.gnu.builder.base">
 								<outputEntries>
 									<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="outputPath" name="make"/>
-									<entry flags="VALUE_WORKSPACE_PATH" kind="outputPath" name="build/linux/linux_amd64_compiler1/jvmg"/>
+									<entry excluding="libjvm*.so" flags="VALUE_WORKSPACE_PATH" kind="outputPath" name="build/linux/linux_amd64_compiler1/jvmg"/>
 								</outputEntries>
 							</builder>
 							<tool id="cdt.managedbuild.tool.gnu.archiver.base.1094883386" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
--- a/.project	Thu Aug 19 14:34:52 2010 -0700
+++ b/.project	Tue Aug 31 22:13:30 2010 -0700
@@ -88,7 +88,7 @@
 		<link>
 			<name>client</name>
 			<type>2</type>
-			<location>/home/ls/source/jre1.7.0/lib/amd64/client</location>
+			<locationURI>PARENT-1-PROJECT_LOC/jre1.7.0/lib/amd64/client</locationURI>
 		</link>
 	</linkedResources>
 </projectDescription>
--- 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();
--- 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
--- 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() {
--- /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;
+    }
+
+}
--- 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 {
+
+}
--- /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 "<clinit>".equals(name);
+    }
+
+    @Override
+    public boolean isConstructor() {
+        return "<init>".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 + ">";
+    }
+
+}
--- /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 "<clinit>".equals(name);
+    }
+
+    @Override
+    public boolean isConstructor() {
+        return "<init>".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);
+    }
+
+}
--- 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};
     }
 
--- 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));
     }
 
--- 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;
     }
 
--- 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;
     }
 
--- 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
--- 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;
--- 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<XirTemplate> newInstanceTemplates = new OndemandTemplates<XirTemplate>() {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, int size) {
+            return buildNewInstance(asm, size);
+        }
+    };
+
+    private final OndemandTemplates<XirPair> multiNewArrayTemplate = new OndemandTemplates<HotSpotXirGenerator.XirPair>() {
+
+        @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<T> {
+
+        private ConcurrentHashMap<Integer, T> templates = new ConcurrentHashMap<Integer, T>();
+
+        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;
+        }
+    }
 }
--- 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
--- 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);
+
 }
--- 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);
 
--- 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
--- 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<Boolean> openStack = new LinkedList<Boolean>();
     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) {
--- 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);
--- 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/
--- 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);
 
--- 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<methodOop>(HotSpotMethod::vmId(_hotspot_method));
+  methodOop method = VmIds::get<methodOop>(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<intptr_t>* bcis = new GrowableArray<intptr_t>(num_handlers);
+  GrowableArray<intptr_t>* scope_depths = new GrowableArray<intptr_t>(num_handlers);
+  GrowableArray<intptr_t>* pcos = new GrowableArray<intptr_t>(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<methodOop>(HotSpotMethod::vmId(hotspot_method));
+  assert(hotspot_method != NULL && hotspot_method->is_a(HotSpotMethodResolved::klass()), "unexpected hotspot method");
+  methodOop method = VmIds::get<methodOop>(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<methodOop>(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<methodOop>(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<klassOop>(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<oop>(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 @@
       }
     }
   }*/
-}
 
--- 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();
+
 };
--- 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<klassOop>(klass), VmIds::toString<Handle>(klass->klass_part()->name(), THREAD), THREAD);
+    KlassHandle klass = (klassOop)type->get_oop();
+    Handle name = VmIds::toString<Handle>(klass->name(), THREAD);
+    return createHotSpotTypeResolved(klass, name, CHECK_NULL);
   } else {
     symbolOop name = ((ciKlass *)type)->name()->get_symbolOop();
     return VMExits::createRiTypeUnresolved(VmIds::toString<Handle>(name, THREAD), VmIds::add<klassOop>(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;
+}
+
+
+
--- 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
 
 
 
--- 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)
 
 
 
--- 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
--- 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<methodOop>(vmId)->method_holder();
-  jlong klassVmId = VmIds::add<klassOop>(klass);
-  Handle name = VmIds::toString<Handle>(klass->klass_part()->name(), CHECK_NULL);
-  oop holder = VMExits::createRiType(klassVmId, name, THREAD);
+  KlassHandle klass = VmIds::get<methodOop>(vmId)->method_holder();
+  Handle name = VmIds::toString<Handle>(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<methodOop>(vmId);
+  method->constMethod()->exception_table();
   return VmIds::toString<jstring>(method->signature(), THREAD);
 }
 
@@ -70,8 +70,45 @@
   return VmIds::get<methodOop>(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<methodOop>(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; i<handler_count; i++) {
+    // exception handlers are stored as four integers: start bci, end bci, handler bci, catch class constant pool index
+    int base = i * 4;
+    Handle entry = instanceKlass::cast(HotSpotExceptionHandler::klass())->allocate_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<klassOop>(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<oop>(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<oop>(obj), CHECK_0);
+    result = VMExits::createCiConstantObject(VmIds::add<oop>(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<constantPoolOop>(vmId);
+  constantPoolHandle cp = VmIds::get<constantPoolOop>(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<Handle>(method->name(), CHECK_NULL);
-  return JNIHandles::make_local(THREAD, VMExits::createRiMethod(VmIds::add<methodOop>(method), name, THREAD));
+  if (cimethod->is_loaded()) {
+    methodOop method = (methodOop)cimethod->get_oop();
+    Handle name = VmIds::toString<Handle>(method->name(), CHECK_NULL);
+    return JNIHandles::make_local(THREAD, VMExits::createRiMethodResolved(VmIds::add<methodOop>(method), name, THREAD));
+  } else {
+    Handle name = VmIds::toString<Handle>((symbolOop)cimethod->name()->get_oop(), CHECK_NULL);
+    Handle signature = VmIds::toString<Handle>((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<constantPoolOop>(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<klassOop>(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<klassOop>(vmId)->klass_part()->oop_is_instance();
+  klassOop klass = VmIds::get<klassOop>(vmId);
+  methodOop method = klass->klass_part()->lookup_method(VmIds::toSymbol(name), VmIds::toSymbol(signature));
+  return JNIHandles::make_local(THREAD, VMExits::createRiMethodResolved(VmIds::add<methodOop>(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<klassOop>(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<klassOop>(vmId);
+  klassOop otherKlass = VmIds::get<klassOop>(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<klassOop>(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<basicTypeCount; i++) {
@@ -327,10 +390,12 @@
 #define SIGNATURE       "Lcom/sun/cri/ri/RiSignature;"
 #define FIELD           "Lcom/sun/cri/ri/RiField;"
 #define CONSTANT_POOL   "Lcom/sun/cri/ri/RiConstantPool;"
+#define EXCEPTION_HANDLERS "[Lcom/sun/cri/ri/RiExceptionHandler;"
 #define TARGET_METHOD   "Lcom/sun/hotspot/c1x/HotSpotTargetMethod;"
 #define CONFIG          "Lcom/sun/hotspot/c1x/HotSpotVMConfig;"
 #define HS_METHOD       "Lcom/sun/hotspot/c1x/HotSpotMethod;"
 #define CI_CONSTANT     "Lcom/sun/cri/ci/CiConstant;"
+#define CI_KIND         "Lcom/sun/cri/ci/CiKind;"
 #define STRING          "Ljava/lang/String;"
 #define OBJECT          "Ljava/lang/Object;"
 
@@ -341,17 +406,17 @@
   {CC"RiMethod_holder",                 CC"("PROXY")"TYPE,                  FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1holder)},
   {CC"RiMethod_signature",              CC"("PROXY")"STRING,                FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1signature)},
   {CC"RiMethod_accessFlags",            CC"("PROXY")I",                     FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1accessFlags)},
+  {CC"RiMethod_exceptionHandlers",      CC"("PROXY")"EXCEPTION_HANDLERS,    FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiMethod_1exceptionHandlers)},
   {CC"RiSignature_lookupType",          CC"("STRING PROXY")"TYPE,           FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiSignature_1lookupType)},
-  {CC"RiConstantPool_lookupConstant",   CC"("PROXY"I)"CI_CONSTANT,          FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupConstant)},
+  {CC"RiConstantPool_lookupConstant",   CC"("PROXY"I)"OBJECT,               FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupConstant)},
   {CC"RiConstantPool_lookupMethod",     CC"("PROXY"IB)"METHOD,              FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupMethod)},
   {CC"RiConstantPool_lookupSignature",  CC"("PROXY"I)"SIGNATURE,            FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupSignature)},
   {CC"RiConstantPool_lookupType",       CC"("PROXY"I)"TYPE,                 FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupType)},
   {CC"RiConstantPool_lookupField",      CC"("PROXY"I)"FIELD,                FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiConstantPool_1lookupField)},
   {CC"RiType_constantPool",             CC"("PROXY")"CONSTANT_POOL,         FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_1constantPool)},
-  {CC"RiType_isArrayClass",             CC"("PROXY")Z",                     FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_1isArrayClass)},
-  {CC"RiType_isInstanceClass",          CC"("PROXY")Z",                     FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_1isInstanceClass)},
-  {CC"RiType_isInterface",              CC"("PROXY")Z",                     FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_1isInterface)},
-  {CC"RiType_instanceSize",             CC"("PROXY")J",                     FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_1instanceSize)},
+  {CC"RiType_resolveMethodImpl",        CC"("PROXY STRING STRING")"METHOD,  FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_3resolveMethodImpl)},
+  {CC"RiType_isSubtypeOf",              CC"("PROXY TYPE")Z",                FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_RiType_2isSubtypeOf)},
+  {CC"getPrimitiveArrayType",           CC"("CI_KIND")"TYPE,                FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_getPrimitiveArrayType)},
   {CC"getConfiguration",                CC"()"CONFIG,                       FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_getConfiguration)},
   {CC"installMethod",                   CC"("TARGET_METHOD")V",             FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_installMethod)},
   {CC"installStub",                     CC"("TARGET_METHOD")"PROXY,         FN_PTR(Java_com_sun_hotspot_c1x_VMEntries_installStub)}
--- a/src/share/vm/c1x/c1x_VMExits.cpp	Thu Aug 19 14:34:52 2010 -0700
+++ b/src/share/vm/c1x/c1x_VMExits.cpp	Tue Aug 31 22:13:30 2010 -0700
@@ -75,15 +75,28 @@
   _vmExitsObject = Handle();
 }
 
-oop VMExits::createRiMethod(jlong vmId, Handle name, TRAPS) {
+oop VMExits::createRiMethodResolved(jlong vmId, Handle name, TRAPS) {
   assert(!name.is_null(), "just checking");
   JavaValue result(T_OBJECT);
   JavaCallArguments args;
   args.push_oop(instance());
   args.push_long(vmId);
   args.push_oop(name);
-  JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createRiMethod_name(), vmSymbols::createRiMethod_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createRiMethod");
+  JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createRiMethodResolved_name(), vmSymbols::createRiMethodResolved_signature(), &args, THREAD);
+  check_pending_exception("Error while calling createRiMethodResolved");
+  return (oop)result.get_jobject();
+}
+
+oop VMExits::createRiMethodUnresolved(Handle name, Handle signature, Handle holder, TRAPS) {
+  assert(!name.is_null(), "just checking");
+  JavaValue result(T_OBJECT);
+  JavaCallArguments args;
+  args.push_oop(instance());
+  args.push_oop(name);
+  args.push_oop(signature);
+  args.push_oop(holder);
+  JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::createRiMethodUnresolved_name(), vmSymbols::createRiMethodUnresolved_signature(), &args, THREAD);
+  check_pending_exception("Error while calling createRiMethodUnresolved");
   return (oop)result.get_jobject();
 }
 
--- a/src/share/vm/c1x/c1x_VMExits.hpp	Thu Aug 19 14:34:52 2010 -0700
+++ b/src/share/vm/c1x/c1x_VMExits.hpp	Tue Aug 31 22:13:30 2010 -0700
@@ -34,23 +34,26 @@
 
 public:
 
-  // public abstract void compileMethod(HotSpotProxy method, String name, int entry_bci);
+  // public abstract void compileMethod(long vmId, String name, int entry_bci);
   static void compileMethod(jlong vmId, Handle name, int entry_bci);
 
-  // public abstract RiMethod createRiMethod(HotSpotProxy method, String name);
-  static oop createRiMethod(jlong vmId, Handle name, TRAPS);
+  // public abstract RiMethod createRiMethodResolved(long vmId, String name);
+  static oop createRiMethodResolved(jlong vmId, Handle name, TRAPS);
+
+  // public abstract RiMethod createRiMethodUnresolved(String name, String signature, RiType holder);
+  static oop createRiMethodUnresolved(Handle name, Handle signature, Handle holder, TRAPS);
 
   // public abstract RiField createRiField(RiType holder, String name, RiType type, int offset);
   static oop createRiField(Handle holder, Handle name, Handle type, int index, TRAPS);
 
-  // public abstract RiType createRiType(HotSpotProxy klassOop, String name);
+  // public abstract RiType createRiType(long vmId, String name);
   static oop createRiType(jlong vmId, Handle name, TRAPS);
 
-  // public abstract RiConstantPool createRiConstantPool(HotSpotProxy constantPool);
-  static oop createRiConstantPool(jlong vmId, TRAPS);
+  // public abstract RiType createRiTypeUnresolved(String name, long accessingClassVmId);
+  static oop createRiTypeUnresolved(Handle name, jlong accessingClassVmId, TRAPS);
 
-  // public abstract RiType createRiTypeUnresolved(String name, HotSpotProxy accessingKlass);
-  static oop createRiTypeUnresolved(Handle name, jlong accessingClassVmId, TRAPS);
+  // public abstract RiConstantPool createRiConstantPool(long vmId);
+  static oop createRiConstantPool(jlong vmId, TRAPS);
 
   // public abstract RiType createRiTypePrimitive(int basicType);
   static oop createRiTypePrimitive(int basicType, TRAPS);
@@ -70,7 +73,7 @@
   // public abstract CiConstant createCiConstantDouble(double value);
   static oop createCiConstantDouble(jdouble value, TRAPS);
 
-  // public abstract CiConstant createCiConstantObject(HotSpotProxy value);
+  // public abstract CiConstant createCiConstantObject(long vmId);
   static oop createCiConstantObject(jlong vmId, TRAPS);
 };
 
--- a/src/share/vm/c1x/c1x_VmIds.hpp	Thu Aug 19 14:34:52 2010 -0700
+++ b/src/share/vm/c1x/c1x_VmIds.hpp	Tue Aug 31 22:13:30 2010 -0700
@@ -33,12 +33,12 @@
 public:
   // this enum needs to have the same values as the one in HotSpotProxy.java
   enum CompilerObjectType {
-    STUB           = 0x100000000000000l,
-    METHOD         = 0x200000000000000l,
-    CLASS          = 0x300000000000000l,
-    SYMBOL         = 0x400000000000000l,
-    CONSTANT_POOL  = 0x500000000000000l,
-    CONSTANT       = 0x600000000000000l,
+    STUB           = 0x100000000000000l,        // address
+    METHOD         = 0x200000000000000l,        // methodOop
+    CLASS          = 0x300000000000000l,        // klassOop
+    SYMBOL         = 0x400000000000000l,        // symbolOop
+    CONSTANT_POOL  = 0x500000000000000l,        // constantPoolOop
+    CONSTANT       = 0x600000000000000l,        // oop
     TYPE_MASK      = 0xf00000000000000l,
     DUMMY_CONSTANT = 0x6ffffffffffffffl
   };
@@ -46,35 +46,57 @@
   static void initializeObjects();
   static void cleanupLocalObjects();
 
+  // Adds a stub address, and returns the corresponding vmId (which is of type STUB)
   static jlong addStub(address stub);
+
+  // Adds an object, and returns the corresponding vmId (with the given type)
   static jlong add(Handle obj, CompilerObjectType type);
+
+  // Adds an object, and returns the corresponding vmId (the type of which is determined by the template parameter)
   template <typename T> 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 <typename T> static T get(jlong id);
 
+
+  // Helper function to convert a symbolOop to a java.lang.String object
   template <typename T> 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>(methodOop obj){
-  assert(obj != NULL && obj->is_method(), "trying to add NULL or mistyped object");
+  assert(obj != NULL, "trying to add NULL<methodOop>");
+  assert(obj->is_method(), "trying to add mistyped object");
   return add(Handle(obj), METHOD);
 }
 template <> inline jlong VmIds::add<klassOop>(klassOop obj) {
-  assert(obj != NULL && obj->is_klass(), "trying to add NULL or mistyped object");
+  assert(obj != NULL, "trying to add NULL<klassOop>");
+  assert(obj->is_klass(), "trying to add mistyped object");
   return add(Handle(obj), CLASS);
 }
 template <> inline jlong VmIds::add<symbolOop>(symbolOop obj) {
-  assert(obj != NULL && obj->is_symbol(), "trying to add NULL or mistyped object");
+  assert(obj != NULL, "trying to add NULL<symbolOop>");
+  assert(obj->is_symbol(), "trying to add mistyped object");
   return add(Handle(obj), SYMBOL);
 }
 template <> inline jlong VmIds::add<constantPoolOop>(constantPoolOop obj) {
-  assert(obj != NULL && obj->is_constantPool(), "trying to add NULL or mistyped object");
+  assert(obj != NULL, "trying to add NULL<constantPoolOop>");
+  assert(obj->is_constantPool(), "trying to add mistyped object");
   return add(Handle(obj), CONSTANT_POOL);
 }
 template <> inline jlong VmIds::add<oop>(oop obj) {
-  assert(obj != NULL && obj->is_oop(), "trying to add NULL or mistyped object");
+  assert(obj != NULL, "trying to add NULL<oop>");
+  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<Handle>(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));
+}
--- 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*/
 
--- 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")                                                  \
--- 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]");
--- 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.
--- 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() {
--- 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