diff graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java @ 9338:0266549ff6e0

added support from compiled stubs to be installed as RuntimeStubs and to be able to directly call C/C++ runtime functions (GRAAL-81) replaced NewArraySlowStubCall with NewArrayRuntimeCall using this support
author Doug Simon <doug.simon@oracle.com>
date Fri, 26 Apr 2013 18:36:41 +0200
parents 27c75e4016db
children bdf4604fec2e
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Fri Apr 26 18:21:10 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Fri Apr 26 18:36:41 2013 +0200
@@ -144,8 +144,8 @@
             }
         }
         params[params.length - 1] = rbpParam;
+        ParametersOp paramsOp = new ParametersOp(params);
 
-        ParametersOp paramsOp = new ParametersOp(params);
         append(paramsOp);
 
         saveRbp = new SaveRbp(new PlaceholderOp(currentBlock, lir.lir(currentBlock).size()));
@@ -171,6 +171,74 @@
         return runtime().asStub(method) != null;
     }
 
+    /**
+     * Map from debug infos that need to be updated with callee save information to the operations
+     * that provide the information.
+     */
+    Map<LIRFrameState, AMD64RestoreRegistersOp> calleeSaveInfo = new HashMap<>();
+
+    private LIRFrameState currentRuntimeCallInfo;
+
+    @Override
+    protected void emitCall(RuntimeCallTarget callTarget, Value result, Value[] arguments, Value[] temps, LIRFrameState info) {
+        boolean needsCalleeSave = callTarget.getDescriptor() == NewArrayRuntimeCall.NEW_ARRAY_RUNTIME;
+        if (needsCalleeSave) {
+            currentRuntimeCallInfo = info;
+        }
+        super.emitCall(callTarget, result, arguments, temps, info);
+    }
+
+    @Override
+    public Variable emitCall(RuntimeCallTarget callTarget, CallingConvention cc, DeoptimizingNode info, Value... args) {
+        boolean needsCalleeSave = callTarget.getDescriptor() == NewArrayRuntimeCall.NEW_ARRAY_RUNTIME;
+
+        RegisterValue[] savedRegisters = null;
+        StackSlot[] savedRegisterLocations = null;
+        if (needsCalleeSave) {
+            Register returnReg = isRegister(cc.getReturn()) ? asRegister(cc.getReturn()) : null;
+            Set<Register> registers = new HashSet<>(Arrays.asList(frameMap.registerConfig.getAllocatableRegisters()));
+            if (returnReg != null) {
+                registers.remove(returnReg);
+            }
+
+            savedRegisters = new RegisterValue[registers.size()];
+            savedRegisterLocations = new StackSlot[savedRegisters.length];
+            int savedRegisterIndex = 0;
+            for (Register reg : registers) {
+                assert reg.isCpu() || reg.isFpu();
+                savedRegisters[savedRegisterIndex++] = reg.asValue(reg.isCpu() ? Kind.Long : Kind.Double);
+            }
+
+            append(new ParametersOp(savedRegisters));
+            for (int i = 0; i < savedRegisters.length; i++) {
+                StackSlot spillSlot = frameMap.allocateSpillSlot(Kind.Long);
+                savedRegisterLocations[i] = spillSlot;
+            }
+            AMD64SaveRegistersOp save = new AMD64SaveRegistersOp(savedRegisters, savedRegisterLocations);
+            append(save);
+
+            Value thread = args[0];
+            AMD64HotSpotCRuntimeCallPrologueOp op = new AMD64HotSpotCRuntimeCallPrologueOp(thread);
+            append(op);
+        }
+
+        Variable result = super.emitCall(callTarget, cc, info, args);
+
+        if (needsCalleeSave) {
+
+            Value thread = args[0];
+            AMD64HotSpotCRuntimeCallEpilogueOp op = new AMD64HotSpotCRuntimeCallEpilogueOp(thread);
+            append(op);
+
+            AMD64RestoreRegistersOp restore = new AMD64RestoreRegistersOp(savedRegisterLocations.clone(), savedRegisters.clone());
+            AMD64RestoreRegistersOp oldValue = calleeSaveInfo.put(currentRuntimeCallInfo, restore);
+            assert oldValue == null;
+            append(restore);
+        }
+
+        return result;
+    }
+
     @Override
     protected CallingConvention createCallingConvention() {
         Stub stub = runtime().asStub(method);
@@ -223,7 +291,6 @@
     @Override
     public void emitTailcall(Value[] args, Value address) {
         append(new AMD64TailcallOp(args, address));
-
     }
 
     @Override
@@ -263,6 +330,13 @@
     }
 
     @Override
+    public void emitDeoptimizeCaller(DeoptimizationAction action, DeoptimizationReason reason) {
+        AMD64HotSpotDeoptimizeCallerOp op = new AMD64HotSpotDeoptimizeCallerOp(action, reason);
+        epilogueOps.add(op);
+        append(op);
+    }
+
+    @Override
     public void beforeRegisterAllocation() {
         boolean hasDebugInfo = lir.hasDebugInfo();
         AllocatableValue savedRbp = saveRbp.finalize(hasDebugInfo);