changeset 14768:3e9a960f0da1

HSAIL: preliminary deopt support Contributed-by: Tom Deneau <tom.deneau@amd.com>
author Doug Simon <doug.simon@oracle.com>
date Wed, 26 Mar 2014 17:33:54 +0100
parents ded08e344e4a
children 141d570b397c
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ExternalCompilationResult.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/AbstractHSAILAssembler.java graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchBase.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchMany16384Test.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchMany20000Test.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchMany5000Test.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchMany8192Test.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchMany987654HighTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchMany987654Test.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchMany99999Test.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchManyBase.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchMost1000Test.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchMost20000Test.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchSingle16384Test.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchSingle20000Test.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchSingle5000Test.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchSingle8192Test.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchSingleBase.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCheckDoubleNonZeroBciTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCheckFailsInMiddleTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCheckFloatNonZeroBciTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCheckInlineTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCheckLongNonZeroBciTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCheckNonZeroBciInstanceTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCheckNonZeroBciTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCheckTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/ClassCastNonZeroBciTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/ClassCastTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntStreamNullCatchNonZeroBciTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntStreamNullCheckNonZeroBciTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntStreamNullCheckTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntStreamNullNonArrayParamCheckTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntStreamNullParamCheckTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/SingleExceptionTestBase.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMandelBoundsCheckTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/Vec3ObjStreamClassCastNonZeroBciTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/Vec3ObjStreamClassCastTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/Vec3ObjStreamNullCheckNonZeroBciTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/Vec3ObjStreamNullCheckTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/Vec3ObjStreamNullParamCheckTest.java graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXMethodInvalidation1Test.java graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTest.java graal/com.oracle.graal.gpu/src/com/oracle/graal/gpu/ExternalCompilationResult.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLoweringProvider.java graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java mx/projects src/gpu/hsail/vm/gpu_hsail.cpp src/gpu/hsail/vm/gpu_hsail.hpp src/gpu/hsail/vm/gpu_hsail_Frame.hpp src/gpu/hsail/vm/hsailArgumentsBase.cpp src/gpu/hsail/vm/hsailArgumentsBase.hpp src/gpu/hsail/vm/hsailJavaCallArguments.hpp src/gpu/hsail/vm/hsailKernelArguments.cpp src/gpu/hsail/vm/hsailKernelArguments.hpp src/gpu/hsail/vm/vmStructs_hsail.hpp src/share/vm/classfile/javaClasses.cpp src/share/vm/classfile/systemDictionary.hpp src/share/vm/classfile/vmSymbols.hpp src/share/vm/graal/graalCompiler.cpp src/share/vm/graal/graalCompiler.hpp src/share/vm/runtime/javaCalls.cpp src/share/vm/runtime/javaCalls.hpp src/share/vm/runtime/sharedRuntime.cpp src/share/vm/runtime/thread.cpp src/share/vm/runtime/thread.hpp src/share/vm/runtime/vmStructs.cpp
diffstat 81 files changed, 4425 insertions(+), 487 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ExternalCompilationResult.java	Wed Mar 26 17:30:40 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2009, 2013, 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 com.oracle.graal.api.code;
-
-/**
- * Represents the output from compiling a method generated by Graal, but executing in a memory and
- * computational subsystem outside the Graal host system.
- * 
- * Output may include the compiled machine code, associated data and references, relocation
- * information, deoptimization information, as this result is generated from a structure graph on
- * the Graal host system.
- */
-public class ExternalCompilationResult extends CompilationResult {
-
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * Address of the point of entry to the external compilation result.
-     */
-    private long entryPoint;
-
-    public ExternalCompilationResult() {
-        super();
-    }
-
-    /**
-     * Set the address for the point of entry to the external compilation result.
-     * 
-     * @param addr the address of the entry point
-     */
-    public void setEntryPoint(long addr) {
-        entryPoint = addr;
-    }
-
-    /**
-     * Return the address for the point of entry to the external compilation result.
-     * 
-     * @return address value
-     */
-    public long getEntryPoint() {
-        return entryPoint;
-    }
-
-    /**
-     * Gets the {@linkplain #getTargetCode() code} in this compilation result as a string.
-     */
-    public String getCodeString() {
-        return new String(getTargetCode(), 0, getTargetCodeSize());
-    }
-}
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java	Wed Mar 26 17:30:40 2014 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java	Wed Mar 26 17:33:54 2014 +0100
@@ -29,6 +29,8 @@
 
     void setRegister(int idx, PlatformKind kind);
 
+    PlatformKind getRegister(int idx);
+
     void setStackSlot(int offset, PlatformKind kind);
 
     boolean hasRegisterRefMap();
--- a/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/AbstractHSAILAssembler.java	Wed Mar 26 17:30:40 2014 +0100
+++ b/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/AbstractHSAILAssembler.java	Wed Mar 26 17:33:54 2014 +0100
@@ -47,7 +47,11 @@
 
     @Override
     public void jmp(Label l) {
-        emitString("brn " + nameOf(l) + ";");
+        emitJumpToLabelName(nameOf(l));
+    }
+
+    public void emitJumpToLabelName(String labelName) {
+        emitString("brn " + labelName + ";");
     }
 
     @Override
--- a/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java	Wed Mar 26 17:30:40 2014 +0100
+++ b/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java	Wed Mar 26 17:33:54 2014 +0100
@@ -20,20 +20,17 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package com.oracle.graal.asm.hsail;
 
-import java.lang.reflect.*;
-
-import com.oracle.graal.api.code.*;
-
 import static com.oracle.graal.api.code.MemoryBarriers.*;
 import static com.oracle.graal.api.code.ValueUtil.*;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hsail.*;
 import com.oracle.graal.graph.GraalInternalError;
 import com.amd.okra.OkraUtil;
+import java.lang.reflect.Array;
 
 /**
  * This class contains routines to emit HSAIL assembly code.
@@ -163,6 +160,10 @@
         emitAddrOp("lda_global_u64", dest, addr);
     }
 
+    public final void emitLoadKernelArg(Value dest, String kernArgName, String argTypeStr) {
+        emitString("ld_kernarg_" + argTypeStr + " " + HSAIL.mapRegister(dest) + ", [" + kernArgName + "];");
+    }
+
     public final void emitStore(Kind kind, Value src, HSAILAddress addr) {
         emitStore(src, addr, getArgTypeFromKind(kind));
     }
@@ -319,6 +320,12 @@
         emitString(prefix + destType + "_" + srcType + " " + HSAIL.mapRegister(dest) + ", " + HSAIL.mapRegister(src) + ";");
     }
 
+    public void emitConvert(Value dest, Value src, Kind destKind, Kind srcKind) {
+        String destType = getArgTypeFromKind(destKind);
+        String srcType = getArgTypeFromKind(srcKind);
+        emitConvert(dest, src, destType, srcType);
+    }
+
     /**
      * Emits a convert instruction that uses unsigned prefix, regardless of the type of dest and
      * src.
@@ -340,6 +347,7 @@
         } else {
             Constant consrc = asConstant(src);
             switch (src.getKind()) {
+                case Boolean:
                 case Int:
                     return Integer.toString(consrc.asInt());
                 case Float:
@@ -421,9 +429,13 @@
                 // Emit an instruction with two source operands.
                 emitString(String.format("%s %s, %s, %s;", instr, HSAIL.mapRegister(dest), mapRegOrConstToString(sources[0]), mapRegOrConstToString(sources[1])));
                 break;
+            case 1:
+                // Emit an instruction with one source operand.
+                emitString(String.format("%s %s, %s;", instr, HSAIL.mapRegister(dest), mapRegOrConstToString(sources[0])));
+                break;
             default:
                 // Emit an instruction with one source operand.
-                emitString(String.format("%s %s, %s;", instr, HSAIL.mapRegister(dest), mapRegOrConstToString(sources[0])));
+                emitString(String.format("%s %s;", instr, HSAIL.mapRegister(dest)));
                 break;
         }
     }
@@ -523,9 +535,20 @@
      * @param newValue the new value that will be written to the memory location if the cmpValue
      *            comparison matches
      */
