changeset 9336:47e7933283f1

added support for adding callee save information to a DebugInfo (GRAAL-81)
author Doug Simon <doug.simon@oracle.com>
date Fri, 26 Apr 2013 18:16:30 +0200
parents ba441e21796f
children e1200d5141fa
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DebugInfo.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RegisterSaveLayout.java graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java
diffstat 6 files changed, 152 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java	Thu Apr 25 17:46:35 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java	Fri Apr 26 18:16:30 2013 +0200
@@ -303,6 +303,14 @@
             }
             sb.append(' ').append(bm).append(nl);
         }
+        RegisterSaveLayout calleeSaveInfo = info.getCalleeSaveInfo();
+        if (calleeSaveInfo != null) {
+            sb.append("callee-save-info:").append(nl);
+            Map<Integer, Register> map = calleeSaveInfo.slotsToRegisters(true);
+            for (Map.Entry<Integer, Register> e : map.entrySet()) {
+                sb.append("    ").append(e.getValue()).append(" -> ").append(formatter.formatStackSlot(e.getKey())).append(nl);
+            }
+        }
         BytecodeFrame frame = info.frame();
         if (frame != null) {
             append(sb, frame);
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Thu Apr 25 17:46:35 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Fri Apr 26 18:16:30 2013 +0200
@@ -507,6 +507,16 @@
         if (info != null) {
             appendRefMap(sb, "stackMap", info.getFrameRefMap());
             appendRefMap(sb, "registerMap", info.getRegisterRefMap());
+            RegisterSaveLayout calleeSaveInfo = info.getCalleeSaveInfo();
+            if (calleeSaveInfo != null) {
+                sb.append(" callee-save-info[");
+                String sep = "";
+                for (Map.Entry<Register, Integer> e : calleeSaveInfo.registersToSlots(true).entrySet()) {
+                    sb.append(sep).append(e.getKey()).append("->").append(e.getValue());
+                    sep = ", ";
+                }
+                sb.append(']');
+            }
             BytecodePosition codePos = info.getBytecodePosition();
             if (codePos != null) {
                 MetaUtil.appendLocation(sb.append(" "), codePos.getMethod(), codePos.getBCI());
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DebugInfo.java	Thu Apr 25 17:46:35 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DebugInfo.java	Fri Apr 26 18:16:30 2013 +0200
@@ -26,8 +26,16 @@
 import java.util.*;
 
 /**
- * Represents the debugging information for a particular place in the code, which includes the code
- * position, a reference map, and deoptimization information.
+ * Represents the debugging information for a particular point of execution. This information
+ * includes:
+ * <ul>
+ * <li>a {@linkplain #getBytecodePosition() bytecode position}</li>
+ * <li>a reference map for {@linkplain #getRegisterRefMap() registers}</li>
+ * <li>a reference map for {@linkplain #getRegisterRefMap() stack slots} in the current frame</li>
+ * <li>a map from bytecode locals and operand stack slots to their values or locations from which
+ * their values can be read</li>
+ * <li>a map from the registers (in the caller's frame) to the slots where they are saved in the
+ * current frame</li>
  */
 public class DebugInfo implements Serializable {
 
@@ -37,6 +45,7 @@
     private final BitSet registerRefMap;
     private final BitSet frameRefMap;
     private final short deoptimizationReason;
+    private RegisterSaveLayout calleeSaveInfo;
 
     /**
      * Creates a new {@link DebugInfo} from the given values.
@@ -125,4 +134,20 @@
     public short getDeoptimizationReason() {
         return deoptimizationReason;
     }
+
+    /**
+     * Sets the map from the registers (in the caller's frame) to the slots where they are saved in
+     * the current frame.
+     */
+    public void setCalleeSaveInfo(RegisterSaveLayout calleeSaveInfo) {
+        this.calleeSaveInfo = calleeSaveInfo;
+    }
+
+    /**
+     * Gets the map from the registers (in the caller's frame) to the slots where they are saved in
+     * the current frame. If no such information is available, {@code null} is returned.
+     */
+    public RegisterSaveLayout getCalleeSaveInfo() {
+        return calleeSaveInfo;
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RegisterSaveLayout.java	Fri Apr 26 18:16:30 2013 +0200
@@ -0,0 +1,93 @@
+/*
+ * 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.api.code;
+
+import java.util.*;
+
+/**
+ * A map from registers to frame slots. This can be used to describe where callee saved registers
+ * are saved in a callee's frame.
+ */
+public class RegisterSaveLayout {
+
+    /**
+     * Keys.
+     */
+    private Register[] registers;
+
+    /**
+     * Slot indexes relative to stack pointer.
+     */
+    private int[] slots;
+
+    /**
+     * Creates a map from registers to frame slots.
+     * 
+     * @param registers the keys in the map
+     * @param slots frame slot index for each register in {@code registers}
+     */
+    public RegisterSaveLayout(Register[] registers, int[] slots) {
+        assert registers.length == slots.length;
+        this.registers = registers;
+        this.slots = slots;
+        assert registersToSlots(false).size() == registers.length : "non-unique registers";
+        assert new HashSet<>(registersToSlots(false).values()).size() == slots.length : "non-unqiue slots";
+    }
+
+    /**
+     * Gets this layout information as a {@link Map} from registers to slots.
+     */
+    public Map<Register, Integer> registersToSlots(boolean sorted) {
+        Map<Register, Integer> result;
+        if (sorted) {
+            result = new TreeMap<>();
+        } else {
+            result = new HashMap<>();
+        }
+        for (int i = 0; i < registers.length; i++) {
+            result.put(registers[i], slots[i]);
+        }
+        return result;
+    }
+
+    /**
+     * Gets this layout information as a {@link Map} from slots to registers.
+     */
+    public Map<Integer, Register> slotsToRegisters(boolean sorted) {
+        Map<Integer, Register> result;
+        if (sorted) {
+            result = new TreeMap<>();
+        } else {
+            result = new HashMap<>();
+        }
+        for (int i = 0; i < registers.length; i++) {
+            result.put(slots[i], registers[i]);
+        }
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return registersToSlots(true).toString();
+    }
+}
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java	Thu Apr 25 17:46:35 2013 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java	Fri Apr 26 18:16:30 2013 +0200
@@ -446,9 +446,10 @@
                 @Override
                 protected void doState(LIRFrameState state) {
                     if (state.hasDebugInfo()) {
-                        stateString.append(debugInfoToString(state.debugInfo().getBytecodePosition(), state.debugInfo().getRegisterRefMap(), state.debugInfo().getFrameRefMap(), target.arch));
+                        DebugInfo di = state.debugInfo();
+                        stateString.append(debugInfoToString(di.getBytecodePosition(), di.getRegisterRefMap(), di.getFrameRefMap(), di.getCalleeSaveInfo(), target.arch));
                     } else {
-                        stateString.append(debugInfoToString(state.topFrame, null, null, target.arch));
+                        stateString.append(debugInfoToString(state.topFrame, null, null, null, target.arch));
                     }
                 }
             });
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java	Thu Apr 25 17:46:35 2013 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java	Fri Apr 26 18:16:30 2013 +0200
@@ -114,7 +114,7 @@
     /**
      * Formats given debug info as a multi line string.
      */
-    protected String debugInfoToString(BytecodePosition codePos, BitSet registerRefMap, BitSet frameRefMap, Architecture arch) {
+    protected String debugInfoToString(BytecodePosition codePos, BitSet registerRefMap, BitSet frameRefMap, RegisterSaveLayout calleeSaveInfo, Architecture arch) {
         StringBuilder sb = new StringBuilder();
 
         if (registerRefMap != null) {
@@ -128,8 +128,16 @@
 
         if (frameRefMap != null) {
             sb.append("frame-ref-map:");
-            for (int reg = frameRefMap.nextSetBit(0); reg >= 0; reg = frameRefMap.nextSetBit(reg + 1)) {
-                sb.append(' ').append("s").append(reg);
+            for (int slot = frameRefMap.nextSetBit(0); slot >= 0; slot = frameRefMap.nextSetBit(slot + 1)) {
+                sb.append(' ').append("s").append(slot);
+            }
+            sb.append("\n");
+        }
+
+        if (calleeSaveInfo != null) {
+            sb.append("callee-save-info:");
+            for (Map.Entry<Register, Integer> e : calleeSaveInfo.registersToSlots(true).entrySet()) {
+                sb.append(" " + e.getKey() + " -> s" + e.getValue());
             }
             sb.append("\n");
         }