8153439: do not install an empty SpeculationLog in an nmethod
authordnsimon
Thu, 07 Apr 2016 08:57:26 -1000
changeset 38027 8a5693d27400
parent 38026 c0cbc69330c1
child 38028 be8cc044b136
8153439: do not install an empty SpeculationLog in an nmethod Reviewed-by: iveresov, twisti
hotspot/.mx.jvmci/suite.py
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SpeculationLog.java
hotspot/test/compiler/jvmci/code/CodeInstallationTest.java
hotspot/test/compiler/jvmci/code/DataPatchTest.java
hotspot/test/compiler/jvmci/code/DebugInfoTest.java
hotspot/test/compiler/jvmci/code/InterpreterFrameSizeTest.java
hotspot/test/compiler/jvmci/code/SimpleCodeInstallationTest.java
hotspot/test/compiler/jvmci/code/SimpleDebugInfoTest.java
hotspot/test/compiler/jvmci/code/TestAssembler.java
hotspot/test/compiler/jvmci/code/VirtualObjectDebugInfoTest.java
hotspot/test/compiler/jvmci/code/amd64/AMD64TestAssembler.java
hotspot/test/compiler/jvmci/code/sparc/SPARCTestAssembler.java
hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/CodeInstallationTest.java
hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DataPatchTest.java
hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DebugInfoTest.java
hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/InterpreterFrameSizeTest.java
hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleCodeInstallationTest.java
hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java
hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/TestAssembler.java
hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInfoTest.java
hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/amd64/AMD64TestAssembler.java
hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/sparc/SPARCTestAssembler.java
--- a/hotspot/.mx.jvmci/suite.py	Thu Apr 07 18:27:50 2016 +0200
+++ b/hotspot/.mx.jvmci/suite.py	Thu Apr 07 08:57:26 2016 -1000
@@ -83,6 +83,21 @@
       "workingSets" : "API,JVMCI",
     },
 
+    "jdk.vm.ci.code.test" : {
+      "subDir" : "test/compiler/jvmci",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "mx:JUNIT",
+        "jdk.vm.ci.amd64",
+        "jdk.vm.ci.sparc",
+        "jdk.vm.ci.code",
+        "jdk.vm.ci.hotspot",
+      ],
+      "checkstyle" : "jdk.vm.ci.services",
+      "javaCompliance" : "1.8",
+      "workingSets" : "API,JVMCI",
+    },
+
     "jdk.vm.ci.runtime" : {
       "subDir" : "src/jdk.vm.ci/share/classes",
       "sourceDirs" : ["src"],
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java	Thu Apr 07 18:27:50 2016 +0200
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java	Thu Apr 07 08:57:26 2016 -1000
@@ -120,7 +120,9 @@
             resultInstalledCode = installedCode;
         }
 
-        int result = runtime.getCompilerToVM().installCode(target, (HotSpotCompiledCode) compiledCode, resultInstalledCode, (HotSpotSpeculationLog) log);
+        HotSpotSpeculationLog speculationLog = (log != null && log.hasSpeculations()) ? (HotSpotSpeculationLog) log : null;
+
+        int result = runtime.getCompilerToVM().installCode(target, (HotSpotCompiledCode) compiledCode, resultInstalledCode, speculationLog);
         if (result != config.codeInstallResultOk) {
             String resultDesc = config.getCodeInstallResultDescription(result);
             if (compiledCode instanceof HotSpotCompiledNmethod) {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java	Thu Apr 07 18:27:50 2016 +0200
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java	Thu Apr 07 08:57:26 2016 -1000
@@ -38,7 +38,7 @@
     /** All speculations that have been a deoptimization reason. */
     private Set<SpeculationReason> failedSpeculations;
 
-    /** Strong references to all reasons embededded in the current nmethod. */
+    /** Strong references to all reasons embedded in the current nmethod. */
     private volatile Collection<SpeculationReason> speculations;
 
     @Override
@@ -81,4 +81,9 @@
 
         return HotSpotObjectConstantImpl.forObject(reason);
     }
+
+    @Override
+    public synchronized boolean hasSpeculations() {
+        return speculations != null && !speculations.isEmpty();
+    }
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SpeculationLog.java	Thu Apr 07 18:27:50 2016 +0200
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SpeculationLog.java	Thu Apr 07 08:57:26 2016 -1000
@@ -56,4 +56,11 @@
      *         argument to the deoptimization function.
      */
     JavaConstant speculate(SpeculationReason reason);
+
+    /**
+     * Returns if this log has speculations.
+     *
+     * @return true if there are speculations, false otherwise
+     */
+    boolean hasSpeculations();
 }