-    public void emitAtomicCas(AllocatableValue result, HSAILAddress address, AllocatableValue cmpValue, AllocatableValue newValue) {
-        emitString(String.format("atomic_cas_global_b%d   %s, %s, %s, %s;", getArgSize(cmpValue), HSAIL.mapRegister(result), mapAddress(address), HSAIL.mapRegister(cmpValue),
-                        HSAIL.mapRegister(newValue)));
+    public void emitAtomicCas(AllocatableValue result, HSAILAddress address, Value cmpValue, Value newValue) {
+        emitString(String.format("atomic_cas_global_b%d   %s, %s, %s, %s;", getArgSize(cmpValue), HSAIL.mapRegister(result), mapAddress(address), mapRegOrConstToString(cmpValue),
+                        mapRegOrConstToString(newValue)));
+    }
+
+    /**
+     * Emits an atomic_add_global instruction.
+     * 
+     * @param result result operand that gets the original contents of the memory location
+     * @param address the memory location
+     * @param deltaValue the amount to add
+     */
+    public void emitAtomicAdd(AllocatableValue result, HSAILAddress address, Value deltaValue) {
+        emitString(String.format("atomic_add_global_u%d   %s, %s, %s;", getArgSize(result), HSAIL.mapRegister(result), mapAddress(address), mapRegOrConstToString(deltaValue)));
     }
 
     /**
@@ -537,7 +560,52 @@
         emitString(comment);
     }
 
+    public String getDeoptInfoName() {
+        return "%_deoptInfo";
+    }
+
+    public String getDeoptLabelName() {
+        return "@L_Deopt";
+    }
+
+    public void emitWorkItemAbsId(Value dest) {
+        emitString(String.format("workitemabsid_u32 %s, 0;", HSAIL.mapRegister(dest)));
+    }
+
+    public void emitCuId(Value dest) {
+        emitString(String.format("cuid_u32 %s;", HSAIL.mapRegister(dest)));
+    }
+
+    public void emitLaneId(Value dest) {
+        emitString(String.format("laneid_u32 %s;", HSAIL.mapRegister(dest)));
+    }
+
+    public void emitWaveId(Value dest) {
+        emitString(String.format("waveid_u32 %s;", HSAIL.mapRegister(dest)));
+    }
+
+    public void emitMaxWaveId(Value dest) {
+        // emitString(String.format("maxwaveid_u32 %s;", HSAIL.mapRegister(dest)));
+        int hardCodedMaxWaveId = 36;
+        emitComment("// Hard-coded maxwaveid=" + hardCodedMaxWaveId + " until it works");
+        emitMov(dest, Constant.forInt(hardCodedMaxWaveId));
+    }
+
+    public void emitMultiplyByWavesize(Value dest) {
+        String regName = HSAIL.mapRegister(dest);
+        emitString(String.format("mul_u%d %s, %s, WAVESIZE;", getArgSize(dest), regName, regName));
+    }
+
+    public void emitGetWavesize(Value dest) {
+        String regName = HSAIL.mapRegister(dest);
+        emitString(String.format("mov_b%d %s, WAVESIZE;", getArgSize(dest), regName));
+    }
+
+    public void emitLoadAcquire(Value dest, HSAILAddress address) {
+        emitString(String.format("ld_global_acq_u%d %s, %s;", getArgSize(dest), HSAIL.mapRegister(dest), mapAddress(address)));
+    }
+
     public void emitStoreRelease(Value src, HSAILAddress address) {
-        emitAddrOp("st_global_rel_u" + getArgSize(src), src, address);
+        emitString(String.format("st_global_rel_u%d %s, %s;", getArgSize(src), HSAIL.mapRegister(src), mapAddress(address)));
     }
 }
--- a/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java	Wed Mar 26 17:30:40 2014 +0100
+++ b/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java	Wed Mar 26 17:33:54 2014 +0100
@@ -39,6 +39,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.gpu.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.hsail.*;
 import com.oracle.graal.hotspot.meta.*;
@@ -131,16 +132,21 @@
 
     // Special overrides for the testGeneratedxxx routines which set
     // required graal options that we need to run any junit test
+
+    private OverrideScope getOverrideScope() {
+        return OptionValue.override(GraalOptions.InlineEverything, true, accessibleRemoveNeverExecutedCode, false);
+    }
+
     @Override
     public void testGeneratedHsail() {
-        try (OverrideScope s = OptionValue.override(GraalOptions.InlineEverything, true, accessibleRemoveNeverExecutedCode, false)) {
+        try (OverrideScope s = getOverrideScope()) {
             super.testGeneratedHsail();
         }
     }
 
     @Override
     public void testGeneratedHsailUsingLambdaMethod() {
-        try (OverrideScope s = OptionValue.override(GraalOptions.InlineEverything, true, accessibleRemoveNeverExecutedCode, false)) {
+        try (OverrideScope s = getOverrideScope()) {
             super.testGeneratedHsailUsingLambdaMethod();
         }
     }
--- a/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java	Wed Mar 26 17:30:40 2014 +0100
+++ b/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java	Wed Mar 26 17:33:54 2014 +0100
@@ -118,6 +118,8 @@
         dispatchMode = DispatchMode.SEQ;
         hsailMode = HsailMode.COMPILED;
         useLambdaMethod = false;
+        // Control which okra instances can run the tests (is Simulator is static).
+        onSimulator = OkraContext.isSimulator();
         this.okraLibExists = okraLibExists;
     }
 
@@ -609,8 +611,12 @@
             fail("wrong arguments invoking " + testMethod + ", check number and type of args passed to dispatchMethodKernel");
         } catch (InvocationTargetException e) {
             Throwable cause = e.getCause();
-            String errstr = testMethod + " threw an exception on gid=" + rangeIndex + ", exception was " + cause;
-            fail(errstr);
+            if (cause instanceof RuntimeException) {
+                throw ((RuntimeException) cause);
+            } else {
+                String errstr = testMethod + " threw a checked exception on gid=" + rangeIndex + ", exception was " + cause;
+                fail(errstr);
+            }
         } catch (Exception e) {
             fail("Unknown exception " + e + " invoking " + testMethod);
         }
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java	Wed Mar 26 17:30:40 2014 +0100
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -26,11 +26,11 @@
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
+import com.oracle.graal.gpu.*;
 import com.oracle.graal.hotspot.hsail.*;
 import com.oracle.graal.hsail.*;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchBase.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester;
+
+/**
+ * Base Class for tests that deopt but then catch the exception in the run routine itself.
+ */
+public abstract class BoundsCatchBase extends GraalKernelTester {
+
+    abstract int getGlobalSize();
+
+    final int num = getGlobalSize();
+    @Result int[] outArray = new int[num];
+
+    void setupArrays() {
+        for (int i = 0; i < num; i++) {
+            outArray[i] = -i;
+        }
+    }
+
+    // Note: could not push the whole run routine here because
+    // problems with indirect call to getDeoptGid
+    int getOutval(int gid) {
+        int adjustment = 0;
+        int tmp = gid + 10;
+        while (tmp > gid) {
+            adjustment += tmp;
+            tmp--;
+        }
+        int outval = (outArray[gid] * -1) + adjustment;
+        return outval;
+    }
+
+    @Override
+    public void runTest() {
+        setupArrays();
+
+        // we should not get an exception escaping from the kernel
+        dispatchMethodKernel(num);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchMany16384Test.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * For globalsize 16384, deopt on many gids but then catch the exception in the run routine itself.
+ */
+public class BoundsCatchMany16384Test extends BoundsCatchManyBase {
+
+    @Override
+    int getGlobalSize() {
+        return 16384;
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchMany20000Test.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * For globalsize 20000, deopt on many gids but then catch the exception in the run routine itself.
+ */
+public class BoundsCatchMany20000Test extends BoundsCatchManyBase {
+
+    @Override
+    int getGlobalSize() {
+        return 20000;
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchMany5000Test.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * For globalsize 5000, deopt on many gids but then catch the exception in the run routine itself.
+ */
+public class BoundsCatchMany5000Test extends BoundsCatchManyBase {
+
+    @Override
+    int getGlobalSize() {
+        return 5000;
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchMany8192Test.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * For globalsize 8192, deopt on many gids but then catch the exception in the run routine itself.
+ */
+public class BoundsCatchMany8192Test extends BoundsCatchManyBase {
+
+    @Override
+    int getGlobalSize() {
+        return 8192;
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchMany987654HighTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * For globalsize 987654, deopt on many gids but then catch the exception in the run routine itself
+ * deopt ids are at the high end.
+ */
+public class BoundsCatchMany987654HighTest extends BoundsCatchManyBase {
+
+    @Override
+    int getGlobalSize() {
+        return 987654;
+    }
+
+    boolean isMyDeoptGid(int gid) {
+        return (gid > getGlobalSize() - 4096 && gid % 512 == 1);
+    }
+
+    // copied run routine here because otherwise polymorphic calls to isDeoptGid
+    @Override
+    public void run(int gid) {
+        int outval = getOutval(gid);
+        try {
+            int index = (isMyDeoptGid(gid) ? num + 1 : gid);
+            outArray[index] = outval;
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // set up so we can detect if we go thru here twice
+            outArray[gid] += outval;
+            // note: cannot record the exceptiongid here for many deopts in parallel
+        }
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchMany987654Test.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * For globalsize 987654, deopt on many gids but then catch the exception in the run routine itself.
+ */
+public class BoundsCatchMany987654Test extends BoundsCatchManyBase {
+
+    @Override
+    int getGlobalSize() {
+        return 987654;
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchMany99999Test.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * For globalsize 99999, deopt on many gids but then catch the exception in the run routine itself.
+ */
+public class BoundsCatchMany99999Test extends BoundsCatchManyBase {
+
+    @Override
+    int getGlobalSize() {
+        return 99999;
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchManyBase.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+/**
+ * Base Class for tests that deopt on multiple gids gid but then catches the exception in the run
+ * routine itself.
+ */
+public abstract class BoundsCatchManyBase extends BoundsCatchBase {
+
+    boolean isDeoptGid(int gid) {
+        return (gid < 4096 && gid % 512 == 1);
+    }
+
+    @Override
+    public int getMisMatchLimit() {
+        return 1000;
+    }
+
+    public void run(int gid) {
+        int outval = getOutval(gid);
+        try {
+            int index = (isDeoptGid(gid) ? num + 1 : gid);
+            outArray[index] = outval;
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // set up so we can detect if we go thru here twice
+            outArray[gid] += outval;
+            // note: cannot record the exceptiongid here for many deopts in parallel
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchMost1000Test.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * For globalsize 1000, deopt on almost all gids but then catch the exception in the run routine
+ * itself.
+ */
+public class BoundsCatchMost1000Test extends BoundsCatchManyBase {
+
+    @Override
+    int getGlobalSize() {
+        return 1000;
+    }
+
+    boolean isMyDeoptGid(int gid) {
+        return (gid % 100 != 1);
+    }
+
+    // copied run routine here because otherwise polymorphic calls to isDeoptGid
+    @Override
+    public void run(int gid) {
+        int outval = getOutval(gid);
+        try {
+            int index = (isMyDeoptGid(gid) ? num + 1 : gid);
+            outArray[index] = outval;
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // set up so we can detect if we go thru here twice
+            outArray[gid] += outval;
+            // note: cannot record the exceptiongid here for many deopts in parallel
+        }
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchMost20000Test.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * For globalsize 20000, deopt on almost all gids but then catch the exception in the run routine
+ * itself.
+ */
+public class BoundsCatchMost20000Test extends BoundsCatchManyBase {
+
+    @Override
+    int getGlobalSize() {
+        return 20000;
+    }
+
+    boolean isMyDeoptGid(int gid) {
+        return (gid % 100 != 1);
+    }
+
+    // copied run routine here because otherwise polymorphic calls to isDeoptGid
+    @Override
+    public void run(int gid) {
+        int outval = getOutval(gid);
+        try {
+            int index = (isMyDeoptGid(gid) ? num + 1 : gid);
+            outArray[index] = outval;
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // set up so we can detect if we go thru here twice
+            outArray[gid] += outval;
+            // note: cannot record the exceptiongid here for many deopts in parallel
+        }
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchSingle16384Test.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * For globalsize 16384, deopt on a single gid but then catch the exception in the run routine
+ * itself.
+ */
+public class BoundsCatchSingle16384Test extends BoundsCatchSingleBase {
+
+    @Override
+    int getGlobalSize() {
+        return 16384;
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchSingle20000Test.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * For globalsize 20000, deopt on a single gid but then catch the exception in the run routine
+ * itself.
+ */
+public class BoundsCatchSingle20000Test extends BoundsCatchSingleBase {
+
+    @Override
+    int getGlobalSize() {
+        return 20000;
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchSingle5000Test.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * For globalsize 5000, deopt on a single gid but then catch the exception in the run routine
+ * itself.
+ */
+public class BoundsCatchSingle5000Test extends BoundsCatchSingleBase {
+
+    @Override
+    int getGlobalSize() {
+        return 5000;
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchSingle8192Test.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * For globalsize 8192, deopt on a single gid but then catch the exception in the run routine
+ * itself.
+ */
+public class BoundsCatchSingle8192Test extends BoundsCatchSingleBase {
+
+    @Override
+    int getGlobalSize() {
+        return 8192;
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCatchSingleBase.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+/**
+ * Base Class for tests that deopt on a single gid but then catch the exception in the run routine
+ * itself.
+ */
+public abstract class BoundsCatchSingleBase extends BoundsCatchBase {
+
+    int getDeoptGid() {
+        return 512;
+    }
+
+    boolean isDeoptGid(int gid) {
+        return (gid == getDeoptGid());
+    }
+
+    @Result public int exceptionGid;
+
+    public void run(int gid) {
+        int outval = getOutval(gid);
+        try {
+            int index = (isDeoptGid(gid) ? num + 1 : gid);
+            outArray[index] = outval;
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // set up so we can detect if we go thru here twice
+            outArray[gid] -= outval;
+            exceptionGid = gid;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCheckDoubleNonZeroBciTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * This test deliberately causes an ArrayIndexOutOfBoundsException to test throwing the exception
+ * back to the java code.
+ */
+public class BoundsCheckDoubleNonZeroBciTest extends SingleExceptionTestBase {
+
+    static final int num = 20;
+    // note: outArray not marked as @Result because we can't predict
+    // which workitems will get done in parallel execution
+    double[] outArray = new double[num];
+
+    void setupArrays(double[] in1, double[] in2) {
+        for (int i = 0; i < num; i++) {
+            in1[i] = i;
+            in2[i] = i + 1;
+            outArray[i] = -i;
+        }
+    }
+
+    static double dummyDouble = 10;
+
+    public static void run(double[] out, double[] ina, double[] inb, int gid) {
+        // This will fail when gid+1==num
+        double adjustment = 0;
+        double tmp = dummyDouble;
+        while (tmp-- >= 0) {
+            adjustment += tmp;
+        }
+        out[gid + 1] = ina[gid] + inb[gid] + adjustment;
+    }
+
+    @Override
+    public void runTest() {
+        double[] inArray1 = new double[num];
+        double[] inArray2 = new double[num];
+        setupArrays(inArray1, inArray2);
+
+        try {
+            dispatchMethodKernel(num, outArray, inArray1, inArray2);
+        } catch (Exception e) {
+            recordException(e);
+        }
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCheckFailsInMiddleTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * This test deliberately causes an ArrayIndexOutOfBoundsException to test throwing the exception
+ * back to the java code, in the middle of the array.
+ */
+public class BoundsCheckFailsInMiddleTest extends SingleExceptionTestBase {
+    static final int num = 128; // * 256;
+    // note: outArray not marked as @Result because we can't predict
+    // which workitems will get done in parallel execution
+    int[] outArray = new int[num];
+    static final int abortingGid = (new java.util.Random()).nextInt(num / 4);
+
+    void setupArrays(int[] in1, int[] in2) {
+        for (int i = 0; i < num; i++) {
+            in1[i] = i;
+            in2[i] = i + 1;
+            outArray[i] = -99;
+        }
+    }
+
+    public static void run(int[] out, int[] ina, int[] inb, int gid) {
+        // Throw in the middle of doing the work
+        out[gid == abortingGid ? (gid + num) : gid] = ina[gid] + inb[gid];
+    }
+
+    @Override
+    public void runTest() {
+        int[] inArray1 = new int[num];
+        int[] inArray2 = new int[num];
+        setupArrays(inArray1, inArray2);
+
+        try {
+            dispatchMethodKernel(num, outArray, inArray1, inArray2);
+        } catch (Exception e) {
+            recordException(e);
+        }
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCheckFloatNonZeroBciTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * This test deliberately causes an ArrayIndexOutOfBoundsException to test throwing the exception
+ * back to the java code.
+ */
+public class BoundsCheckFloatNonZeroBciTest extends SingleExceptionTestBase {
+
+    static final int num = 20;
+    // note: outArray not marked as @Result because we can't predict
+    // which workitems will get done in parallel execution
+    float[] outArray = new float[num];
+
+    void setupArrays(float[] in1, float[] in2) {
+        for (int i = 0; i < num; i++) {
+            in1[i] = i;
+            in2[i] = i + 1;
+            outArray[i] = -i;
+        }
+    }
+
+    static float dummyFloat = 10;
+
+    public static void run(float[] out, float[] ina, float[] inb, int gid) {
+        // This will fail when gid+1==num
+        float adjustment = 0;
+        float tmp = dummyFloat;
+        while (tmp-- >= 0) {
+            adjustment += tmp;
+        }
+        out[gid + 1] = ina[gid] + inb[gid] + adjustment;
+    }
+
+    @Override
+    public void runTest() {
+        float[] inArray1 = new float[num];
+        float[] inArray2 = new float[num];
+        setupArrays(inArray1, inArray2);
+
+        try {
+            dispatchMethodKernel(num, outArray, inArray1, inArray2);
+        } catch (Exception e) {
+            recordException(e);
+        }
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCheckInlineTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * 
+ * @author ecaspole
+ */
+public class BoundsCheckInlineTest extends SingleExceptionTestBase {
+
+    static final int num = 20;
+    // note: outArray not marked as @Result because we can't predict
+    // which workitems will get done in parallel execution
+    int[] outArray = new int[num];
+
+    void setupArrays(int[] in1, int[] in2) {
+        for (int i = 0; i < num; i++) {
+            in1[i] = i;
+            in2[i] = i + 1;
+            outArray[i] = -i;
+        }
+    }
+
+    static volatile int dummy;
+
+    static void writesum(int[] out, int gid, int val) {
+        out[gid + 1] = val;
+    }
+
+    public static void run(int[] out, int[] ina, int[] inb, int gid) {
+        // This will fail when gid+1==num
+        writesum(out, gid, ina[gid] + inb[gid]);
+    }
+
+    @Override
+    public void runTest() {
+        int[] inArray1 = new int[num];
+        int[] inArray2 = new int[num];
+        setupArrays(inArray1, inArray2);
+
+        try {
+            dispatchMethodKernel(num, outArray, inArray1, inArray2);
+        } catch (Exception e) {
+            recordException(e);
+        }
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCheckLongNonZeroBciTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * This test deliberately causes an ArrayIndexOutOfBoundsException to test throwing the exception
+ * back to the java code.
+ */
+public class BoundsCheckLongNonZeroBciTest extends SingleExceptionTestBase {
+
+    static final int num = 20;
+    // note: outArray not marked as @Result because we can't predict
+    // which workitems will get done in parallel execution
+    long[] outArray = new long[num];
+
+    void setupArrays(long[] in1, long[] in2) {
+        for (int i = 0; i < num; i++) {
+            in1[i] = i;
+            in2[i] = i + 1;
+            outArray[i] = -i;
+        }
+    }
+
+    static long dummyLong = 10;
+
+    public static void run(long[] out, long[] ina, long[] inb, int gid) {
+        // This will fail when gid+1==num
+        long adjustment = 0x1234567890abcdefL;
+        long tmp = dummyLong;
+        while (tmp-- >= 0) {
+            adjustment += tmp;
+        }
+        out[gid + 1] = ina[gid] + inb[gid] + adjustment;
+    }
+
+    @Override
+    public void runTest() {
+        long[] inArray1 = new long[num];
+        long[] inArray2 = new long[num];
+        setupArrays(inArray1, inArray2);
+
+        try {
+            dispatchMethodKernel(num, outArray, inArray1, inArray2);
+        } catch (Exception e) {
+            recordException(e);
+        }
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCheckNonZeroBciInstanceTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * This test deliberately causes an ArrayIndexOutOfBoundsException to test throwing the exception
+ * back to the java code.
+ */
+public class BoundsCheckNonZeroBciInstanceTest extends SingleExceptionTestBase {
+
+    static final int num = 20;
+    // note: outArray not marked as @Result because we can't predict
+    // which workitems will get done in parallel execution
+    int[] outArray = new int[num];
+    int[] inArray1 = new int[num];
+    int[] inArray2 = new int[num];
+
+    void setupArrays(int[] in1, int[] in2) {
+        for (int i = 0; i < num; i++) {
+            in1[i] = i;
+            in2[i] = i + 1;
+            outArray[i] = -i;
+        }
+    }
+
+    int dummyInt = 10;
+
+    public void run(int gid) {
+        // This will fail when gid+1==num
+        int adjustment = 0;
+        int tmp = dummyInt;
+        while (tmp-- >= 0) {
+            adjustment += tmp;
+        }
+        outArray[gid + 1] = inArray1[gid] + inArray2[gid] + adjustment;
+    }
+
+    @Override
+    public void runTest() {
+        setupArrays(inArray1, inArray2);
+
+        try {
+            dispatchMethodKernel(num);
+        } catch (Exception e) {
+            recordException(e);
+        }
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCheckNonZeroBciTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * This test deliberately causes an ArrayIndexOutOfBoundsException to test throwing the exception
+ * back to the java code.
+ */
+public class BoundsCheckNonZeroBciTest extends SingleExceptionTestBase {
+
+    static final int num = 20;
+    // note: outArray not marked as @Result because we can't predict
+    // which workitems will get done in parallel execution
+    int[] outArray = new int[num];
+
+    void setupArrays(int[] in1, int[] in2) {
+        for (int i = 0; i < num; i++) {
+            in1[i] = i;
+            in2[i] = i + 1;
+            outArray[i] = -i;
+        }
+    }
+
+    static int dummyInt = 10;
+
+    public static void run(int[] out, int[] ina, int[] inb, int gid) {
+        // This will fail when gid+1==num
+        int adjustment = 0;
+        int tmp = dummyInt;
+        while (tmp-- >= 0) {
+            adjustment += tmp;
+        }
+        out[gid + 1] = ina[gid] + inb[gid] + adjustment;
+    }
+
+    @Override
+    public void runTest() {
+        int[] inArray1 = new int[num];
+        int[] inArray2 = new int[num];
+        setupArrays(inArray1, inArray2);
+
+        try {
+            dispatchMethodKernel(num, outArray, inArray1, inArray2);
+        } catch (Exception e) {
+            recordException(e);
+        }
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BoundsCheckTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * This test deliberately causes an ArrayIndexOutOfBoundsException to test throwing the exception
+ * back to the java code.
+ */
+public class BoundsCheckTest extends SingleExceptionTestBase {
+
+    static final int num = 20;
+    // note: outArray not marked as @Result because we can't predict
+    // which workitems will get done in parallel execution
+    int[] outArray = new int[num];
+
+    void setupArrays(int[] in1, int[] in2) {
+        for (int i = 0; i < num; i++) {
+            in1[i] = i;
+            in2[i] = i + 1;
+            outArray[i] = -i;
+        }
+    }
+
+    public static void run(int[] out, int[] ina, int[] inb, int gid) {
+        // This will fail when gid+1==num
+        out[gid + 1] = ina[gid] + inb[gid];
+    }
+
+    @Override
+    public void runTest() {
+        int[] inArray1 = new int[num];
+        int[] inArray2 = new int[num];
+        setupArrays(inArray1, inArray2);
+
+        try {
+            dispatchMethodKernel(num, outArray, inArray1, inArray2);
+        } catch (Exception e) {
+            recordException(e);
+        }
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/ClassCastNonZeroBciTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2013, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * This test deliberately causes a ClassCastException to test throwing the exception back to the
+ * java code.
+ */
+public class ClassCastNonZeroBciTest extends SingleExceptionTestBase {
+
+    static final int num = 20;
+
+    static class BasePoint {
+        int x;
+        int y;
+
+        public BasePoint(int x, int y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        public int getX() {
+            return x;
+        }
+
+        public int getY() {
+            return y;
+        }
+    }
+
+    static class MyPoint extends BasePoint {
+        public MyPoint(int x, int y) {
+            super(x, y);
+        }
+    }
+
+    BasePoint[] inputs = new BasePoint[num];
+    MyPoint[] outputs = new MyPoint[num];
+
+    void setupArrays() {
+        for (int i = 0; i < num; i++) {
+            inputs[i] = new MyPoint(i, i + 1);
+        }
+        inputs[2] = new BasePoint(1, 1);
+    }
+
+    public void run(int gid) {
+        // gid 2 should always throw ClassCastException
+        int adjustment = 0;
+        int tmp = gid;
+        while (tmp-- >= 0) {
+            adjustment += tmp;
+        }
+        MyPoint mp = (MyPoint) inputs[gid];
+        mp.x = mp.y + adjustment;
+        outputs[gid] = mp;
+    }
+
+    @Override
+    public void runTest() {
+        setupArrays();
+        try {
+            dispatchMethodKernel(num);
+        } catch (Exception e) {
+            recordException(e);
+        }
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/ClassCastTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2013, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * This test deliberately causes a ClassCastException to test throwing the exception back to the
+ * java code.
+ */
+public class ClassCastTest extends SingleExceptionTestBase {
+
+    static final int num = 20;
+
+    static class BasePoint {
+        int x;
+        int y;
+
+        public BasePoint(int x, int y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        public int getX() {
+            return x;
+        }
+
+        public int getY() {
+            return y;
+        }
+    }
+
+    static class MyPoint extends BasePoint {
+        public MyPoint(int x, int y) {
+            super(x, y);
+        }
+    }
+
+    BasePoint[] inputs = new BasePoint[num];
+    MyPoint[] outputs = new MyPoint[num];
+
+    void setupArrays() {
+        for (int i = 0; i < num; i++) {
+            inputs[i] = new MyPoint(i, i + 1);
+        }
+        inputs[2] = new BasePoint(1, 1);
+    }
+
+    public void run(int gid) {
+        // gid 2 should always throw ClassCastException
+        MyPoint mp = (MyPoint) inputs[gid];
+        mp.x = mp.y + 2;
+        outputs[gid] = mp;
+    }
+
+    @Override
+    public void runTest() {
+        setupArrays();
+        try {
+            dispatchMethodKernel(num);
+        } catch (Exception e) {
+            recordException(e);
+        }
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntStreamNullCatchNonZeroBciTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2013, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * This test tests an int stream where we deliberately cause a NPE to test throwing the exception
+ * back to the java code. In addition, it is set up so the bci of the exception point is not zero.
+ */
+public class IntStreamNullCatchNonZeroBciTest extends SingleExceptionTestBase {
+
+    static final int num = 20;
+
+    static class BasePoint {
+        int x;
+        int y;
+
+        public BasePoint(int x, int y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        public int getX() {
+            return x;
+        }
+
+        public int getY() {
+            return y;
+        }
+    }
+
+    static class MyPoint extends BasePoint {
+        public MyPoint(int x, int y) {
+            super(x, y);
+        }
+    }
+
+    BasePoint[] inputs = new BasePoint[num];
+    MyPoint[] outputs = new MyPoint[num];
+
+    void setupArrays() {
+        for (int i = 0; i < num; i++) {
+            inputs[i] = new MyPoint(i, i + 1);
+        }
+        inputs[10] = null;
+    }
+
+    @Result public int nullSeenGid;
+    @Result public int nullSeenAdjustment;
+
+    public void run(int gid) {
+        // gid 10 should always throw NPE
+        MyPoint mp = (MyPoint) inputs[gid];
+        int adjustment = 0;
+        int tmp = gid;
+        while (tmp-- >= 0) {
+            adjustment += tmp;
+        }
+        try {
+            mp.x = mp.y + adjustment;
+        } catch (NullPointerException e) {
+            nullSeenGid = gid;
+            nullSeenAdjustment = adjustment;
+        }
+        outputs[gid] = mp;
+    }
+
+    @Override
+    public void runTest() {
+        setupArrays();
+        try {
+            dispatchMethodKernel(num);
+        } catch (Exception e) {
+            recordException(e);
+        }
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntStreamNullCheckNonZeroBciTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2013, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * This test tests an int stream where we deliberately cause a NPE to test throwing the exception
+ * back to the java code. In addition, it is set up so the bci of the exception point is not zero.
+ */
+public class IntStreamNullCheckNonZeroBciTest extends SingleExceptionTestBase {
+
+    static final int num = 20;
+
+    static class BasePoint {
+        int x;
+        int y;
+
+        public BasePoint(int x, int y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        public int getX() {
+            return x;
+        }
+
+        public int getY() {
+            return y;
+        }
+    }
+
+    static class MyPoint extends BasePoint {
+        public MyPoint(int x, int y) {
+            super(x, y);
+        }
+    }
+
+    BasePoint[] inputs = new BasePoint[num];
+    MyPoint[] outputs = new MyPoint[num];
+
+    void setupArrays() {
+        for (int i = 0; i < num; i++) {
+            inputs[i] = new MyPoint(i, i + 1);
+        }
+        inputs[10] = null;
+    }
+
+    public void run(int gid) {
+        // gid 10 should always throw NPE
+        MyPoint mp = (MyPoint) inputs[gid];
+        int adjustment = 0;
+        int tmp = gid;
+        while (tmp-- >= 0) {
+            adjustment += tmp;
+        }
+        mp.x = mp.y + adjustment;
+        outputs[gid] = mp;
+    }
+
+    @Override
+    public void runTest() {
+        setupArrays();
+        try {
+            dispatchMethodKernel(num);
+        } catch (Exception e) {
+            recordException(e);
+        }
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntStreamNullCheckTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2013, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * This test tests an int stream where we deliberately cause a NPE to test throwing the exception
+ * back to the java code.
+ */
+public class IntStreamNullCheckTest extends SingleExceptionTestBase {
+
+    static final int num = 20;
+
+    static class BasePoint {
+        int x;
+        int y;
+
+        public BasePoint(int x, int y) {
+            this.x = x;
+            this.y = y;
+        }
+
+        public int getX() {
+            return x;
+        }
+
+        public int getY() {
+            return y;
+        }
+    }
+
+    static class MyPoint extends BasePoint {
+        public MyPoint(int x, int y) {
+            super(x, y);
+        }
+    }
+
+    BasePoint[] inputs = new BasePoint[num];
+    MyPoint[] outputs = new MyPoint[num];
+
+    void setupArrays() {
+        for (int i = 0; i < num; i++) {
+            inputs[i] = new MyPoint(i, i + 1);
+        }
+        inputs[10] = null;
+    }
+
+    public void run(int gid) {
+        // gid 10 should always throw NPE
+        MyPoint mp = (MyPoint) inputs[gid];
+        mp.x = mp.y + 2;
+        outputs[gid] = mp;
+    }
+
+    @Override
+    public void runTest() {
+        setupArrays();
+        try {
+            dispatchMethodKernel(num);
+        } catch (Exception e) {
+            recordException(e);
+        }
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntStreamNullNonArrayParamCheckTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * Tests one of the kernel parameters being null.
+ */
+public class IntStreamNullNonArrayParamCheckTest extends SingleExceptionTestBase {
+
+    static final int num = 20;
+    @Result protected int[] outArray = new int[num];
+
+    static class MyObj {
+        public int val;
+    }
+
+    public static void run(int[] out, int[] ina, MyObj adjustment, int gid) {
+        out[gid] = ina[gid] + adjustment.val;
+    }
+
+    @Override
+    public void runTest() {
+        int[] inArray1 = new int[num];
+        int[] inArray2 = new int[num];
+        setupArrays(inArray1, inArray2);
+
+        try {
+            dispatchMethodKernel(num, outArray, inArray1, null);
+        } catch (Exception e) {
+            recordException(e);
+        }
+    }
+
+    void setupArrays(int[] in1, int[] in2) {
+        for (int i = 0; i < num; i++) {
+            // Fill input arrays with a mix of positive and negative values.
+            in1[i] = i < num / 2 ? i + 1 : -(i + 1);
+            in2[i] = (i & 1) == 0 ? in1[i] + 10 : -(in1[i] + 10);
+            outArray[i] = -i;
+        }
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/IntStreamNullParamCheckTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+
+/**
+ * Tests one of the kernel parameters being null.
+ */
+public class IntStreamNullParamCheckTest extends SingleExceptionTestBase {
+
+    static final int num = 20;
+    @Result protected int[] outArray = new int[num];
+
+    public static void run(int[] out, int[] ina, int[] inb, int gid) {
+        out[gid] = ina[gid] + inb[gid];
+    }
+
+    @Override
+    public void runTest() {
+        int[] inArray1 = new int[num];
+        int[] inArray2 = new int[num];
+        setupArrays(inArray1, inArray2);
+
+        try {
+            dispatchMethodKernel(num, outArray, null, inArray2);
+        } catch (Exception e) {
+            recordException(e);
+        }
+    }
+
+    void setupArrays(int[] in1, int[] in2) {
+        for (int i = 0; i < num; i++) {
+            // Fill input arrays with a mix of positive and negative values.
+            in1[i] = i < num / 2 ? i + 1 : -(i + 1);
+            in2[i] = (i & 1) == 0 ? in1[i] + 10 : -(in1[i] + 10);
+            outArray[i] = -i;
+        }
+    }
+
+    @Test
+    public void test() {
+        super.testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/SingleExceptionTestBase.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester;
+
+/**
+ * 
+ * @author ecaspole
+ */
+public abstract class SingleExceptionTestBase extends GraalKernelTester {
+
+    @Result Class<?> exceptionClass;
+    @Result String exceptionString;
+    @Result StackTraceElement firstStackTraceElement;
+
+    void recordException(Exception e) {
+        // for now we just test that the class the of the exception
+        // matches for the java and gpu side
+        exceptionClass = e.getClass();
+        // exception = e;
+        StackTraceElement[] elems = e.getStackTrace();
+        firstStackTraceElement = elems[0];
+        // for tests where the exception was in the method parameters
+        // ignore the firstStackTraceElement matching
+        if (firstStackTraceElement.getClassName().contains("KernelTester")) {
+            firstStackTraceElement = null;
+        }
+        for (StackTraceElement elem : elems) {
+            if (elem.toString().contains("KernelTester")) {
+                break;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMandelBoundsCheckTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.Test;
+import static org.junit.Assume.*;
+
+/**
+ * Unit test that simulates the Mandelbrot application. The run method here is a static method
+ * version of the original mandel kernel and the invoke parameters are for the starting point of the
+ * mandel demo. Note: this will likely not pass the junit test on real hardware, but should pass on
+ * the simulator.
+ */
+public class StaticMandelBoundsCheckTest extends SingleExceptionTestBase {
+
+    static final int initWidth = 768;
+    static final int initHeight = initWidth;
+    static final int maxIterations = 64;
+    static final int range = initWidth * initHeight;
+    private int[] rgb = new int[range];
+
+    public static void run(int[] rgb, int[] pallette, float xoffset, float yoffset, float scale, int gid) {
+        final int width = initWidth;
+        final int height = initHeight;
+        float lx = (((gid % width * scale) - ((scale / 2) * width)) / width) + xoffset;
+        float ly = (((gid / width * scale) - ((scale / 2) * height)) / height) + yoffset;
+        int count = 0;
+        float zx = lx;
+        float zy = ly;
+        float newzx = 0f;
+
+        // Iterate until the algorithm converges or until maxIterations are reached.
+        while (count < maxIterations && zx * zx + zy * zy < 8) {
+            newzx = zx * zx - zy * zy + lx;
+            zy = 2 * zx * zy + ly;
+            zx = newzx;
+            count++;
+        }
+        rgb[gid + 1] = pallette[count];   // will cause exception on last of range
+    }
+
+    void setupPalette(int[] in) {
+        for (int i = 0; i < in.length; i++) {
+            in[i] = i;
+        }
+    }
+
+    @Override
+    public void runTest() {
+        int[] palette = new int[256];
+        setupPalette(palette);
+        /**
+         * Call it for a range, specifying testmethod args (but not the fields it uses or the gid
+         * argument).
+         */
+        try {
+            dispatchMethodKernel(range, rgb, palette, -1f, 0f, 3f);
+        } catch (Exception e) {
+            recordException(e);
+        }
+    }
+
+    @Test
+    public void test() {
+        assumeTrue(runningOnSimulator());
+        testGeneratedHsail();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/Vec3ObjStreamClassCastNonZeroBciTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.*;
+
+/**
+ * Tests an object array stream with one element being of the wrong class.
+ */
+public class Vec3ObjStreamClassCastNonZeroBciTest extends SingleExceptionTestBase {
+
+    static final int NUM = 20;
+
+    public Vec3[] inArray = new Vec3[NUM];
+
+    static class MyVec3 extends Vec3 {
+        public MyVec3(float x, float y, float z) {
+            super(x, y, z);
+        }
+    }
+
+    void setupArrays() {
+        for (int i = 0; i < NUM; i++) {
+            inArray[i] = new MyVec3(i, i + 1, -1);
+        }
+        // insert one wrong type
+        inArray[10] = new Vec3(10, 11, -1);
+    }
+
+    int dummyInt = 10;
+
+    /**
+     * The "kernel" method we will be testing. For Array Stream, an object from the array will be
+     * the last parameter
+     */
+    public void run(Vec3 vec3) {
+        int adjustment = 0;
+        int tmp = dummyInt;
+        while (tmp-- >= 0) {
+            adjustment += tmp;
+        }
+        MyVec3 myvec3 = (MyVec3) vec3;
+        myvec3.z = myvec3.x + myvec3.y + adjustment;
+    }
+
+    @Override
+    public void runTest() {
+        setupArrays();
+        try {
+            dispatchMethodKernel(inArray);
+        } catch (Exception e) {
+            recordException(e);
+        }
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/Vec3ObjStreamClassCastTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.*;
+
+/**
+ * Tests an object array stream with one element being of the wrong class.
+ */
+public class Vec3ObjStreamClassCastTest extends SingleExceptionTestBase {
+
+    static final int NUM = 20;
+
+    public Vec3[] inArray = new Vec3[NUM];
+
+    static class MyVec3 extends Vec3 {
+        public MyVec3(float x, float y, float z) {
+            super(x, y, z);
+        }
+    }
+
+    void setupArrays() {
+        for (int i = 0; i < NUM; i++) {
+            inArray[i] = new MyVec3(i, i + 1, -1);
+        }
+        // insert one wrong type
+        inArray[10] = new Vec3(10, 11, -1);
+    }
+
+    /**
+     * The "kernel" method we will be testing. For Array Stream, an object from the array will be
+     * the last parameter
+     */
+    public void run(Vec3 vec3) {
+        MyVec3 myvec3 = (MyVec3) vec3;
+        myvec3.z = myvec3.x + myvec3.y;
+    }
+
+    @Override
+    public void runTest() {
+        setupArrays();
+        try {
+            dispatchMethodKernel(inArray);
+        } catch (Exception e) {
+            recordException(e);
+        }
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/Vec3ObjStreamNullCheckNonZeroBciTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.*;
+
+/**
+ * Tests an object array stream with one element being null.
+ */
+public class Vec3ObjStreamNullCheckNonZeroBciTest extends SingleExceptionTestBase {
+
+    static final int NUM = 20;
+
+    public Vec3[] inArray = new Vec3[NUM];
+
+    static class MyVec3 extends Vec3 {
+        public MyVec3(float x, float y, float z) {
+            super(x, y, z);
+        }
+    }
+
+    void setupArrays() {
+        for (int i = 0; i < NUM; i++) {
+            inArray[i] = new MyVec3(i, i + 1, -1);
+        }
+        // insert one null
+        inArray[10] = null;
+    }
+
+    int dummyInt = 10;
+
+    /**
+     * The "kernel" method we will be testing. For Array Stream, an object from the array will be
+     * the last parameter
+     */
+    public void run(Vec3 vec3) {
+        int adjustment = 0;
+        int tmp = dummyInt;
+        while (tmp-- >= 0) {
+            adjustment += tmp;
+        }
+        vec3.z = vec3.x + vec3.y + adjustment;
+    }
+
+    @Override
+    public void runTest() {
+        setupArrays();
+        try {
+            dispatchMethodKernel(inArray);
+        } catch (Exception e) {
+            recordException(e);
+        }
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/Vec3ObjStreamNullCheckTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.*;
+
+/**
+ * Tests an object array stream with one element being null.
+ */
+public class Vec3ObjStreamNullCheckTest extends SingleExceptionTestBase {
+
+    static final int NUM = 20;
+
+    public Vec3[] inArray = new Vec3[NUM];
+
+    static class MyVec3 extends Vec3 {
+        public MyVec3(float x, float y, float z) {
+            super(x, y, z);
+        }
+    }
+
+    void setupArrays() {
+        for (int i = 0; i < NUM; i++) {
+            inArray[i] = new MyVec3(i, i + 1, -1);
+        }
+        // insert one null
+        inArray[10] = null;
+    }
+
+    /**
+     * The "kernel" method we will be testing. For Array Stream, an object from the array will be
+     * the last parameter
+     */
+    public void run(Vec3 vec3) {
+        vec3.z = vec3.x + vec3.y;
+    }
+
+    @Override
+    public void runTest() {
+        setupArrays();
+        try {
+            dispatchMethodKernel(inArray);
+        } catch (Exception e) {
+            recordException(e);
+        }
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/Vec3ObjStreamNullParamCheckTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2009, 2012, 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 com.oracle.graal.compiler.hsail.test;
+
+import org.junit.*;
+
+/**
+ * Tests an object array stream with the object stream itself being null.
+ */
+public class Vec3ObjStreamNullParamCheckTest extends SingleExceptionTestBase {
+
+    static final int NUM = 20;
+
+    public Vec3[] inArray = new Vec3[NUM];
+
+    static class MyVec3 extends Vec3 {
+        public MyVec3(float x, float y, float z) {
+            super(x, y, z);
+        }
+    }
+
+    void setupArrays() {
+        for (int i = 0; i < NUM; i++) {
+            inArray[i] = new MyVec3(i, i + 1, -1);
+        }
+        // insert one null
+        inArray[10] = null;
+    }
+
+    /**
+     * The "kernel" method we will be testing. For Array Stream, an object from the array will be
+     * the last parameter
+     */
+    public void run(Vec3 vec3) {
+        MyVec3 myvec3 = (MyVec3) vec3;
+        myvec3.z = myvec3.x + myvec3.y;
+    }
+
+    @Override
+    public void runTest() {
+        setupArrays();
+        try {
+            dispatchMethodKernel(null);
+        } catch (Exception e) {
+            recordException(e);
+        }
+    }
+
+    @Test
+    public void test() {
+        testGeneratedHsail();
+    }
+
+}
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Wed Mar 26 17:30:40 2014 +0100
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Wed Mar 26 17:33:54 2014 +0100
@@ -868,12 +868,12 @@
      */
     @Override
     protected void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget) {
-        if (key.getKind() == Kind.Int) {
+        if ((key.getKind() == Kind.Int) || (key.getKind() == Kind.Long)) {
             // Append the LIR instruction for generating compare and branch instructions.
             append(new StrategySwitchOp(strategy, keyTargets, defaultTarget, key));
         } else {
             // Throw an exception if the keys aren't ints.
-            throw GraalInternalError.unimplemented("Switch statements are only supported for keys of type int");
+            throw GraalInternalError.unimplemented("Switch statements are only supported for keys of type int or long, not " + key.getKind());
         }
     }
 
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXMethodInvalidation1Test.java	Wed Mar 26 17:30:40 2014 +0100
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXMethodInvalidation1Test.java	Wed Mar 26 17:33:54 2014 +0100
@@ -24,8 +24,8 @@
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.gpu.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.ptx.*;
 
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTest.java	Wed Mar 26 17:30:40 2014 +0100
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTest.java	Wed Mar 26 17:33:54 2014 +0100
@@ -33,6 +33,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.gpu.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.ptx.*;
 import com.oracle.graal.nodes.*;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.gpu/src/com/oracle/graal/gpu/ExternalCompilationResult.java	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2009, 2013, 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 com.oracle.graal.gpu;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.nodes.*;
+
+/**
+ * Represents the output from compiling a method generated by Graal, but executing in a memory and
+ * computational subsystem outside the Graal host system.
+ * 
+ * Output may include the compiled machine code, associated data and references, relocation
+ * information, deoptimization information, as this result is generated from a structure graph on
+ * the Graal host system.
+ */
+public class ExternalCompilationResult extends CompilationResult {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Address of the point of entry to the external compilation result.
+     */
+    private long entryPoint;
+    private StructuredGraph hostGraph;
+
+    /**
+     * Set the address for the point of entry to the external compilation result.
+     * 
+     * @param addr the address of the entry point
+     */
+    public void setEntryPoint(long addr) {
+        entryPoint = addr;
+    }
+
+    /**
+     * Return the address for the point of entry to the external compilation result.
+     * 
+     * @return address value
+     */
+    public long getEntryPoint() {
+        return entryPoint;
+    }
+
+    /**
+     * Gets the {@linkplain #getTargetCode() code} in this compilation result as a string.
+     */
+    public String getCodeString() {
+        return new String(getTargetCode(), 0, getTargetCodeSize());
+    }
+
+    public void setHostGraph(StructuredGraph hostGraph) {
+        this.hostGraph = hostGraph;
+    }
+
+    public StructuredGraph getHostGraph() {
+        return hostGraph;
+    }
+}
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java	Wed Mar 26 17:30:40 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java	Wed Mar 26 17:33:54 2014 +0100
@@ -42,6 +42,7 @@
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.util.*;
 import com.oracle.graal.printer.*;
+import com.oracle.graal.gpu.*;
 
 /**
  * Implements compile and dispatch of Java code containing lambda constructs. Currently only used by
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Wed Mar 26 17:30:40 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Wed Mar 26 17:33:54 2014 +0100
@@ -32,15 +32,24 @@
 
 import com.amd.okra.*;
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.Assumptions.Assumption;
 import com.oracle.graal.api.code.CallingConvention.Type;
+import com.oracle.graal.api.code.CompilationResult.Call;
+import com.oracle.graal.api.code.CompilationResult.CodeAnnotation;
+import com.oracle.graal.api.code.CompilationResult.DataPatch;
+import com.oracle.graal.api.code.CompilationResult.ExceptionHandler;
+import com.oracle.graal.api.code.CompilationResult.Infopoint;
+import com.oracle.graal.api.code.CompilationResult.Mark;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.hsail.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
+import com.oracle.graal.gpu.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.bridge.CompilerToVM.CodeInstallResult;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hsail.*;
 import com.oracle.graal.java.*;
@@ -48,8 +57,8 @@
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.hsail.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.*;
-import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.tiers.*;
 
 /**
@@ -59,6 +68,8 @@
 
     private Map<String, String> paramTypeMap = new HashMap<>();
     private final boolean deviceInitialized;
+    // TODO: get maximum Concurrency from okra
+    private int maxDeoptIndex = 8 * 40 * 64;   // see gpu_hsail.hpp
 
     public HSAILHotSpotBackend(HotSpotGraalRuntime runtime, HotSpotProviders providers) {
         super(runtime, providers);
@@ -85,6 +96,18 @@
     private static native boolean initialize();
 
     /**
+     * Control how many threads run on simulator (used only from junit tests).
+     */
+    public void setSimulatorSingleThreaded() {
+        String simThrEnv = System.getenv("SIMTHREADS");
+        if (simThrEnv == null || !simThrEnv.equals("1")) {
+            setSimulatorSingleThreaded0();
+        }
+    }
+
+    private static native void setSimulatorSingleThreaded0();
+
+    /**
      * Determines if the GPU device (or simulator) is available and initialized.
      */
     public boolean isDeviceInitialized() {
@@ -127,13 +150,37 @@
     public ExternalCompilationResult compileKernel(ResolvedJavaMethod method, boolean makeBinary) {
         StructuredGraph graph = new StructuredGraph(method);
         HotSpotProviders providers = getProviders();
-        new GraphBuilderPhase.Instance(providers.getMetaAccess(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
+        MetaAccessProvider metaAccess = getProviders().getMetaAccess();
+
+        // changed this from default to help us generate deopts when needed
+        OptimisticOptimizations optimisticOpts = OptimisticOptimizations.ALL;
+        optimisticOpts.remove(OptimisticOptimizations.Optimization.UseExceptionProbabilityForOperations);
+        new GraphBuilderPhase.Instance(metaAccess, GraphBuilderConfiguration.getSnippetDefault(), optimisticOpts).apply(graph);
         PhaseSuite<HighTierContext> graphBuilderSuite = providers.getSuites().getDefaultGraphBuilderSuite();
-        graphBuilderSuite.appendPhase(new NonNullParametersPhase());
         CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
+
+        // append special HSAILNonNullParametersPhase
+        int numArgs = cc.getArguments().length;
+        graphBuilderSuite.appendPhase(new HSAILNonNullParametersPhase(numArgs));
+
         Suites suites = providers.getSuites().getDefaultSuites();
-        ExternalCompilationResult hsailCode = compileGraph(graph, null, cc, method, providers, this, this.getTarget(), null, graphBuilderSuite, OptimisticOptimizations.NONE, getProfilingInfo(graph),
-                        null, suites, new ExternalCompilationResult(), CompilationResultBuilderFactory.Default);
+        ExternalCompilationResult hsailCode = compileGraph(graph, null, cc, method, providers, this, this.getTarget(), null, graphBuilderSuite, optimisticOpts, getProfilingInfo(graph), null, suites,
+                        new ExternalCompilationResult(), CompilationResultBuilderFactory.Default);
+
+        // this code added to dump infopoints
+        try (Scope s = Debug.scope("CodeGen")) {
+            if (Debug.isLogEnabled()) {
+                // show infopoints
+                List<Infopoint> infoList = hsailCode.getInfopoints();
+                Debug.log(infoList.size() + " HSAIL infopoints");
+                for (Infopoint info : infoList) {
+                    Debug.log(info.toString());
+                    Debug.log(info.debugInfo.frame().toString());
+                }
+            }
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
 
         if (makeBinary) {
             if (!deviceInitialized) {
@@ -152,6 +199,26 @@
         return hsailCode;
     }
 
+    private static class HSAILNonNullParametersPhase extends Phase {
+        // we use this to limit the stamping to exclude the final argument in an obj stream method
+        private int numArgs;
+
+        public HSAILNonNullParametersPhase(int numArgs) {
+            this.numArgs = numArgs;
+        }
+
+        @Override
+        protected void run(StructuredGraph graph) {
+            int argCount = 0;
+            for (ParameterNode param : graph.getNodes(ParameterNode.class)) {
+                argCount++;
+                if (argCount < numArgs && param.stamp() instanceof ObjectStamp) {
+                    param.setStamp(StampFactory.declaredNonNull(((ObjectStamp) param.stamp()).type()));
+                }
+            }
+        }
+    }
+
     /**
      * Generates a GPU binary from HSAIL code.
      */
@@ -167,17 +234,121 @@
      */
     public final HotSpotNmethod installKernel(ResolvedJavaMethod method, ExternalCompilationResult hsailCode) {
         assert hsailCode.getEntryPoint() != 0L;
-        return getProviders().getCodeCache().addExternalMethod(method, hsailCode);
+        // code below here lifted from HotSpotCodeCacheProviders.addExternalMethod
+        // used to be return getProviders().getCodeCache().addExternalMethod(method, hsailCode);
+        HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) method;
+        if (hsailCode.getId() == -1) {
+            hsailCode.setId(javaMethod.allocateCompileId(hsailCode.getEntryBCI()));
+        }
+        CompilationResult compilationResult = hsailCode;
+        StructuredGraph hostGraph = hsailCode.getHostGraph();
+        if (hostGraph != null) {
+            // TODO get rid of the unverified entry point in the host code
+            try (Scope ds = Debug.scope("GeneratingHostGraph")) {
+                HotSpotBackend hostBackend = getRuntime().getHostBackend();
+                JavaType[] parameterTypes = new JavaType[hostGraph.getNodes(ParameterNode.class).count()];
+                Debug.log("Param count :" + parameterTypes.length);
+                for (int i = 0; i < parameterTypes.length; i++) {
+                    ParameterNode parameter = hostGraph.getParameter(i);
+                    Debug.log("Param [" + i + "]=" + parameter);
+                    parameterTypes[i] = parameter.stamp().javaType(hostBackend.getProviders().getMetaAccess());
+                    Debug.log(" " + parameterTypes[i]);
+                }
+                CallingConvention cc = hostBackend.getProviders().getCodeCache().getRegisterConfig().getCallingConvention(Type.JavaCallee, method.getSignature().getReturnType(null), parameterTypes,
+                                hostBackend.getTarget(), false);
+                CompilationResult hostCode = compileGraph(hostGraph, null, cc, method, hostBackend.getProviders(), hostBackend, this.getTarget(), null,
+                                hostBackend.getProviders().getSuites().getDefaultGraphBuilderSuite(), OptimisticOptimizations.NONE, null, null,
+                                hostBackend.getProviders().getSuites().getDefaultSuites(), new CompilationResult(), CompilationResultBuilderFactory.Default);
+                compilationResult = merge(hostCode, hsailCode);
+            } catch (Throwable e) {
+                throw Debug.handle(e);
+            }
+        }
+
+        HotSpotNmethod code = new HotSpotNmethod(javaMethod, hsailCode.getName(), false, true);
+        HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(getTarget(), javaMethod, compilationResult);
+        CodeInstallResult result = getRuntime().getCompilerToVM().installCode(compiled, code, null);
+        if (result != CodeInstallResult.OK) {
+            return null;
+        }
+        return code;
+    }
+
+    private static ExternalCompilationResult merge(CompilationResult hostCode, ExternalCompilationResult hsailCode) {
+        ExternalCompilationResult result = new ExternalCompilationResult();
+
+        // from hsail code
+        result.setEntryPoint(hsailCode.getEntryPoint());
+        result.setId(hsailCode.getId());
+        result.setEntryBCI(hsailCode.getEntryBCI());
+        assert hsailCode.getMarks().isEmpty();
+        assert hsailCode.getExceptionHandlers().isEmpty();
+        assert hsailCode.getDataReferences().isEmpty();
+
+        // from host code
+        result.setFrameSize(hostCode.getFrameSize());
+        result.setCustomStackAreaOffset(hostCode.getCustomStackAreaOffset());
+        result.setRegisterRestoreEpilogueOffset(hostCode.getRegisterRestoreEpilogueOffset());
+        result.setTargetCode(hostCode.getTargetCode(), hostCode.getTargetCodeSize());
+        for (CodeAnnotation annotation : hostCode.getAnnotations()) {
+            result.addAnnotation(annotation);
+        }
+        CompilationResult.Mark[] noMarks = {};
+        for (Mark mark : hostCode.getMarks()) {
+            result.recordMark(mark.pcOffset, mark.id, noMarks);
+        }
+        for (ExceptionHandler handler : hostCode.getExceptionHandlers()) {
+            result.recordExceptionHandler(handler.pcOffset, handler.handlerPos);
+        }
+        for (DataPatch patch : hostCode.getDataReferences()) {
+            if (patch.data != null) {
+                if (patch.inline) {
+                    result.recordInlineData(patch.pcOffset, patch.data);
+                } else {
+                    result.recordDataReference(patch.pcOffset, patch.data);
+                }
+            }
+        }
+        for (Infopoint infopoint : hostCode.getInfopoints()) {
+            if (infopoint instanceof Call) {
+                Call call = (Call) infopoint;
+                result.recordCall(call.pcOffset, call.size, call.target, call.debugInfo, call.direct);
+            } else {
+                result.recordInfopoint(infopoint.pcOffset, infopoint.debugInfo, infopoint.reason);
+            }
+        }
+
+        // merged
+        Assumptions mergedAssumptions = new Assumptions(true);
+        if (hostCode.getAssumptions() != null) {
+            for (Assumption assumption : hostCode.getAssumptions().getAssumptions()) {
+                if (assumption != null) {
+                    mergedAssumptions.record(assumption);
+                }
+            }
+        }
+        if (hsailCode.getAssumptions() != null) {
+            for (Assumption assumption : hsailCode.getAssumptions().getAssumptions()) {
+                if (assumption != null) {
+                    mergedAssumptions.record(assumption);
+                }
+            }
+        }
+        if (!mergedAssumptions.isEmpty()) {
+            result.setAssumptions(mergedAssumptions);
+        }
+        return result;
     }
 
     public boolean executeKernel(HotSpotInstalledCode kernel, int jobSize, Object[] args) throws InvalidInstalledCodeException {
         if (!deviceInitialized) {
             throw new GraalInternalError("Cannot execute GPU kernel if device is not initialized");
         }
-        return executeKernel0(kernel, jobSize, args);
+        Object[] oopsSaveArea = new Object[maxDeoptIndex * 16];
+        return executeKernel0(kernel, jobSize, args, oopsSaveArea);
     }
 
-    private static native boolean executeKernel0(HotSpotInstalledCode kernel, int jobSize, Object[] args) throws InvalidInstalledCodeException;
+    private static native boolean executeKernel0(HotSpotInstalledCode kernel, int jobSize, Object[] args, Object[] oopsSave) throws InvalidInstalledCodeException;
 
     /**
      * Use the HSAIL register set when the compilation target is HSAIL.
@@ -209,6 +380,19 @@
         }
     }
 
+    /**
+     * a class to allow us to save lirGen.
+     */
+    static class HSAILCompilationResultBuilder extends CompilationResultBuilder {
+        public HSAILHotSpotLIRGenerator lirGen;
+
+        public HSAILCompilationResultBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, Assembler asm, FrameContext frameContext,
+                        CompilationResult compilationResult, LIRGenerator lirGen) {
+            super(codeCache, foreignCalls, frameMap, asm, frameContext, compilationResult);
+            this.lirGen = (HSAILHotSpotLIRGenerator) lirGen;
+        }
+    }
+
     @Override
     protected Assembler createAssembler(FrameMap frameMap) {
         return new HSAILAssembler(getTarget());
@@ -219,7 +403,8 @@
         FrameMap frameMap = lirGen.frameMap;
         Assembler masm = createAssembler(frameMap);
         HotSpotFrameContext frameContext = new HotSpotFrameContext();
-        CompilationResultBuilder crb = factory.createBuilder(getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult);
+        // save lirGen for later use by setHostGraph
+        CompilationResultBuilder crb = new HSAILCompilationResultBuilder(getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult, lirGen);
         crb.setFrameSize(frameMap.frameSize());
         return crb;
     }
@@ -227,10 +412,12 @@
     @Override
     public void emitCode(CompilationResultBuilder crb, LIR lir, ResolvedJavaMethod method) {
         assert method != null : lir + " is not associated with a method";
+
+        boolean usesDeoptInfo = true;     // TODO: make this conditional on something?
+
         // Emit the prologue.
-        Assembler asm = crb.asm;
-        asm.emitString0("version 0:95: $full : $large;");
-        asm.emitString("");
+        HSAILAssembler asm = (HSAILAssembler) crb.asm;
+        asm.emitString0("version 0:95: $full : $large;\n");
 
         Signature signature = method.getSignature();
         int sigParamCount = signature.getParameterCount(false);
@@ -275,10 +462,8 @@
             }
         }
 
-        asm.emitString0("// " + (isStatic ? "static" : "instance") + " method " + method);
-        asm.emitString("");
-        asm.emitString0("kernel &run (");
-        asm.emitString("");
+        asm.emitString0("// " + (isStatic ? "static" : "instance") + " method " + method + "\n");
+        asm.emitString0("kernel &run ( \n");
 
         FrameMap frameMap = crb.frameMap;
         RegisterConfig regConfig = frameMap.registerConfig;
@@ -310,11 +495,17 @@
         for (int i = 0; i < totalParamCount; i++) {
             String str = "align 8 kernarg_" + paramHsailSizes[i] + " " + paramNames[i];
 
-            if (i != totalParamCount - 1) {
+            if (usesDeoptInfo || (i != totalParamCount - 1)) {
                 str += ",";
             }
             asm.emitString(str);
         }
+
+        if (usesDeoptInfo) {
+            // add in the deoptInfo parameter
+            asm.emitString("kernarg_u64 " + asm.getDeoptInfoName());
+        }
+
         asm.emitString(") {");
 
         /*
@@ -333,10 +524,28 @@
         String workItemReg = "$s" + Integer.toString(asRegister(cc.getArgument(nonConstantParamCount)).encoding());
         asm.emitString("workitemabsid_u32 " + workItemReg + ", 0;");
 
+        final int offsetToDeoptSaveStates = getRuntime().getConfig().hsailSaveStatesOffset0;
+        final int sizeofKernelDeopt = getRuntime().getConfig().hsailSaveStatesOffset1 - getRuntime().getConfig().hsailSaveStatesOffset0;
+        final int offsetToDeopt = getRuntime().getConfig().hsailDeoptOffset;
+        final int offsetToNeverRanArray = getRuntime().getConfig().hsailNeverRanArrayOffset;
+        final int offsetToDeoptNextIndex = getRuntime().getConfig().hsailDeoptNextIndexOffset;
+        final String deoptInProgressLabel = "@LHandleDeoptInProgress";
+
+        if (usesDeoptInfo) {
+            AllocatableValue scratch64 = HSAIL.d16.asValue(Kind.Object);
+            AllocatableValue scratch32 = HSAIL.s34.asValue(Kind.Int);
+            HSAILAddress deoptInfoAddr = new HSAILAddressValue(Kind.Int, scratch64, offsetToDeopt).toAddress();
+            asm.emitLoadKernelArg(scratch64, asm.getDeoptInfoName(), "u64");
+            asm.emitComment("// Check if a deopt has occurred and abort if true before doing any work");
+            asm.emitLoadAcquire(scratch32, deoptInfoAddr);
+            asm.emitCompare(scratch32, Constant.forInt(0), "ne", false, false);
+            asm.cbr(deoptInProgressLabel);
+        }
+
         /*
          * Note the logic used for this spillseg size is to leave space and then go back and patch
          * in the correct size once we have generated all the instructions. This should probably be
-         * done in a more robust way by implementing something like codeBuffer.insertString.
+         * done in a more robust way by implementing something like asm.insertString.
          */
         int spillsegDeclarationPosition = asm.position() + 1;
         String spillsegTemplate = "align 4 spill_u8 %spillseg[123456];";
@@ -373,9 +582,14 @@
                     if (narrowOopBase == 0) {
                         asm.emitString("shl_u64 " + iterationObjArgReg + ", " + tmpReg + ", " + narrowOopShift + "; // do narrowOopShift");
                     } else if (narrowOopShift == 0) {
+                        // not sure if we ever get add with 0 shift but just in case
+                        asm.emitString("cmp_eq_b1_u64  $c0, " + tmpReg + ", 0x0; // avoid add if compressed is null");
                         asm.emitString("add_u64 " + iterationObjArgReg + ", " + tmpReg + ", " + narrowOopBase + "; // add narrowOopBase");
+                        asm.emitString("cmov_b64 " + iterationObjArgReg + ", $c0, 0x0, " + iterationObjArgReg + "; // avoid add if compressed is null");
                     } else {
+                        asm.emitString("cmp_eq_b1_u64  $c0, " + tmpReg + ", 0x0; // avoid shift-add if compressed is null");
                         asm.emitString("mad_u64 " + iterationObjArgReg + ", " + tmpReg + ", " + (1 << narrowOopShift) + ", " + narrowOopBase + "; // shift and add narrowOopBase");
+                        asm.emitString("cmov_b64 " + iterationObjArgReg + ", $c0, 0x0, " + iterationObjArgReg + "; // avoid shift-add if compressed is null");
                     }
                 }
 
@@ -397,9 +611,155 @@
             spillsegStringFinal = spillsegTemplate.replace("123456", String.format("%6d", maxStackSize));
         }
         asm.emitString(spillsegStringFinal, spillsegDeclarationPosition);
+        // Emit the epilogue.
 
-        // Emit the epilogue.
-        asm.emitString0("};");
-        asm.emitString("");
+        final int offsetToDeoptimizationWorkItem = getRuntime().getConfig().hsailDeoptimizationWorkItem;
+        final int offsetToDeoptimizationReason = getRuntime().getConfig().hsailDeoptimizationReason;
+        final int offsetToDeoptimizationFrame = getRuntime().getConfig().hsailDeoptimizationFrame;
+        final int offsetToFramePc = getRuntime().getConfig().hsailFramePcOffset;
+        final int offsetToNumSaves = getRuntime().getConfig().hsailFrameNumSRegOffset;
+        final int offsetToSaveArea = getRuntime().getConfig().hsailFrameSaveAreaOffset;
+
+        // TODO: keep track of whether we need it
+        if (usesDeoptInfo) {
+            AllocatableValue scratch64 = HSAIL.d16.asValue(Kind.Object);
+            AllocatableValue cuSaveAreaPtr = HSAIL.d17.asValue(Kind.Object);
+            AllocatableValue waveMathScratch1 = HSAIL.d18.asValue(Kind.Object);
+            AllocatableValue waveMathScratch2 = HSAIL.d19.asValue(Kind.Object);
+
+            AllocatableValue actionAndReasonReg = HSAIL.s32.asValue(Kind.Int);
+            AllocatableValue codeBufferOffsetReg = HSAIL.s33.asValue(Kind.Int);
+            AllocatableValue scratch32 = HSAIL.s34.asValue(Kind.Int);
+            AllocatableValue workidreg = HSAIL.s35.asValue(Kind.Int);
+            AllocatableValue dregOopMapReg = HSAIL.s39.asValue(Kind.Int);
+
+            HSAILAddress deoptNextIndexAddr = new HSAILAddressValue(Kind.Int, scratch64, offsetToDeoptNextIndex).toAddress();
+            HSAILAddress neverRanArrayAddr = new HSAILAddressValue(Kind.Int, scratch64, offsetToNeverRanArray).toAddress();
+
+            // The just-started lanes that see the deopt flag will jump here
+            asm.emitString0(deoptInProgressLabel + ":\n");
+            asm.emitLoad(Kind.Object, waveMathScratch1, neverRanArrayAddr);
+            asm.emitWorkItemAbsId(workidreg);
+            asm.emitConvert(waveMathScratch2, workidreg, Kind.Object, Kind.Int);
+            asm.emit("add", waveMathScratch1, waveMathScratch1, waveMathScratch2);
+            HSAILAddress neverRanStoreAddr = new HSAILAddressValue(Kind.Byte, waveMathScratch1, 0).toAddress();
+            asm.emitStore(Kind.Byte, Constant.forInt(1), neverRanStoreAddr);
+            asm.emitString("ret;");
+
+            // The deoptimizing lanes will jump here
+            asm.emitString0(asm.getDeoptLabelName() + ":\n");
+            String labelExit = asm.getDeoptLabelName() + "_Exit";
+
+            HSAILAddress deoptInfoAddr = new HSAILAddressValue(Kind.Int, scratch64, offsetToDeopt).toAddress();
+            asm.emitLoadKernelArg(scratch64, asm.getDeoptInfoName(), "u64");
+
+            // Set deopt occurred flag
+            asm.emitMov(scratch32, Constant.forInt(1));
+            asm.emitStoreRelease(scratch32, deoptInfoAddr);
+
+            asm.emitComment("// Determine next deopt save slot");
+            asm.emitAtomicAdd(scratch32, deoptNextIndexAddr, Constant.forInt(1));
+            // scratch32 now holds next index to use
+            // set error condition if no room in save area
+            asm.emitComment("// assert room to save deopt");
+            asm.emitCompare(scratch32, Constant.forInt(maxDeoptIndex), "lt", false, false);
+            asm.cbr("@L_StoreDeopt");
+            // if assert fails, store a guaranteed negative workitemid in top level deopt occurred
+            // flag
+            asm.emitWorkItemAbsId(scratch32);
+            asm.emit("mad", scratch32, scratch32, Constant.forInt(-1), Constant.forInt(-1));
+            asm.emitStore(scratch32, deoptInfoAddr);
+            asm.emitString("ret;");
+
+            asm.emitString0("@L_StoreDeopt" + ":\n");
+
+            // Store deopt for this workitem into its slot in the HSAILComputeUnitSaveStates array
+
+            asm.emitComment("// Convert id's for ptr math");
+            asm.emitConvert(cuSaveAreaPtr, scratch32, Kind.Object, Kind.Int);
+            asm.emitComment("// multiply by sizeof KernelDeoptArea");
+            asm.emit("mul", cuSaveAreaPtr, cuSaveAreaPtr, Constant.forInt(sizeofKernelDeopt));
+            asm.emitComment("// Add computed offset to deoptInfoPtr base");
+            asm.emit("add", cuSaveAreaPtr, cuSaveAreaPtr, scratch64);
+            // Add offset to _deopt_save_states[0]
+            asm.emit("add", scratch64, cuSaveAreaPtr, Constant.forInt(offsetToDeoptSaveStates));
+
+            HSAILAddress workItemAddr = new HSAILAddressValue(Kind.Int, scratch64, offsetToDeoptimizationWorkItem).toAddress();
+            HSAILAddress actionReasonStoreAddr = new HSAILAddressValue(Kind.Int, scratch64, offsetToDeoptimizationReason).toAddress();
+
+            asm.emitComment("// Get _deopt_info._first_frame");
+            asm.emit("add", waveMathScratch1, scratch64, Constant.forInt(offsetToDeoptimizationFrame));
+            // Now scratch64 is the _deopt_info._first_frame
+            HSAILAddress pcStoreAddr = new HSAILAddressValue(Kind.Int, waveMathScratch1, offsetToFramePc).toAddress();
+            HSAILAddress regCountsAddr = new HSAILAddressValue(Kind.Int, waveMathScratch1, offsetToNumSaves).toAddress();
+            HSAILAddress dregOopMapAddr = new HSAILAddressValue(Kind.Int, waveMathScratch1, offsetToNumSaves + 2).toAddress();
+
+            asm.emitComment("// store deopting workitem");
+            asm.emitWorkItemAbsId(scratch32);
+            asm.emitStore(Kind.Int, scratch32, workItemAddr);
+            asm.emitComment("// store actionAndReason");
+            asm.emitStore(Kind.Int, actionAndReasonReg, actionReasonStoreAddr);
+            asm.emitComment("// store PC");
+            asm.emitStore(Kind.Int, codeBufferOffsetReg, pcStoreAddr);
+            asm.emitComment("// store regCounts");
+            asm.emitStore(Kind.Short, Constant.forInt(32 + (16 << 8) + (0 << 16)), regCountsAddr);
+            asm.emitComment("// store dreg ref map bits");
+            asm.emitStore(Kind.Short, dregOopMapReg, dregOopMapAddr);
+
+            // get the union of registers needed to be saved at the infopoints
+            // usedRegs array assumes d15 has the highest register number we wish to save
+            // and initially has all registers as false
+            boolean[] infoUsedRegs = new boolean[HSAIL.d15.number + 1];
+            List<Infopoint> infoList = crb.compilationResult.getInfopoints();
+            for (Infopoint info : infoList) {
+                BytecodeFrame frame = info.debugInfo.frame();
+                for (int i = 0; i < frame.numLocals + frame.numStack; i++) {
+                    Value val = frame.values[i];
+                    if (isLegal(val) && isRegister(val)) {
+                        Register reg = asRegister(val);
+                        infoUsedRegs[reg.number] = true;
+                    }
+                }
+            }
+
+            // loop storing each of the 32 s registers that are used by infopoints
+            // we always store in a fixed location, even if some registers are not stored
+            asm.emitComment("// store used s regs");
+            int ofst = offsetToSaveArea;
+            for (Register sreg : HSAIL.sRegisters) {
+                if (infoUsedRegs[sreg.number]) {
+                    Kind kind = Kind.Int;
+                    HSAILAddress addr = new HSAILAddressValue(kind, waveMathScratch1, ofst).toAddress();
+                    AllocatableValue sregValue = sreg.asValue(kind);
+                    asm.emitStore(kind, sregValue, addr);
+                }
+                ofst += 4;
+            }
+
+            // loop storing each of the 16 d registers that are used by infopoints
+            asm.emitComment("// store used d regs");
+            for (Register dreg : HSAIL.dRegisters) {
+                if (infoUsedRegs[dreg.number]) {
+                    Kind kind = Kind.Long;
+                    HSAILAddress addr = new HSAILAddressValue(kind, waveMathScratch1, ofst).toAddress();
+                    AllocatableValue dregValue = dreg.asValue(kind);
+                    asm.emitStore(kind, dregValue, addr);
+                }
+                ofst += 8;
+            }
+
+            // for now, ignore saving the spill variables but that would come here
+
+            asm.emitString0(labelExit + ":\n");
+
+            // and emit the return
+            crb.frameContext.leave(crb);
+            asm.exit();
+        }
+
+        asm.emitString0("}; \n");
+
+        ExternalCompilationResult compilationResult = (ExternalCompilationResult) crb.compilationResult;
+        compilationResult.setHostGraph(((HSAILCompilationResultBuilder) crb).lirGen.prepareHostGraph());
     }
 }
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java	Wed Mar 26 17:30:40 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java	Wed Mar 26 17:33:54 2014 +0100
@@ -23,27 +23,43 @@
 
 package com.oracle.graal.hotspot.hsail;
 
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.api.meta.LocationIdentity.*;
+
+import java.util.*;
+
 import sun.misc.*;
 
 import com.oracle.graal.api.code.*;
-import static com.oracle.graal.api.code.ValueUtil.asConstant;
-import static com.oracle.graal.api.code.ValueUtil.isConstant;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.hsail.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.hsail.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.hsail.*;
-import com.oracle.graal.lir.hsail.HSAILControlFlow.*;
-import com.oracle.graal.lir.hsail.HSAILMove.*;
-import com.oracle.graal.phases.util.*;
+import com.oracle.graal.lir.hsail.HSAILControlFlow.CondMoveOp;
+import com.oracle.graal.lir.hsail.HSAILControlFlow.DeoptimizeOp;
+import com.oracle.graal.lir.hsail.HSAILControlFlow.ForeignCall1ArgOp;
+import com.oracle.graal.lir.hsail.HSAILControlFlow.ForeignCall2ArgOp;
+import com.oracle.graal.lir.hsail.HSAILControlFlow.ForeignCallNoArgOp;
+import com.oracle.graal.lir.hsail.HSAILMove.CompareAndSwapCompressedOp;
+import com.oracle.graal.lir.hsail.HSAILMove.CompareAndSwapOp;
+import com.oracle.graal.lir.hsail.HSAILMove.LoadCompressedPointer;
+import com.oracle.graal.lir.hsail.HSAILMove.LoadOp;
+import com.oracle.graal.lir.hsail.HSAILMove.StoreCompressedPointer;
+import com.oracle.graal.lir.hsail.HSAILMove.StoreConstantOp;
+import com.oracle.graal.lir.hsail.HSAILMove.StoreOp;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.StructuredGraph.GuardsStage;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.phases.util.*;
 
 /**
  * The HotSpot specific portion of the HSAIL LIR generator.
@@ -51,10 +67,144 @@
 public class HSAILHotSpotLIRGenerator extends HSAILLIRGenerator implements HotSpotLIRGenerator {
 
     private final HotSpotVMConfig config;
+    private final List<DeoptimizeOp> deopts = new ArrayList<>();
+    private final ResolvedJavaMethod method;
 
     public HSAILHotSpotLIRGenerator(StructuredGraph graph, Providers providers, HotSpotVMConfig config, FrameMap frameMap, CallingConvention cc, LIR lir) {
         super(graph, providers, frameMap, cc, lir);
         this.config = config;
+        this.method = graph.method();
+    }
+
+    protected StructuredGraph prepareHostGraph() {
+        if (deopts.isEmpty()) {
+            return null;
+        }
+        StructuredGraph hostGraph = new StructuredGraph(method, -2);
+        ParameterNode deoptId = hostGraph.unique(new ParameterNode(0, StampFactory.intValue()));
+        ParameterNode hsailFrame = hostGraph.unique(new ParameterNode(1, StampFactory.forKind(getProviders().getCodeCache().getTarget().wordKind)));
+        ParameterNode reasonAndAction = hostGraph.unique(new ParameterNode(2, StampFactory.intValue()));
+        ParameterNode speculation = hostGraph.unique(new ParameterNode(3, StampFactory.object()));
+        AbstractBeginNode[] branches = new AbstractBeginNode[deopts.size() + 1];
+        int[] keys = new int[deopts.size()];
+        int[] keySuccessors = new int[deopts.size() + 1];
+        double[] keyProbabilities = new double[deopts.size() + 1];
+        int i = 0;
+        Collections.sort(deopts, new Comparator<DeoptimizeOp>() {
+            public int compare(DeoptimizeOp o1, DeoptimizeOp o2) {
+                return o1.getCodeBufferPos() - o2.getCodeBufferPos();
+            }
+        });
+        for (DeoptimizeOp deopt : deopts) {
+            keySuccessors[i] = i;
+            keyProbabilities[i] = 1.0 / deopts.size();
+            keys[i] = deopt.getCodeBufferPos();
+            assert keys[i] >= 0;
+            branches[i] = createHostDeoptBranch(deopt, hsailFrame, reasonAndAction, speculation);
+
+            i++;
+        }
+        keyProbabilities[deopts.size()] = 0; // default
+        keySuccessors[deopts.size()] = deopts.size();
+        branches[deopts.size()] = createHostCrashBranch(hostGraph, deoptId);
+        IntegerSwitchNode switchNode = hostGraph.add(new IntegerSwitchNode(deoptId, branches, keys, keyProbabilities, keySuccessors));
+        StartNode start = hostGraph.start();
+        start.setNext(switchNode);
+        /*
+         * printf.setNext(printf2); printf2.setNext(switchNode);
+         */
+        hostGraph.setGuardsStage(GuardsStage.AFTER_FSA);
+        return hostGraph;
+    }
+
+    private static AbstractBeginNode createHostCrashBranch(StructuredGraph hostGraph, ValueNode deoptId) {
+        VMErrorNode vmError = hostGraph.add(new VMErrorNode("Error in HSAIL deopt. DeoptId=%d", deoptId));
+        // ConvertNode.convert(hostGraph, Kind.Long, deoptId)));
+        vmError.setNext(hostGraph.add(new ReturnNode(ConstantNode.defaultForKind(hostGraph.method().getSignature().getReturnKind(), hostGraph))));
+        return BeginNode.begin(vmError);
+    }
+
+    private AbstractBeginNode createHostDeoptBranch(DeoptimizeOp deopt, ParameterNode hsailFrame, ValueNode reasonAndAction, ValueNode speculation) {
+        BeginNode branch = hsailFrame.graph().add(new BeginNode());
+        DynamicDeoptimizeNode deoptimization = hsailFrame.graph().add(new DynamicDeoptimizeNode(reasonAndAction, speculation));
+        deoptimization.setStateBefore(createFrameState(deopt.getFrameState().topFrame, hsailFrame));
+        branch.setNext(deoptimization);
+        return branch;
+    }
+
+    private FrameState createFrameState(BytecodeFrame lowLevelFrame, ParameterNode hsailFrame) {
+        StructuredGraph hostGraph = hsailFrame.graph();
+        ValueNode[] locals = new ValueNode[lowLevelFrame.numLocals];
+        for (int i = 0; i < lowLevelFrame.numLocals; i++) {
+            locals[i] = getNodeForValueFromFrame(lowLevelFrame.getLocalValue(i), hsailFrame, hostGraph);
+        }
+        List<ValueNode> stack = new ArrayList<>(lowLevelFrame.numStack);
+        for (int i = 0; i < lowLevelFrame.numStack; i++) {
+            stack.add(getNodeForValueFromFrame(lowLevelFrame.getStackValue(i), hsailFrame, hostGraph));
+        }
+        ValueNode[] locks = new ValueNode[lowLevelFrame.numLocks];
+        MonitorIdNode[] monitorIds = new MonitorIdNode[lowLevelFrame.numLocks];
+        for (int i = 0; i < lowLevelFrame.numLocks; i++) {
+            HotSpotMonitorValue lockValue = (HotSpotMonitorValue) lowLevelFrame.getLockValue(i);
+            locks[i] = getNodeForValueFromFrame(lockValue, hsailFrame, hostGraph);
+            monitorIds[i] = getMonitorIdForHotSpotMonitorValueFromFrame(lockValue, hsailFrame, hostGraph);
+        }
+        FrameState frameState = hostGraph.add(new FrameState(lowLevelFrame.getMethod(), lowLevelFrame.getBCI(), locals, stack, locks, monitorIds, lowLevelFrame.rethrowException, false));
+        if (lowLevelFrame.caller() != null) {
+            frameState.setOuterFrameState(createFrameState(lowLevelFrame.caller(), hsailFrame));
+        }
+        return frameState;
+    }
+
+    @SuppressWarnings({"unused", "static-method"})
+    private MonitorIdNode getMonitorIdForHotSpotMonitorValueFromFrame(HotSpotMonitorValue lockValue, ParameterNode hsailFrame, StructuredGraph hsailGraph) {
+        if (lockValue.isEliminated()) {
+            return null;
+        }
+        throw GraalInternalError.unimplemented();
+    }
+
+    private ValueNode getNodeForValueFromFrame(Value localValue, ParameterNode hsailFrame, StructuredGraph hostGraph) {
+        ValueNode valueNode;
+        if (localValue instanceof Constant) {
+            valueNode = ConstantNode.forConstant((Constant) localValue, getProviders().getMetaAccess(), hostGraph);
+        } else if (localValue instanceof VirtualObject) {
+            throw GraalInternalError.unimplemented();
+        } else if (localValue instanceof StackSlot) {
+            throw GraalInternalError.unimplemented();
+        } else if (localValue instanceof HotSpotMonitorValue) {
+            HotSpotMonitorValue hotSpotMonitorValue = (HotSpotMonitorValue) localValue;
+            return getNodeForValueFromFrame(hotSpotMonitorValue.getOwner(), hsailFrame, hostGraph);
+        } else if (localValue instanceof RegisterValue) {
+            RegisterValue registerValue = (RegisterValue) localValue;
+            int regNumber = registerValue.getRegister().number;
+            valueNode = getNodeForRegisterFromFrame(regNumber, localValue.getKind(), hsailFrame, hostGraph);
+        } else if (Value.ILLEGAL.equals(localValue)) {
+            valueNode = null;
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+        return valueNode;
+    }
+
+    private ValueNode getNodeForRegisterFromFrame(int regNumber, Kind valueKind, ParameterNode hsailFrame, StructuredGraph hostGraph) {
+        ValueNode valueNode;
+        LocationNode location;
+        if (regNumber >= HSAIL.s0.number && regNumber <= HSAIL.s31.number) {
+            int intSize = getProviders().getCodeCache().getTarget().arch.getSizeInBytes(Kind.Int);
+            long offset = config.hsailFrameSaveAreaOffset + intSize * (regNumber - HSAIL.s0.number);
+            location = ConstantLocationNode.create(FINAL_LOCATION, valueKind, offset, hostGraph);
+        } else if (regNumber >= HSAIL.d0.number && regNumber <= HSAIL.d15.number) {
+            int longSize = getProviders().getCodeCache().getTarget().arch.getSizeInBytes(Kind.Long);
+            long offset = config.hsailFrameSaveAreaOffset + longSize * (regNumber - HSAIL.d0.number);
+            LocationNode numSRegsLocation = ConstantLocationNode.create(FINAL_LOCATION, Kind.Byte, config.hsailFrameNumSRegOffset, hostGraph);
+            ValueNode numSRegs = hostGraph.unique(new FloatingReadNode(hsailFrame, numSRegsLocation, null, StampFactory.forKind(Kind.Byte)));
+            location = IndexedLocationNode.create(FINAL_LOCATION, valueKind, offset, numSRegs, hostGraph, 4);
+        } else {
+            throw GraalInternalError.shouldNotReachHere("unknown hsail register: " + regNumber);
+        }
+        valueNode = hostGraph.unique(new FloatingReadNode(hsailFrame, location, null, StampFactory.forKind(valueKind)));
+        return valueNode;
     }
 
     @Override
@@ -231,11 +381,34 @@
         }
     }
 
+    @Override
+    public void emitDeoptimize(Value actionAndReason, Value failedSpeculation, DeoptimizingNode deopting) {
+        emitDeoptimizeInner(actionAndReason, state(deopting), "emitDeoptimize");
+    }
+
+    /***
+     * We need 64-bit and 32-bit scratch registers for the codegen $s0 can be live at this block.
+     */
+    private void emitDeoptimizeInner(Value actionAndReason, LIRFrameState lirFrameState, String emitName) {
+        DeoptimizeOp deopt = new DeoptimizeOp(actionAndReason, lirFrameState, emitName, getMetaAccess());
+        deopts.add(deopt);
+        append(deopt);
+    }
+
+    @Override
+    protected void emitNode(ValueNode node) {
+        if (node instanceof CurrentJavaThreadNode) {
+            throw new GraalInternalError("HSAILHotSpotLIRGenerator cannot handle node: " + node);
+        } else {
+            super.emitNode(node);
+        }
+    }
+
     /***
      * This is a very temporary solution to emitForeignCall. We don't really support foreign calls
      * yet, but we do want to generate dummy code for them. The ForeignCallXXXOps just end up
      * emitting a comment as to what Foreign call they would have made.
-     **/
+     */
     @Override
     public Variable emitForeignCall(ForeignCallLinkage linkage, DeoptimizingNode info, Value... args) {
         Variable result = newVariable(Kind.Object);  // linkage.getDescriptor().getResultType());
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLoweringProvider.java	Wed Mar 26 17:30:40 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLoweringProvider.java	Wed Mar 26 17:33:54 2014 +0100
@@ -27,21 +27,92 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
+import java.util.HashMap;
 
 public class HSAILHotSpotLoweringProvider extends HotSpotLoweringProvider {
 
+    abstract static class LoweringStrategy {
+        abstract void lower(Node n, LoweringTool tool);
+    }
+
+    static LoweringStrategy PassThruStrategy = new LoweringStrategy() {
+        @Override
+        void lower(Node n, LoweringTool tool) {
+            return;
+        }
+    };
+
+    static LoweringStrategy RejectStrategy = new LoweringStrategy() {
+        @Override
+        void lower(Node n, LoweringTool tool) {
+            throw new GraalInternalError("Node implementing Lowerable not handled in HSAIL Backend: " + n);
+        }
+    };
+
+    // strategy to replace an UnwindNode with a DeoptNode
+    static LoweringStrategy UnwindNodeStrategy = new LoweringStrategy() {
+        @Override
+        void lower(Node n, LoweringTool tool) {
+            StructuredGraph graph = (StructuredGraph) n.graph();
+            UnwindNode unwind = (UnwindNode) n;
+            ValueNode exception = unwind.exception();
+            if (exception instanceof ForeignCallNode) {
+                // build up action and reason
+                String callName = ((ForeignCallNode) exception).getDescriptor().getName();
+                DeoptimizationReason reason;
+                switch (callName) {
+                    case "createOutOfBoundsException":
+                        reason = DeoptimizationReason.BoundsCheckException;
+                        break;
+                    case "createNullPointerException":
+                        reason = DeoptimizationReason.NullCheckException;
+                        break;
+                    default:
+                        reason = DeoptimizationReason.None;
+                }
+                unwind.replaceAtPredecessor(graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, reason)));
+                unwind.safeDelete();
+            } else {
+                // unwind whose exception is not an instance of ForeignCallNode
+                throw new GraalInternalError("UnwindNode seen without ForeignCallNode: " + exception);
+            }
+        }
+    };
+
+    private static HashMap<Class<?>, LoweringStrategy> strategyMap = new HashMap<>();
+    static {
+        strategyMap.put(ConvertNode.class, PassThruStrategy);
+        strategyMap.put(FloatConvertNode.class, PassThruStrategy);
+        strategyMap.put(NewInstanceNode.class, RejectStrategy);
+        strategyMap.put(NewArrayNode.class, RejectStrategy);
+        strategyMap.put(NewMultiArrayNode.class, RejectStrategy);
+        strategyMap.put(DynamicNewArrayNode.class, RejectStrategy);
+        strategyMap.put(MonitorEnterNode.class, RejectStrategy);
+        strategyMap.put(MonitorExitNode.class, RejectStrategy);
+        strategyMap.put(UnwindNode.class, UnwindNodeStrategy);
+    }
+
+    private static LoweringStrategy getStrategy(Node n) {
+        return strategyMap.get(n.getClass());
+    }
+
     public HSAILHotSpotLoweringProvider(HotSpotGraalRuntime runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers) {
         super(runtime, metaAccess, foreignCalls, registers);
     }
 
     @Override
     public void lower(Node n, LoweringTool tool) {
-        if (n instanceof ConvertNode) {
-            return;
+        LoweringStrategy strategy = getStrategy(n);
+        // if not in map, let superclass handle it
+        if (strategy == null) {
+            super.lower(n, tool);
         } else {
-            super.lower(n, tool);
+            strategy.lower(n, tool);
         }
     }
 
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java	Wed Mar 26 17:30:40 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java	Wed Mar 26 17:33:54 2014 +0100
@@ -39,6 +39,7 @@
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
+import com.oracle.graal.gpu.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java	Wed Mar 26 17:30:40 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java	Wed Mar 26 17:33:54 2014 +0100
@@ -76,6 +76,18 @@
         }
     }
 
+    public PlatformKind getRegister(int idx) {
+        int refMapIndex = idx * 2;
+        if (registerRefMap.get(refMapIndex)) {
+            if (registerRefMap.get(refMapIndex + 1)) {
+                return NarrowOopStamp.NarrowOop;
+            } else {
+                return Kind.Object;
+            }
+        }
+        return null;
+    }
+
     public void setStackSlot(int offset, PlatformKind kind) {
         int idx = offset / frameSlotSize;
         if (kind == Kind.Object) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Wed Mar 26 17:30:40 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Wed Mar 26 17:33:54 2014 +0100
@@ -1005,6 +1005,24 @@
     @HotSpotVMField(name = "ThreadShadow::_pending_failed_speculation", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int pendingFailedSpeculationOffset;
 
     /**
+     * Offsets of Hsail deoptimization fields (defined in gpu_hsail.hpp). Used to propagate
+     * exceptions from Hsail back to C++ runtime.
+     */
+    @HotSpotVMField(name = "Hsail::HSAILDeoptimizationInfo::_deopt_save_states[0]", type = "Hsail::HSAILKernelDeoptimization", get = HotSpotVMField.Type.OFFSET) @Stable public int hsailSaveStatesOffset0;
+    @HotSpotVMField(name = "Hsail::HSAILDeoptimizationInfo::_deopt_save_states[1]", type = "Hsail::HSAILKernelDeoptimization", get = HotSpotVMField.Type.OFFSET) @Stable public int hsailSaveStatesOffset1;
+    @HotSpotVMField(name = "Hsail::HSAILDeoptimizationInfo::_deopt_occurred", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int hsailDeoptOffset;
+    @HotSpotVMField(name = "Hsail::HSAILDeoptimizationInfo::_never_ran_array", type = "jboolean *", get = HotSpotVMField.Type.OFFSET) @Stable public int hsailNeverRanArrayOffset;
+    @HotSpotVMField(name = "Hsail::HSAILDeoptimizationInfo::_deopt_next_index", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int hsailDeoptNextIndexOffset;
+
+    @HotSpotVMField(name = "Hsail::HSAILKernelDeoptimization::_workitemid", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int hsailDeoptimizationWorkItem;
+    @HotSpotVMField(name = "Hsail::HSAILKernelDeoptimization::_actionAndReason", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int hsailDeoptimizationReason;
+    @HotSpotVMField(name = "Hsail::HSAILKernelDeoptimization::_first_frame", type = "HSAILFrame", get = HotSpotVMField.Type.OFFSET) @Stable public int hsailDeoptimizationFrame;
+
+    @HotSpotVMField(name = "HSAILFrame::_pc_offset", type = "jint", get = HotSpotVMField.Type.OFFSET) @Stable public int hsailFramePcOffset;
+    @HotSpotVMField(name = "HSAILFrame::_num_s_regs", type = "jbyte", get = HotSpotVMField.Type.OFFSET) @Stable public int hsailFrameNumSRegOffset;
+    @HotSpotVMField(name = "HSAILFrame::_save_area[0]", type = "jlong", get = HotSpotVMField.Type.OFFSET) @Stable public int hsailFrameSaveAreaOffset;
+
+    /**
      * Mark word right shift to get identity hash code.
      */
     @HotSpotVMConstant(name = "markOopDesc::hash_shift") @Stable public int identityHashCodeShift;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java	Wed Mar 26 17:30:40 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java	Wed Mar 26 17:33:54 2014 +0100
@@ -43,7 +43,7 @@
     @Input private ValueNode value;
     public static final ForeignCallDescriptor VM_ERROR = new ForeignCallDescriptor("vm_error", void.class, long.class, long.class, long.class);
 
-    private VMErrorNode(String format, ValueNode value) {
+    public VMErrorNode(String format, ValueNode value) {
         super(StampFactory.forVoid());
         this.format = format;
         this.value = value;
--- a/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java	Wed Mar 26 17:30:40 2014 +0100
+++ b/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java	Wed Mar 26 17:33:54 2014 +0100
@@ -118,6 +118,20 @@
     public static final Register q14 = new Register(70, 14, "q14", CPU);
     public static final Register q15 = new Register(71, 15, "q15", CPU);
 
+    // non-allocatable registers used for deopt
+    public static final Register s32 = new Register(72, 32, "s32", CPU);
+    public static final Register s33 = new Register(73, 33, "s33", CPU);
+    public static final Register s34 = new Register(74, 34, "s34", CPU);
+    public static final Register s35 = new Register(75, 35, "s35", CPU);
+    public static final Register s36 = new Register(76, 36, "s36", CPU);
+    public static final Register s37 = new Register(77, 37, "s37", CPU);
+    public static final Register s38 = new Register(78, 38, "s38", CPU);
+    public static final Register s39 = new Register(79, 39, "s39", CPU);
+    public static final Register d16 = new Register(80, 16, "d16", CPU);
+    public static final Register d17 = new Register(81, 17, "d17", CPU);
+    public static final Register d18 = new Register(82, 18, "d18", CPU);
+    public static final Register d19 = new Register(83, 19, "d19", CPU);
+
     // @formatter:off
     public static final Register[] cRegisters = {
         c0, c1, c2, c3, c4, c5, c6, c7
--- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java	Wed Mar 26 17:30:40 2014 +0100
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java	Wed Mar 26 17:33:54 2014 +0100
@@ -34,6 +34,11 @@
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.calc.*;
 
+import static com.oracle.graal.api.code.ValueUtil.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.hsail.HSAIL;
+
 /**
  * Implementation of control flow instructions.
  */
@@ -96,11 +101,11 @@
                 protected void conditionalJump(int index, Condition condition, Label target) {
                     switch (key.getKind()) {
                         case Int:
+                        case Long:
                             // Generate cascading compare and branches for each case.
                             masm.emitCompare(key, keyConstants[index], HSAILCompare.conditionToString(condition), false, false);
                             masm.cbr(masm.nameOf(target));
                             break;
-                        case Long:
                         case Object:
                         default:
                             throw new GraalInternalError("switch only supported for int");
@@ -126,6 +131,100 @@
         }
     }
 
+    /***
+     * The ALIVE annotation is so we can get a scratch32 register that does not clobber
+     * actionAndReason.
+     */
+    public static class DeoptimizeOp extends ReturnOp {
+
+        @Alive({REG, CONST}) protected Value actionAndReason;
+        @State protected LIRFrameState frameState;
+        protected MetaAccessProvider metaAccessProvider;
+        protected String emitName;
+        protected int codeBufferPos = -1;
+        protected int dregOopMap = 0;
+
+        public DeoptimizeOp(Value actionAndReason, LIRFrameState frameState, String emitName, MetaAccessProvider metaAccessProvider) {
+            super(Value.ILLEGAL);   // return with no ret value
+            this.actionAndReason = actionAndReason;
+            this.frameState = frameState;
+            this.emitName = emitName;
+            this.metaAccessProvider = metaAccessProvider;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
+            String reasonString;
+            if (isConstant(actionAndReason)) {
+                DeoptimizationReason reason = metaAccessProvider.decodeDeoptReason((Constant) actionAndReason);
+                reasonString = reason.toString();
+            } else {
+                reasonString = "Variable Reason";
+            }
+
+            masm.emitComment("// " + emitName + ", Deoptimization for " + reasonString);
+
+            if (frameState == null) {
+                masm.emitComment("// frameState == null");
+                // and emit the return
+                super.emitCode(crb, masm);
+                return;
+            }
+            // get a unique codeBuffer position
+            // when we save our state, we will save this as well (it can be used as a key to get the
+            // debugInfo)
+            codeBufferPos = masm.position();
+
+            // get the bitmap of $d regs that contain references
+            ReferenceMap referenceMap = frameState.debugInfo().getReferenceMap();
+            for (int dreg = HSAIL.d0.number; dreg <= HSAIL.d15.number; dreg++) {
+                if (referenceMap.getRegister(dreg) == Kind.Object) {
+                    dregOopMap |= 1 << (dreg - HSAIL.d0.number);
+                }
+            }
+
+            // here we will by convention use some never-allocated registers to pass to the epilogue
+            // deopt code
+            // todo: define these in HSAIL.java
+            // we need to pass the actionAndReason and the codeBufferPos
+
+            AllocatableValue actionAndReasonReg = HSAIL.s32.asValue(Kind.Int);
+            AllocatableValue codeBufferOffsetReg = HSAIL.s33.asValue(Kind.Int);
+            AllocatableValue dregOopMapReg = HSAIL.s39.asValue(Kind.Int);
+            masm.emitMov(actionAndReasonReg, actionAndReason);
+            masm.emitMov(codeBufferOffsetReg, Constant.forInt(codeBufferPos));
+            masm.emitMov(dregOopMapReg, Constant.forInt(dregOopMap));
+            masm.emitJumpToLabelName(masm.getDeoptLabelName());
+
+            // now record the debuginfo
+            crb.recordInfopoint(codeBufferPos, frameState, InfopointReason.IMPLICIT_EXCEPTION);
+        }
+
+        public LIRFrameState getFrameState() {
+            return frameState;
+        }
+
+        public int getCodeBufferPos() {
+            return codeBufferPos;
+        }
+    }
+
+    public static class UnwindOp extends ReturnOp {
+
+        protected String commentMessage;
+
+        public UnwindOp(String commentMessage) {
+            super(Value.ILLEGAL);   // return with no ret value
+            this.commentMessage = commentMessage;
+        }
+
+        @Override
+        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
+            masm.emitComment("// " + commentMessage);
+            super.emitCode(crb, masm);
+        }
+    }
+
     public static class ForeignCallNoArgOp extends HSAILLIRInstruction {
 
         @Def({REG}) protected Value out;
@@ -224,7 +323,7 @@
         @Override
         public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
             HSAILCompare.emit(crb, masm, condition, left, right, right, false);
-            cmove(crb, masm, result, false, trueValue, falseValue);
+            cmove(masm, result, trueValue, falseValue);
         }
     }
 
@@ -240,12 +339,11 @@
         @Override
         public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
             HSAILCompare.emit(crb, masm, condition, left, right, right, unorderedIsTrue);
-            cmove(crb, masm, result, false, trueValue, falseValue);
+            cmove(masm, result, trueValue, falseValue);
         }
     }
 
-    @SuppressWarnings("unused")
-    private static void cmove(CompilationResultBuilder crb, HSAILAssembler masm, Value result, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
+    private static void cmove(HSAILAssembler masm, Value result, Value trueValue, Value falseValue) {
         // Check that we don't overwrite an input operand before it is used.
         assert (result.getKind() == trueValue.getKind() && result.getKind() == falseValue.getKind());
         int width;
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java	Wed Mar 26 17:30:40 2014 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java	Wed Mar 26 17:33:54 2014 +0100
@@ -24,7 +24,6 @@
 
 import java.util.*;
 
-import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.util.*;
@@ -64,98 +63,14 @@
     }
 
     public NodesToDoubles apply() {
-        adjustControlSplitProbabilities();
+        // adjustControlSplitProbabilities();
         new PropagateProbability(graph.start()).apply();
         computeLoopFactors();
         new PropagateLoopFrequency(graph.start()).apply();
-        assert verifyProbabilities();
+        // assert verifyProbabilities();
         return nodeProbabilities;
     }
 
-    /**
-     * Assume that paths with a DeoptimizeNode at their end are taken infrequently.
-     */
-    private void adjustControlSplitProbabilities() {
-        Set<ControlSplitNode> result = new ArraySet<>();
-        NodeBitMap visitedNodes = new NodeBitMap(graph);
-        for (AbstractDeoptimizeNode n : graph.getNodes(AbstractDeoptimizeNode.class)) {
-            if (!(n instanceof DeoptimizeNode) || ((DeoptimizeNode) n).action().doesInvalidateCompilation()) {
-                findParentControlSplitNodes(result, n, visitedNodes);
-            }
-        }
-
-        for (ControlSplitNode n : result) {
-            if (!allSuxVisited(n, visitedNodes)) {
-                modifyProbabilities(n, visitedNodes);
-            }
-        }
-    }
-
-    private static void findParentControlSplitNodes(Set<ControlSplitNode> result, AbstractDeoptimizeNode n, NodeBitMap visitedNodes) {
-        ArrayDeque<FixedNode> nodes = new ArrayDeque<>();
-        nodes.push(n);
-
-        Node currentNode;
-        do {
-            currentNode = nodes.pop();
-            visitedNodes.mark(currentNode);
-
-            for (Node pred : currentNode.cfgPredecessors()) {
-                FixedNode fixedPred = (FixedNode) pred;
-                if (visitedNodes.isMarked(fixedPred) && allPredsVisited(fixedPred, visitedNodes)) {
-                    DebugScope.dump(n.graph(), "ComputeProbabilityClosure");
-                    GraalInternalError.shouldNotReachHere(String.format("Endless loop because %s was already visited", fixedPred));
-                } else if (allSuxVisited(fixedPred, visitedNodes)) {
-                    nodes.push(fixedPred);
-                } else {
-                    assert fixedPred instanceof ControlSplitNode : "only control splits can have more than one sux";
-                    result.add((ControlSplitNode) fixedPred);
-                }
-            }
-        } while (!nodes.isEmpty());
-    }
-
-    private static void modifyProbabilities(ControlSplitNode controlSplit, NodeBitMap visitedNodes) {
-        assert !allSuxVisited(controlSplit, visitedNodes);
-        for (Node sux : controlSplit.successors()) {
-            if (visitedNodes.isMarked(sux)) {
-                controlSplit.setProbability((AbstractBeginNode) sux, 0);
-            }
-        }
-    }
-
-    private static boolean allSuxVisited(FixedNode node, NodeBitMap visitedNodes) {
-        return allVisited(node.successors(), visitedNodes);
-    }
-
-    private static boolean allPredsVisited(FixedNode node, NodeBitMap visitedNodes) {
-        return allVisited(node.cfgPredecessors(), visitedNodes);
-    }
-
-    private static boolean allVisited(Iterable<? extends Node> nodes, NodeBitMap visitedNodes) {
-        for (Node sux : nodes) {
-            if (!visitedNodes.contains(sux)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private boolean verifyProbabilities() {
-        if (doesNotAlwaysDeopt(graph)) {
-            for (AbstractDeoptimizeNode n : graph.getNodes(AbstractDeoptimizeNode.class)) {
-                if (nodeProbabilities.get(n) > 0.01 && (!(n instanceof DeoptimizeNode) || ((DeoptimizeNode) n).action().doesInvalidateCompilation())) {
-                    throw new AssertionError(String.format("%s with probability %f in graph %s", n, nodeProbabilities.get(n), graph));
-                }
-            }
-        }
-        return true;
-    }
-
-    private static boolean doesNotAlwaysDeopt(StructuredGraph graph) {
-        return graph.getNodes(ReturnNode.class).isNotEmpty();
-    }
-
     private void computeLoopFactors() {
         for (LoopInfo info : loopInfos) {
             double frequency = info.loopFrequency(nodeProbabilities);
--- a/mx/projects	Wed Mar 26 17:30:40 2014 +0100
+++ b/mx/projects	Wed Mar 26 17:33:54 2014 +0100
@@ -125,7 +125,7 @@
 # graal.ptx
 project@com.oracle.graal.ptx@subDir=graal
 project@com.oracle.graal.ptx@sourceDirs=src
-project@com.oracle.graal.ptx@dependencies=com.oracle.graal.api.code
+project@com.oracle.graal.ptx@dependencies=com.oracle.graal.gpu
 project@com.oracle.graal.ptx@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.ptx@javaCompliance=1.8
 project@com.oracle.graal.ptx@workingSets=Graal,PTX
@@ -568,10 +568,17 @@
 project@com.oracle.graal.asm.amd64.test@javaCompliance=1.8
 project@com.oracle.graal.asm.amd64.test@workingSets=Graal,Assembler,AMD64,Test
 
+# graal.gpu
+project@com.oracle.graal.gpu@subDir=graal
+project@com.oracle.graal.gpu@sourceDirs=src
+project@com.oracle.graal.gpu@dependencies=com.oracle.graal.api.code,com.oracle.graal.nodes
+project@com.oracle.graal.gpu@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.gpu@javaCompliance=1.8
+
 # graal.hsail
 project@com.oracle.graal.hsail@subDir=graal
 project@com.oracle.graal.hsail@sourceDirs=src
-project@com.oracle.graal.hsail@dependencies=com.oracle.graal.graph
+project@com.oracle.graal.hsail@dependencies=com.oracle.graal.graph,com.oracle.graal.gpu
 project@com.oracle.graal.hsail@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.hsail@javaCompliance=1.8
 
--- a/src/gpu/hsail/vm/gpu_hsail.cpp	Wed Mar 26 17:30:40 2014 +0100
+++ b/src/gpu/hsail/vm/gpu_hsail.cpp	Wed Mar 26 17:33:54 2014 +0100
@@ -25,15 +25,22 @@
 #include "precompiled.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/gpu.hpp"
+#include "runtime/deoptimization.hpp"
+#include "gpu_hsail.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/exceptions.hpp"
 #include "hsail/vm/gpu_hsail.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/ostream.hpp"
-#include "memory/allocation.hpp"
-#include "memory/allocation.inline.hpp"
 #include "graal/graalEnv.hpp"
 #include "graal/graalCompiler.hpp"
 #include "graal/graalJavaAccess.hpp"
 #include "hsailKernelArguments.hpp"
+#include "hsailJavaCallArguments.hpp"
+#include "code/pcDesc.hpp"
+#include "code/scopeDesc.hpp"
+#include "graal/graalVMToCompiler.hpp"
+#include "gpu_hsail_Frame.hpp"
 
 // Entry to GPU native method implementation that transitions current thread to '_thread_in_vm'.
 #define GPU_VMENTRY(result_type, name, signature) \
@@ -53,13 +60,15 @@
 #define OBJECT                "Ljava/lang/Object;"
 #define STRING                "Ljava/lang/String;"
 #define HS_INSTALLED_CODE     "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;"
+#define HS_COMPILED_NMETHOD   "Lcom/oracle/graal/hotspot/HotSpotCompiledNmethod;"
+#define HS_NMETHOD            "Lcom/oracle/graal/hotspot/meta/HotSpotNmethod;"
 
 //  public native void executeKernel(HotSpotNmethod kernel, int jobSize, int i, int j, Object[] args) throws InvalidInstalledCodeException;
 
 JNINativeMethod Hsail::HSAIL_methods[] = {
   {CC"initialize",       CC"()Z",                               FN_PTR(Hsail::initialize)},
   {CC"generateKernel",   CC"([B" STRING ")J",                   FN_PTR(Hsail::generate_kernel)},
-  {CC"executeKernel0",   CC"("HS_INSTALLED_CODE"I["OBJECT")Z",  FN_PTR(Hsail::execute_kernel_void_1d)},
+  {CC"executeKernel0",   CC"("HS_INSTALLED_CODE"I["OBJECT"["OBJECT")Z",  FN_PTR(Hsail::execute_kernel_void_1d)},
 };
 
 void * Hsail::_device_context = NULL;
@@ -88,7 +97,7 @@
   _okra_register_heap(Universe::heap()->base(), Universe::heap()->capacity());
 }
 
-GPU_VMENTRY(jboolean, Hsail::execute_kernel_void_1d, (JNIEnv* env, jclass, jobject kernel_handle, jint dimX, jobject args_handle))
+GPU_VMENTRY(jboolean, Hsail::execute_kernel_void_1d, (JNIEnv* env, jclass, jobject kernel_handle, jint dimX, jobject args_handle, jobject oops_save_handle))
 
   ResourceMark rm;
   jlong nmethodValue = HotSpotInstalledCode::codeBlob(kernel_handle);
@@ -104,17 +113,210 @@
     SharedRuntime::throw_and_post_jvmti_exception(JavaThread::current(), vmSymbols::com_oracle_graal_api_code_InvalidInstalledCodeException(), NULL);
   }
 
-  objArrayOop args = (objArrayOop) JNIHandles::resolve(args_handle);
+  return execute_kernel_void_1d_internal((address) kernel, dimX, args_handle, mh, nm, oops_save_handle, CHECK_0);
+GPU_END
+
+static void showRanges(jboolean *a, int len) {
+  // show ranges
+  bool lookFor = true;
+  for (int i = 0; i < len; i++) {
+    if ((lookFor == true) && (a[i] != 0)) {
+      tty->print("%d", i);
+      lookFor = false;
+    } else if ((lookFor == false) && (a[i] == 0)) {
+      tty->print_cr("-%d", i-1);
+      lookFor = true;
+    }
+  }
+  if (lookFor == false) {
+    tty->print_cr("-%d", len-1);
+  }
+}
+
+
+// for experimentation
+static bool useDeoptInfo = true;
+
+jboolean Hsail::execute_kernel_void_1d_internal(address kernel, int dimX, jobject args_handle, methodHandle& mh, nmethod *nm, jobject oops_save_handle, TRAPS) {
+
+  ResourceMark rm(THREAD);
+  objArrayOop argsArray = (objArrayOop) JNIHandles::resolve(args_handle);
 
   // Reset the kernel arguments
   _okra_clearargs(kernel);
 
+  
+  HSAILDeoptimizationInfo* e;
+  if (useDeoptInfo) {
+    e = new (ResourceObj::C_HEAP, mtInternal) HSAILDeoptimizationInfo();
+    e->set_never_ran_array(NEW_C_HEAP_ARRAY(jboolean, dimX, mtInternal));
+    memset(e->never_ran_array(), 0, dimX * sizeof(jboolean));
+  }
+
   // This object sets up the kernel arguments
-  HSAILKernelArguments hka((address) kernel, mh->signature(), args, mh->is_static());
+  HSAILKernelArguments hka((address) kernel, mh->signature(), argsArray, mh->is_static(), e);
+
+  // if any object passed was null, throw an exception here
+  // doing this means the kernel code can avoid null checks on the object parameters.
+  if (hka.getFirstNullParameterIndex() >= 0) {
+    char buf[64];
+    sprintf(buf, "Null Kernel Parameter seen, Parameter Index: %d", hka.getFirstNullParameterIndex());
+    JavaThread* thread = (JavaThread*)THREAD;
+    thread->set_gpu_exception_bci(0);
+    thread->set_gpu_exception_method(mh());
+    THROW_MSG_0(vmSymbols::java_lang_NullPointerException(), buf);
+  }
 
   // Run the kernel
-  return _okra_execute_with_range(kernel, dimX);
-GPU_END
+  bool success = _okra_execute_with_range(kernel, dimX);
+  // check if any workitem requested a deopt
+  // currently we only support at most one such workitem
+
+
+  int deoptcode = e->deopt_occurred();
+  if (useDeoptInfo &&  deoptcode != 0) {
+    if (deoptcode != 1) {
+      // error condition detected in deopt code
+      char msg[200];
+      sprintf(msg, "deopt error detected, slot for workitem %d was not empty", -1*(deoptcode + 1));
+      guarantee(deoptcode == 1, msg);
+    }
+    if (TraceGPUInteraction) {
+      tty->print_cr("deopt happened.");
+      HSAILKernelDeoptimization * pdeopt = &e->_deopt_save_states[0];
+      tty->print_cr("first deopter was workitem %d", pdeopt->workitem());
+    }
+
+    // Before handling any deopting workitems, save the pointers from
+    // the hsail frames in oops_save so they get adjusted by any
+    // GC. Need to do this before leaving thread_in_vm mode.
+    // resolve handle only needed once here (not exiting vm mode)
+    objArrayOop oopsSaveArray = (objArrayOop) JNIHandles::resolve(oops_save_handle);
+
+    // since slots are allocated from the beginning, we know how far to look
+    assert(e->num_deopts() < MAX_DEOPT_SAVE_STATES_SIZE, "deopt save state overflow");
+    for (int k = 0; k < e->num_deopts(); k++) {
+      HSAILKernelDeoptimization * pdeopt = &e->_deopt_save_states[k];
+      jint workitem = pdeopt->workitem();
+      if (workitem != -1) {      
+        // this is a workitem that deopted
+        HSAILFrame *hsailFrame = pdeopt->first_frame();
+        int dregOopMap = hsailFrame->dreg_oops_map();
+        for (int bit = 0; bit < 16; bit++) {
+          if ((dregOopMap & (1 << bit)) != 0) {
+            // the dregister at this bit is an oop, save it in the array
+            int index = k * 16 + bit;
+            void* saved_oop = (void*) hsailFrame->get_d_reg(bit);
+            oopsSaveArray->obj_at_put(index, (oop) saved_oop);
+          }
+        }
+      }
+    }   
+
+    // Handle any deopting workitems. 
+    int count_deoptimized = 0;
+    for (int k = 0; k < e->num_deopts(); k++) {
+      HSAILKernelDeoptimization * pdeopt = &e->_deopt_save_states[k];
+    
+      jint workitem = pdeopt->workitem();
+      if (workitem != -1) {      
+        int deoptId = pdeopt->pc_offset();
+        HSAILFrame *hsailFrame = pdeopt->first_frame();
+
+        // update the hsailFrame from the oopsSaveArray
+        // re-resolve the handle
+        oopsSaveArray = (objArrayOop) JNIHandles::resolve(oops_save_handle);
+
+        int dregOopMap = hsailFrame->dreg_oops_map();
+        for (int bit = 0; bit < 16; bit++) {
+          if ((dregOopMap & (1 << bit)) != 0) {
+            // the dregister at this bit is an oop, retrieve it from array and put back in frame
+            int index = k * 16 + bit;
+            void * dregValue = (void *) oopsSaveArray->obj_at(index);
+            void * oldDregValue = (void *) hsailFrame->get_d_reg(bit);
+            assert((oldDregValue != 0 ? dregValue != 0 : dregValue == 0) , "bad dregValue retrieved");
+            if (TraceGPUInteraction) {
+              if (dregValue != oldDregValue) {
+                tty->print_cr("oop moved for $d%d, workitem %d, slot %d, old=%p, new=%p", bit, workitem, k, oldDregValue, dregValue);
+              }
+            }
+            hsailFrame->put_d_reg(bit, (jlong) dregValue);
+          }
+        }
+       
+        JavaValue result(T_VOID);
+        JavaCallArguments javaArgs;
+        javaArgs.set_alternative_target(nm);
+        javaArgs.push_int(deoptId);
+        javaArgs.push_long((jlong) hsailFrame);
+
+        // override the deoptimization action with Action_none until we decide
+        // how to handle the other actions.
+        int myActionReason = Deoptimization::make_trap_request(Deoptimization::trap_request_reason(pdeopt->reason()), Deoptimization::Action_none);
+        javaArgs.push_int(myActionReason);
+        javaArgs.push_oop((oop)NULL);
+        if (TraceGPUInteraction) {
+          int dregOopMap = hsailFrame->dreg_oops_map();
+          tty->print_cr("[HSAIL] Deoptimizing to host for workitem=%d (slot=%d) with deoptId=%d, frame=" INTPTR_FORMAT ", actionAndReason=%d, dregOopMap=%04x", workitem, k, deoptId, hsailFrame, myActionReason, dregOopMap);
+          // show the registers containing references
+          for (int bit = 0; bit < 16; bit++) {
+            if ((dregOopMap & (1 << bit)) != 0) {
+              tty->print_cr("  oop $d%d = %p", bit, hsailFrame->get_d_reg(bit));
+            }
+          }
+        }
+        JavaCalls::call(&result, mh, &javaArgs, THREAD);
+        count_deoptimized++;
+      }
+    }    
+    if (TraceGPUInteraction) {
+      tty->print_cr("[HSAIL] Deoptimizing to host completed for %d workitems", count_deoptimized);
+    }
+
+    // Handle any never_ran workitems if there were any
+    int count_never_ran = 0;
+    bool handleNeverRansHere = true;
+    // turn off verbose trace stuff for javacall arg setup
+    bool savedTraceGPUInteraction = TraceGPUInteraction;
+    TraceGPUInteraction = false;
+    jboolean *never_ran_array = e->never_ran_array();
+    if (handleNeverRansHere) {
+      for (int k = 0; k < dimX; k++) {
+        if (never_ran_array[k]) {
+          // run it as a javaCall
+          KlassHandle methKlass = mh->method_holder();
+          Thread* THREAD = Thread::current();
+          JavaValue result(T_VOID);
+          JavaCallArguments javaArgs;
+          // re-resolve the args_handle here
+          objArrayOop resolvedArgsArray = (objArrayOop) JNIHandles::resolve(args_handle);
+          // This object sets up the javaCall arguments
+          // the way argsArray is set up, this should work for instance methods as well
+          // (the receiver will be the first oop pushed)
+          HSAILJavaCallArguments hjca(&javaArgs, k, mh->signature(), resolvedArgsArray, mh->is_static());
+          if (mh->is_static()) {
+            JavaCalls::call_static(&result, methKlass, mh->name(), mh->signature(), &javaArgs, THREAD);
+          } else {
+            JavaCalls::call_virtual(&result, methKlass, mh->name(), mh->signature(), &javaArgs, THREAD);
+          }
+          count_never_ran++;
+        }
+      }
+      TraceGPUInteraction = savedTraceGPUInteraction;
+      if (TraceGPUInteraction) {
+        tty->print_cr("%d workitems never ran, have been run via JavaCall", count_never_ran);
+        showRanges(never_ran_array, dimX);
+      }
+    } // end of never-ran handling
+
+  }
+
+  if (useDeoptInfo) {
+    FREE_C_HEAP_ARRAY(jboolean, e->never_ran_array(), mtInternal);
+    delete e;
+  }
+  return success;
+}
 
 GPU_ENTRY(jlong, Hsail::generate_kernel, (JNIEnv *env, jclass, jbyteArray code_handle, jstring name_handle))
   guarantee(_okra_create_kernel != NULL, "[HSAIL] Okra not linked");
@@ -172,6 +374,7 @@
   if (TraceGPUInteraction) {
       tty->print_cr("[HSAIL] library is %s", okra_library_name);
   }
+
   void *handle = os::dll_load(okra_library_name, ebuf, O_BUFLEN);
   // try alternate location if env variable set
   char *okra_lib_name_from_env_var = getenv("_OKRA_SIM_LIB_PATH_");
@@ -212,6 +415,7 @@
   return true;
 GPU_END
 
+
 bool Hsail::register_natives(JNIEnv* env) {
   jclass klass = env->FindClass("com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend");
   if (klass == NULL) {
--- a/src/gpu/hsail/vm/gpu_hsail.hpp	Wed Mar 26 17:30:40 2014 +0100
+++ b/src/gpu/hsail/vm/gpu_hsail.hpp	Wed Mar 26 17:33:54 2014 +0100
@@ -25,7 +25,60 @@
 #ifndef GPU_HSAIL_HPP
 #define GPU_HSAIL_HPP
 
+#include "utilities/exceptions.hpp"
+#include "graal/graalEnv.hpp"
+// #include "graal/graalCodeInstaller.hpp"
+#include "gpu_hsail_Frame.hpp"
+
 class Hsail {
+  friend class gpu;
+
+  public:
+  class HSAILKernelDeoptimization {
+    friend class VMStructs;
+   private:
+    // TODO: separate workitemid and actionAndReason out
+    // since they are there only once even if there are multiple frames
+    // for now, though we only ever have one hsail fram
+    jint  _workitemid;
+    jint  _actionAndReason;
+    // the first (innermost) "hsail frame" starts here
+    HSAILFrame _first_frame;
+
+   public:
+    inline jint workitem() { return _workitemid; }
+    inline jint reason() { return _actionAndReason; }
+    inline jint pc_offset() { return _first_frame.pc_offset(); }
+    inline HSAILFrame *first_frame() { return &_first_frame; }
+  };
+
+// 8 compute units * 40 waves per cu * wavesize 64
+#define MAX_DEOPT_SAVE_STATES_SIZE    (8 * 40 * 64)
+
+  class HSAILDeoptimizationInfo : public ResourceObj {
+    friend class VMStructs;
+   private:
+    jint _deopt_occurred;
+    jint _deopt_next_index;
+    jboolean * _never_ran_array;
+
+   public:
+    HSAILKernelDeoptimization _deopt_save_states[MAX_DEOPT_SAVE_STATES_SIZE];
+
+    inline HSAILDeoptimizationInfo() {
+      _deopt_occurred = 0;
+      _deopt_next_index = 0;
+    }
+
+    inline jint deopt_occurred() {
+      // Check that hsail did not write in the wrong place
+      return _deopt_occurred;
+    }
+    inline jint num_deopts() { return _deopt_next_index; }
+    inline jboolean *never_ran_array() { return _never_ran_array; }
+    inline void  set_never_ran_array(jboolean *p) { _never_ran_array = p; }
+  };
+
 
 private:
 
@@ -38,10 +91,18 @@
   JNIEXPORT static jlong generate_kernel(JNIEnv *env, jclass, jbyteArray code_handle, jstring name_handle);
 
   // static native boolean executeKernel0(HotSpotInstalledCode kernel, int jobSize, Object[] args);
-  JNIEXPORT static jboolean execute_kernel_void_1d(JNIEnv *env, jclass, jobject hotspotInstalledCode, jint dimX, jobject args);
+  JNIEXPORT static jboolean execute_kernel_void_1d(JNIEnv *env, jclass, jobject hotspotInstalledCode, jint dimX, jobject args, jobject oopsSave);
+
+  // static native void setSimulatorSingleThreaded0();
+  JNIEXPORT static void setSimulatorSingleThreaded0(JNIEnv *env, jclass);
+
+
+  static jboolean execute_kernel_void_1d_internal(address kernel, int dimX, jobject args, methodHandle& mh, nmethod *nm, jobject oopsSave, TRAPS);
 
   static void register_heap();
 
+  static GraalEnv::CodeInstallResult install_code(Handle& compiled_code, CodeBlob*& cb, Handle installed_code, Handle triggered_deoptimizations);
+
 public:
 
   // Registers the implementations for the native methods in HSAILHotSpotBackend
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gpu/hsail/vm/gpu_hsail_Frame.hpp	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,44 @@
+#ifndef GPU_HSAIL_FRAME_HPP
+#define GPU_HSAIL_FRAME_HPP
+
+#include "graal/graalEnv.hpp"
+#include "code/debugInfo.hpp"
+#include "code/location.hpp"
+
+// maximum registers that could be saved for now
+#define MAX_SREGS 32
+#define MAX_DREGS 16
+
+class HSAILFrame {
+  friend class VMStructs;
+private:
+  jint  _pc_offset;  // The HSAIL "pc_offset" where the exception happens
+  jbyte _num_s_regs;
+  jbyte _num_d_regs;
+  jshort _dreg_oops_map;  // bits = 1 if that dreg is an oop
+  jlong  _save_area[MAX_SREGS/2 + MAX_DREGS];  
+
+public:
+  // Accessors
+  jint pc_offset() { return _pc_offset; }
+  jint num_s_regs() {return _num_s_regs; }
+  jint num_d_regs() {return _num_d_regs; }
+  jint dreg_oops_map() {return _dreg_oops_map; }
+  jlong get_d_reg(int idx) {
+    char *p = (char *) _save_area;
+    int ofst = num_s_regs() * 4 + idx * 8;
+    return(*(jlong *) (p + ofst));
+  }
+  jint get_s_reg(int idx) {
+    char *p = (char *) _save_area;
+    int ofst = idx * 4;
+    return(*(jint *) (p + ofst));
+  }
+  void put_d_reg(int idx, jlong val) {
+    char *p = (char *) _save_area;
+    int ofst = num_s_regs() * 4 + idx * 8;
+    (*(jlong *) (p + ofst)) = val;
+  }
+};
+  
+#endif // GPU_HSAIL_FRAME_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gpu/hsail/vm/hsailArgumentsBase.cpp	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "hsailArgumentsBase.hpp"
+#include "runtime/javaCalls.hpp"
+
+
+// Get next java argument
+oop HSAILArgumentsBase::next_arg(BasicType expectedType) {
+  assert(_index < _args->length(), "out of bounds");
+
+  oop arg = ((objArrayOop) (_args))->obj_at(_index++);
+  assert(expectedType == T_OBJECT ||
+         java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch");
+
+  return arg;
+}
+
+void HSAILArgumentsBase::do_bool() {
+  // Get the boxed value
+  oop arg = _args->obj_at(_index++);
+  assert(java_lang_boxing_object::is_instance(arg, T_BOOLEAN), "arg type mismatch");
+  
+  jvalue jValue;
+  java_lang_boxing_object::get_value(arg, &jValue);
+  
+  pushBool(jValue.z);
+}
+
+void HSAILArgumentsBase::do_byte() {
+  // Get the boxed value
+  oop arg = _args->obj_at(_index++);
+  assert(java_lang_boxing_object::is_instance(arg, T_BYTE), "arg type mismatch");
+  
+  jvalue jValue;
+  java_lang_boxing_object::get_value(arg, &jValue);
+
+  pushByte(jValue.b);
+}
+
+void HSAILArgumentsBase::do_double() {
+  // Get the boxed value
+  oop arg = _args->obj_at(_index++);
+  assert(java_lang_boxing_object::is_instance(arg, T_DOUBLE), "arg type mismatch");
+  
+  jvalue jValue;
+  java_lang_boxing_object::get_value(arg, &jValue);
+  if (TraceGPUInteraction) {
+    tty->print_cr("[HSAIL] %s::do_double, _index=%d, value = %e", argsBuilderName(), _index - 1, jValue.d);
+  }  
+  pushDouble(jValue.d);
+}
+
+void HSAILArgumentsBase::do_float() {
+  // Get the boxed value
+  oop arg = _args->obj_at(_index++);
+  assert(java_lang_boxing_object::is_instance(arg, T_FLOAT), "arg type mismatch");
+  
+  jvalue jValue;
+  java_lang_boxing_object::get_value(arg, &jValue);
+  if (TraceGPUInteraction) {
+    tty->print_cr("[HSAIL] %s::do_float, _index=%d, value = %f", argsBuilderName(), _index - 1, jValue.f);
+  }  
+  pushFloat(jValue.f);
+}
+
+void HSAILArgumentsBase::do_int() {
+  // If the last parameter is an int, it is handled in a special way
+  // For kernel arguments we don't pass it since we use the HSAIL workitemid in place of that int value
+  // For javaCall arguments we pass the actual workitemid
+  if (isLastParameter()) {
+    handleFinalIntParameter();
+    return;
+  }
+
+  // not the final int parameter, Get the boxed int
+  oop arg = _args->obj_at(_index++);
+  assert(java_lang_boxing_object::is_instance(arg, T_INT), "arg type mismatch");
+  
+  jvalue jValue;
+  java_lang_boxing_object::get_value(arg, &jValue);
+  if (TraceGPUInteraction) {
+    tty->print_cr("[HSAIL] %s::do_int, _index=%d, value = %d", argsBuilderName(), _index - 1, jValue.i);
+  }    
+  
+  pushInt(jValue.i);
+}
+
+void HSAILArgumentsBase::do_long() {
+  // Get the boxed value
+  oop arg = _args->obj_at(_index++);
+  assert(java_lang_boxing_object::is_instance(arg, T_LONG), "arg type mismatch");
+  
+  jvalue jValue;
+  java_lang_boxing_object::get_value(arg, &jValue);
+  if (TraceGPUInteraction) {
+    tty->print_cr("[HSAIL] %s::do_long, _index=%d, value = %d", argsBuilderName(), _index - 1, jValue.j);
+  }    
+
+  pushLong(jValue.j);
+}
+
+void HSAILArgumentsBase::do_array(int begin, int end) {
+  oop arg = _args->obj_at(_index++);
+  if (arg == NULL) {
+      recordNullObjectParameter();
+  } else {
+      assert(arg->is_array(), "arg type mismatch");
+  }
+  if (TraceGPUInteraction) {
+    tty->print_cr("[HSAIL] %s::do_array, _index=%d, 0x%08x, is a %s", argsBuilderName(), _index - 1, (address) arg,
+                  arg == NULL ? "null" : arg->klass()->external_name());
+  }
+    
+  pushObject(arg);
+}
+
+void HSAILArgumentsBase::do_object() {
+  bool isLastParam = isLastParameter();  // determine this before incrementing _index
+
+  oop arg = _args->obj_at(_index++);
+  if (TraceGPUInteraction) {
+    tty->print_cr("[HSAIL] %s::do_object, _index=%d, 0x%08x is a %s", argsBuilderName(), _index - 1, (address) arg,
+                  arg == NULL ? "null" : arg->klass()->external_name());
+  }
+  if (arg == NULL) {
+      recordNullObjectParameter();
+  }
+
+  // check if this is last arg in signature
+  // an object as last parameter requires special handling
+  if (isLastParam) {
+    if (TraceGPUInteraction) {
+      tty->print_cr("[HSAIL] %s, trailing object ref should be object source array ref", argsBuilderName());
+    }
+    assert(arg->is_objArray(), "arg type mismatch");
+    handleFinalObjParameter(arg);
+  } else {
+    // not the final parameter, just push
+    pushObject(arg);
+  }
+}
+
+void HSAILArgumentsBase::do_object(int begin, int end) {
+  do_object();
+}
+
+void HSAILArgumentsBase::do_void() {
+    return;
+}
+
+// TODO implement other do_*
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gpu/hsail/vm/hsailArgumentsBase.hpp	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ */
+
+#ifndef BASE_ARGUMENTS_HSAIL_HPP
+#define BASE_ARGUMENTS_HSAIL_HPP
+
+#include "runtime/signature.hpp"
+
+
+/***
+ * Base class which iterates thru a signature and pulls from a
+ * objArrayOop of boxed values.  Used as base for HSAILKernelArguments
+ * and HSAILJavaCallArguments The derived classes specify how to push
+ * args onto their data structure
+ ***/
+
+class HSAILArgumentsBase : public SignatureIterator {
+
+public:
+
+private:
+  // Array of java argument oops
+  objArrayOop _args;
+  // Length of args array
+  int   _length;
+  // Current index into _args
+  int _index;
+  // number of parameters in the signature
+  int _parameter_count;
+
+  Symbol * _signature;
+  bool _is_static;
+
+  // records first null parameter seen
+  int _first_null_parameter_index;
+  
+  // Get next java argument
+  oop next_arg(BasicType expectedType);
+
+    virtual char *argsBuilderName() = 0;
+    virtual void pushObject(void * obj) = 0;
+    virtual void pushBool(jboolean z) = 0;
+    virtual void pushByte(jbyte b) = 0;
+    virtual void pushDouble(jdouble d) = 0;
+    virtual void pushFloat(jfloat f) = 0;
+    virtual void pushInt(jint i) = 0;
+    virtual void pushLong(jlong j) = 0;
+    virtual void handleFinalIntParameter() = 0;
+    virtual void handleFinalObjParameter(void *obj) = 0;
+    virtual void pushTrailingArgs() = 0;
+
+    void recordNullObjectParameter() {
+        if (_first_null_parameter_index == -1) _first_null_parameter_index = _parameter_index;
+    }
+
+ public:
+  HSAILArgumentsBase(Symbol* signature, objArrayOop args, bool is_static) : SignatureIterator(signature) {
+    this->_return_type = T_ILLEGAL;
+    _index = 0;
+    _args = args;
+    _is_static = is_static;
+    _signature = signature;
+
+    _length = args->length();
+    _parameter_count = ArgumentCount(signature).size();
+
+    _first_null_parameter_index = -1;
+
+  }
+
+  int getFirstNullParameterIndex() {
+    return _first_null_parameter_index;
+  }
+
+  void collectArgs() {
+    if (TraceGPUInteraction) {
+      tty->print_cr("[HSAIL] %s::collectArgs, sig:%s  args length=%d", argsBuilderName(), _signature->as_C_string(), _length);
+    }    
+    if (!_is_static) {      
+      // First object in args should be 'this'
+      oop arg = _args->obj_at(_index++);
+      assert(arg->is_instance() && (! arg->is_array()), "First arg should be 'this'");
+      if (TraceGPUInteraction) {
+        tty->print_cr("[HSAIL] %s, instance method, this " PTR_FORMAT ", is a %s", argsBuilderName(), (address) arg, arg->klass()->external_name());
+      }
+      pushObject(arg);
+    } else {
+      if (TraceGPUInteraction) {
+          tty->print_cr("[HSAIL] %s, static method", argsBuilderName());
+      }
+    }
+    // Iterate over the entire signature
+    iterate();
+    
+    pushTrailingArgs();
+  }
+
+  void do_bool();
+  void do_byte();
+  void do_double();
+  void do_float();
+  void do_int();
+  void do_long();
+  void do_array(int begin, int end);
+  void do_object();
+  void do_object(int begin, int end);
+
+  void do_void();
+
+  inline void do_char()   {
+    /* TODO : To be implemented */
+    guarantee(false, "do_char:NYI");
+  }
+  inline void do_short()  {
+    /* TODO : To be implemented */
+    guarantee(false, "do_short:NYI");
+  }
+
+  bool isLastParameter() {
+      return  (_index == (_is_static ?  _parameter_count - 1 : _parameter_count));
+  }
+
+};
+
+#endif  // BASE_ARGUMENTS_HSAIL_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gpu/hsail/vm/hsailJavaCallArguments.hpp	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ */
+
+#ifndef JAVACALL_ARGUMENTS_HSAIL_HPP
+#define JAVACALL_ARGUMENTS_HSAIL_HPP
+
+#include "hsailArgumentsBase.hpp"
+#include "runtime/javaCalls.hpp"
+
+class HSAILJavaCallArguments : public HSAILArgumentsBase {
+
+public:
+
+private:
+  // JavaCall Args to push into
+  JavaCallArguments *_javaArgs;
+  int _workitemid;
+ public:
+    HSAILJavaCallArguments(JavaCallArguments *javaArgs, int workitemid, Symbol* signature, objArrayOop args, bool is_static) : HSAILArgumentsBase(signature, args, is_static) {
+        _javaArgs = javaArgs;
+        _workitemid = workitemid;
+        collectArgs();
+    }
+    virtual char *argsBuilderName() {return (char *)"HSAILJavaCallArguments";}
+    virtual void pushObject(void *obj) { _javaArgs->push_oop((oop) obj);  }
+    virtual void pushBool(jboolean z) { pushInt(z); }
+    virtual void pushByte(jbyte b) { pushInt(b); }
+    virtual void pushDouble(jdouble d) { _javaArgs->push_double(d); }
+    virtual void pushFloat(jfloat f) { _javaArgs->push_float(f); }
+    virtual void pushInt(jint i) { _javaArgs->push_int(i); }
+    virtual void pushLong(jlong j) { _javaArgs->push_long(j); }
+    virtual void pushTrailingArgs() {  }
+
+    // For javaCall the final int parameter gets replaced with the workitemid
+    // which was passed back in the deopt info
+    virtual void handleFinalIntParameter() {
+      if (TraceGPUInteraction) {
+        tty->print_cr("[HSAIL] HSAILJavaCallArguments, passing workitemid %d as trailing int parameter", _workitemid);
+      }
+      pushInt(_workitemid);
+    }
+    // for kernel arguments, final obj parameter should be an object
+    // stream source array (already checked in the base class) so for
+    // a javacall we need to extract the correct obj from it based on
+    // the workitemid
+    virtual void handleFinalObjParameter(void *arg) {
+      objArrayOop objArrayArg = (objArrayOop) arg;
+      oop extractedObj = objArrayArg->obj_at(_workitemid);
+      if (TraceGPUInteraction) {
+        tty->print_cr("[HSAIL] HSAILJavaCallArguments, extracted obj #%d from array, 0x%08x is a %s",
+                      _workitemid, (address) extractedObj,
+                      (extractedObj == NULL ? "null" : extractedObj->klass()->external_name()));
+      }
+      pushObject(extractedObj);
+    }
+
+};
+
+#endif  // JAVACALL_ARGUMENTS_HSAIL_HPP
+
--- a/src/gpu/hsail/vm/hsailKernelArguments.cpp	Wed Mar 26 17:30:40 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,177 +0,0 @@
-/*
- * Copyright (c) 2013, 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.
- *
- */
-
-#include "precompiled.hpp"
-#include "hsailKernelArguments.hpp"
-#include "runtime/javaCalls.hpp"
-
-
-// Get next java argument
-oop HSAILKernelArguments::next_arg(BasicType expectedType) {
-  assert(_index < _args->length(), "out of bounds");
-
-  oop arg = ((objArrayOop) (_args))->obj_at(_index++);
-  assert(expectedType == T_OBJECT ||
-         java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch");
-
-  return arg;
-}
-
-void HSAILKernelArguments::do_bool() {
-  // Get the boxed value
-  oop arg = _args->obj_at(_index++);
-  assert(java_lang_boxing_object::is_instance(arg, T_BOOLEAN), "arg type mismatch");
-  
-  jvalue jValue;
-  java_lang_boxing_object::get_value(arg, &jValue);
-  
-  bool pushed = Hsail::_okra_push_boolean(_kernel, jValue.z);
-  assert(pushed == true, "arg push failed");
-}
-
-void HSAILKernelArguments::do_byte() {
-  // Get the boxed value
-  oop arg = _args->obj_at(_index++);
-  assert(java_lang_boxing_object::is_instance(arg, T_BYTE), "arg type mismatch");
-  
-  jvalue jValue;
-  java_lang_boxing_object::get_value(arg, &jValue);
-  
-  bool pushed = Hsail::_okra_push_byte(_kernel, jValue.b);
-  assert(pushed == true, "arg push failed");
-}
-
-void HSAILKernelArguments::do_double() {
-  // Get the boxed value
-  oop arg = _args->obj_at(_index++);
-  assert(java_lang_boxing_object::is_instance(arg, T_DOUBLE), "arg type mismatch");
-  
-  jvalue jValue;
-  java_lang_boxing_object::get_value(arg, &jValue);
-  if (TraceGPUInteraction) {
-    tty->print_cr("[HSAIL] HSAILKernelArguments::do_double, _index=%d, value = %e", _index - 1, jValue.d);
-  }  
-  bool pushed = Hsail::_okra_push_double(_kernel, jValue.d);
-  assert(pushed == true, "arg push failed");
-}
-
-void HSAILKernelArguments::do_float() {
-  // Get the boxed value
-  oop arg = _args->obj_at(_index++);
-  assert(java_lang_boxing_object::is_instance(arg, T_FLOAT), "arg type mismatch");
-  
-  jvalue jValue;
-  java_lang_boxing_object::get_value(arg, &jValue);
-  if (TraceGPUInteraction) {
-    tty->print_cr("[HSAIL] HSAILKernelArguments::do_float, _index=%d, value = %f", _index - 1, jValue.f);
-  }    
-  bool pushed = Hsail::_okra_push_float(_kernel, jValue.f);
-  assert(pushed == true, "float push failed");
-}
-
-void HSAILKernelArguments::do_int() {
-  // The last int is the iteration variable in an IntStream, but we don't pass it
-  // since we use the HSAIL workitemid in place of that int value
-  if (isLastParameter()) {
-    if (TraceGPUInteraction) {
-      tty->print_cr("[HSAIL] HSAILKernelArguments::not pushing trailing int");
-    }
-    return;
-  }
-
-  // Get the boxed int
-  oop arg = _args->obj_at(_index++);
-  assert(java_lang_boxing_object::is_instance(arg, T_INT), "arg type mismatch");
-  
-  jvalue jValue;
-  java_lang_boxing_object::get_value(arg, &jValue);
-  if (TraceGPUInteraction) {
-    tty->print_cr("[HSAIL] HSAILKernelArguments::do_int, _index=%d, value = %d", _index - 1, jValue.i);
-  }    
-  
-  bool pushed = Hsail::_okra_push_int(_kernel, jValue.i);
-  assert(pushed == true, "arg push failed");
-}
-
-void HSAILKernelArguments::do_long() {
-  // Get the boxed value
-  oop arg = _args->obj_at(_index++);
-  assert(java_lang_boxing_object::is_instance(arg, T_LONG), "arg type mismatch");
-  
-  jvalue jValue;
-  java_lang_boxing_object::get_value(arg, &jValue);
-  if (TraceGPUInteraction) {
-    tty->print_cr("[HSAIL] HSAILKernelArguments::do_long, _index=%d, value = %d", _index - 1, jValue.j);
-  }    
-  
-  bool pushed = Hsail::_okra_push_long(_kernel, jValue.j);
-  assert(pushed == true, "arg push failed");  
-}
-
-void HSAILKernelArguments::do_array(int begin, int end) {
-  oop arg = _args->obj_at(_index++);
-  assert(arg->is_array(), "arg type mismatch");
-  if (TraceGPUInteraction) {
-    tty->print_cr("[HSAIL] HSAILKernelArguments::do_array, _index=%d, 0x%08x, is a %s", _index - 1, (address) arg, arg->klass()->external_name());
-  }
-    
-  bool pushed = Hsail::_okra_push_object(_kernel, arg);
-  assert(pushed == true, "arg push failed");  
-}
-
-void HSAILKernelArguments::do_object() {
-  
-  bool isLastParam = isLastParameter();  // determine this before incrementing _index
-
-  oop arg = _args->obj_at(_index++);
-
-  // check if this is last arg in signature
-  // an object as last parameter requires an object stream source array to be passed
-  if (isLastParam) {
-    if (TraceGPUInteraction) {
-      tty->print_cr("[HSAIL] HSAILKernelArguments::trailing object ref should be object source array ref");
-    }
-    assert(arg->is_objArray(), "arg type mismatch");
-  }
-
-  if (TraceGPUInteraction) {
-    tty->print_cr("[HSAIL] HSAILKernelArguments::do_object, _index=%d, 0x%08x is a %s", _index - 1, (address) arg, arg->klass()->external_name());
-  }
-    
-  bool pushed = Hsail::_okra_push_object(_kernel, arg);
-  assert(pushed == true, "arg push failed");  
-}
-
-void HSAILKernelArguments::do_object(int begin, int end) {
-  if (TraceGPUInteraction) {
-      tty->print_cr("[HSAIL] HSAILKernelArguments::do_object(int begin, int end), begin=%d, end=%d.", begin, end);
-  }
-  do_object();
-}
-
-void HSAILKernelArguments::do_void() {
-    return;
-}
-
-// TODO implement other do_*
--- a/src/gpu/hsail/vm/hsailKernelArguments.hpp	Wed Mar 26 17:30:40 2014 +0100
+++ b/src/gpu/hsail/vm/hsailKernelArguments.hpp	Wed Mar 26 17:33:54 2014 +0100
@@ -25,90 +25,80 @@
 #ifndef KERNEL_ARGUMENTS_HSAIL_HPP
 #define KERNEL_ARGUMENTS_HSAIL_HPP
 
-#include "runtime/gpu.hpp"
-#include "hsail/vm/gpu_hsail.hpp"
+#include "gpu_hsail.hpp"
 #include "runtime/signature.hpp"
+#include "hsailArgumentsBase.hpp"
 
-class HSAILKernelArguments : public SignatureIterator {
+class HSAILKernelArguments : public HSAILArgumentsBase {
   friend class Hsail;
 
 public:
 
 private:
-  // Array of java argument oops
-  objArrayOop _args;
-  // Length of args array
-  int   _length;
-  // Current index into _args
-  int _index;
   // Kernel to push into
   address _kernel;
-  // number of parameters in the signature
-  int _parameter_count;
-
-  bool _is_static;
-  
-  // Get next java argument
-  oop next_arg(BasicType expectedType);
+  void * _exceptionHolder;
 
  public:
-  HSAILKernelArguments(address kernel, Symbol* signature, objArrayOop args, bool is_static) : SignatureIterator(signature) {
-    this->_return_type = T_ILLEGAL;
-    _index = 0;
-    _args = args;
-    _kernel = kernel;
-    _is_static = is_static;
+    HSAILKernelArguments(address kernel, Symbol* signature, objArrayOop args, bool is_static, void* exceptionHolder) : HSAILArgumentsBase(signature, args, is_static) {
+        _kernel = kernel;
+        _exceptionHolder = exceptionHolder;
+        collectArgs();
+    }
+    virtual char *argsBuilderName() {return (char *)"HSAILKernelArguments";}
+    virtual void pushObject(void *obj) {
+        bool pushed = Hsail::_okra_push_object(_kernel, obj);
+        assert(pushed == true, "arg push failed");
+    }
+    virtual void pushBool(jboolean z) {
+        bool pushed = Hsail::_okra_push_boolean(_kernel, z);
+        assert(pushed == true, "arg push failed");
+    }
+    virtual void pushByte(jbyte b) {
+        bool pushed = Hsail::_okra_push_byte(_kernel, b);
+        assert(pushed == true, "arg push failed");
+    }
 
-    _length = args->length();
-    _parameter_count = ArgumentCount(signature).size();
+    virtual void pushDouble(jdouble d) {
+        bool pushed = Hsail::_okra_push_double(_kernel, d);
+        assert(pushed == true, "arg push failed");
+    }
 
-    if (TraceGPUInteraction) {
-      char buf[O_BUFLEN];
-      tty->print_cr("[HSAIL] sig:%s  args length=%d, _parameter_count=%d", signature->as_C_string(buf, O_BUFLEN), _length, _parameter_count);
-    }    
-    if (!_is_static) {      
-      // First object in args should be 'this'
-      oop arg = args->obj_at(_index++);
-      assert(arg->is_instance() && (! arg->is_array()), "First arg should be 'this'");
+    virtual void pushFloat(jfloat f) {
+        bool pushed = Hsail::_okra_push_float(_kernel, f);
+        assert(pushed == true, "arg push failed");
+    }
+
+    virtual void pushInt(jint i) {
+        bool pushed = Hsail::_okra_push_int(_kernel, i);
+        assert(pushed == true, "arg push failed");
+    }
+
+    virtual void pushLong(jlong j) {
+        bool pushed = Hsail::_okra_push_long(_kernel, j);
+        assert(pushed == true, "arg push failed");
+    }
+    virtual void pushTrailingArgs() {
+        // Last argument is the exception info block
+        if (TraceGPUInteraction) {
+            tty->print_cr("[HSAIL] exception block=" PTR_FORMAT, _exceptionHolder);
+        }
+        pushObject(_exceptionHolder);
+    }
+
+    // For kernel arguments we don't pass the final int parameter
+    // since we use the HSAIL workitemid instruction in place of that int value
+    virtual void handleFinalIntParameter() {
       if (TraceGPUInteraction) {
-        tty->print_cr("[HSAIL] instance method, this 0x%08x, is a %s", (address) arg, arg->klass()->external_name());
-      }
-      bool pushed = Hsail::_okra_push_object(kernel, arg);
-      assert(pushed == true, "'this' push failed");
-    } else {
-      if (TraceGPUInteraction) {
-        tty->print_cr("[HSAIL] static method");
+        tty->print_cr("[HSAIL] HSAILKernelArguments, not pushing trailing int");
       }
     }
-    // Iterate over the entire signature
-    iterate();
-  }
 
-  void do_bool();
-  void do_byte();
-  void do_double();
-  void do_float();
-  void do_int();
-  void do_long();
-  void do_array(int begin, int end);
-  void do_object();
-  void do_object(int begin, int end);
-
-  void do_void();
-
-  inline void do_char()   {
-    /* TODO : To be implemented */
-    guarantee(false, "do_char:NYI");
-  }
-  inline void do_short()  {
-    /* TODO : To be implemented */
-    guarantee(false, "do_short:NYI");
-  }
-
-  bool isLastParameter() {
-      return  (_index == (_is_static ?  _parameter_count - 1 : _parameter_count));
-  }
-
+    // for kernel arguments, final obj parameter should be an object
+    // stream source array (already checked in the base class) so here we just pass it
+    virtual void handleFinalObjParameter(void *arg) {
+      pushObject(arg);
+    }
 };
 
-#endif  // KERNEL_ARGUMENTS_HPP
+#endif  // KERNEL_ARGUMENTS_HSAIL_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gpu/hsail/vm/vmStructs_hsail.hpp	Wed Mar 26 17:33:54 2014 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2001, 2010, 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.
+ *
+ */
+
+#ifndef GPU_HSAIL_VM_VMSTRUCTS_HSAIL_HPP
+#define GPU_HSAIL_VM_VMSTRUCTS_HSAIL_HPP
+
+#include "gpu_hsail.hpp"
+#include "gpu_hsail_Frame.hpp"
+
+// These are the CPU-specific fields, types and integer
+// constants required by the Serviceability Agent. This file is
+// referenced by vmStructs.cpp.
+
+#define VM_STRUCTS_GPU_HSAIL(nonstatic_field)                                                                                                    \
+  nonstatic_field(HSAILFrame, _pc_offset,                                                  jint)                                      \
+  nonstatic_field(HSAILFrame, _num_s_regs,                                                 jbyte)                                     \
+  nonstatic_field(HSAILFrame, _save_area[0],                                               jlong)                                     \
+                                                                                                                                                                                                                                                                                      \
+  nonstatic_field(Hsail::HSAILKernelDeoptimization, _workitemid,                                jint)                                 \
+  nonstatic_field(Hsail::HSAILKernelDeoptimization, _actionAndReason,                           jint)                                 \
+  nonstatic_field(Hsail::HSAILKernelDeoptimization, _first_frame,                               HSAILFrame)                      \
+                                                                                                                                           \
+  nonstatic_field(Hsail::HSAILDeoptimizationInfo, _deopt_occurred,                         jint)                                      \
+  nonstatic_field(Hsail::HSAILDeoptimizationInfo, _deopt_next_index,                       jint)                                      \
+  nonstatic_field(Hsail::HSAILDeoptimizationInfo, _never_ran_array,                        jboolean *)                                \
+  nonstatic_field(Hsail::HSAILDeoptimizationInfo, _deopt_save_states[0],                   Hsail::HSAILKernelDeoptimization)          \
+  nonstatic_field(Hsail::HSAILDeoptimizationInfo, _deopt_save_states[1],                   Hsail::HSAILKernelDeoptimization)
+
+#define VM_TYPES_GPU_HSAIL(declare_type, declare_toplevel_type)                 \
+  declare_toplevel_type(HSAILFrame)                                  \
+  declare_toplevel_type(HSAILFrame*)                                 \
+  declare_toplevel_type(Hsail::HSAILKernelDeoptimization)            \
+  declare_toplevel_type(Hsail::HSAILDeoptimizationInfo)
+
+#endif // GPU_HSAIL_VM_VMSTRUCTS_HSAIL_HPP
--- a/src/share/vm/classfile/javaClasses.cpp	Wed Mar 26 17:30:40 2014 +0100
+++ b/src/share/vm/classfile/javaClasses.cpp	Wed Mar 26 17:33:54 2014 +0100
@@ -1530,6 +1530,16 @@
     }
     return;
   }
+  
+  // Check for gpu exception to add as top frame
+  Method* gpu_method = thread->get_gpu_exception_method();
+  if (gpu_method != NULL) {
+    jint gpu_bci = thread->get_gpu_exception_bci();
+    bt.push(gpu_method, gpu_bci, CHECK);
+    // Clear the gpu exception state, it is not used after here
+    thread->set_gpu_exception_bci(0);
+    thread->set_gpu_exception_method(NULL);  
+  }
 
   // Instead of using vframe directly, this version of fill_in_stack_trace
   // basically handles everything by hand. This significantly improved the
--- a/src/share/vm/classfile/systemDictionary.hpp	Wed Mar 26 17:30:40 2014 +0100
+++ b/src/share/vm/classfile/systemDictionary.hpp	Wed Mar 26 17:33:54 2014 +0100
@@ -222,7 +222,7 @@
   do_klass(CompilationResult_Mark_klass,          com_oracle_graal_api_code_CompilationResult_Mark,             Opt) \
   do_klass(CompilationResult_Infopoint_klass,     com_oracle_graal_api_code_CompilationResult_Infopoint,        Opt) \
   do_klass(CompilationResult_Site_klass,          com_oracle_graal_api_code_CompilationResult_Site,             Opt) \
-  do_klass(ExternalCompilationResult_klass,       com_oracle_graal_api_code_ExternalCompilationResult,          Opt) \
+  do_klass(ExternalCompilationResult_klass,       com_oracle_graal_gpu_ExternalCompilationResult,               Opt) \
   do_klass(InfopointReason_klass,                 com_oracle_graal_api_code_InfopointReason,                    Opt) \
   do_klass(code_Register_klass,                   com_oracle_graal_api_code_Register,                           Opt) \
   do_klass(RegisterValue_klass,                   com_oracle_graal_api_code_RegisterValue,                      Opt) \
--- a/src/share/vm/classfile/vmSymbols.hpp	Wed Mar 26 17:30:40 2014 +0100
+++ b/src/share/vm/classfile/vmSymbols.hpp	Wed Mar 26 17:33:54 2014 +0100
@@ -338,7 +338,6 @@
   template(com_oracle_graal_api_code_CompilationResult_Mark,         "com/oracle/graal/api/code/CompilationResult$Mark")              \
   template(com_oracle_graal_api_code_CompilationResult_Infopoint,    "com/oracle/graal/api/code/CompilationResult$Infopoint")         \
   template(com_oracle_graal_api_code_CompilationResult_Site,         "com/oracle/graal/api/code/CompilationResult$Site")              \
-  template(com_oracle_graal_api_code_ExternalCompilationResult,      "com/oracle/graal/api/code/ExternalCompilationResult")           \
   template(com_oracle_graal_api_code_InfopointReason,                "com/oracle/graal/api/code/InfopointReason")                     \
   template(com_oracle_graal_api_code_BytecodeFrame,                  "com/oracle/graal/api/code/BytecodeFrame")                       \
   template(com_oracle_graal_api_code_BytecodePosition,               "com/oracle/graal/api/code/BytecodePosition")                    \
@@ -350,6 +349,8 @@
   template(com_oracle_graal_api_code_RegisterSaveLayout,             "com/oracle/graal/api/code/RegisterSaveLayout")                  \
   template(com_oracle_graal_api_code_InvalidInstalledCodeException,  "com/oracle/graal/api/code/InvalidInstalledCodeException")       \
   template(com_oracle_graal_api_code_SpeculationLog,                 "com/oracle/graal/api/code/SpeculationLog")                      \
+  /* graal.gpu */                                                                                                                     \
+  template(com_oracle_graal_gpu_ExternalCompilationResult,           "com/oracle/graal/gpu/ExternalCompilationResult")                \
   /* graal.truffle */                                                                                                                 \
   template(com_oracle_graal_truffle_GraalTruffleRuntime,             "com/oracle/graal/truffle/GraalTruffleRuntime")                  \
   template(startCompiler_name,                    "startCompiler")                                                                    \
--- a/src/share/vm/graal/graalCompiler.cpp	Wed Mar 26 17:30:40 2014 +0100
+++ b/src/share/vm/graal/graalCompiler.cpp	Wed Mar 26 17:33:54 2014 +0100
@@ -97,6 +97,7 @@
     VMToCompiler::finalizeOptions(CITime || CITimeEach);
 
     if (UseCompiler) {
+      _external_deopt_i2c_entry = create_external_deopt_i2c();
       bool bootstrap = COMPILERGRAAL_PRESENT(BootstrapGraal) NOT_COMPILERGRAAL(false);
       VMToCompiler::startCompiler(bootstrap);
       _initialized = true;
@@ -126,6 +127,34 @@
   }
 }
 
+address GraalCompiler::create_external_deopt_i2c() {
+  ResourceMark rm;
+  BufferBlob* buffer = BufferBlob::create("externalDeopt", 1*K);
+  CodeBuffer cb(buffer);
+  short buffer_locs[20];
+  cb.insts()->initialize_shared_locs((relocInfo*)buffer_locs, sizeof(buffer_locs)/sizeof(relocInfo));
+  MacroAssembler masm(&cb);
+
+  int total_args_passed = 5;
+
+  BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed);
+  VMRegPair* regs   = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed);
+  int i = 0;
+  sig_bt[i++] = T_INT;
+  sig_bt[i++] = T_LONG;
+  sig_bt[i++] = T_VOID; // long stakes 2 slots
+  sig_bt[i++] = T_INT;
+  sig_bt[i++] = T_OBJECT;
+
+  int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false);
+
+  SharedRuntime::gen_i2c_adapter(&masm, total_args_passed, comp_args_on_stack, sig_bt, regs);
+  masm.flush();
+
+  return AdapterBlob::create(&cb)->content_begin();
+}
+
+
 BufferBlob* GraalCompiler::initialize_buffer_blob() {
   JavaThread* THREAD = JavaThread::current();
   BufferBlob* buffer_blob = THREAD->get_buffer_blob();
--- a/src/share/vm/graal/graalCompiler.hpp	Wed Mar 26 17:30:40 2014 +0100
+++ b/src/share/vm/graal/graalCompiler.hpp	Wed Mar 26 17:33:54 2014 +0100
@@ -35,7 +35,7 @@
   bool                  _initialized;
 
   static GraalCompiler* _instance;
-
+  address               _external_deopt_i2c_entry;
 public:
 
   GraalCompiler();
@@ -67,9 +67,13 @@
 
   void exit();
 
+  address get_external_deopt_i2c_entry() {return _external_deopt_i2c_entry;}
+
   static BasicType kindToBasicType(jchar ch);
 
   static BufferBlob* initialize_buffer_blob();
+
+  static address create_external_deopt_i2c();
 };
 
 // Tracing macros
--- a/src/share/vm/runtime/javaCalls.cpp	Wed Mar 26 17:30:40 2014 +0100
+++ b/src/share/vm/runtime/javaCalls.cpp	Wed Mar 26 17:33:54 2014 +0100
@@ -40,11 +40,13 @@
 #include "runtime/signature.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "runtime/thread.inline.hpp"
+#include "graal/graalJavaAccess.hpp"
+#include "graal/graalCompiler.hpp"
 
 // -----------------------------------------------------
 // Implementation of JavaCallWrapper
 
-JavaCallWrapper::JavaCallWrapper(methodHandle callee_method, Handle receiver, JavaValue* result, TRAPS) {
+JavaCallWrapper::JavaCallWrapper(methodHandle callee_method, JavaValue* result, TRAPS) {
   JavaThread* thread = (JavaThread *)THREAD;
   bool clear_pending_exception = true;
 
@@ -75,10 +77,9 @@
   // Make sure to set the oop's after the thread transition - since we can block there. No one is GC'ing
   // the JavaCallWrapper before the entry frame is on the stack.
   _callee_method = callee_method();
-  _receiver = receiver();
 
 #ifdef CHECK_UNHANDLED_OOPS
-  THREAD->allow_unhandled_oop(&_receiver);
+  // THREAD->allow_unhandled_oop(&_receiver);
 #endif // CHECK_UNHANDLED_OOPS
 
   _thread       = (JavaThread *)thread;
@@ -142,7 +143,6 @@
 
 
 void JavaCallWrapper::oops_do(OopClosure* f) {
-  f->do_oop((oop*)&_receiver);
   handles()->oops_do(f);
 }
 
@@ -335,14 +335,19 @@
 
   CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
 
+#ifdef GRAAL
+  nmethod* nm = args->alternative_target();
+  if (nm == NULL) {
+#endif
   // Verify the arguments
 
   if (CheckJNICalls)  {
     args->verify(method, result->get_type(), thread);
   }
   else debug_only(args->verify(method, result->get_type(), thread));
-
-#ifndef GRAAL
+#ifdef GRAAL
+  }
+#else
   // Ignore call if method is empty
   if (method->is_empty_method()) {
     assert(result->get_type() == T_VOID, "an empty method must return a void value");
@@ -385,9 +390,6 @@
   // the call to call_stub, the optimizer produces wrong code.
   intptr_t* result_val_address = (intptr_t*)(result->get_value_addr());
 
-  // Find receiver
-  Handle receiver = (!method->is_static()) ? args->receiver() : Handle();
-
   // When we reenter Java, we need to reenable the yellow zone which
   // might already be disabled when we are in VM.
   if (thread->stack_yellow_zone_disabled()) {
@@ -406,11 +408,15 @@
   }
 
 #ifdef GRAAL
-  nmethod* nm = args->alternative_target();
   if (nm != NULL) {
     if (nm->is_alive()) {
       ((JavaThread*) THREAD)->set_graal_alternate_call_target(nm->verified_entry_point());
+      oop graalInstalledCode = nm->graal_installed_code();
+      if (graalInstalledCode != NULL && HotSpotNmethod::isExternal(graalInstalledCode)) {
+        entry_point = GraalCompiler::instance()->get_external_deopt_i2c_entry();
+      } else {
       entry_point = method->adapter()->get_i2c_entry();
+      }
     } else {
       THROW(vmSymbols::com_oracle_graal_api_code_InvalidInstalledCodeException());
     }
@@ -418,7 +424,7 @@
 #endif
   
   // do call
-  { JavaCallWrapper link(method, receiver, result, CHECK);
+  { JavaCallWrapper link(method, result, CHECK);
     { HandleMark hm(thread);  // HandleMark used by HandleMarkCleaner
 
       StubRoutines::call_stub()(
--- a/src/share/vm/runtime/javaCalls.hpp	Wed Mar 26 17:30:40 2014 +0100
+++ b/src/share/vm/runtime/javaCalls.hpp	Wed Mar 26 17:33:54 2014 +0100
@@ -57,7 +57,6 @@
   JavaThread*      _thread;                 // the thread to which this call belongs
   JNIHandleBlock*  _handles;                // the saved handle block
   Method*          _callee_method;          // to be able to collect arguments if entry frame is top frame
-  oop              _receiver;               // the receiver of the call (if a non-static call)
 
   JavaFrameAnchor  _anchor;                 // last thread anchor state that we must restore
 
@@ -65,7 +64,7 @@
 
  public:
   // Construction/destruction
-   JavaCallWrapper(methodHandle callee_method, Handle receiver, JavaValue* result, TRAPS);
+   JavaCallWrapper(methodHandle callee_method, JavaValue* result, TRAPS);
   ~JavaCallWrapper();
 
   // Accessors
@@ -77,7 +76,6 @@
   JavaValue*       result() const           { return _result; }
   // GC support
   Method*          callee_method()          { return _callee_method; }
-  oop              receiver()               { return _receiver; }
   void             oops_do(OopClosure* f);
 
   bool             is_first_frame() const   { return _anchor.last_Java_sp() == NULL; }
--- a/src/share/vm/runtime/sharedRuntime.cpp	Wed Mar 26 17:30:40 2014 +0100
+++ b/src/share/vm/runtime/sharedRuntime.cpp	Wed Mar 26 17:33:54 2014 +0100
@@ -1171,7 +1171,6 @@
     assert(fr.is_entry_frame(), "must be");
     // fr is now pointing to the entry frame.
     callee_method = methodHandle(THREAD, fr.entry_frame_call_wrapper()->callee_method());
-    assert(fr.entry_frame_call_wrapper()->receiver() == NULL || !callee_method->is_static(), "non-null receiver for static call??");
   } else {
     Bytecodes::Code bc;
     CallInfo callinfo;
--- a/src/share/vm/runtime/thread.cpp	Wed Mar 26 17:30:40 2014 +0100
+++ b/src/share/vm/runtime/thread.cpp	Wed Mar 26 17:33:54 2014 +0100
@@ -1445,6 +1445,8 @@
   clear_must_deopt_id();
   set_monitor_chunks(NULL);
   set_next(NULL);
+  set_gpu_exception_bci(0);
+  set_gpu_exception_method(NULL);  
   set_thread_state(_thread_new);
 #if INCLUDE_NMT
   set_recorder(NULL);
--- a/src/share/vm/runtime/thread.hpp	Wed Mar 26 17:30:40 2014 +0100
+++ b/src/share/vm/runtime/thread.hpp	Wed Mar 26 17:33:54 2014 +0100
@@ -946,6 +946,17 @@
   volatile address _exception_handler_pc;        // PC for handler of exception
   volatile int     _is_method_handle_return;     // true (== 1) if the current exception PC is a MethodHandle call site.
 
+  // Record the method and bci from a gpu kernel exception so
+  // it can be added into the exception stack trace
+  jint    _gpu_exception_bci;
+  Method* _gpu_exception_method;
+ public:
+  void set_gpu_exception_bci(jint bci)           { _gpu_exception_bci = bci; } 
+  jint get_gpu_exception_bci()                   { return _gpu_exception_bci; }
+  void set_gpu_exception_method(Method* method)  { _gpu_exception_method = method; }
+  Method* get_gpu_exception_method()             { return _gpu_exception_method; }
+  
+ private:  
   // support for JNI critical regions
   jint    _jni_active_critical;                  // count of entries into JNI critical region
 
--- a/src/share/vm/runtime/vmStructs.cpp	Wed Mar 26 17:30:40 2014 +0100
+++ b/src/share/vm/runtime/vmStructs.cpp	Wed Mar 26 17:33:54 2014 +0100
@@ -90,6 +90,7 @@
 #include "runtime/deoptimization.hpp"
 #include "runtime/vframeArray.hpp"
 #include "runtime/globals.hpp"
+#include "runtime/gpu.hpp"
 #include "runtime/java.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/perfMemory.hpp"
@@ -154,6 +155,9 @@
 #ifdef TARGET_OS_ARCH_bsd_zero
 # include "vmStructs_bsd_zero.hpp"
 #endif
+
+#include "hsail/vm/vmStructs_hsail.hpp"
+
 #if INCLUDE_ALL_GCS
 #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp"
@@ -3035,6 +3039,8 @@
                  GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY,
                  GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY)
 
+  VM_STRUCTS_GPU_HSAIL(GENERATE_NONSTATIC_VM_STRUCT_ENTRY)
+          
   VM_STRUCTS_OS_CPU(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
                     GENERATE_STATIC_VM_STRUCT_ENTRY,
                     GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY,
@@ -3085,6 +3091,9 @@
                GENERATE_C2_VM_TYPE_ENTRY,
                GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY)
 
+  VM_TYPES_GPU_HSAIL(GENERATE_VM_TYPE_ENTRY,
+               GENERATE_TOPLEVEL_VM_TYPE_ENTRY)
+
   VM_TYPES_OS_CPU(GENERATE_VM_TYPE_ENTRY,
                   GENERATE_TOPLEVEL_VM_TYPE_ENTRY,
                   GENERATE_OOP_VM_TYPE_ENTRY,
@@ -3189,6 +3198,8 @@
                  CHECK_NO_OP,
                  CHECK_NO_OP);
 
+  VM_STRUCTS_GPU_HSAIL(CHECK_NONSTATIC_VM_STRUCT_ENTRY);
+
   VM_STRUCTS_OS_CPU(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
                     CHECK_STATIC_VM_STRUCT_ENTRY,
                     CHECK_NO_OP,
@@ -3229,6 +3240,9 @@
                CHECK_C2_VM_TYPE_ENTRY,
                CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY);
 
+  VM_TYPES_GPU_HSAIL(CHECK_VM_TYPE_ENTRY,
+               CHECK_SINGLE_ARG_VM_TYPE_NO_OP);
+
   VM_TYPES_OS_CPU(CHECK_VM_TYPE_ENTRY,
                   CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
                   CHECK_SINGLE_ARG_VM_TYPE_NO_OP,