changeset 18431:84ac6a1a0dcb

Introduce FrameMappingTool.
author Josef Eisl <josef.eisl@jku.at>
date Wed, 05 Nov 2014 20:16:00 +0100
parents 9c590632d079
children 6b58802e45b2
files graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerationResult.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/DelayedFrameMapBuilder.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMapBuilder.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java
diffstat 6 files changed, 62 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java	Wed Nov 05 19:29:26 2014 +0100
+++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java	Wed Nov 05 20:16:00 2014 +0100
@@ -134,6 +134,7 @@
 
             RegisterConfig registerConfig = null;
             FrameMapBuilder frameMapBuilder = backend.newFrameMapBuilder(registerConfig);
+            frameMapBuilder.requireMapping(lir);
             TargetDescription target = backend.getTarget();
             CallingConvention cc = CodeUtil.getCallingConvention(backend.getProviders().getCodeCache(), CallingConvention.Type.JavaCallee, method, false);
             this.lirGenRes = backend.newLIRGenerationResult(lir, frameMapBuilder, method, null);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Wed Nov 05 19:29:26 2014 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Wed Nov 05 20:16:00 2014 +0100
@@ -322,6 +322,7 @@
         }
         try (Scope ds = Debug.scope("BackEnd", lir)) {
             FrameMapBuilder frameMapBuilder = backend.newFrameMapBuilder(registerConfig);
+            frameMapBuilder.requireMapping(lir);
             LIRGenerationResult lirGenRes = backend.newLIRGenerationResult(lir, frameMapBuilder, graph.method(), stub);
             LIRGeneratorTool lirGen = backend.newLIRGenerator(cc, lirGenRes);
             NodeLIRBuilderTool nodeLirGen = backend.newNodeLIRBuilder(graph, lirGen);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerationResult.java	Wed Nov 05 19:29:26 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerationResult.java	Wed Nov 05 20:16:00 2014 +0100
@@ -29,17 +29,18 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.FrameMapBuilder.FrameMappingTool;
 import com.oracle.graal.lir.StandardOp.SaveRegistersOp;
 import com.oracle.graal.lir.gen.*;
 
-public class AMD64HotSpotLIRGenerationResult extends LIRGenerationResultBase {
+public class AMD64HotSpotLIRGenerationResult extends LIRGenerationResultBase implements FrameMapBuilder.FrameMappable {
 
     /**
      * The slot reserved for storing the original return address when a frame is marked for
      * deoptimization. The return address slot in the callee is overwritten with the address of a
      * deoptimization stub.
      */
-    private VirtualStackSlot deoptimizationRescueSlot;
+    private StackSlotValue deoptimizationRescueSlot;
     private final Object stub;
 
     /**
@@ -61,7 +62,7 @@
         return asStackSlot(deoptimizationRescueSlot);
     }
 
-    public final void setDeoptimizationRescueSlot(VirtualStackSlot stackSlot) {
+    public final void setDeoptimizationRescueSlot(StackSlotValue stackSlot) {
         this.deoptimizationRescueSlot = stackSlot;
     }
 
@@ -73,4 +74,7 @@
         return calleeSaveInfo;
     }
 
+    public void map(FrameMappingTool tool) {
+        deoptimizationRescueSlot = tool.getStackSlot(asVirtualStackSlot(deoptimizationRescueSlot));
+    }
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/DelayedFrameMapBuilder.java	Wed Nov 05 19:29:26 2014 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/DelayedFrameMapBuilder.java	Wed Nov 05 20:16:00 2014 +0100
@@ -52,9 +52,11 @@
         this.factory = factory;
         this.stackSlots = new ArrayList<>();
         this.calls = new ArrayList<>();
+        this.mappables = new ArrayList<>();
     }
 
     private Set<VirtualStackSlot> freedSlots;
+    private final List<FrameMappable> mappables;
 
     public VirtualStackSlot allocateSpillSlot(LIRKind kind) {
         if (freedSlots != null) {
@@ -186,7 +188,9 @@
         for (CallingConvention cc : calls) {
             frameMap.callsMethod(cc);
         }
-        // end fill
+        // rewrite
+        mappables.forEach(m -> m.map(mapping::get));
+        //
         if (freedSlots != null) {
             // If the freed slots cover the complete spill area (except for the return
             // address slot), then the spill size is reset to its initial value.
@@ -212,4 +216,8 @@
         }
     }
 
+    public void requireMapping(FrameMappable mappable) {
+        this.mappables.add(mappable);
+    }
+
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMapBuilder.java	Wed Nov 05 19:29:26 2014 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMapBuilder.java	Wed Nov 05 20:16:00 2014 +0100
@@ -35,6 +35,22 @@
 public interface FrameMapBuilder {
 
     /**
+     * A tool to get the real stack slot from a virtual stack slot.
+     */
+    @FunctionalInterface
+    interface FrameMappingTool {
+        StackSlot getStackSlot(VirtualStackSlot slot);
+    }
+
+    /**
+     * This interface should be implemented by all classes that store virtual stack slots to convert
+     * them into real stack slots when {@link FrameMapBuilder#buildFrameMap} is called.
+     */
+    interface FrameMappable {
+        void map(FrameMappingTool tool);
+    }
+
+    /**
      * Reserves a spill slot in the frame of the method being compiled. The returned slot is aligned
      * on its natural alignment, i.e., an 8-byte spill slot is aligned at an 8-byte boundary, unless
      * overridden by a subclass.
@@ -78,6 +94,12 @@
     void callsMethod(CallingConvention cc);
 
     /**
+     * Registers a FrameMappable class so that virtual stack slots can be changed to real stack
+     * slots.
+     */
+    void requireMapping(FrameMappable mappable);
+
+    /**
      * Creates a {@linkplain FrameMap} based on the information collected by this
      * {@linkplain FrameMapBuilder}.
      */
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Wed Nov 05 19:29:26 2014 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Wed Nov 05 20:16:00 2014 +0100
@@ -22,17 +22,22 @@
  */
 package com.oracle.graal.lir;
 
+import static com.oracle.graal.api.code.ValueUtil.*;
+
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.cfg.*;
-import com.oracle.graal.lir.StandardOp.*;
+import com.oracle.graal.lir.FrameMapBuilder.FrameMappable;
+import com.oracle.graal.lir.FrameMapBuilder.FrameMappingTool;
+import com.oracle.graal.lir.StandardOp.BlockEndOp;
+import com.oracle.graal.lir.StandardOp.LabelOp;
 
 /**
  * This class implements the overall container for the LIR graph and directs its construction,
  * optimization, and finalization.
  */
-public class LIR {
+public class LIR implements FrameMappable {
 
     private final AbstractControlFlowGraph<?> cfg;
 
@@ -218,4 +223,19 @@
             }
         }
     }
+
+    public void map(FrameMappingTool tool) {
+        ValueProcedure updateProc = (value, mode, flags) -> {
+            if (isVirtualStackSlot(value)) {
+                return tool.getStackSlot(asVirtualStackSlot(value));
+            }
+            return value;
+        };
+        for (AbstractBlock<?> block : getControlFlowGraph().getBlocks()) {
+            for (LIRInstruction inst : getLIRforBlock(block)) {
+                inst.forEachAlive(updateProc);
+            }
+        }
+    }
+
 }