--- a/hotspot/test/compiler/jvmci/code/CodeInstallationTest.java	Thu Apr 07 18:27:50 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package compiler.jvmci.code;
-
-import java.lang.reflect.Method;
-
-import jdk.vm.ci.amd64.AMD64;
-import jdk.vm.ci.code.Architecture;
-import jdk.vm.ci.code.CodeCacheProvider;
-import jdk.vm.ci.code.InstalledCode;
-import jdk.vm.ci.code.TargetDescription;
-import jdk.vm.ci.hotspot.HotSpotCompiledCode;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
-import jdk.vm.ci.meta.ConstantReflectionProvider;
-import jdk.vm.ci.meta.MetaAccessProvider;
-import jdk.vm.ci.runtime.JVMCI;
-import jdk.vm.ci.runtime.JVMCIBackend;
-import jdk.vm.ci.sparc.SPARC;
-
-import org.junit.Assert;
-
-import compiler.jvmci.code.amd64.AMD64TestAssembler;
-import compiler.jvmci.code.sparc.SPARCTestAssembler;
-
-/**
- * Base class for code installation tests.
- */
-public class CodeInstallationTest {
-
-    protected final MetaAccessProvider metaAccess;
-    protected final CodeCacheProvider codeCache;
-    protected final TargetDescription target;
-    protected final ConstantReflectionProvider constantReflection;
-
-    public CodeInstallationTest() {
-        JVMCIBackend backend = JVMCI.getRuntime().getHostJVMCIBackend();
-        metaAccess = backend.getMetaAccess();
-        codeCache = backend.getCodeCache();
-        target = backend.getTarget();
-        constantReflection = backend.getConstantReflection();
-    }
-
-    protected interface TestCompiler {
-
-        void compile(TestAssembler asm);
-    }
-
-    private TestAssembler createAssembler() {
-        Architecture arch = codeCache.getTarget().arch;
-        if (arch instanceof AMD64) {
-            return new AMD64TestAssembler(codeCache);
-        } else if (arch instanceof SPARC) {
-            return new SPARCTestAssembler(codeCache);
-        } else {
-            Assert.fail("unsupported architecture");
-            return null;
-        }
-    }
-
-    protected Method getMethod(String name, Class<?>... args) {
-        try {
-            return getClass().getMethod(name, args);
-        } catch (NoSuchMethodException e) {
-            Assert.fail("method not found");
-            return null;
-        }
-    }
-
-    protected void test(TestCompiler compiler, Method method, Object... args) {
-        HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(method);
-        TestAssembler asm = createAssembler();
-
-        asm.emitPrologue();
-        compiler.compile(asm);
-        asm.emitEpilogue();
-
-        HotSpotCompiledCode code = asm.finish(resolvedMethod);
-        InstalledCode installed = codeCache.addCode(resolvedMethod, code, null, null);
-
-        try {
-            Object expected = method.invoke(null, args);
-            Object actual = installed.executeVarargs(args);
-            Assert.assertEquals(expected, actual);
-        } catch (Exception e) {
-            e.printStackTrace();
-            Assert.fail(e.toString());
-        }
-    }
-}
--- a/hotspot/test/compiler/jvmci/code/DataPatchTest.java	Thu Apr 07 18:27:50 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
- * @library /
- * @modules jdk.vm.ci/jdk.vm.ci.hotspot
- *          jdk.vm.ci/jdk.vm.ci.meta
- *          jdk.vm.ci/jdk.vm.ci.code
- *          jdk.vm.ci/jdk.vm.ci.code.site
- *          jdk.vm.ci/jdk.vm.ci.runtime
- *          jdk.vm.ci/jdk.vm.ci.amd64
- *          jdk.vm.ci/jdk.vm.ci.sparc
- * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI compiler.jvmci.code.DataPatchTest
- */
-
-package compiler.jvmci.code;
-
-import jdk.vm.ci.code.Register;
-import jdk.vm.ci.code.site.DataSectionReference;
-import jdk.vm.ci.hotspot.HotSpotConstant;
-import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider;
-import jdk.vm.ci.hotspot.HotSpotSymbol;
-import jdk.vm.ci.hotspot.HotSpotVMConfig;
-import jdk.vm.ci.meta.ResolvedJavaType;
-
-import org.junit.Assume;
-import org.junit.Test;
-
-/**
- * Test code installation with data patches.
- */
-public class DataPatchTest extends CodeInstallationTest {
-
-    public static Class<?> getConstClass() {
-        return DataPatchTest.class;
-    }
-
-    private void test(TestCompiler compiler) {
-        test(compiler, getMethod("getConstClass"));
-    }
-
-    @Test
-    public void testInlineObject() {
-        test(asm -> {
-            ResolvedJavaType type = metaAccess.lookupJavaType(getConstClass());
-            HotSpotConstant c = (HotSpotConstant) constantReflection.asJavaClass(type);
-            Register ret = asm.emitLoadPointer(c);
-            asm.emitPointerRet(ret);
-        });
-    }
-
-    @Test
-    public void testInlineNarrowObject() {
-        Assume.assumeTrue(HotSpotVMConfig.config().useCompressedOops);
-        test(asm -> {
-            ResolvedJavaType type = metaAccess.lookupJavaType(getConstClass());
-            HotSpotConstant c = (HotSpotConstant) constantReflection.asJavaClass(type);
-            Register compressed = asm.emitLoadPointer((HotSpotConstant) c.compress());
-            Register ret = asm.emitUncompressPointer(compressed, HotSpotVMConfig.config().narrowOopBase, HotSpotVMConfig.config().narrowOopShift);
-            asm.emitPointerRet(ret);
-        });
-    }
-
-    @Test
-    public void testDataSectionReference() {
-        test(asm -> {
-            ResolvedJavaType type = metaAccess.lookupJavaType(getConstClass());
-            HotSpotConstant c = (HotSpotConstant) constantReflection.asJavaClass(type);
-            DataSectionReference ref = asm.emitDataItem(c);
-            Register ret = asm.emitLoadPointer(ref);
-            asm.emitPointerRet(ret);
-        });
-    }
-
-    @Test
-    public void testNarrowDataSectionReference() {
-        Assume.assumeTrue(HotSpotVMConfig.config().useCompressedOops);
-        test(asm -> {
-            ResolvedJavaType type = metaAccess.lookupJavaType(getConstClass());
-            HotSpotConstant c = (HotSpotConstant) constantReflection.asJavaClass(type);
-            HotSpotConstant cCompressed = (HotSpotConstant) c.compress();
-            DataSectionReference ref = asm.emitDataItem(cCompressed);
-            Register compressed = asm.emitLoadNarrowPointer(ref);
-            Register ret = asm.emitUncompressPointer(compressed, HotSpotVMConfig.config().narrowOopBase, HotSpotVMConfig.config().narrowOopShift);
-            asm.emitPointerRet(ret);
-        });
-    }
-
-    @Test
-    public void testInlineMetadata() {
-        test(asm -> {
-            ResolvedJavaType type = metaAccess.lookupJavaType(getConstClass());
-            Register klass = asm.emitLoadPointer((HotSpotConstant) constantReflection.asObjectHub(type));
-            Register ret = asm.emitLoadPointer(klass, HotSpotVMConfig.config().classMirrorOffset);
-            asm.emitPointerRet(ret);
-        });
-    }
-
-    @Test
-    public void testInlineNarrowMetadata() {
-        Assume.assumeTrue(HotSpotVMConfig.config().useCompressedClassPointers);
-        test(asm -> {
-            ResolvedJavaType type = metaAccess.lookupJavaType(getConstClass());
-            HotSpotConstant hub = (HotSpotConstant) constantReflection.asObjectHub(type);
-            Register narrowKlass = asm.emitLoadPointer((HotSpotConstant) hub.compress());
-            Register klass = asm.emitUncompressPointer(narrowKlass, HotSpotVMConfig.config().narrowKlassBase, HotSpotVMConfig.config().narrowKlassShift);
-            Register ret = asm.emitLoadPointer(klass, HotSpotVMConfig.config().classMirrorOffset);
-            asm.emitPointerRet(ret);
-        });
-    }
-
-    @Test
-    public void testMetadataInDataSection() {
-        test(asm -> {
-            ResolvedJavaType type = metaAccess.lookupJavaType(getConstClass());
-            HotSpotConstant hub = (HotSpotConstant) constantReflection.asObjectHub(type);
-            DataSectionReference ref = asm.emitDataItem(hub);
-            Register klass = asm.emitLoadPointer(ref);
-            Register ret = asm.emitLoadPointer(klass, HotSpotVMConfig.config().classMirrorOffset);
-            asm.emitPointerRet(ret);
-        });
-    }
-
-    @Test
-    public void testNarrowMetadataInDataSection() {
-        Assume.assumeTrue(HotSpotVMConfig.config().useCompressedClassPointers);
-        test(asm -> {
-            ResolvedJavaType type = metaAccess.lookupJavaType(getConstClass());
-            HotSpotConstant hub = (HotSpotConstant) constantReflection.asObjectHub(type);
-            HotSpotConstant narrowHub = (HotSpotConstant) hub.compress();
-            DataSectionReference ref = asm.emitDataItem(narrowHub);
-            Register narrowKlass = asm.emitLoadNarrowPointer(ref);
-            Register klass = asm.emitUncompressPointer(narrowKlass, HotSpotVMConfig.config().narrowKlassBase, HotSpotVMConfig.config().narrowKlassShift);
-            Register ret = asm.emitLoadPointer(klass, HotSpotVMConfig.config().classMirrorOffset);
-            asm.emitPointerRet(ret);
-        });
-    }
-
-
-    public static long getConstSymbol(HotSpotMetaAccessProvider meta) {
-        HotSpotSymbol symbol = meta.lookupSymbol("java/lang/Object");
-        return symbol.getMetaspacePointer();
-    }
-
-    private void testSymbol(TestCompiler compiler) {
-        test(compiler, getMethod("getConstSymbol", HotSpotMetaAccessProvider.class), (HotSpotMetaAccessProvider) metaAccess);
-    }
-
-    @Test
-    public void testInlineSymbol() {
-        testSymbol(asm -> {
-            HotSpotSymbol symbol = ((HotSpotMetaAccessProvider) metaAccess).lookupSymbol("java/lang/Object");
-            Register ret = asm.emitLoadPointer((HotSpotConstant) symbol.asConstant());
-            asm.emitPointerRet(ret);
-        });
-    }
-
-    @Test
-    public void testSymbolInDataSection() {
-        testSymbol(asm -> {
-            HotSpotSymbol symbol = ((HotSpotMetaAccessProvider) metaAccess).lookupSymbol("java/lang/Object");
-            DataSectionReference ref = asm.emitDataItem((HotSpotConstant) symbol.asConstant());
-            Register ret = asm.emitLoadPointer(ref);
-            asm.emitPointerRet(ret);
-        });
-    }
-}
--- a/hotspot/test/compiler/jvmci/code/DebugInfoTest.java	Thu Apr 07 18:27:50 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package compiler.jvmci.code;
-
-import java.lang.reflect.Method;
-
-import jdk.vm.ci.code.BytecodeFrame;
-import jdk.vm.ci.code.DebugInfo;
-import jdk.vm.ci.code.Location;
-import jdk.vm.ci.code.VirtualObject;
-import jdk.vm.ci.hotspot.HotSpotReferenceMap;
-import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.JavaValue;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-
-/**
- * Test code installation with debug information.
- */
-public class DebugInfoTest extends CodeInstallationTest {
-
-    protected interface DebugInfoCompiler {
-
-        VirtualObject[] compile(TestAssembler asm, JavaValue[] frameValues);
-    }
-
-    protected void test(DebugInfoCompiler compiler, Method method, int bci, JavaKind... slotKinds) {
-        ResolvedJavaMethod resolvedMethod = metaAccess.lookupJavaMethod(method);
-
-        int numLocals = resolvedMethod.getMaxLocals();
-        int numStack = slotKinds.length - numLocals;
-        JavaValue[] values = new JavaValue[slotKinds.length];
-        test(asm -> {
-            VirtualObject[] vobjs = compiler.compile(asm, values);
-
-            BytecodeFrame frame = new BytecodeFrame(null, resolvedMethod, bci, false, false, values, slotKinds, numLocals, numStack, 0);
-            DebugInfo info = new DebugInfo(frame, vobjs);
-            info.setReferenceMap(new HotSpotReferenceMap(new Location[0], new Location[0], new int[0], 8));
-
-            asm.emitTrap(info);
-        }, method);
-    }
-}
--- a/hotspot/test/compiler/jvmci/code/InterpreterFrameSizeTest.java	Thu Apr 07 18:27:50 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
- * @modules jdk.vm.ci/jdk.vm.ci.hotspot
- *          jdk.vm.ci/jdk.vm.ci.code
- *          jdk.vm.ci/jdk.vm.ci.code.site
- *          jdk.vm.ci/jdk.vm.ci.meta
- *          jdk.vm.ci/jdk.vm.ci.runtime
- *          jdk.vm.ci/jdk.vm.ci.common
- *          jdk.vm.ci/jdk.vm.ci.amd64
- *          jdk.vm.ci/jdk.vm.ci.sparc
- * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java amd64/AMD64TestAssembler.java sparc/SPARCTestAssembler.java
- * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI compiler.jvmci.code.InterpreterFrameSizeTest
- */
-
-package compiler.jvmci.code;
-
-import java.lang.reflect.Method;
-
-import jdk.vm.ci.code.BytecodeFrame;
-import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.JavaValue;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-
-import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-public class InterpreterFrameSizeTest extends CodeInstallationTest {
-
-    HotSpotCodeCacheProvider hotspotCodeCache() {
-        return (HotSpotCodeCacheProvider) codeCache;
-    }
-
-    @Test
-    public void testNull() {
-        try {
-            hotspotCodeCache().interpreterFrameSize(null);
-        } catch (NullPointerException npe) {
-            System.out.println("threw NPE as expected");
-            return;
-        }
-        Assert.fail("expected NullPointerException");
-    }
-
-    @Test
-    public void test() {
-        ResolvedJavaMethod resolvedMethod = metaAccess.lookupJavaMethod(getMethod("testNull"));
-
-        int bci = 0;
-        int numLocals = resolvedMethod.getMaxLocals();
-        int numStack = 0;
-        JavaValue[] values = new JavaValue[numLocals];
-        JavaKind[] slotKinds = new JavaKind[numLocals];
-        BytecodeFrame frame = new BytecodeFrame(null, resolvedMethod, bci, false, false, values, slotKinds, numLocals, numStack, 0);
-        int size = hotspotCodeCache().interpreterFrameSize(frame);
-        System.out.println("Frame size is " + size + " bytes");
-        if (size <= 0) {
-            Assert.fail("expected non-zero result");
-        }
-    }
-}
--- a/hotspot/test/compiler/jvmci/code/SimpleCodeInstallationTest.java	Thu Apr 07 18:27:50 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
- * @library /
- * @modules jdk.vm.ci/jdk.vm.ci.hotspot
- *          jdk.vm.ci/jdk.vm.ci.meta
- *          jdk.vm.ci/jdk.vm.ci.code
- *          jdk.vm.ci/jdk.vm.ci.code.site
- *          jdk.vm.ci/jdk.vm.ci.runtime
- *          jdk.vm.ci/jdk.vm.ci.amd64
- *          jdk.vm.ci/jdk.vm.ci.sparc
- * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI compiler.jvmci.code.SimpleCodeInstallationTest
- */
-
-package compiler.jvmci.code;
-
-import jdk.vm.ci.code.Register;
-
-import org.junit.Test;
-
-/**
- * Test simple code installation.
- */
-public class SimpleCodeInstallationTest extends CodeInstallationTest {
-
-    public static int add(int a, int b) {
-        return a + b;
-    }
-
-    private static void compileAdd(TestAssembler asm) {
-        Register arg0 = asm.emitIntArg0();
-        Register arg1 = asm.emitIntArg1();
-        Register ret = asm.emitIntAdd(arg0, arg1);
-        asm.emitIntRet(ret);
-    }
-
-    @Test
-    public void test() {
-        test(SimpleCodeInstallationTest::compileAdd, getMethod("add", int.class, int.class), 5, 7);
-    }
-}
--- a/hotspot/test/compiler/jvmci/code/SimpleDebugInfoTest.java	Thu Apr 07 18:27:50 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,285 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
- * @library /
- * @modules jdk.vm.ci/jdk.vm.ci.hotspot
- *          jdk.vm.ci/jdk.vm.ci.meta
- *          jdk.vm.ci/jdk.vm.ci.code
- *          jdk.vm.ci/jdk.vm.ci.code.site
- *          jdk.vm.ci/jdk.vm.ci.runtime
- *          jdk.vm.ci/jdk.vm.ci.amd64
- *          jdk.vm.ci/jdk.vm.ci.sparc
- * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI compiler.jvmci.code.SimpleDebugInfoTest
- */
-
-package compiler.jvmci.code;
-
-import jdk.vm.ci.code.Register;
-import jdk.vm.ci.hotspot.HotSpotConstant;
-import jdk.vm.ci.hotspot.HotSpotVMConfig;
-import jdk.vm.ci.meta.JavaConstant;
-import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.ResolvedJavaType;
-import jdk.vm.ci.meta.Value;
-
-import org.junit.Assume;
-import org.junit.Test;
-
-public class SimpleDebugInfoTest extends DebugInfoTest {
-
-    public static int intOnStack() {
-        return 42;
-    }
-
-    private void testIntOnStack(DebugInfoCompiler compiler) {
-        test(compiler, getMethod("intOnStack"), 2, JavaKind.Int);
-    }
-
-    public static int intInLocal() {
-        int local = 42;
-        return local;
-    }
-
-    public void testIntInLocal(DebugInfoCompiler compiler) {
-        test(compiler, getMethod("intInLocal"), 3, JavaKind.Int);
-    }
-
-    @Test
-    public void testConstInt() {
-        DebugInfoCompiler compiler = (asm, values) -> {
-            values[0] = JavaConstant.forInt(42);
-            return null;
-        };
-        testIntOnStack(compiler);
-        testIntInLocal(compiler);
-    }
-
-    @Test
-    public void testRegInt() {
-        DebugInfoCompiler compiler = (asm, values) -> {
-            Register reg = asm.emitLoadInt(42);
-            values[0] = reg.asValue(target.getLIRKind(JavaKind.Int));
-            return null;
-        };
-        testIntOnStack(compiler);
-        testIntInLocal(compiler);
-    }
-
-    @Test
-    public void testStackInt() {
-        DebugInfoCompiler compiler = (asm, values) -> {
-            Register reg = asm.emitLoadInt(42);
-            values[0] = asm.emitIntToStack(reg);
-            return null;
-        };
-        testIntOnStack(compiler);
-        testIntInLocal(compiler);
-    }
-
-
-    public static float floatOnStack() {
-        return 42.0f;
-    }
-
-    private void testFloatOnStack(DebugInfoCompiler compiler) {
-        test(compiler, getMethod("floatOnStack"), 2, JavaKind.Float);
-    }
-
-    public static float floatInLocal() {
-        float local = 42.0f;
-        return local;
-    }
-
-    private void testFloatInLocal(DebugInfoCompiler compiler) {
-        test(compiler, getMethod("floatInLocal"), 3, JavaKind.Float);
-    }
-
-    @Test
-    public void testConstFloat() {
-        DebugInfoCompiler compiler = (asm, values) -> {
-            values[0] = JavaConstant.forFloat(42.0f);
-            return null;
-        };
-        testFloatOnStack(compiler);
-        testFloatInLocal(compiler);
-    }
-
-    @Test
-    public void testRegFloat() {
-        DebugInfoCompiler compiler = (asm, values) -> {
-            Register reg = asm.emitLoadFloat(42.0f);
-            values[0] = reg.asValue(target.getLIRKind(JavaKind.Float));
-            return null;
-        };
-        testFloatOnStack(compiler);
-        testFloatInLocal(compiler);
-    }
-
-    @Test
-    public void testStackFloat() {
-        DebugInfoCompiler compiler = (asm, values) -> {
-            Register reg = asm.emitLoadFloat(42.0f);
-            values[0] = asm.emitFloatToStack(reg);
-            return null;
-        };
-        testFloatOnStack(compiler);
-        testFloatInLocal(compiler);
-    }
-
-
-    public static long longOnStack() {
-        return 42;
-    }
-
-    private void testLongOnStack(DebugInfoCompiler compiler) {
-        test(compiler, getMethod("longOnStack"), 3, JavaKind.Long, JavaKind.Illegal);
-    }
-
-    public static long longInLocal() {
-        long local = 42;
-        return local;
-    }
-
-    private void testLongInLocal(DebugInfoCompiler compiler) {
-        test(compiler, getMethod("longInLocal"), 4, JavaKind.Long, JavaKind.Illegal);
-    }
-
-    @Test
-    public void testConstLong() {
-        DebugInfoCompiler compiler = (asm, values) -> {
-            values[0] = JavaConstant.forLong(42);
-            values[1] = Value.ILLEGAL;
-            return null;
-        };
-        testLongOnStack(compiler);
-        testLongInLocal(compiler);
-    }
-
-    @Test
-    public void testRegLong() {
-        DebugInfoCompiler compiler = (asm, values) -> {
-            Register reg = asm.emitLoadLong(42);
-            values[0] = reg.asValue(target.getLIRKind(JavaKind.Long));
-            values[1] = Value.ILLEGAL;
-            return null;
-        };
-        testLongOnStack(compiler);
-        testLongInLocal(compiler);
-    }
-
-    @Test
-    public void testStackLong() {
-        DebugInfoCompiler compiler = (asm, values) -> {
-            Register reg = asm.emitLoadLong(42);
-            values[0] = asm.emitLongToStack(reg);
-            values[1] = Value.ILLEGAL;
-            return null;
-        };
-        testLongOnStack(compiler);
-        testLongInLocal(compiler);
-    }
-
-
-    public static Class<?> objectOnStack() {
-        return SimpleDebugInfoTest.class;
-    }
-
-    private void testObjectOnStack(DebugInfoCompiler compiler) {
-        test(compiler, getMethod("objectOnStack"), 2, JavaKind.Object);
-    }
-
-    public static Class<?> objectInLocal() {
-        Class<?> local = SimpleDebugInfoTest.class;
-        return local;
-    }
-
-    private void testObjectInLocal(DebugInfoCompiler compiler) {
-        test(compiler, getMethod("objectInLocal"), 3, JavaKind.Object);
-    }
-
-    @Test
-    public void testConstObject() {
-        ResolvedJavaType type = metaAccess.lookupJavaType(objectOnStack());
-        DebugInfoCompiler compiler = (asm, values) -> {
-            values[0] = constantReflection.asJavaClass(type);
-            return null;
-        };
-        testObjectOnStack(compiler);
-        testObjectInLocal(compiler);
-    }
-
-    @Test
-    public void testRegObject() {
-        ResolvedJavaType type = metaAccess.lookupJavaType(objectOnStack());
-        DebugInfoCompiler compiler = (asm, values) -> {
-            Register reg = asm.emitLoadPointer((HotSpotConstant) constantReflection.asJavaClass(type));
-            values[0] = reg.asValue(target.getLIRKind(JavaKind.Object));
-            return null;
-        };
-        testObjectOnStack(compiler);
-        testObjectInLocal(compiler);
-    }
-
-    @Test
-    public void testStackObject() {
-        ResolvedJavaType type = metaAccess.lookupJavaType(objectOnStack());
-        DebugInfoCompiler compiler = (asm, values) -> {
-            Register reg = asm.emitLoadPointer((HotSpotConstant) constantReflection.asJavaClass(type));
-            values[0] = asm.emitPointerToStack(reg);
-            return null;
-        };
-        testObjectOnStack(compiler);
-        testObjectInLocal(compiler);
-    }
-
-    @Test
-    public void testRegNarrowObject() {
-        Assume.assumeTrue(HotSpotVMConfig.config().useCompressedOops);
-        ResolvedJavaType type = metaAccess.lookupJavaType(objectOnStack());
-        DebugInfoCompiler compiler = (asm, values) -> {
-            HotSpotConstant wide = (HotSpotConstant) constantReflection.asJavaClass(type);
-            Register reg = asm.emitLoadPointer((HotSpotConstant) wide.compress());
-            values[0] = reg.asValue(asm.narrowOopKind);
-            return null;
-        };
-        testObjectOnStack(compiler);
-        testObjectInLocal(compiler);
-    }
-
-    @Test
-    public void testStackNarrowObject() {
-        Assume.assumeTrue(HotSpotVMConfig.config().useCompressedOops);
-        ResolvedJavaType type = metaAccess.lookupJavaType(objectOnStack());
-        DebugInfoCompiler compiler = (asm, values) -> {
-            HotSpotConstant wide = (HotSpotConstant) constantReflection.asJavaClass(type);
-            Register reg = asm.emitLoadPointer((HotSpotConstant) wide.compress());
-            values[0] = asm.emitNarrowPointerToStack(reg);
-            return null;
-        };
-        testObjectOnStack(compiler);
-        testObjectInLocal(compiler);
-    }
-}
--- a/hotspot/test/compiler/jvmci/code/TestAssembler.java	Thu Apr 07 18:27:50 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,333 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package compiler.jvmci.code;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-import jdk.vm.ci.code.CodeCacheProvider;
-import jdk.vm.ci.code.DebugInfo;
-import jdk.vm.ci.code.Register;
-import jdk.vm.ci.code.StackSlot;
-import jdk.vm.ci.code.site.Call;
-import jdk.vm.ci.code.site.ConstantReference;
-import jdk.vm.ci.code.site.DataPatch;
-import jdk.vm.ci.code.site.DataSectionReference;
-import jdk.vm.ci.code.site.Infopoint;
-import jdk.vm.ci.code.site.InfopointReason;
-import jdk.vm.ci.code.site.Mark;
-import jdk.vm.ci.code.site.Reference;
-import jdk.vm.ci.code.site.Site;
-import jdk.vm.ci.hotspot.HotSpotCompiledCode;
-import jdk.vm.ci.hotspot.HotSpotCompiledCode.Comment;
-import jdk.vm.ci.hotspot.HotSpotCompiledNmethod;
-import jdk.vm.ci.hotspot.HotSpotConstant;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
-import jdk.vm.ci.meta.Assumptions.Assumption;
-import jdk.vm.ci.meta.InvokeTarget;
-import jdk.vm.ci.meta.LIRKind;
-import jdk.vm.ci.meta.PlatformKind;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.vm.ci.meta.VMConstant;
-
-/**
- * Simple assembler used by the code installation tests.
- */
-public abstract class TestAssembler {
-
-    /**
-     * Emit the method prologue code (e.g. building the new stack frame).
-     */
-    public abstract void emitPrologue();
-
-    /**
-     * Emit the method epilogue code (e.g. the deopt handler).
-     */
-    public abstract void emitEpilogue();
-
-    /**
-     * Emit code to grow the stack frame.
-     *
-     * @param size the size in bytes that the stack should grow
-     */
-    public abstract void emitGrowStack(int size);
-
-    /**
-     * Get the register containing the first 32-bit integer argument.
-     */
-    public abstract Register emitIntArg0();
-
-    /**
-     * Get the register containing the second 32-bit integer argument.
-     */
-    public abstract Register emitIntArg1();
-
-    /**
-     * Emit code to add two 32-bit integer registers. May reuse one of the argument registers.
-     */
-    public abstract Register emitIntAdd(Register a, Register b);
-
-    /**
-     * Emit code to load a constant 32-bit integer to a register.
-     */
-    public abstract Register emitLoadInt(int value);
-
-    /**
-     * Emit code to load a constant 64-bit integer to a register.
-     */
-    public abstract Register emitLoadLong(long value);
-
-    /**
-     * Emit code to load a constant single-precision float to a register.
-     */
-    public abstract Register emitLoadFloat(float value);
-
-    /**
-     * Emit code to load a constant oop or metaspace pointer to a register. The pointer may be wide
-     * or narrow, depending on {@link HotSpotConstant#isCompressed() c.isCompressed()}.
-     */
-    public abstract Register emitLoadPointer(HotSpotConstant c);
-
-    /**
-     * Emit code to load a wide pointer from the {@link HotSpotCompiledCode#dataSection} to a
-     * register.
-     */
-    public abstract Register emitLoadPointer(DataSectionReference ref);
-
-    /**
-     * Emit code to load a narrow pointer from the {@link HotSpotCompiledCode#dataSection} to a
-     * register.
-     */
-    public abstract Register emitLoadNarrowPointer(DataSectionReference ref);
-
-    /**
-     * Emit code to load a (wide) pointer from a memory location to a register.
-     */
-    public abstract Register emitLoadPointer(Register base, int offset);
-
-    /**
-     * Emit code to store a 32-bit integer from a register to a new stack slot.
-     */
-    public abstract StackSlot emitIntToStack(Register a);
-
-    /**
-     * Emit code to store a 64-bit integer from a register to a new stack slot.
-     */
-    public abstract StackSlot emitLongToStack(Register a);
-
-    /**
-     * Emit code to store a single-precision float from a register to a new stack slot.
-     */
-    public abstract StackSlot emitFloatToStack(Register a);
-
-    /**
-     * Emit code to store a wide pointer from a register to a new stack slot.
-     */
-    public abstract StackSlot emitPointerToStack(Register a);
-
-    /**
-     * Emit code to store a narrow pointer from a register to a new stack slot.
-     */
-    public abstract StackSlot emitNarrowPointerToStack(Register a);
-
-    /**
-     * Emit code to uncompress a narrow pointer. The input pointer is guaranteed to be non-null.
-     */
-    public abstract Register emitUncompressPointer(Register compressed, long base, int shift);
-
-    /**
-     * Emit code to return from a function, returning a 32-bit integer.
-     */
-    public abstract void emitIntRet(Register a);
-
-    /**
-     * Emit code to return from a function, returning a wide oop pointer.
-     */
-    public abstract void emitPointerRet(Register a);
-
-    /**
-     * Emit code that traps, forcing a deoptimization.
-     */
-    public abstract void emitTrap(DebugInfo info);
-
-    public final LIRKind narrowOopKind;
-
-    protected final Buffer code;
-    protected final Buffer data;
-    private final ArrayList<Site> sites;
-    private final ArrayList<DataPatch> dataPatches;
-
-    protected final CodeCacheProvider codeCache;
-
-    private final Register[] registers;
-    private int nextRegister;
-
-    protected int frameSize;
-    private int stackAlignment;
-    private int curStackSlot;
-
-    private StackSlot deoptRescue;
-
-    protected TestAssembler(CodeCacheProvider codeCache, int initialFrameSize, int stackAlignment, PlatformKind narrowOopKind, Register... registers) {
-        this.narrowOopKind = LIRKind.reference(narrowOopKind);
-
-        this.code = new Buffer();
-        this.data = new Buffer();
-        this.sites = new ArrayList<>();
-        this.dataPatches = new ArrayList<>();
-
-        this.codeCache = codeCache;
-
-        this.registers = registers;
-        this.nextRegister = 0;
-
-        this.frameSize = initialFrameSize;
-        this.stackAlignment = stackAlignment;
-        this.curStackSlot = initialFrameSize;
-    }
-
-    protected Register newRegister() {
-        return registers[nextRegister++];
-    }
-
-    protected StackSlot newStackSlot(LIRKind kind) {
-        curStackSlot += kind.getPlatformKind().getSizeInBytes();
-        if (curStackSlot > frameSize) {
-            int newFrameSize = curStackSlot;
-            if (newFrameSize % stackAlignment != 0) {
-                newFrameSize += stackAlignment - (newFrameSize % stackAlignment);
-            }
-            emitGrowStack(newFrameSize - frameSize);
-            frameSize = newFrameSize;
-        }
-        return StackSlot.get(kind, -curStackSlot, true);
-    }
-
-    protected void setDeoptRescueSlot(StackSlot deoptRescue) {
-        this.deoptRescue = deoptRescue;
-    }
-
-    protected void recordCall(InvokeTarget target, int size, boolean direct, DebugInfo debugInfo) {
-        sites.add(new Call(target, code.position(), size, direct, debugInfo));
-    }
-
-    protected void recordMark(Object id) {
-        sites.add(new Mark(code.position(), id));
-    }
-
-    protected void recordImplicitException(DebugInfo info) {
-        sites.add(new Infopoint(code.position(), info, InfopointReason.IMPLICIT_EXCEPTION));
-    }
-
-    protected void recordDataPatchInCode(Reference ref) {
-        sites.add(new DataPatch(code.position(), ref));
-    }
-
-    protected void recordDataPatchInData(Reference ref) {
-        dataPatches.add(new DataPatch(data.position(), ref));
-    }
-
-    public DataSectionReference emitDataItem(HotSpotConstant c) {
-        DataSectionReference ref = new DataSectionReference();
-        ref.setOffset(data.position());
-
-        recordDataPatchInData(new ConstantReference((VMConstant) c));
-        if (c.isCompressed()) {
-            data.emitInt(0xDEADDEAD);
-        } else {
-            data.emitLong(0xDEADDEADDEADDEADL);
-        }
-
-        return ref;
-    }
-
-    public HotSpotCompiledCode finish(HotSpotResolvedJavaMethod method) {
-        int id = method.allocateCompileId(0);
-        byte[] finishedCode = code.finish();
-        Site[] finishedSites = sites.toArray(new Site[0]);
-        byte[] finishedData = data.finish();
-        DataPatch[] finishedDataPatches = dataPatches.toArray(new DataPatch[0]);
-        return new HotSpotCompiledNmethod(method.getName(), finishedCode, finishedCode.length, finishedSites, new Assumption[0], new ResolvedJavaMethod[]{method}, new Comment[0], finishedData, 16,
-                        finishedDataPatches, false, frameSize, deoptRescue, method, 0, id, 0L, false);
-    }
-
-    protected static class Buffer {
-
-        private ByteBuffer data = ByteBuffer.allocate(32).order(ByteOrder.nativeOrder());
-
-        private void ensureSize(int length) {
-            if (length >= data.limit()) {
-                byte[] newBuf = Arrays.copyOf(data.array(), length * 4);
-                ByteBuffer newData = ByteBuffer.wrap(newBuf);
-                newData.order(data.order());
-                newData.position(data.position());
-                data = newData;
-            }
-        }
-
-        public int position() {
-            return data.position();
-        }
-
-        public void emitByte(int b) {
-            ensureSize(data.position() + 1);
-            data.put((byte) (b & 0xFF));
-        }
-
-        public void emitShort(int b) {
-            ensureSize(data.position() + 2);
-            data.putShort((short) b);
-        }
-
-        public void emitInt(int b) {
-            ensureSize(data.position() + 4);
-            data.putInt(b);
-        }
-
-        public void emitLong(long b) {
-            ensureSize(data.position() + 8);
-            data.putLong(b);
-        }
-
-        public void emitFloat(float f) {
-            ensureSize(data.position() + 4);
-            data.putFloat(f);
-        }
-
-        public void align(int alignment) {
-            int pos = data.position();
-            int misaligned = pos % alignment;
-            if (misaligned != 0) {
-                pos += alignment - misaligned;
-                data.position(pos);
-            }
-        }
-
-        private byte[] finish() {
-            return Arrays.copyOf(data.array(), data.position());
-        }
-    }
-}
--- a/hotspot/test/compiler/jvmci/code/VirtualObjectDebugInfoTest.java	Thu Apr 07 18:27:50 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,177 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
- * @library /
- * @modules jdk.vm.ci/jdk.vm.ci.hotspot
- *          jdk.vm.ci/jdk.vm.ci.meta
- *          jdk.vm.ci/jdk.vm.ci.code
- *          jdk.vm.ci/jdk.vm.ci.code.site
- *          jdk.vm.ci/jdk.vm.ci.runtime
- *          jdk.vm.ci/jdk.vm.ci.amd64
- *          jdk.vm.ci/jdk.vm.ci.sparc
- * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI compiler.jvmci.code.VirtualObjectDebugInfoTest
- */
-
-package compiler.jvmci.code;
-
-import java.util.ArrayList;
-import java.util.Objects;
-
-import jdk.vm.ci.code.Register;
-import jdk.vm.ci.code.VirtualObject;
-import jdk.vm.ci.hotspot.HotSpotConstant;
-import jdk.vm.ci.meta.JavaConstant;
-import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.JavaValue;
-import jdk.vm.ci.meta.ResolvedJavaField;
-import jdk.vm.ci.meta.ResolvedJavaType;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-public class VirtualObjectDebugInfoTest extends DebugInfoTest {
-
-    private static class TestClass {
-
-        private long longField;
-        private int intField;
-        private float floatField;
-        private Object[] arrayField;
-
-        public TestClass() {
-            this.longField = 8472;
-            this.intField = 42;
-            this.floatField = 3.14f;
-            this.arrayField = new Object[] { Integer.valueOf(58), this, null, Integer.valueOf(17), "Hello, World!" };
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (!(o instanceof TestClass)) {
-                return false;
-            }
-
-            TestClass other = (TestClass) o;
-            if (this.longField != other.longField
-                || this.intField != other.intField
-                || this.floatField != other.floatField
-                || this.arrayField.length != other.arrayField.length) {
-                return false;
-            }
-
-            for (int i = 0; i < this.arrayField.length; i++) {
-                // break cycle
-                if (this.arrayField[i] == this && other.arrayField[i] == other) {
-                    continue;
-                }
-
-                if (!Objects.equals(this.arrayField[i], other.arrayField[i])) {
-                    return false;
-                }
-            }
-
-            return true;
-        }
-    }
-
-    public static TestClass buildObject() {
-        return new TestClass();
-    }
-
-    private VirtualObject[] compileBuildObject(TestAssembler asm, JavaValue[] values) {
-        TestClass template = new TestClass();
-        ArrayList<VirtualObject> vobjs = new ArrayList<>();
-
-        ResolvedJavaType retType = metaAccess.lookupJavaType(TestClass.class);
-        VirtualObject ret = VirtualObject.get(retType, vobjs.size());
-        vobjs.add(ret);
-        values[0] = ret;
-
-        ResolvedJavaType arrayType = metaAccess.lookupJavaType(Object[].class);
-        VirtualObject array = VirtualObject.get(arrayType, vobjs.size());
-        vobjs.add(array);
-
-        // build array for ret.arrayField
-        ResolvedJavaType integerType = metaAccess.lookupJavaType(Integer.class);
-        JavaValue[] arrayContent = new JavaValue[template.arrayField.length];
-        JavaKind[] arrayKind = new JavaKind[template.arrayField.length];
-        for (int i = 0; i < arrayContent.length; i++) {
-            arrayKind[i] = JavaKind.Object;
-            if (template.arrayField[i] == null) {
-                arrayContent[i] = JavaConstant.NULL_POINTER;
-            } else if (template.arrayField[i] == template) {
-                arrayContent[i] = ret;
-            } else if (template.arrayField[i] instanceof Integer) {
-                int value = (Integer) template.arrayField[i];
-                VirtualObject boxed = VirtualObject.get(integerType, vobjs.size());
-                vobjs.add(boxed);
-                arrayContent[i] = boxed;
-                boxed.setValues(new JavaValue[]{JavaConstant.forInt(value)}, new JavaKind[]{JavaKind.Int});
-            } else if (template.arrayField[i] instanceof String) {
-                String value = (String) template.arrayField[i];
-                Register reg = asm.emitLoadPointer((HotSpotConstant) constantReflection.forString(value));
-                arrayContent[i] = reg.asValue(target.getLIRKind(JavaKind.Object));
-            } else {
-                Assert.fail("unexpected value");
-            }
-        }
-        array.setValues(arrayContent, arrayKind);
-
-        // build return object
-        ResolvedJavaField[] fields = retType.getInstanceFields(true);
-        JavaValue[] retContent = new JavaValue[fields.length];
-        JavaKind[] retKind = new JavaKind[fields.length];
-        for (int i = 0; i < fields.length; i++) {
-            retKind[i] = fields[i].getJavaKind();
-            switch (retKind[i]) {
-                case Long: // template.longField
-                    retContent[i] = JavaConstant.forLong(template.longField);
-                    break;
-                case Int: // template.intField
-                    Register intReg = asm.emitLoadInt(template.intField);
-                    retContent[i] = asm.emitIntToStack(intReg);
-                    break;
-                case Float: // template.floatField
-                    Register fReg = asm.emitLoadFloat(template.floatField);
-                    retContent[i] = fReg.asValue(target.getLIRKind(JavaKind.Float));
-                    break;
-                case Object: // template.arrayField
-                    retContent[i] = array;
-                    break;
-                default:
-                    Assert.fail("unexpected field");
-            }
-        }
-        ret.setValues(retContent, retKind);
-
-        return vobjs.toArray(new VirtualObject[0]);
-    }
-
-    @Test
-    public void testBuildObject() {
-        test(this::compileBuildObject, getMethod("buildObject"), 7, JavaKind.Object);
-    }
-}
--- a/hotspot/test/compiler/jvmci/code/amd64/AMD64TestAssembler.java	Thu Apr 07 18:27:50 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,287 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package compiler.jvmci.code.amd64;
-
-import jdk.vm.ci.amd64.AMD64;
-import jdk.vm.ci.amd64.AMD64Kind;
-import jdk.vm.ci.code.CodeCacheProvider;
-import jdk.vm.ci.code.DebugInfo;
-import jdk.vm.ci.code.Register;
-import jdk.vm.ci.code.StackSlot;
-import jdk.vm.ci.code.site.ConstantReference;
-import jdk.vm.ci.code.site.DataSectionReference;
-import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
-import jdk.vm.ci.hotspot.HotSpotConstant;
-import jdk.vm.ci.hotspot.HotSpotForeignCallTarget;
-import jdk.vm.ci.hotspot.HotSpotVMConfig;
-import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.LIRKind;
-import jdk.vm.ci.meta.VMConstant;
-
-import compiler.jvmci.code.TestAssembler;
-
-public class AMD64TestAssembler extends TestAssembler {
-
-    public AMD64TestAssembler(CodeCacheProvider codeCache) {
-        super(codeCache, 16, 16, AMD64Kind.DWORD, AMD64.rax, AMD64.rcx, AMD64.rdi, AMD64.r8, AMD64.r9, AMD64.r10);
-    }
-
-    private void emitFatNop() {
-        // 5 byte NOP:
-        // NOP DWORD ptr [EAX + EAX*1 + 00H]
-        code.emitByte(0x0F);
-        code.emitByte(0x1F);
-        code.emitByte(0x44);
-        code.emitByte(0x00);
-        code.emitByte(0x00);
-    }
-
-    @Override
-    public void emitPrologue() {
-        // WARNING: Initial instruction MUST be 5 bytes or longer so that
-        // NativeJump::patch_verified_entry will be able to patch out the entry
-        // code safely.
-        emitFatNop();
-        code.emitByte(0x50 | AMD64.rbp.encoding);  // PUSH rbp
-        emitMove(true, AMD64.rbp, AMD64.rsp);      // MOV rbp, rsp
-        setDeoptRescueSlot(newStackSlot(LIRKind.value(AMD64Kind.QWORD)));
-    }
-
-    @Override
-    public void emitEpilogue() {
-        HotSpotVMConfig config = HotSpotVMConfig.config();
-        recordMark(config.MARKID_DEOPT_HANDLER_ENTRY);
-        recordCall(new HotSpotForeignCallTarget(config.handleDeoptStub), 5, true, null);
-        code.emitByte(0xE8); // CALL rel32
-        code.emitInt(0xDEADDEAD);
-    }
-
-    @Override
-    public void emitGrowStack(int size) {
-        // SUB rsp, size
-        code.emitByte(0x48);
-        code.emitByte(0x81);
-        code.emitByte(0xEC);
-        code.emitInt(size);
-    }
-
-    @Override
-    public Register emitIntArg0() {
-        return codeCache.getRegisterConfig().getCallingConventionRegisters(HotSpotCallingConventionType.JavaCall, JavaKind.Int)[0];
-    }
-
-    @Override
-    public Register emitIntArg1() {
-        return codeCache.getRegisterConfig().getCallingConventionRegisters(HotSpotCallingConventionType.JavaCall, JavaKind.Int)[1];
-    }
-
-    private void emitREX(boolean w, int r, int x, int b) {
-        int wrxb = (w ? 0x08 : 0) | ((r >> 3) << 2) | ((x >> 3) << 1) | (b >> 3);
-        if (wrxb != 0) {
-            code.emitByte(0x40 | wrxb);
-        }
-    }
-
-    private void emitModRMReg(boolean w, int opcode, int r, int m) {
-        emitREX(w, r, 0, m);
-        code.emitByte((byte) opcode);
-        code.emitByte((byte) 0xC0 | ((r & 0x7) << 3) | (m & 0x7));
-    }
-
-    private void emitModRMMemory(boolean w, int opcode, int r, int b, int offset) {
-        emitREX(w, r, 0, b);
-        code.emitByte((byte) opcode);
-        code.emitByte((byte) 0x80 | ((r & 0x7) << 3) | (b & 0x7));
-        code.emitInt(offset);
-    }
-
-    @Override
-    public Register emitLoadInt(int c) {
-        Register ret = newRegister();
-        emitREX(false, 0, 0, ret.encoding);
-        code.emitByte(0xB8 | (ret.encoding & 0x7)); // MOV r32, imm32
-        code.emitInt(c);
-        return ret;
-    }
-
-    @Override
-    public Register emitLoadLong(long c) {
-        Register ret = newRegister();
-        emitREX(true, 0, 0, ret.encoding);
-        code.emitByte(0xB8 | (ret.encoding & 0x7)); // MOV r64, imm64
-        code.emitLong(c);
-        return ret;
-    }
-
-    @Override
-    public Register emitLoadFloat(float c) {
-        DataSectionReference ref = new DataSectionReference();
-        ref.setOffset(data.position());
-        data.emitFloat(c);
-
-        recordDataPatchInCode(ref);
-        Register ret = AMD64.xmm0;
-        emitREX(false, ret.encoding, 0, 0);
-        code.emitByte(0xF3);
-        code.emitByte(0x0F);
-        code.emitByte(0x10);                               // MOVSS xmm1, xmm2/m32
-        code.emitByte(0x05 | ((ret.encoding & 0x7) << 3)); // xmm, [rip+offset]
-        code.emitInt(0xDEADDEAD);
-        return ret;
-    }
-
-    @Override
-    public Register emitLoadPointer(HotSpotConstant c) {
-        recordDataPatchInCode(new ConstantReference((VMConstant) c));
-        if (c.isCompressed()) {
-            Register ret = newRegister();
-            emitREX(false, 0, 0, ret.encoding);
-            code.emitByte(0xB8 | (ret.encoding & 0x7)); // MOV r32, imm32
-            code.emitInt(0xDEADDEAD);
-            return ret;
-        } else {
-            return emitLoadLong(0xDEADDEADDEADDEADl);
-        }
-    }
-
-    private Register emitLoadPointer(DataSectionReference ref, boolean narrow) {
-        recordDataPatchInCode(ref);
-        Register ret = newRegister();
-        emitREX(!narrow, ret.encoding, 0, 0);
-        code.emitByte(0x8B);                               // MOV r64,r/m64
-        code.emitByte(0x05 | ((ret.encoding & 0x7) << 3)); // r64, [rip+offset]
-        code.emitInt(0xDEADDEAD);
-        return ret;
-    }
-
-    @Override
-    public Register emitLoadPointer(DataSectionReference ref) {
-        return emitLoadPointer(ref, false);
-    }
-
-    @Override
-    public Register emitLoadNarrowPointer(DataSectionReference ref) {
-        return emitLoadPointer(ref, true);
-    }
-
-    @Override
-    public Register emitLoadPointer(Register b, int offset) {
-        Register ret = newRegister();
-        emitModRMMemory(true, 0x8B, ret.encoding, b.encoding, offset); // MOV r64,r/m64
-        return ret;
-    }
-
-    @Override
-    public StackSlot emitIntToStack(Register a) {
-        StackSlot ret = newStackSlot(LIRKind.value(AMD64Kind.DWORD));
-        emitModRMMemory(false, 0x89, a.encoding, AMD64.rbp.encoding, ret.getRawOffset() + 16); // MOV r/m32,r32
-        return ret;
-    }
-
-    @Override
-    public StackSlot emitLongToStack(Register a) {
-        StackSlot ret = newStackSlot(LIRKind.value(AMD64Kind.QWORD));
-        emitModRMMemory(true, 0x89, a.encoding, AMD64.rbp.encoding, ret.getRawOffset() + 16); // MOV r/m64,r64
-        return ret;
-    }
-
-    @Override
-    public StackSlot emitFloatToStack(Register a) {
-        StackSlot ret = newStackSlot(LIRKind.value(AMD64Kind.SINGLE));
-        emitREX(false, a.encoding, 0, 0);
-        code.emitByte(0xF3);
-        code.emitByte(0x0F);
-        code.emitByte(0x11);                               // MOVSS xmm2/m32, xmm1
-        code.emitByte(0x85 | ((a.encoding & 0x7) << 3));   // [rbp+offset]
-        code.emitInt(ret.getRawOffset() + 16);
-        return ret;
-    }
-
-    @Override
-    public StackSlot emitPointerToStack(Register a) {
-        StackSlot ret = newStackSlot(LIRKind.reference(AMD64Kind.QWORD));
-        emitModRMMemory(true, 0x89, a.encoding, AMD64.rbp.encoding, ret.getRawOffset() + 16); // MOV r/m64,r64
-        return ret;
-    }
-
-    @Override
-    public StackSlot emitNarrowPointerToStack(Register a) {
-        StackSlot ret = newStackSlot(LIRKind.reference(AMD64Kind.DWORD));
-        emitModRMMemory(false, 0x89, a.encoding, AMD64.rbp.encoding, ret.getRawOffset() + 16); // MOV r/m32,r32
-        return ret;
-    }
-
-    @Override
-    public Register emitUncompressPointer(Register compressed, long base, int shift) {
-        if (shift > 0) {
-            emitModRMReg(true, 0xC1, 4, compressed.encoding);
-            code.emitByte(shift);
-        }
-        if (base == 0) {
-            return compressed;
-        } else {
-            Register tmp = emitLoadLong(base);
-            emitModRMReg(true, 0x03, tmp.encoding, compressed.encoding);
-            return tmp;
-        }
-    }
-
-    @Override
-    public Register emitIntAdd(Register a, Register b) {
-        emitModRMReg(false, 0x03, a.encoding, b.encoding);
-        return a;
-    }
-
-    private void emitMove(boolean w, Register to, Register from) {
-        if (to != from) {
-            emitModRMReg(w, 0x8B, to.encoding, from.encoding);
-        }
-    }
-
-    @Override
-    public void emitIntRet(Register a) {
-        emitMove(false, AMD64.rax, a);             // MOV eax, ...
-        emitMove(true, AMD64.rsp, AMD64.rbp);      // MOV rsp, rbp
-        code.emitByte(0x58 | AMD64.rbp.encoding);  // POP rbp
-        code.emitByte(0xC3);                       // RET
-    }
-
-    @Override
-    public void emitPointerRet(Register a) {
-        emitMove(true, AMD64.rax, a);              // MOV rax, ...
-        emitMove(true, AMD64.rsp, AMD64.rbp);      // MOV rsp, rbp
-        code.emitByte(0x58 | AMD64.rbp.encoding);  // POP rbp
-        code.emitByte(0xC3);                       // RET
-    }
-
-    @Override
-    public void emitTrap(DebugInfo info) {
-        recordImplicitException(info);
-        // MOV rax, [0]
-        code.emitByte(0x8B);
-        code.emitByte(0x04);
-        code.emitByte(0x25);
-        code.emitInt(0);
-    }
-}
--- a/hotspot/test/compiler/jvmci/code/sparc/SPARCTestAssembler.java	Thu Apr 07 18:27:50 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,288 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package compiler.jvmci.code.sparc;
-
-import jdk.vm.ci.code.CodeCacheProvider;
-import jdk.vm.ci.code.DebugInfo;
-import jdk.vm.ci.code.Register;
-import jdk.vm.ci.code.StackSlot;
-import jdk.vm.ci.code.site.ConstantReference;
-import jdk.vm.ci.code.site.DataSectionReference;
-import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
-import jdk.vm.ci.hotspot.HotSpotCompiledCode;
-import jdk.vm.ci.hotspot.HotSpotConstant;
-import jdk.vm.ci.hotspot.HotSpotForeignCallTarget;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
-import jdk.vm.ci.hotspot.HotSpotVMConfig;
-import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.LIRKind;
-import jdk.vm.ci.meta.VMConstant;
-import jdk.vm.ci.sparc.SPARC;
-import jdk.vm.ci.sparc.SPARCKind;
-
-import compiler.jvmci.code.TestAssembler;
-
-public class SPARCTestAssembler extends TestAssembler {
-
-    private static final int MASK13 = (1 << 13) - 1;
-
-    public SPARCTestAssembler(CodeCacheProvider codeCache) {
-        super(codeCache, 0, 16, SPARCKind.WORD, SPARC.l0, SPARC.l1, SPARC.l2, SPARC.l3, SPARC.l4, SPARC.l5, SPARC.l6, SPARC.l7);
-    }
-
-    private void emitOp2(Register rd, int op2, int imm22) {
-        code.emitInt((0b00 << 30) | (rd.encoding << 25) | (op2 << 22) | imm22);
-    }
-
-    private void emitOp3(int op, Register rd, int op3, Register rs1, Register rs2) {
-        code.emitInt((op << 30) | (rd.encoding << 25) | (op3 << 19) | (rs1.encoding << 14) | rs2.encoding);
-    }
-
-    private void emitOp3(int op, Register rd, int op3, Register rs1, int simm13) {
-        code.emitInt((op << 30) | (rd.encoding << 25) | (op3 << 19) | (rs1.encoding << 14) | (1 << 13) | (simm13 & MASK13));
-    }
-
-    private void emitNop() {
-        code.emitInt(1 << 24);
-    }
-
-    @Override
-    public void emitPrologue() {
-        emitOp3(0b10, SPARC.sp, 0b111100, SPARC.sp, -SPARC.REGISTER_SAFE_AREA_SIZE); // SAVE sp, -128, sp
-        setDeoptRescueSlot(newStackSlot(LIRKind.value(SPARCKind.XWORD)));
-    }
-
-    @Override
-    public void emitEpilogue() {
-        HotSpotVMConfig config = HotSpotVMConfig.config();
-        recordMark(config.MARKID_DEOPT_HANDLER_ENTRY);
-        recordCall(new HotSpotForeignCallTarget(config.handleDeoptStub), 4, true, null);
-        code.emitInt(1 << 30); // CALL
-    }
-
-    @Override
-    public HotSpotCompiledCode finish(HotSpotResolvedJavaMethod method) {
-        frameSize += SPARC.REGISTER_SAFE_AREA_SIZE;
-        return super.finish(method);
-    }
-
-    @Override
-    public void emitGrowStack(int size) {
-        emitOp3(0b10, SPARC.sp, 0b000100, SPARC.sp, size); // SUB sp, size, sp
-    }
-
-    @Override
-    public Register emitIntArg0() {
-        return codeCache.getRegisterConfig().getCallingConventionRegisters(HotSpotCallingConventionType.JavaCallee, JavaKind.Int)[0];
-    }
-
-    @Override
-    public Register emitIntArg1() {
-        return codeCache.getRegisterConfig().getCallingConventionRegisters(HotSpotCallingConventionType.JavaCallee, JavaKind.Int)[1];
-    }
-
-    @Override
-    public Register emitLoadInt(int c) {
-        Register ret = newRegister();
-        int hi = c >>> 10;
-        int lo = c & ((1 << 10) - 1);
-        if (hi == 0) {
-            emitOp3(0b10, ret, 0b000010, SPARC.g0, lo); // OR g0, lo, ret
-        } else {
-            emitOp2(ret, 0b100, hi);                    // SETHI hi, ret
-            if (lo != 0) {
-                emitOp3(0b10, ret, 0b000010, ret, lo);  // OR ret, lo, ret
-            }
-        }
-        return ret;
-    }
-
-    @Override
-    public Register emitLoadLong(long c) {
-        if ((c & 0xFFFF_FFFFL) == c) {
-            return emitLoadInt((int) c);
-        } else {
-            DataSectionReference ref = new DataSectionReference();
-            data.align(8);
-            ref.setOffset(data.position());
-            data.emitLong(c);
-            return emitLoadPointer(ref);
-        }
-    }
-
-    private void emitPatchableSethi(Register ret, boolean wide) {
-        int startPos = code.position();
-        emitOp2(ret, 0b100, 0);              // SETHI 0, ret
-        if (wide) {
-            // pad for later patching
-            while (code.position() < (startPos + 28)) {
-                emitNop();
-            }
-        }
-    }
-
-    @Override
-    public Register emitLoadFloat(float c) {
-        DataSectionReference ref = new DataSectionReference();
-        data.align(4);
-        ref.setOffset(data.position());
-        data.emitFloat(c);
-
-        Register ptr = newRegister();
-        recordDataPatchInCode(ref);
-        emitPatchableSethi(ptr, true);
-        emitOp3(0b11, SPARC.f0, 0b100000, ptr, 0); // LDF [ptr+0], f0
-        return SPARC.f0;
-    }
-
-    @Override
-    public Register emitLoadPointer(HotSpotConstant c) {
-        Register ret = newRegister();
-        recordDataPatchInCode(new ConstantReference((VMConstant) c));
-
-        emitPatchableSethi(ret, !c.isCompressed());
-        emitOp3(0b10, ret, 0b000010, ret, 0); // OR ret, 0, ret
-
-        return ret;
-    }
-
-    @Override
-    public Register emitLoadPointer(DataSectionReference ref) {
-        Register ret = newRegister();
-        recordDataPatchInCode(ref);
-        emitPatchableSethi(ret, true);
-        emitOp3(0b11, ret, 0b001011, ret, 0); // LDX [ret+0], ret
-        return ret;
-    }
-
-    @Override
-    public Register emitLoadNarrowPointer(DataSectionReference ref) {
-        Register ret = newRegister();
-        recordDataPatchInCode(ref);
-        emitPatchableSethi(ret, true);
-        emitOp3(0b11, ret, 0b000000, ret, 0); // LDUW [ret+0], ret
-        return ret;
-    }
-
-    @Override
-    public Register emitLoadPointer(Register b, int offset) {
-        Register ret = newRegister();
-        emitOp3(0b11, ret, 0b001011, b, offset); // LDX [b+offset], ret
-        return ret;
-    }
-
-    @Override
-    public StackSlot emitIntToStack(Register a) {
-        StackSlot ret = newStackSlot(LIRKind.value(SPARCKind.WORD));
-        emitOp3(0b11, a, 0b000100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS); // STW a, [fp+offset]
-        return ret;
-    }
-
-    @Override
-    public StackSlot emitLongToStack(Register a) {
-        StackSlot ret = newStackSlot(LIRKind.value(SPARCKind.XWORD));
-        emitOp3(0b11, a, 0b001110, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS); // STX a, [fp+offset]
-        return ret;
-    }
-
-    @Override
-    public StackSlot emitFloatToStack(Register a) {
-        StackSlot ret = newStackSlot(LIRKind.value(SPARCKind.SINGLE));
-        emitOp3(0b11, a, 0b100100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS); // STF a, [fp+offset]
-        return ret;
-    }
-
-    @Override
-    public StackSlot emitPointerToStack(Register a) {
-        StackSlot ret = newStackSlot(LIRKind.reference(SPARCKind.XWORD));
-        emitOp3(0b11, a, 0b001110, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS); // STX a, [fp+offset]
-        return ret;
-    }
-
-    @Override
-    public StackSlot emitNarrowPointerToStack(Register a) {
-        StackSlot ret = newStackSlot(LIRKind.reference(SPARCKind.WORD));
-        emitOp3(0b11, a, 0b000100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS); // STW a, [fp+offset]
-        return ret;
-    }
-
-    @Override
-    public Register emitUncompressPointer(Register compressed, long base, int shift) {
-        Register ret;
-        if (shift > 0) {
-            ret = newRegister();
-            emitOp3(0b10, ret, 0b100101, compressed, shift); // SLL compressed, shift, ret
-        } else {
-            ret = compressed;
-        }
-        if (base == 0) {
-            return ret;
-        } else {
-            Register b = emitLoadLong(base);
-            emitOp3(0b10, b, 0b00000, ret, b); // ADD b, ret, b
-            return b;
-        }
-    }
-
-    @Override
-    public Register emitIntAdd(Register a, Register b) {
-        Register ret = newRegister();
-        emitOp3(0b10, ret, 0b00000, a, b); // ADD a, b, ret
-        return ret;
-    }
-
-    private void emitMove(Register to, Register from) {
-        if (to != from) {
-            emitOp3(0b10, to, 0b000010, from, SPARC.g0); // OR from, g0, to
-        }
-    }
-
-    @Override
-    public void emitIntRet(Register a) {
-        emitPointerRet(a);
-    }
-
-    @Override
-    public void emitPointerRet(Register a) {
-        emitMove(SPARC.i0, a);
-        emitOp3(0b10, SPARC.g0, 0b111000, SPARC.i7, 8);        // JMPL [i7+8], g0
-        emitOp3(0b10, SPARC.g0, 0b111101, SPARC.g0, SPARC.g0); // RESTORE g0, g0, g0
-    }
-
-    @Override
-    public void emitTrap(DebugInfo info) {
-        recordImplicitException(info);
-        emitOp3(0b11, SPARC.g0, 0b001011, SPARC.g0, 0); // LDX [g0+0], g0
-    }
-
-    @Override
-    public DataSectionReference emitDataItem(HotSpotConstant c) {
-        if (c.isCompressed()) {
-            data.align(4);
-        } else {
-            data.align(8);
-        }
-        return super.emitDataItem(c);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/CodeInstallationTest.java	Thu Apr 07 08:57:26 2016 -1000
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.code.test;
+
+import java.lang.reflect.Method;
+
+import org.junit.Assert;
+
+import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.code.Architecture;
+import jdk.vm.ci.code.CodeCacheProvider;
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.code.test.amd64.AMD64TestAssembler;
+import jdk.vm.ci.code.test.sparc.SPARCTestAssembler;
+import jdk.vm.ci.hotspot.HotSpotCompiledCode;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
+import jdk.vm.ci.meta.ConstantReflectionProvider;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.runtime.JVMCI;
+import jdk.vm.ci.runtime.JVMCIBackend;
+import jdk.vm.ci.sparc.SPARC;
+
+/**
+ * Base class for code installation tests.
+ */
+public class CodeInstallationTest {
+
+    protected final MetaAccessProvider metaAccess;
+    protected final CodeCacheProvider codeCache;
+    protected final TargetDescription target;
+    protected final ConstantReflectionProvider constantReflection;
+
+    public CodeInstallationTest() {
+        JVMCIBackend backend = JVMCI.getRuntime().getHostJVMCIBackend();
+        metaAccess = backend.getMetaAccess();
+        codeCache = backend.getCodeCache();
+        target = backend.getTarget();
+        constantReflection = backend.getConstantReflection();
+    }
+
+    protected interface TestCompiler {
+
+        void compile(TestAssembler asm);
+    }
+
+    private TestAssembler createAssembler() {
+        Architecture arch = codeCache.getTarget().arch;
+        if (arch instanceof AMD64) {
+            return new AMD64TestAssembler(codeCache);
+        } else if (arch instanceof SPARC) {
+            return new SPARCTestAssembler(codeCache);
+        } else {
+            Assert.fail("unsupported architecture");
+            return null;
+        }
+    }
+
+    protected Method getMethod(String name, Class<?>... args) {
+        try {
+            return getClass().getMethod(name, args);
+        } catch (NoSuchMethodException e) {
+            Assert.fail("method not found");
+            return null;
+        }
+    }
+
+    protected void test(TestCompiler compiler, Method method, Object... args) {
+        HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(method);
+        TestAssembler asm = createAssembler();
+
+        asm.emitPrologue();
+        compiler.compile(asm);
+        asm.emitEpilogue();
+
+        HotSpotCompiledCode code = asm.finish(resolvedMethod);
+        InstalledCode installed = codeCache.addCode(resolvedMethod, code, null, null);
+
+        try {
+            Object expected = method.invoke(null, args);
+            Object actual = installed.executeVarargs(args);
+            Assert.assertEquals(expected, actual);
+        } catch (Exception e) {
+            e.printStackTrace();
+            Assert.fail(e.toString());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DataPatchTest.java	Thu Apr 07 08:57:26 2016 -1000
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /
+ * @modules jdk.vm.ci/jdk.vm.ci.hotspot
+ *          jdk.vm.ci/jdk.vm.ci.meta
+ *          jdk.vm.ci/jdk.vm.ci.code
+ *          jdk.vm.ci/jdk.vm.ci.code.site
+ *          jdk.vm.ci/jdk.vm.ci.runtime
+ *          jdk.vm.ci/jdk.vm.ci.amd64
+ *          jdk.vm.ci/jdk.vm.ci.sparc
+ * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java amd64/AMD64TestAssembler.java sparc/SPARCTestAssembler.java
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.code.test.DataPatchTest
+ */
+
+package jdk.vm.ci.code.test;
+
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.site.DataSectionReference;
+import jdk.vm.ci.hotspot.HotSpotConstant;
+import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider;
+import jdk.vm.ci.hotspot.HotSpotSymbol;
+import jdk.vm.ci.hotspot.HotSpotVMConfig;
+import jdk.vm.ci.meta.ResolvedJavaType;
+
+import org.junit.Assume;
+import org.junit.Test;
+
+/**
+ * Test code installation with data patches.
+ */
+public class DataPatchTest extends CodeInstallationTest {
+
+    public static Class<?> getConstClass() {
+        return DataPatchTest.class;
+    }
+
+    private void test(TestCompiler compiler) {
+        test(compiler, getMethod("getConstClass"));
+    }
+
+    @Test
+    public void testInlineObject() {
+        test(asm -> {
+            ResolvedJavaType type = metaAccess.lookupJavaType(getConstClass());
+            HotSpotConstant c = (HotSpotConstant) constantReflection.asJavaClass(type);
+            Register ret = asm.emitLoadPointer(c);
+            asm.emitPointerRet(ret);
+        });
+    }
+
+    @Test
+    public void testInlineNarrowObject() {
+        Assume.assumeTrue(HotSpotVMConfig.config().useCompressedOops);
+        test(asm -> {
+            ResolvedJavaType type = metaAccess.lookupJavaType(getConstClass());
+            HotSpotConstant c = (HotSpotConstant) constantReflection.asJavaClass(type);
+            Register compressed = asm.emitLoadPointer((HotSpotConstant) c.compress());
+            Register ret = asm.emitUncompressPointer(compressed, HotSpotVMConfig.config().narrowOopBase, HotSpotVMConfig.config().narrowOopShift);
+            asm.emitPointerRet(ret);
+        });
+    }
+
+    @Test
+    public void testDataSectionReference() {
+        test(asm -> {
+            ResolvedJavaType type = metaAccess.lookupJavaType(getConstClass());
+            HotSpotConstant c = (HotSpotConstant) constantReflection.asJavaClass(type);
+            DataSectionReference ref = asm.emitDataItem(c);
+            Register ret = asm.emitLoadPointer(ref);
+            asm.emitPointerRet(ret);
+        });
+    }
+
+    @Test
+    public void testNarrowDataSectionReference() {
+        Assume.assumeTrue(HotSpotVMConfig.config().useCompressedOops);
+        test(asm -> {
+            ResolvedJavaType type = metaAccess.lookupJavaType(getConstClass());
+            HotSpotConstant c = (HotSpotConstant) constantReflection.asJavaClass(type);
+            HotSpotConstant cCompressed = (HotSpotConstant) c.compress();
+            DataSectionReference ref = asm.emitDataItem(cCompressed);
+            Register compressed = asm.emitLoadNarrowPointer(ref);
+            Register ret = asm.emitUncompressPointer(compressed, HotSpotVMConfig.config().narrowOopBase, HotSpotVMConfig.config().narrowOopShift);
+            asm.emitPointerRet(ret);
+        });
+    }
+
+    @Test
+    public void testInlineMetadata() {
+        test(asm -> {
+            ResolvedJavaType type = metaAccess.lookupJavaType(getConstClass());
+            Register klass = asm.emitLoadPointer((HotSpotConstant) constantReflection.asObjectHub(type));
+            Register ret = asm.emitLoadPointer(klass, HotSpotVMConfig.config().classMirrorOffset);
+            asm.emitPointerRet(ret);
+        });
+    }
+
+    @Test
+    public void testInlineNarrowMetadata() {
+        Assume.assumeTrue(HotSpotVMConfig.config().useCompressedClassPointers);
+        test(asm -> {
+            ResolvedJavaType type = metaAccess.lookupJavaType(getConstClass());
+            HotSpotConstant hub = (HotSpotConstant) constantReflection.asObjectHub(type);
+            Register narrowKlass = asm.emitLoadPointer((HotSpotConstant) hub.compress());
+            Register klass = asm.emitUncompressPointer(narrowKlass, HotSpotVMConfig.config().narrowKlassBase, HotSpotVMConfig.config().narrowKlassShift);
+            Register ret = asm.emitLoadPointer(klass, HotSpotVMConfig.config().classMirrorOffset);
+            asm.emitPointerRet(ret);
+        });
+    }
+
+    @Test
+    public void testMetadataInDataSection() {
+        test(asm -> {
+            ResolvedJavaType type = metaAccess.lookupJavaType(getConstClass());
+            HotSpotConstant hub = (HotSpotConstant) constantReflection.asObjectHub(type);
+            DataSectionReference ref = asm.emitDataItem(hub);
+            Register klass = asm.emitLoadPointer(ref);
+            Register ret = asm.emitLoadPointer(klass, HotSpotVMConfig.config().classMirrorOffset);
+            asm.emitPointerRet(ret);
+        });
+    }
+
+    @Test
+    public void testNarrowMetadataInDataSection() {
+        Assume.assumeTrue(HotSpotVMConfig.config().useCompressedClassPointers);
+        test(asm -> {
+            ResolvedJavaType type = metaAccess.lookupJavaType(getConstClass());
+            HotSpotConstant hub = (HotSpotConstant) constantReflection.asObjectHub(type);
+            HotSpotConstant narrowHub = (HotSpotConstant) hub.compress();
+            DataSectionReference ref = asm.emitDataItem(narrowHub);
+            Register narrowKlass = asm.emitLoadNarrowPointer(ref);
+            Register klass = asm.emitUncompressPointer(narrowKlass, HotSpotVMConfig.config().narrowKlassBase, HotSpotVMConfig.config().narrowKlassShift);
+            Register ret = asm.emitLoadPointer(klass, HotSpotVMConfig.config().classMirrorOffset);
+            asm.emitPointerRet(ret);
+        });
+    }
+
+    public static long getConstSymbol(HotSpotMetaAccessProvider meta) {
+        HotSpotSymbol symbol = meta.lookupSymbol("java/lang/Object");
+        return symbol.getMetaspacePointer();
+    }
+
+    private void testSymbol(TestCompiler compiler) {
+        test(compiler, getMethod("getConstSymbol", HotSpotMetaAccessProvider.class), (HotSpotMetaAccessProvider) metaAccess);
+    }
+
+    @Test
+    public void testInlineSymbol() {
+        testSymbol(asm -> {
+            HotSpotSymbol symbol = ((HotSpotMetaAccessProvider) metaAccess).lookupSymbol("java/lang/Object");
+            Register ret = asm.emitLoadPointer((HotSpotConstant) symbol.asConstant());
+            asm.emitPointerRet(ret);
+        });
+    }
+
+    @Test
+    public void testSymbolInDataSection() {
+        testSymbol(asm -> {
+            HotSpotSymbol symbol = ((HotSpotMetaAccessProvider) metaAccess).lookupSymbol("java/lang/Object");
+            DataSectionReference ref = asm.emitDataItem((HotSpotConstant) symbol.asConstant());
+            Register ret = asm.emitLoadPointer(ref);
+            asm.emitPointerRet(ret);
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DebugInfoTest.java	Thu Apr 07 08:57:26 2016 -1000
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.code.test;
+
+import java.lang.reflect.Method;
+
+import jdk.vm.ci.code.BytecodeFrame;
+import jdk.vm.ci.code.DebugInfo;
+import jdk.vm.ci.code.Location;
+import jdk.vm.ci.code.VirtualObject;
+import jdk.vm.ci.hotspot.HotSpotReferenceMap;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaValue;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+/**
+ * Test code installation with debug information.
+ */
+public class DebugInfoTest extends CodeInstallationTest {
+
+    protected interface DebugInfoCompiler {
+
+        VirtualObject[] compile(TestAssembler asm, JavaValue[] frameValues);
+    }
+
+    protected void test(DebugInfoCompiler compiler, Method method, int bci, JavaKind... slotKinds) {
+        ResolvedJavaMethod resolvedMethod = metaAccess.lookupJavaMethod(method);
+
+        int numLocals = resolvedMethod.getMaxLocals();
+        int numStack = slotKinds.length - numLocals;
+        JavaValue[] values = new JavaValue[slotKinds.length];
+        test(asm -> {
+            VirtualObject[] vobjs = compiler.compile(asm, values);
+
+            BytecodeFrame frame = new BytecodeFrame(null, resolvedMethod, bci, false, false, values, slotKinds, numLocals, numStack, 0);
+            DebugInfo info = new DebugInfo(frame, vobjs);
+            info.setReferenceMap(new HotSpotReferenceMap(new Location[0], new Location[0], new int[0], 8));
+
+            asm.emitTrap(info);
+        }, method);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/InterpreterFrameSizeTest.java	Thu Apr 07 08:57:26 2016 -1000
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @modules jdk.vm.ci/jdk.vm.ci.hotspot
+ *          jdk.vm.ci/jdk.vm.ci.code
+ *          jdk.vm.ci/jdk.vm.ci.code.site
+ *          jdk.vm.ci/jdk.vm.ci.meta
+ *          jdk.vm.ci/jdk.vm.ci.runtime
+ *          jdk.vm.ci/jdk.vm.ci.common
+ *          jdk.vm.ci/jdk.vm.ci.amd64
+ *          jdk.vm.ci/jdk.vm.ci.sparc
+ * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java amd64/AMD64TestAssembler.java sparc/SPARCTestAssembler.java
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.code.test.InterpreterFrameSizeTest
+ */
+
+package jdk.vm.ci.code.test;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import jdk.vm.ci.code.BytecodeFrame;
+import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaValue;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+public class InterpreterFrameSizeTest extends CodeInstallationTest {
+
+    HotSpotCodeCacheProvider hotspotCodeCache() {
+        return (HotSpotCodeCacheProvider) codeCache;
+    }
+
+    @Test
+    public void testNull() {
+        try {
+            hotspotCodeCache().interpreterFrameSize(null);
+        } catch (NullPointerException npe) {
+            // Threw NPE as expected.
+            return;
+        }
+        Assert.fail("expected NullPointerException");
+    }
+
+    @Test
+    public void test() {
+        ResolvedJavaMethod resolvedMethod = metaAccess.lookupJavaMethod(getMethod("testNull"));
+
+        int bci = 0;
+        int numLocals = resolvedMethod.getMaxLocals();
+        int numStack = 0;
+        JavaValue[] values = new JavaValue[numLocals];
+        JavaKind[] slotKinds = new JavaKind[numLocals];
+        BytecodeFrame frame = new BytecodeFrame(null, resolvedMethod, bci, false, false, values, slotKinds, numLocals, numStack, 0);
+        int size = hotspotCodeCache().interpreterFrameSize(frame);
+        if (size <= 0) {
+            Assert.fail("expected non-zero result");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleCodeInstallationTest.java	Thu Apr 07 08:57:26 2016 -1000
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /
+ * @modules jdk.vm.ci/jdk.vm.ci.hotspot
+ *          jdk.vm.ci/jdk.vm.ci.meta
+ *          jdk.vm.ci/jdk.vm.ci.code
+ *          jdk.vm.ci/jdk.vm.ci.code.site
+ *          jdk.vm.ci/jdk.vm.ci.runtime
+ *          jdk.vm.ci/jdk.vm.ci.amd64
+ *          jdk.vm.ci/jdk.vm.ci.sparc
+ * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java amd64/AMD64TestAssembler.java sparc/SPARCTestAssembler.java
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.code.test.SimpleCodeInstallationTest
+ */
+
+package jdk.vm.ci.code.test;
+
+import org.junit.Test;
+
+import jdk.vm.ci.code.Register;
+
+/**
+ * Test simple code installation.
+ */
+public class SimpleCodeInstallationTest extends CodeInstallationTest {
+
+    public static int add(int a, int b) {
+        return a + b;
+    }
+
+    private static void compileAdd(TestAssembler asm) {
+        Register arg0 = asm.emitIntArg0();
+        Register arg1 = asm.emitIntArg1();
+        Register ret = asm.emitIntAdd(arg0, arg1);
+        asm.emitIntRet(ret);
+    }
+
+    @Test
+    public void test() {
+        test(SimpleCodeInstallationTest::compileAdd, getMethod("add", int.class, int.class), 5, 7);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java	Thu Apr 07 08:57:26 2016 -1000
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /
+ * @modules jdk.vm.ci/jdk.vm.ci.hotspot
+ *          jdk.vm.ci/jdk.vm.ci.meta
+ *          jdk.vm.ci/jdk.vm.ci.code
+ *          jdk.vm.ci/jdk.vm.ci.code.site
+ *          jdk.vm.ci/jdk.vm.ci.runtime
+ *          jdk.vm.ci/jdk.vm.ci.amd64
+ *          jdk.vm.ci/jdk.vm.ci.sparc
+ * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java amd64/AMD64TestAssembler.java sparc/SPARCTestAssembler.java
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.code.test.SimpleDebugInfoTest
+ */
+
+package jdk.vm.ci.code.test;
+
+import org.junit.Assume;
+import org.junit.Test;
+
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.hotspot.HotSpotConstant;
+import jdk.vm.ci.hotspot.HotSpotVMConfig;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.Value;
+
+public class SimpleDebugInfoTest extends DebugInfoTest {
+
+    public static int intOnStack() {
+        return 42;
+    }
+
+    private void testIntOnStack(DebugInfoCompiler compiler) {
+        test(compiler, getMethod("intOnStack"), 2, JavaKind.Int);
+    }
+
+    public static int intInLocal() {
+        int local = 42;
+        return local;
+    }
+
+    public void testIntInLocal(DebugInfoCompiler compiler) {
+        test(compiler, getMethod("intInLocal"), 3, JavaKind.Int);
+    }
+
+    @Test
+    public void testConstInt() {
+        DebugInfoCompiler compiler = (asm, values) -> {
+            values[0] = JavaConstant.forInt(42);
+            return null;
+        };
+        testIntOnStack(compiler);
+        testIntInLocal(compiler);
+    }
+
+    @Test
+    public void testRegInt() {
+        DebugInfoCompiler compiler = (asm, values) -> {
+            Register reg = asm.emitLoadInt(42);
+            values[0] = reg.asValue(target.getLIRKind(JavaKind.Int));
+            return null;
+        };
+        testIntOnStack(compiler);
+        testIntInLocal(compiler);
+    }
+
+    @Test
+    public void testStackInt() {
+        DebugInfoCompiler compiler = (asm, values) -> {
+            Register reg = asm.emitLoadInt(42);
+            values[0] = asm.emitIntToStack(reg);
+            return null;
+        };
+        testIntOnStack(compiler);
+        testIntInLocal(compiler);
+    }
+
+    public static float floatOnStack() {
+        return 42.0f;
+    }
+
+    private void testFloatOnStack(DebugInfoCompiler compiler) {
+        test(compiler, getMethod("floatOnStack"), 2, JavaKind.Float);
+    }
+
+    public static float floatInLocal() {
+        float local = 42.0f;
+        return local;
+    }
+
+    private void testFloatInLocal(DebugInfoCompiler compiler) {
+        test(compiler, getMethod("floatInLocal"), 3, JavaKind.Float);
+    }
+
+    @Test
+    public void testConstFloat() {
+        DebugInfoCompiler compiler = (asm, values) -> {
+            values[0] = JavaConstant.forFloat(42.0f);
+            return null;
+        };
+        testFloatOnStack(compiler);
+        testFloatInLocal(compiler);
+    }
+
+    @Test
+    public void testRegFloat() {
+        DebugInfoCompiler compiler = (asm, values) -> {
+            Register reg = asm.emitLoadFloat(42.0f);
+            values[0] = reg.asValue(target.getLIRKind(JavaKind.Float));
+            return null;
+        };
+        testFloatOnStack(compiler);
+        testFloatInLocal(compiler);
+    }
+
+    @Test
+    public void testStackFloat() {
+        DebugInfoCompiler compiler = (asm, values) -> {
+            Register reg = asm.emitLoadFloat(42.0f);
+            values[0] = asm.emitFloatToStack(reg);
+            return null;
+        };
+        testFloatOnStack(compiler);
+        testFloatInLocal(compiler);
+    }
+
+    public static long longOnStack() {
+        return 42;
+    }
+
+    private void testLongOnStack(DebugInfoCompiler compiler) {
+        test(compiler, getMethod("longOnStack"), 3, JavaKind.Long, JavaKind.Illegal);
+    }
+
+    public static long longInLocal() {
+        long local = 42;
+        return local;
+    }
+
+    private void testLongInLocal(DebugInfoCompiler compiler) {
+        test(compiler, getMethod("longInLocal"), 4, JavaKind.Long, JavaKind.Illegal);
+    }
+
+    @Test
+    public void testConstLong() {
+        DebugInfoCompiler compiler = (asm, values) -> {
+            values[0] = JavaConstant.forLong(42);
+            values[1] = Value.ILLEGAL;
+            return null;
+        };
+        testLongOnStack(compiler);
+        testLongInLocal(compiler);
+    }
+
+    @Test
+    public void testRegLong() {
+        DebugInfoCompiler compiler = (asm, values) -> {
+            Register reg = asm.emitLoadLong(42);
+            values[0] = reg.asValue(target.getLIRKind(JavaKind.Long));
+            values[1] = Value.ILLEGAL;
+            return null;
+        };
+        testLongOnStack(compiler);
+        testLongInLocal(compiler);
+    }
+
+    @Test
+    public void testStackLong() {
+        DebugInfoCompiler compiler = (asm, values) -> {
+            Register reg = asm.emitLoadLong(42);
+            values[0] = asm.emitLongToStack(reg);
+            values[1] = Value.ILLEGAL;
+            return null;
+        };
+        testLongOnStack(compiler);
+        testLongInLocal(compiler);
+    }
+
+    public static Class<?> objectOnStack() {
+        return SimpleDebugInfoTest.class;
+    }
+
+    private void testObjectOnStack(DebugInfoCompiler compiler) {
+        test(compiler, getMethod("objectOnStack"), 2, JavaKind.Object);
+    }
+
+    public static Class<?> objectInLocal() {
+        Class<?> local = SimpleDebugInfoTest.class;
+        return local;
+    }
+
+    private void testObjectInLocal(DebugInfoCompiler compiler) {
+        test(compiler, getMethod("objectInLocal"), 3, JavaKind.Object);
+    }
+
+    @Test
+    public void testConstObject() {
+        ResolvedJavaType type = metaAccess.lookupJavaType(objectOnStack());
+        DebugInfoCompiler compiler = (asm, values) -> {
+            values[0] = constantReflection.asJavaClass(type);
+            return null;
+        };
+        testObjectOnStack(compiler);
+        testObjectInLocal(compiler);
+    }
+
+    @Test
+    public void testRegObject() {
+        ResolvedJavaType type = metaAccess.lookupJavaType(objectOnStack());
+        DebugInfoCompiler compiler = (asm, values) -> {
+            Register reg = asm.emitLoadPointer((HotSpotConstant) constantReflection.asJavaClass(type));
+            values[0] = reg.asValue(target.getLIRKind(JavaKind.Object));
+            return null;
+        };
+        testObjectOnStack(compiler);
+        testObjectInLocal(compiler);
+    }
+
+    @Test
+    public void testStackObject() {
+        ResolvedJavaType type = metaAccess.lookupJavaType(objectOnStack());
+        DebugInfoCompiler compiler = (asm, values) -> {
+            Register reg = asm.emitLoadPointer((HotSpotConstant) constantReflection.asJavaClass(type));
+            values[0] = asm.emitPointerToStack(reg);
+            return null;
+        };
+        testObjectOnStack(compiler);
+        testObjectInLocal(compiler);
+    }
+
+    @Test
+    public void testRegNarrowObject() {
+        Assume.assumeTrue(HotSpotVMConfig.config().useCompressedOops);
+        ResolvedJavaType type = metaAccess.lookupJavaType(objectOnStack());
+        DebugInfoCompiler compiler = (asm, values) -> {
+            HotSpotConstant wide = (HotSpotConstant) constantReflection.asJavaClass(type);
+            Register reg = asm.emitLoadPointer((HotSpotConstant) wide.compress());
+            values[0] = reg.asValue(asm.narrowOopKind);
+            return null;
+        };
+        testObjectOnStack(compiler);
+        testObjectInLocal(compiler);
+    }
+
+    @Test
+    public void testStackNarrowObject() {
+        Assume.assumeTrue(HotSpotVMConfig.config().useCompressedOops);
+        ResolvedJavaType type = metaAccess.lookupJavaType(objectOnStack());
+        DebugInfoCompiler compiler = (asm, values) -> {
+            HotSpotConstant wide = (HotSpotConstant) constantReflection.asJavaClass(type);
+            Register reg = asm.emitLoadPointer((HotSpotConstant) wide.compress());
+            values[0] = asm.emitNarrowPointerToStack(reg);
+            return null;
+        };
+        testObjectOnStack(compiler);
+        testObjectInLocal(compiler);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/TestAssembler.java	Thu Apr 07 08:57:26 2016 -1000
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.vm.ci.code.test;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import jdk.vm.ci.code.CodeCacheProvider;
+import jdk.vm.ci.code.DebugInfo;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.StackSlot;
+import jdk.vm.ci.code.site.Call;
+import jdk.vm.ci.code.site.ConstantReference;
+import jdk.vm.ci.code.site.DataPatch;
+import jdk.vm.ci.code.site.DataSectionReference;
+import jdk.vm.ci.code.site.Infopoint;
+import jdk.vm.ci.code.site.InfopointReason;
+import jdk.vm.ci.code.site.Mark;
+import jdk.vm.ci.code.site.Reference;
+import jdk.vm.ci.code.site.Site;
+import jdk.vm.ci.hotspot.HotSpotCompiledCode;
+import jdk.vm.ci.hotspot.HotSpotCompiledCode.Comment;
+import jdk.vm.ci.hotspot.HotSpotCompiledNmethod;
+import jdk.vm.ci.hotspot.HotSpotConstant;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
+import jdk.vm.ci.meta.Assumptions.Assumption;
+import jdk.vm.ci.meta.InvokeTarget;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.PlatformKind;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.VMConstant;
+
+/**
+ * Simple assembler used by the code installation tests.
+ */
+public abstract class TestAssembler {
+
+    /**
+     * Emit the method prologue code (e.g. building the new stack frame).
+     */
+    public abstract void emitPrologue();
+
+    /**
+     * Emit the method epilogue code (e.g. the deopt handler).
+     */
+    public abstract void emitEpilogue();
+
+    /**
+     * Emit code to grow the stack frame.
+     *
+     * @param size the size in bytes that the stack should grow
+     */
+    public abstract void emitGrowStack(int size);
+
+    /**
+     * Get the register containing the first 32-bit integer argument.
+     */
+    public abstract Register emitIntArg0();
+
+    /**
+     * Get the register containing the second 32-bit integer argument.
+     */
+    public abstract Register emitIntArg1();
+
+    /**
+     * Emit code to add two 32-bit integer registers. May reuse one of the argument registers.
+     */
+    public abstract Register emitIntAdd(Register a, Register b);
+
+    /**
+     * Emit code to load a constant 32-bit integer to a register.
+     */
+    public abstract Register emitLoadInt(int value);
+
+    /**
+     * Emit code to load a constant 64-bit integer to a register.
+     */
+    public abstract Register emitLoadLong(long value);
+
+    /**
+     * Emit code to load a constant single-precision float to a register.
+     */
+    public abstract Register emitLoadFloat(float value);
+
+    /**
+     * Emit code to load a constant oop or metaspace pointer to a register. The pointer may be wide
+     * or narrow, depending on {@link HotSpotConstant#isCompressed() c.isCompressed()}.
+     */
+    public abstract Register emitLoadPointer(HotSpotConstant c);
+
+    /**
+     * Emit code to load a wide pointer from the {@link HotSpotCompiledCode#dataSection} to a
+     * register.
+     */
+    public abstract Register emitLoadPointer(DataSectionReference ref);
+
+    /**
+     * Emit code to load a narrow pointer from the {@link HotSpotCompiledCode#dataSection} to a
+     * register.
+     */
+    public abstract Register emitLoadNarrowPointer(DataSectionReference ref);
+
+    /**
+     * Emit code to load a (wide) pointer from a memory location to a register.
+     */
+    public abstract Register emitLoadPointer(Register base, int offset);
+
+    /**
+     * Emit code to store a 32-bit integer from a register to a new stack slot.
+     */
+    public abstract StackSlot emitIntToStack(Register a);
+
+    /**
+     * Emit code to store a 64-bit integer from a register to a new stack slot.
+     */
+    public abstract StackSlot emitLongToStack(Register a);
+
+    /**
+     * Emit code to store a single-precision float from a register to a new stack slot.
+     */
+    public abstract StackSlot emitFloatToStack(Register a);
+
+    /**
+     * Emit code to store a wide pointer from a register to a new stack slot.
+     */
+    public abstract StackSlot emitPointerToStack(Register a);
+
+    /**
+     * Emit code to store a narrow pointer from a register to a new stack slot.
+     */
+    public abstract StackSlot emitNarrowPointerToStack(Register a);
+
+    /**
+     * Emit code to uncompress a narrow pointer. The input pointer is guaranteed to be non-null.
+     */
+    public abstract Register emitUncompressPointer(Register compressed, long base, int shift);
+
+    /**
+     * Emit code to return from a function, returning a 32-bit integer.
+     */
+    public abstract void emitIntRet(Register a);
+
+    /**
+     * Emit code to return from a function, returning a wide oop pointer.
+     */
+    public abstract void emitPointerRet(Register a);
+
+    /**
+     * Emit code that traps, forcing a deoptimization.
+     */
+    public abstract void emitTrap(DebugInfo info);
+
+    public final LIRKind narrowOopKind;
+
+    protected final Buffer code;
+    protected final Buffer data;
+    private final ArrayList<Site> sites;
+    private final ArrayList<DataPatch> dataPatches;
+
+    protected final CodeCacheProvider codeCache;
+
+    private final Register[] registers;
+    private int nextRegister;
+
+    protected int frameSize;
+    private int stackAlignment;
+    private int curStackSlot;
+
+    private StackSlot deoptRescue;
+
+    protected TestAssembler(CodeCacheProvider codeCache, int initialFrameSize, int stackAlignment, PlatformKind narrowOopKind, Register... registers) {
+        this.narrowOopKind = LIRKind.reference(narrowOopKind);
+
+        this.code = new Buffer();
+        this.data = new Buffer();
+        this.sites = new ArrayList<>();
+        this.dataPatches = new ArrayList<>();
+
+        this.codeCache = codeCache;
+
+        this.registers = registers;
+        this.nextRegister = 0;
+
+        this.frameSize = initialFrameSize;
+        this.stackAlignment = stackAlignment;
+        this.curStackSlot = initialFrameSize;
+    }
+
+    protected Register newRegister() {
+        return registers[nextRegister++];
+    }
+
+    protected StackSlot newStackSlot(LIRKind kind) {
+        curStackSlot += kind.getPlatformKind().getSizeInBytes();
+        if (curStackSlot > frameSize) {
+            int newFrameSize = curStackSlot;
+            if (newFrameSize % stackAlignment != 0) {
+                newFrameSize += stackAlignment - (newFrameSize % stackAlignment);
+            }
+            emitGrowStack(newFrameSize - frameSize);
+            frameSize = newFrameSize;
+        }
+        return StackSlot.get(kind, -curStackSlot, true);
+    }
+
+    protected void setDeoptRescueSlot(StackSlot deoptRescue) {
+        this.deoptRescue = deoptRescue;
+    }
+
+    protected void recordCall(InvokeTarget target, int size, boolean direct, DebugInfo debugInfo) {
+        sites.add(new Call(target, code.position(), size, direct, debugInfo));
+    }
+
+    protected void recordMark(Object id) {
+        sites.add(new Mark(code.position(), id));
+    }
+
+    protected void recordImplicitException(DebugInfo info) {
+        sites.add(new Infopoint(code.position(), info, InfopointReason.IMPLICIT_EXCEPTION));
+    }
+
+    protected void recordDataPatchInCode(Reference ref) {
+        sites.add(new DataPatch(code.position(), ref));
+    }
+
+    protected void recordDataPatchInData(Reference ref) {
+        dataPatches.add(new DataPatch(data.position(), ref));
+    }
+
+    public DataSectionReference emitDataItem(HotSpotConstant c) {
+        DataSectionReference ref = new DataSectionReference();
+        ref.setOffset(data.position());
+
+        recordDataPatchInData(new ConstantReference((VMConstant) c));
+        if (c.isCompressed()) {
+            data.emitInt(0xDEADDEAD);
+        } else {
+            data.emitLong(0xDEADDEADDEADDEADL);
+        }
+
+        return ref;
+    }
+
+    public HotSpotCompiledCode finish(HotSpotResolvedJavaMethod method) {
+        int id = method.allocateCompileId(0);
+        byte[] finishedCode = code.finish();
+        Site[] finishedSites = sites.toArray(new Site[0]);
+        byte[] finishedData = data.finish();
+        DataPatch[] finishedDataPatches = dataPatches.toArray(new DataPatch[0]);
+        return new HotSpotCompiledNmethod(method.getName(), finishedCode, finishedCode.length, finishedSites, new Assumption[0], new ResolvedJavaMethod[]{method}, new Comment[0], finishedData, 16,
+                        finishedDataPatches, false, frameSize, deoptRescue, method, 0, id, 0L, false);
+    }
+
+    protected static class Buffer {
+
+        private ByteBuffer data = ByteBuffer.allocate(32).order(ByteOrder.nativeOrder());
+
+        private void ensureSize(int length) {
+            if (length >= data.limit()) {
+                byte[] newBuf = Arrays.copyOf(data.array(), length * 4);
+                ByteBuffer newData = ByteBuffer.wrap(newBuf);
+                newData.order(data.order());
+                newData.position(data.position());
+                data = newData;
+            }
+        }
+
+        public int position() {
+            return data.position();
+        }
+
+        public void emitByte(int b) {
+            ensureSize(data.position() + 1);
+            data.put((byte) (b & 0xFF));
+        }
+
+        public void emitShort(int b) {
+            ensureSize(data.position() + 2);
+            data.putShort((short) b);
+        }
+
+        public void emitInt(int b) {
+            ensureSize(data.position() + 4);
+            data.putInt(b);
+        }
+
+        public void emitLong(long b) {
+            ensureSize(data.position() + 8);
+            data.putLong(b);
+        }
+
+        public void emitFloat(float f) {
+            ensureSize(data.position() + 4);
+            data.putFloat(f);
+        }
+
+        public void align(int alignment) {
+            int pos = data.position();
+            int misaligned = pos % alignment;
+            if (misaligned != 0) {
+                pos += alignment - misaligned;
+                data.position(pos);
+            }
+        }
+
+        private byte[] finish() {
+            return Arrays.copyOf(data.array(), data.position());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInfoTest.java	Thu Apr 07 08:57:26 2016 -1000
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
+ * @library /
+ * @modules jdk.vm.ci/jdk.vm.ci.hotspot
+ *          jdk.vm.ci/jdk.vm.ci.meta
+ *          jdk.vm.ci/jdk.vm.ci.code
+ *          jdk.vm.ci/jdk.vm.ci.code.site
+ *          jdk.vm.ci/jdk.vm.ci.runtime
+ *          jdk.vm.ci/jdk.vm.ci.amd64
+ *          jdk.vm.ci/jdk.vm.ci.sparc
+ * @compile CodeInstallationTest.java DebugInfoTest.java TestAssembler.java amd64/AMD64TestAssembler.java sparc/SPARCTestAssembler.java
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.code.test.VirtualObjectDebugInfoTest
+ */
+
+package jdk.vm.ci.code.test;
+
+import java.util.ArrayList;
+import java.util.Objects;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.VirtualObject;
+import jdk.vm.ci.hotspot.HotSpotConstant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaValue;
+import jdk.vm.ci.meta.ResolvedJavaField;
+import jdk.vm.ci.meta.ResolvedJavaType;
+
+public class VirtualObjectDebugInfoTest extends DebugInfoTest {
+
+    private static class TestClass {
+
+        private long longField;
+        private int intField;
+        private float floatField;
+        private Object[] arrayField;
+
+        TestClass() {
+            this.longField = 8472;
+            this.intField = 42;
+            this.floatField = 3.14f;
+            this.arrayField = new Object[]{Integer.valueOf(58), this, null, Integer.valueOf(17), "Hello, World!"};
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof TestClass)) {
+                return false;
+            }
+
+            TestClass other = (TestClass) o;
+            if (this.longField != other.longField || this.intField != other.intField || this.floatField != other.floatField || this.arrayField.length != other.arrayField.length) {
+                return false;
+            }
+
+            for (int i = 0; i < this.arrayField.length; i++) {
+                // break cycle
+                if (this.arrayField[i] == this && other.arrayField[i] == other) {
+                    continue;
+                }
+
+                if (!Objects.equals(this.arrayField[i], other.arrayField[i])) {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            return super.hashCode();
+        }
+    }
+
+    public static TestClass buildObject() {
+        return new TestClass();
+    }
+
+    private VirtualObject[] compileBuildObject(TestAssembler asm, JavaValue[] values) {
+        TestClass template = new TestClass();
+        ArrayList<VirtualObject> vobjs = new ArrayList<>();
+
+        ResolvedJavaType retType = metaAccess.lookupJavaType(TestClass.class);
+        VirtualObject ret = VirtualObject.get(retType, vobjs.size());
+        vobjs.add(ret);
+        values[0] = ret;
+
+        ResolvedJavaType arrayType = metaAccess.lookupJavaType(Object[].class);
+        VirtualObject array = VirtualObject.get(arrayType, vobjs.size());
+        vobjs.add(array);
+
+        // build array for ret.arrayField
+        ResolvedJavaType integerType = metaAccess.lookupJavaType(Integer.class);
+        JavaValue[] arrayContent = new JavaValue[template.arrayField.length];
+        JavaKind[] arrayKind = new JavaKind[template.arrayField.length];
+        for (int i = 0; i < arrayContent.length; i++) {
+            arrayKind[i] = JavaKind.Object;
+            if (template.arrayField[i] == null) {
+                arrayContent[i] = JavaConstant.NULL_POINTER;
+            } else if (template.arrayField[i] == template) {
+                arrayContent[i] = ret;
+            } else if (template.arrayField[i] instanceof Integer) {
+                int value = (Integer) template.arrayField[i];
+                VirtualObject boxed = VirtualObject.get(integerType, vobjs.size());
+                vobjs.add(boxed);
+                arrayContent[i] = boxed;
+                boxed.setValues(new JavaValue[]{JavaConstant.forInt(value)}, new JavaKind[]{JavaKind.Int});
+            } else if (template.arrayField[i] instanceof String) {
+                String value = (String) template.arrayField[i];
+                Register reg = asm.emitLoadPointer((HotSpotConstant) constantReflection.forString(value));
+                arrayContent[i] = reg.asValue(target.getLIRKind(JavaKind.Object));
+            } else {
+                Assert.fail("unexpected value");
+            }
+        }
+        array.setValues(arrayContent, arrayKind);
+
+        // build return object
+        ResolvedJavaField[] fields = retType.getInstanceFields(true);
+        JavaValue[] retContent = new JavaValue[fields.length];
+        JavaKind[] retKind = new JavaKind[fields.length];
+        for (int i = 0; i < fields.length; i++) {
+            retKind[i] = fields[i].getJavaKind();
+            switch (retKind[i]) {
+                case Long: // template.longField
+                    retContent[i] = JavaConstant.forLong(template.longField);
+                    break;
+                case Int: // template.intField
+                    Register intReg = asm.emitLoadInt(template.intField);
+                    retContent[i] = asm.emitIntToStack(intReg);
+                    break;
+                case Float: // template.floatField
+                    Register fReg = asm.emitLoadFloat(template.floatField);
+                    retContent[i] = fReg.asValue(target.getLIRKind(JavaKind.Float));
+                    break;
+                case Object: // template.arrayField
+                    retContent[i] = array;
+                    break;
+                default:
+                    Assert.fail("unexpected field");
+            }
+        }
+        ret.setValues(retContent, retKind);
+
+        return vobjs.toArray(new VirtualObject[0]);
+    }
+
+    @Test
+    public void testBuildObject() {
+        test(this::compileBuildObject, getMethod("buildObject"), 7, JavaKind.Object);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/amd64/AMD64TestAssembler.java	Thu Apr 07 08:57:26 2016 -1000
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.vm.ci.code.test.amd64;
+
+import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.amd64.AMD64Kind;
+import jdk.vm.ci.code.CodeCacheProvider;
+import jdk.vm.ci.code.DebugInfo;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.StackSlot;
+import jdk.vm.ci.code.site.ConstantReference;
+import jdk.vm.ci.code.site.DataSectionReference;
+import jdk.vm.ci.code.test.TestAssembler;
+import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
+import jdk.vm.ci.hotspot.HotSpotConstant;
+import jdk.vm.ci.hotspot.HotSpotForeignCallTarget;
+import jdk.vm.ci.hotspot.HotSpotVMConfig;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.VMConstant;
+
+public class AMD64TestAssembler extends TestAssembler {
+
+    public AMD64TestAssembler(CodeCacheProvider codeCache) {
+        super(codeCache, 16, 16, AMD64Kind.DWORD, AMD64.rax, AMD64.rcx, AMD64.rdi, AMD64.r8, AMD64.r9, AMD64.r10);
+    }
+
+    private void emitFatNop() {
+        // 5 byte NOP:
+        // NOP DWORD ptr [EAX + EAX*1 + 00H]
+        code.emitByte(0x0F);
+        code.emitByte(0x1F);
+        code.emitByte(0x44);
+        code.emitByte(0x00);
+        code.emitByte(0x00);
+    }
+
+    @Override
+    public void emitPrologue() {
+        // WARNING: Initial instruction MUST be 5 bytes or longer so that
+        // NativeJump::patch_verified_entry will be able to patch out the entry
+        // code safely.
+        emitFatNop();
+        code.emitByte(0x50 | AMD64.rbp.encoding);  // PUSH rbp
+        emitMove(true, AMD64.rbp, AMD64.rsp);      // MOV rbp, rsp
+        setDeoptRescueSlot(newStackSlot(LIRKind.value(AMD64Kind.QWORD)));
+    }
+
+    @Override
+    public void emitEpilogue() {
+        HotSpotVMConfig config = HotSpotVMConfig.config();
+        recordMark(config.MARKID_DEOPT_HANDLER_ENTRY);
+        recordCall(new HotSpotForeignCallTarget(config.handleDeoptStub), 5, true, null);
+        code.emitByte(0xE8); // CALL rel32
+        code.emitInt(0xDEADDEAD);
+    }
+
+    @Override
+    public void emitGrowStack(int size) {
+        // SUB rsp, size
+        code.emitByte(0x48);
+        code.emitByte(0x81);
+        code.emitByte(0xEC);
+        code.emitInt(size);
+    }
+
+    @Override
+    public Register emitIntArg0() {
+        return codeCache.getRegisterConfig().getCallingConventionRegisters(HotSpotCallingConventionType.JavaCall, JavaKind.Int)[0];
+    }
+
+    @Override
+    public Register emitIntArg1() {
+        return codeCache.getRegisterConfig().getCallingConventionRegisters(HotSpotCallingConventionType.JavaCall, JavaKind.Int)[1];
+    }
+
+    private void emitREX(boolean w, int r, int x, int b) {
+        int wrxb = (w ? 0x08 : 0) | ((r >> 3) << 2) | ((x >> 3) << 1) | (b >> 3);
+        if (wrxb != 0) {
+            code.emitByte(0x40 | wrxb);
+        }
+    }
+
+    private void emitModRMReg(boolean w, int opcode, int r, int m) {
+        emitREX(w, r, 0, m);
+        code.emitByte((byte) opcode);
+        code.emitByte((byte) 0xC0 | ((r & 0x7) << 3) | (m & 0x7));
+    }
+
+    private void emitModRMMemory(boolean w, int opcode, int r, int b, int offset) {
+        emitREX(w, r, 0, b);
+        code.emitByte((byte) opcode);
+        code.emitByte((byte) 0x80 | ((r & 0x7) << 3) | (b & 0x7));
+        code.emitInt(offset);
+    }
+
+    @Override
+    public Register emitLoadInt(int c) {
+        Register ret = newRegister();
+        emitREX(false, 0, 0, ret.encoding);
+        code.emitByte(0xB8 | (ret.encoding & 0x7)); // MOV r32, imm32
+        code.emitInt(c);
+        return ret;
+    }
+
+    @Override
+    public Register emitLoadLong(long c) {
+        Register ret = newRegister();
+        emitREX(true, 0, 0, ret.encoding);
+        code.emitByte(0xB8 | (ret.encoding & 0x7)); // MOV r64, imm64
+        code.emitLong(c);
+        return ret;
+    }
+
+    @Override
+    public Register emitLoadFloat(float c) {
+        DataSectionReference ref = new DataSectionReference();
+        ref.setOffset(data.position());
+        data.emitFloat(c);
+
+        recordDataPatchInCode(ref);
+        Register ret = AMD64.xmm0;
+        emitREX(false, ret.encoding, 0, 0);
+        code.emitByte(0xF3);
+        code.emitByte(0x0F);
+        code.emitByte(0x10);                               // MOVSS xmm1, xmm2/m32
+        code.emitByte(0x05 | ((ret.encoding & 0x7) << 3)); // xmm, [rip+offset]
+        code.emitInt(0xDEADDEAD);
+        return ret;
+    }
+
+    @Override
+    public Register emitLoadPointer(HotSpotConstant c) {
+        recordDataPatchInCode(new ConstantReference((VMConstant) c));
+        if (c.isCompressed()) {
+            Register ret = newRegister();
+            emitREX(false, 0, 0, ret.encoding);
+            code.emitByte(0xB8 | (ret.encoding & 0x7)); // MOV r32, imm32
+            code.emitInt(0xDEADDEAD);
+            return ret;
+        } else {
+            return emitLoadLong(0xDEADDEADDEADDEADL);
+        }
+    }
+
+    private Register emitLoadPointer(DataSectionReference ref, boolean narrow) {
+        recordDataPatchInCode(ref);
+        Register ret = newRegister();
+        emitREX(!narrow, ret.encoding, 0, 0);
+        code.emitByte(0x8B);                               // MOV r64,r/m64
+        code.emitByte(0x05 | ((ret.encoding & 0x7) << 3)); // r64, [rip+offset]
+        code.emitInt(0xDEADDEAD);
+        return ret;
+    }
+
+    @Override
+    public Register emitLoadPointer(DataSectionReference ref) {
+        return emitLoadPointer(ref, false);
+    }
+
+    @Override
+    public Register emitLoadNarrowPointer(DataSectionReference ref) {
+        return emitLoadPointer(ref, true);
+    }
+
+    @Override
+    public Register emitLoadPointer(Register b, int offset) {
+        Register ret = newRegister();
+        emitModRMMemory(true, 0x8B, ret.encoding, b.encoding, offset); // MOV r64,r/m64
+        return ret;
+    }
+
+    @Override
+    public StackSlot emitIntToStack(Register a) {
+        StackSlot ret = newStackSlot(LIRKind.value(AMD64Kind.DWORD));
+        // MOV r/m32,r32
+        emitModRMMemory(false, 0x89, a.encoding, AMD64.rbp.encoding, ret.getRawOffset() + 16);
+        return ret;
+    }
+
+    @Override
+    public StackSlot emitLongToStack(Register a) {
+        StackSlot ret = newStackSlot(LIRKind.value(AMD64Kind.QWORD));
+        // MOV r/m64,r64
+        emitModRMMemory(true, 0x89, a.encoding, AMD64.rbp.encoding, ret.getRawOffset() + 16);
+        return ret;
+    }
+
+    @Override
+    public StackSlot emitFloatToStack(Register a) {
+        StackSlot ret = newStackSlot(LIRKind.value(AMD64Kind.SINGLE));
+        emitREX(false, a.encoding, 0, 0);
+        code.emitByte(0xF3);
+        code.emitByte(0x0F);
+        code.emitByte(0x11);                               // MOVSS xmm2/m32, xmm1
+        code.emitByte(0x85 | ((a.encoding & 0x7) << 3));   // [rbp+offset]
+        code.emitInt(ret.getRawOffset() + 16);
+        return ret;
+    }
+
+    @Override
+    public StackSlot emitPointerToStack(Register a) {
+        StackSlot ret = newStackSlot(LIRKind.reference(AMD64Kind.QWORD));
+        // MOV r/m64,r64
+        emitModRMMemory(true, 0x89, a.encoding, AMD64.rbp.encoding, ret.getRawOffset() + 16);
+        return ret;
+    }
+
+    @Override
+    public StackSlot emitNarrowPointerToStack(Register a) {
+        StackSlot ret = newStackSlot(LIRKind.reference(AMD64Kind.DWORD));
+        // MOV r/m32,r32
+        emitModRMMemory(false, 0x89, a.encoding, AMD64.rbp.encoding, ret.getRawOffset() + 16);
+        return ret;
+    }
+
+    @Override
+    public Register emitUncompressPointer(Register compressed, long base, int shift) {
+        if (shift > 0) {
+            emitModRMReg(true, 0xC1, 4, compressed.encoding);
+            code.emitByte(shift);
+        }
+        if (base == 0) {
+            return compressed;
+        } else {
+            Register tmp = emitLoadLong(base);
+            emitModRMReg(true, 0x03, tmp.encoding, compressed.encoding);
+            return tmp;
+        }
+    }
+
+    @Override
+    public Register emitIntAdd(Register a, Register b) {
+        emitModRMReg(false, 0x03, a.encoding, b.encoding);
+        return a;
+    }
+
+    private void emitMove(boolean w, Register to, Register from) {
+        if (to != from) {
+            emitModRMReg(w, 0x8B, to.encoding, from.encoding);
+        }
+    }
+
+    @Override
+    public void emitIntRet(Register a) {
+        emitMove(false, AMD64.rax, a);             // MOV eax, ...
+        emitMove(true, AMD64.rsp, AMD64.rbp);      // MOV rsp, rbp
+        code.emitByte(0x58 | AMD64.rbp.encoding);  // POP rbp
+        code.emitByte(0xC3);                       // RET
+    }
+
+    @Override
+    public void emitPointerRet(Register a) {
+        emitMove(true, AMD64.rax, a);              // MOV rax, ...
+        emitMove(true, AMD64.rsp, AMD64.rbp);      // MOV rsp, rbp
+        code.emitByte(0x58 | AMD64.rbp.encoding);  // POP rbp
+        code.emitByte(0xC3);                       // RET
+    }
+
+    @Override
+    public void emitTrap(DebugInfo info) {
+        recordImplicitException(info);
+        // MOV rax, [0]
+        code.emitByte(0x8B);
+        code.emitByte(0x04);
+        code.emitByte(0x25);
+        code.emitInt(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/sparc/SPARCTestAssembler.java	Thu Apr 07 08:57:26 2016 -1000
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.vm.ci.code.test.sparc;
+
+import jdk.vm.ci.code.CodeCacheProvider;
+import jdk.vm.ci.code.DebugInfo;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.StackSlot;
+import jdk.vm.ci.code.site.ConstantReference;
+import jdk.vm.ci.code.site.DataSectionReference;
+import jdk.vm.ci.code.test.TestAssembler;
+import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
+import jdk.vm.ci.hotspot.HotSpotCompiledCode;
+import jdk.vm.ci.hotspot.HotSpotConstant;
+import jdk.vm.ci.hotspot.HotSpotForeignCallTarget;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
+import jdk.vm.ci.hotspot.HotSpotVMConfig;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.VMConstant;
+import jdk.vm.ci.sparc.SPARC;
+import jdk.vm.ci.sparc.SPARCKind;
+
+public class SPARCTestAssembler extends TestAssembler {
+
+    private static final int MASK13 = (1 << 13) - 1;
+
+    public SPARCTestAssembler(CodeCacheProvider codeCache) {
+        super(codeCache, 0, 16, SPARCKind.WORD, SPARC.l0, SPARC.l1, SPARC.l2, SPARC.l3, SPARC.l4, SPARC.l5, SPARC.l6, SPARC.l7);
+    }
+
+    private void emitOp2(Register rd, int op2, int imm22) {
+        code.emitInt((0b00 << 30) | (rd.encoding << 25) | (op2 << 22) | imm22);
+    }
+
+    private void emitOp3(int op, Register rd, int op3, Register rs1, Register rs2) {
+        code.emitInt((op << 30) | (rd.encoding << 25) | (op3 << 19) | (rs1.encoding << 14) | rs2.encoding);
+    }
+
+    private void emitOp3(int op, Register rd, int op3, Register rs1, int simm13) {
+        code.emitInt((op << 30) | (rd.encoding << 25) | (op3 << 19) | (rs1.encoding << 14) | (1 << 13) | (simm13 & MASK13));
+    }
+
+    private void emitNop() {
+        code.emitInt(1 << 24);
+    }
+
+    @Override
+    public void emitPrologue() {
+        // SAVE sp, -128, sp
+        emitOp3(0b10, SPARC.sp, 0b111100, SPARC.sp, -SPARC.REGISTER_SAFE_AREA_SIZE);
+        setDeoptRescueSlot(newStackSlot(LIRKind.value(SPARCKind.XWORD)));
+    }
+
+    @Override
+    public void emitEpilogue() {
+        HotSpotVMConfig config = HotSpotVMConfig.config();
+        recordMark(config.MARKID_DEOPT_HANDLER_ENTRY);
+        recordCall(new HotSpotForeignCallTarget(config.handleDeoptStub), 4, true, null);
+        code.emitInt(1 << 30); // CALL
+    }
+
+    @Override
+    public HotSpotCompiledCode finish(HotSpotResolvedJavaMethod method) {
+        frameSize += SPARC.REGISTER_SAFE_AREA_SIZE;
+        return super.finish(method);
+    }
+
+    @Override
+    public void emitGrowStack(int size) {
+        emitOp3(0b10, SPARC.sp, 0b000100, SPARC.sp, size); // SUB sp, size, sp
+    }
+
+    @Override
+    public Register emitIntArg0() {
+        return codeCache.getRegisterConfig().getCallingConventionRegisters(HotSpotCallingConventionType.JavaCallee, JavaKind.Int)[0];
+    }
+
+    @Override
+    public Register emitIntArg1() {
+        return codeCache.getRegisterConfig().getCallingConventionRegisters(HotSpotCallingConventionType.JavaCallee, JavaKind.Int)[1];
+    }
+
+    @Override
+    public Register emitLoadInt(int c) {
+        Register ret = newRegister();
+        int hi = c >>> 10;
+        int lo = c & ((1 << 10) - 1);
+        if (hi == 0) {
+            emitOp3(0b10, ret, 0b000010, SPARC.g0, lo); // OR g0, lo, ret
+        } else {
+            emitOp2(ret, 0b100, hi);                    // SETHI hi, ret
+            if (lo != 0) {
+                emitOp3(0b10, ret, 0b000010, ret, lo);  // OR ret, lo, ret
+            }
+        }
+        return ret;
+    }
+
+    @Override
+    public Register emitLoadLong(long c) {
+        if ((c & 0xFFFF_FFFFL) == c) {
+            return emitLoadInt((int) c);
+        } else {
+            DataSectionReference ref = new DataSectionReference();
+            data.align(8);
+            ref.setOffset(data.position());
+            data.emitLong(c);
+            return emitLoadPointer(ref);
+        }
+    }
+
+    private void emitPatchableSethi(Register ret, boolean wide) {
+        int startPos = code.position();
+        emitOp2(ret, 0b100, 0);              // SETHI 0, ret
+        if (wide) {
+            // pad for later patching
+            while (code.position() < (startPos + 28)) {
+                emitNop();
+            }
+        }
+    }
+
+    @Override
+    public Register emitLoadFloat(float c) {
+        DataSectionReference ref = new DataSectionReference();
+        data.align(4);
+        ref.setOffset(data.position());
+        data.emitFloat(c);
+
+        Register ptr = newRegister();
+        recordDataPatchInCode(ref);
+        emitPatchableSethi(ptr, true);
+        emitOp3(0b11, SPARC.f0, 0b100000, ptr, 0); // LDF [ptr+0], f0
+        return SPARC.f0;
+    }
+
+    @Override
+    public Register emitLoadPointer(HotSpotConstant c) {
+        Register ret = newRegister();
+        recordDataPatchInCode(new ConstantReference((VMConstant) c));
+
+        emitPatchableSethi(ret, !c.isCompressed());
+        emitOp3(0b10, ret, 0b000010, ret, 0); // OR ret, 0, ret
+
+        return ret;
+    }
+
+    @Override
+    public Register emitLoadPointer(DataSectionReference ref) {
+        Register ret = newRegister();
+        recordDataPatchInCode(ref);
+        emitPatchableSethi(ret, true);
+        emitOp3(0b11, ret, 0b001011, ret, 0); // LDX [ret+0], ret
+        return ret;
+    }
+
+    @Override
+    public Register emitLoadNarrowPointer(DataSectionReference ref) {
+        Register ret = newRegister();
+        recordDataPatchInCode(ref);
+        emitPatchableSethi(ret, true);
+        emitOp3(0b11, ret, 0b000000, ret, 0); // LDUW [ret+0], ret
+        return ret;
+    }
+
+    @Override
+    public Register emitLoadPointer(Register b, int offset) {
+        Register ret = newRegister();
+        emitOp3(0b11, ret, 0b001011, b, offset); // LDX [b+offset], ret
+        return ret;
+    }
+
+    @Override
+    public StackSlot emitIntToStack(Register a) {
+        StackSlot ret = newStackSlot(LIRKind.value(SPARCKind.WORD));
+        // STW a, [fp+offset]
+        emitOp3(0b11, a, 0b000100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
+        return ret;
+    }
+
+    @Override
+    public StackSlot emitLongToStack(Register a) {
+        StackSlot ret = newStackSlot(LIRKind.value(SPARCKind.XWORD));
+        // STX a, [fp+offset]
+        emitOp3(0b11, a, 0b001110, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
+        return ret;
+    }
+
+    @Override
+    public StackSlot emitFloatToStack(Register a) {
+        StackSlot ret = newStackSlot(LIRKind.value(SPARCKind.SINGLE));
+        // STF a, [fp+offset]
+        emitOp3(0b11, a, 0b100100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
+        return ret;
+    }
+
+    @Override
+    public StackSlot emitPointerToStack(Register a) {
+        StackSlot ret = newStackSlot(LIRKind.reference(SPARCKind.XWORD));
+        // STX a, [fp+offset]
+        emitOp3(0b11, a, 0b001110, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
+        return ret;
+    }
+
+    @Override
+    public StackSlot emitNarrowPointerToStack(Register a) {
+        StackSlot ret = newStackSlot(LIRKind.reference(SPARCKind.WORD));
+        // STW a, [fp+offset]
+        emitOp3(0b11, a, 0b000100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
+        return ret;
+    }
+
+    @Override
+    public Register emitUncompressPointer(Register compressed, long base, int shift) {
+        Register ret;
+        if (shift > 0) {
+            ret = newRegister();
+            emitOp3(0b10, ret, 0b100101, compressed, shift); // SLL compressed, shift, ret
+        } else {
+            ret = compressed;
+        }
+        if (base == 0) {
+            return ret;
+        } else {
+            Register b = emitLoadLong(base);
+            emitOp3(0b10, b, 0b00000, ret, b); // ADD b, ret, b
+            return b;
+        }
+    }
+
+    @Override
+    public Register emitIntAdd(Register a, Register b) {
+        Register ret = newRegister();
+        emitOp3(0b10, ret, 0b00000, a, b); // ADD a, b, ret
+        return ret;
+    }
+
+    private void emitMove(Register to, Register from) {
+        if (to != from) {
+            emitOp3(0b10, to, 0b000010, from, SPARC.g0); // OR from, g0, to
+        }
+    }
+
+    @Override
+    public void emitIntRet(Register a) {
+        emitPointerRet(a);
+    }
+
+    @Override
+    public void emitPointerRet(Register a) {
+        emitMove(SPARC.i0, a);
+        emitOp3(0b10, SPARC.g0, 0b111000, SPARC.i7, 8);        // JMPL [i7+8], g0
+        emitOp3(0b10, SPARC.g0, 0b111101, SPARC.g0, SPARC.g0); // RESTORE g0, g0, g0
+    }
+
+    @Override
+    public void emitTrap(DebugInfo info) {
+        recordImplicitException(info);
+        emitOp3(0b11, SPARC.g0, 0b001011, SPARC.g0, 0); // LDX [g0+0], g0
+    }
+
+    @Override
+    public DataSectionReference emitDataItem(HotSpotConstant c) {
+        if (c.isCompressed()) {
+            data.align(4);
+        } else {
+            data.align(8);
+        }
+        return super.emitDataItem(c);
+    }
+}