changeset 5275:290b3025b66f

added support for disassembling code after installation (so that the result of patching and relocation can be seen)
author Doug Simon <doug.simon@oracle.com>
date Mon, 23 Apr 2012 15:49:11 +0200
parents e72dd6533eb9
children d0877209410d
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotTargetMethod.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotCodeInfo.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotCompiledMethod.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiCodeInfo.java graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiRuntime.java src/share/vm/classfile/systemDictionary.hpp src/share/vm/classfile/vmSymbols.hpp src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalCodeInstaller.hpp src/share/vm/graal/graalCompilerToVM.cpp src/share/vm/graal/graalJavaAccess.hpp
diffstat 16 files changed, 273 insertions(+), 85 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Mon Apr 23 15:42:30 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Mon Apr 23 15:49:11 2012 +0200
@@ -128,7 +128,8 @@
                     TTY.println(String.format("%-6d Graal %-70s %-45s %-50s | %4dnodes %5dB", id, "", "", "", 0, (result != null ? result.targetCodeSize() : -1)));
                 }
             }
-            compiler.getRuntime().installMethod(method, result);
+
+            installMethod(result);
         } catch (CiBailout bailout) {
             Debug.metric("Bailouts").increment();
             if (GraalOptions.ExitVMOnBailout) {
@@ -148,6 +149,20 @@
         stats.finish(method);
     }
 
+    private void installMethod(final CiTargetMethod tm) {
+        Debug.scope("CodeInstall", new Object[] {compiler.getCompiler(), method}, new Runnable() {
+            @Override
+            public void run() {
+                final HotSpotCodeInfo info = Debug.isDumpEnabled() ? new HotSpotCodeInfo(compiler, tm, method) : null;
+                compiler.getRuntime().installMethod(method, tm, info);
+                if (info != null) {
+                    Debug.dump(info, "After code installation");
+                }
+            }
+
+        });
+    }
+
     @Override
     public int compareTo(CompilationTask o) {
         if (priority < o.priority) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotTargetMethod.java	Mon Apr 23 15:42:30 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotTargetMethod.java	Mon Apr 23 15:49:11 2012 +0200
@@ -100,8 +100,8 @@
         return result;
     }
 
-    public static Object installStub(Compiler compiler, CiTargetMethod targetMethod, String name) {
-        return compiler.getVMEntries().installStub(new HotSpotTargetMethod(compiler, targetMethod, name));
+    public static Object installStub(Compiler compiler, CiTargetMethod targetMethod, String name, HotSpotCodeInfo info) {
+        return compiler.getVMEntries().installStub(new HotSpotTargetMethod(compiler, targetMethod, name), info);
     }
 
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Mon Apr 23 15:42:30 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Mon Apr 23 15:49:11 2012 +0200
@@ -63,9 +63,9 @@
 
     void RiConstantPool_loadReferencedType(HotSpotTypeResolved pool, int cpi, byte byteCode);
 
-    HotSpotCompiledMethod installMethod(HotSpotTargetMethod targetMethod, boolean installCode);
+    HotSpotCompiledMethod installMethod(HotSpotTargetMethod targetMethod, boolean installCode, HotSpotCodeInfo info);
 
-    long installStub(HotSpotTargetMethod targetMethod);
+    long installStub(HotSpotTargetMethod targetMethod, HotSpotCodeInfo info);
 
     HotSpotVMConfig getConfiguration();
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Mon Apr 23 15:42:30 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Mon Apr 23 15:49:11 2012 +0200
@@ -78,10 +78,10 @@
     public native RiField RiConstantPool_lookupField(HotSpotTypeResolved pool, int cpi, byte byteCode);
 
     @Override
-    public native HotSpotCompiledMethod installMethod(HotSpotTargetMethod targetMethod, boolean installCode);
+    public native HotSpotCompiledMethod installMethod(HotSpotTargetMethod targetMethod, boolean installCode, HotSpotCodeInfo info);
 
     @Override
-    public native long installStub(HotSpotTargetMethod targetMethod);
+    public native long installStub(HotSpotTargetMethod targetMethod, HotSpotCodeInfo info);
 
     @Override
     public native HotSpotVMConfig getConfiguration();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotCodeInfo.java	Mon Apr 23 15:49:11 2012 +0200
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2011, 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.hotspot.ri;
+
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.Compiler;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+
+/**
+ * Implementation of {@link RiCodeInfo} for HotSpot.
+ */
+public class HotSpotCodeInfo extends CompilerObject implements RiCodeInfo {
+
+    private static final long serialVersionUID = -6766490427732498354L;
+
+    private long start;
+    private byte[] code;
+    public final CiTargetMethod targetMethod;
+    private HotSpotMethodResolved method;
+
+    public HotSpotCodeInfo(Compiler compiler, CiTargetMethod targetMethod, HotSpotMethodResolved method) {
+        super(compiler);
+        assert targetMethod != null;
+        this.method = method;
+        this.targetMethod = targetMethod;
+    }
+
+    @Override
+    public long start() {
+        return start;
+    }
+
+    @Override
+    public byte[] code() {
+        return code;
+    }
+
+    @Override
+    public String toString() {
+        int size = code == null ? 0 : code.length;
+        return "installed code @[" + Long.toHexString(start) + "-" + Long.toHexString(start + size) + "]";
+
+    }
+
+    @Override
+    public CiTargetMethod targetMethod() {
+        return targetMethod;
+    }
+
+    @Override
+    public RiResolvedMethod method() {
+        return method;
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotCompiledMethod.java	Mon Apr 23 15:42:30 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotCompiledMethod.java	Mon Apr 23 15:49:11 2012 +0200
@@ -30,14 +30,17 @@
 import com.oracle.graal.hotspot.Compiler;
 
 /**
- * Implementation of RiCompiledMethod for HotSpot. Stores a reference to the nmethod which contains the compiled code.
+ * Implementation of RiCompiledMethod for HotSpot.
+ * Stores a reference to the nmethod which contains the compiled code.
+ * The nmethod also stores a weak reference to the HotSpotCompiledMethod
+ * instance which is necessary to keep the nmethod from being unloaded.
  */
 public class HotSpotCompiledMethod extends CompilerObject implements RiCompiledMethod {
 
     private static final long serialVersionUID = 156632908220561612L;
 
     private final RiResolvedMethod method;
-    public long nmethod;
+    private long nmethod;
 
     public HotSpotCompiledMethod(Compiler compiler, RiResolvedMethod method) {
         super(compiler);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java	Mon Apr 23 15:42:30 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java	Mon Apr 23 15:49:11 2012 +0200
@@ -82,8 +82,38 @@
     }
 
     @Override
-    public String disassemble(byte[] code, long address) {
-        return compiler.getVMEntries().disassembleNative(code, address);
+    public String disassemble(RiCodeInfo info) {
+        byte[] code = info.code();
+        CiTarget target = compiler.getTarget();
+        HexCodeFile hcf = new HexCodeFile(code, info.start(), target.arch.name, target.wordSize * 8);
+        CiTargetMethod tm = info.targetMethod();
+        if (tm != null) {
+            HexCodeFile.addAnnotations(hcf, tm.annotations());
+            addExceptionHandlersComment(tm, hcf);
+            CiRegister fp = regConfig.getFrameRegister();
+            RefMapFormatter slotFormatter = new RefMapFormatter(target.arch, target.wordSize, fp, 0);
+            for (Safepoint safepoint : tm.safepoints) {
+                if (safepoint instanceof Call) {
+                    Call call = (Call) safepoint;
+                    if (call.debugInfo != null) {
+                        hcf.addComment(call.pcOffset + call.size, CiUtil.append(new StringBuilder(100), call.debugInfo, slotFormatter).toString());
+                    }
+                    addOperandComment(hcf, call.pcOffset, "{" + getTargetName(call) + "}");
+                } else {
+                    if (safepoint.debugInfo != null) {
+                        hcf.addComment(safepoint.pcOffset, CiUtil.append(new StringBuilder(100), safepoint.debugInfo, slotFormatter).toString());
+                    }
+                    addOperandComment(hcf, safepoint.pcOffset, "{safepoint}");
+                }
+            }
+            for (DataPatch site : tm.dataReferences) {
+                hcf.addOperandComment(site.pcOffset, "{" + site.constant + "}");
+            }
+            for (Mark mark : tm.marks) {
+                hcf.addComment(mark.pcOffset, getMarkName(mark));
+            }
+        }
+        return hcf.toEmbeddedString();
     }
 
     /**
@@ -124,38 +154,6 @@
         return "MARK:" + mark.id;
     }
 
-    @Override
-    public String disassemble(CiTargetMethod tm) {
-        byte[] code = Arrays.copyOf(tm.targetCode(), tm.targetCodeSize());
-        CiTarget target = compiler.getTarget();
-        HexCodeFile hcf = new HexCodeFile(code, 0L, target.arch.name, target.wordSize * 8);
-        HexCodeFile.addAnnotations(hcf, tm.annotations());
-        addExceptionHandlersComment(tm, hcf);
-        CiRegister fp = regConfig.getFrameRegister();
-        RefMapFormatter slotFormatter = new RefMapFormatter(target.arch, target.wordSize, fp, 0);
-        for (Safepoint safepoint : tm.safepoints) {
-            if (safepoint instanceof Call) {
-                Call call = (Call) safepoint;
-                if (call.debugInfo != null) {
-                    hcf.addComment(call.pcOffset + call.size, CiUtil.append(new StringBuilder(100), call.debugInfo, slotFormatter).toString());
-                }
-                addOperandComment(hcf, call.pcOffset, "{" + getTargetName(call) + "}");
-            } else {
-                if (safepoint.debugInfo != null) {
-                    hcf.addComment(safepoint.pcOffset, CiUtil.append(new StringBuilder(100), safepoint.debugInfo, slotFormatter).toString());
-                }
-                addOperandComment(hcf, safepoint.pcOffset, "{safepoint}");
-            }
-        }
-        for (DataPatch site : tm.dataReferences) {
-            hcf.addOperandComment(site.pcOffset, "{" + site.constant + "}");
-        }
-        for (Mark mark : tm.marks) {
-            hcf.addComment(mark.pcOffset, getMarkName(mark));
-        }
-        return hcf.toEmbeddedString();
-    }
-
     private static void addExceptionHandlersComment(CiTargetMethod tm, HexCodeFile hcf) {
         if (!tm.exceptionHandlers.isEmpty()) {
             String nl = HexCodeFile.NEW_LINE;
@@ -198,8 +196,8 @@
     }
 
     @Override
-    public Object registerCompilerStub(CiTargetMethod targetMethod, String name) {
-        return HotSpotTargetMethod.installStub(compiler, targetMethod, name);
+    public Object registerCompilerStub(CiTargetMethod targetMethod, String name, RiCodeInfo info) {
+        return HotSpotTargetMethod.installStub(compiler, targetMethod, name, (HotSpotCodeInfo) info);
     }
 
     @Override
@@ -481,13 +479,13 @@
     }
 
     @Override
-    public void installMethod(RiResolvedMethod method, CiTargetMethod code) {
-        compiler.getVMEntries().installMethod(new HotSpotTargetMethod(compiler, (HotSpotMethodResolved) method, code), true);
+    public void installMethod(RiResolvedMethod method, CiTargetMethod code, RiCodeInfo info) {
+        compiler.getVMEntries().installMethod(new HotSpotTargetMethod(compiler, (HotSpotMethodResolved) method, code), true, (HotSpotCodeInfo) info);
     }
 
     @Override
     public RiCompiledMethod addMethod(RiResolvedMethod method, CiTargetMethod code) {
-        return compiler.getVMEntries().installMethod(new HotSpotTargetMethod(compiler, (HotSpotMethodResolved) method, code), false);
+        return compiler.getVMEntries().installMethod(new HotSpotTargetMethod(compiler, (HotSpotMethodResolved) method, code), false, null);
     }
 
     @Override
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java	Mon Apr 23 15:42:30 2012 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java	Mon Apr 23 15:49:11 2012 +0200
@@ -46,7 +46,7 @@
 public class CFGPrinterObserver implements DebugDumpHandler {
 
     private CFGPrinter cfgPrinter;
-    private Graph curGraph;
+    private RiResolvedMethod curMethod;
 
     @Override
     public void dump(Object object, String message) {
@@ -57,6 +57,16 @@
         }
     }
 
+    private static RiResolvedMethod lookupMethod() {
+        RiResolvedMethod method = Debug.contextLookup(RiResolvedMethod.class);
+        if (method != null) {
+            return method;
+        }
+        StructuredGraph graph = Debug.contextLookup(StructuredGraph.class);
+        assert graph != null && graph.method() != null : "cannot find method context for CFG dump";
+        return graph.method();
+    }
+
     public void dumpSandboxed(Object object, String message) {
         GraalCompiler compiler = Debug.contextLookup(GraalCompiler.class);
         if (compiler == null) {
@@ -74,11 +84,12 @@
             TTY.println("CFGPrinter: Output to file %s", file);
         }
 
-        StructuredGraph newGraph = Debug.contextLookup(StructuredGraph.class);
-        if (newGraph != curGraph) {
-            cfgPrinter.printCompilation(newGraph.method());
-            TTY.println("CFGPrinter: Dumping method %s", newGraph.method());
-            curGraph = newGraph;
+        RiResolvedMethod newMethod = lookupMethod();
+
+        if (newMethod != curMethod) {
+            cfgPrinter.printCompilation(newMethod);
+            TTY.println("CFGPrinter: Dumping method %s", newMethod);
+            curMethod = newMethod;
         }
 
         cfgPrinter.target = compiler.target;
@@ -109,8 +120,25 @@
             cfgPrinter.printCFG(message, Arrays.asList(cfgPrinter.cfg.getBlocks()));
 
         } else if (object instanceof CiTargetMethod) {
-            cfgPrinter.printMachineCode(runtime.disassemble((CiTargetMethod) object), message);
-
+            final CiTargetMethod tm = (CiTargetMethod) object;
+            final byte[] code = Arrays.copyOf(tm.targetCode(), tm.targetCodeSize());
+            RiCodeInfo info = new RiCodeInfo() {
+                public CiTargetMethod targetMethod() {
+                    return tm;
+                }
+                public long start() {
+                    return 0L;
+                }
+                public RiResolvedMethod method() {
+                    return null;
+                }
+                public byte[] code() {
+                    return code;
+                }
+            };
+            cfgPrinter.printMachineCode(runtime.disassemble(info), message);
+        } else if (object instanceof RiCodeInfo) {
+            cfgPrinter.printMachineCode(runtime.disassemble((RiCodeInfo) object), message);
         } else if (object instanceof Interval[]) {
             cfgPrinter.printIntervals(message, (Interval[]) object);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiCodeInfo.java	Mon Apr 23 15:49:11 2012 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 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.max.cri.ri;
+
+import com.oracle.max.cri.ci.*;
+
+
+/**
+ * Represents some code installed in the code cache of the runtime.
+ * This encapsulated details are only for informational purposes.
+ * At any time, the runtime may invalidate the underlying code (e.g. due to deopt etc).
+ */
+public interface RiCodeInfo {
+
+    /**
+     * Gets the start address of this installed code.
+     */
+    long start();
+
+    /**
+     * Gets a copy of this installed code.
+     */
+    byte[] code();
+
+    /**
+     * Gets the target method (if any) from which this installed code was produced.
+     */
+    CiTargetMethod targetMethod();
+
+    /**
+     * Gets the method (if any) from which this installed code was compiled.
+     */
+    RiResolvedMethod method();
+}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiRuntime.java	Mon Apr 23 15:42:30 2012 +0200
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiRuntime.java	Mon Apr 23 15:49:11 2012 +0200
@@ -61,25 +61,15 @@
     int codeOffset();
 
     /**
-     * Returns the disassembly of the given code bytes. Used for debugging purposes only.
+     * Returns a disassembly of the given installed code.
      *
-     * @param code the code bytes that should be disassembled
-     * @param address an address at which the bytes are located. This can be used for an address prefix per line of disassembly.
-     * @return the disassembly. This will be of length 0 if the runtime does not support disassembling.
+     * @param code the code that should be disassembled
+     * @return a disassembly. This will be of length 0 if the runtime does not support disassembling.
      */
-    String disassemble(byte[] code, long address);
-
-    /**
-     * Returns the disassembly of the given code bytes. Used for debugging purposes only.
-     *
-     * @param targetMethod the {@link CiTargetMethod} containing the code bytes that should be disassembled
-     * @return the disassembly. This will be of length 0 if the runtime does not support disassembling.
-     */
-    String disassemble(CiTargetMethod targetMethod);
+    String disassemble(RiCodeInfo code);
 
     /**
      * Returns the disassembly of the given method in a {@code javap}-like format.
-     * Used for debugging purposes only.
      *
      * @param method the method that should be disassembled
      * @return the disassembly. This will be of length 0 if the runtime does not support disassembling.
@@ -92,9 +82,10 @@
      *
      * @param targetMethod the target method representing the code of the compiler stub
      * @param name the name of the stub, used for debugging purposes only
+     * @param info the object into which details of the installed code will be written (ignored if null)
      * @return the identification object
      */
-    Object registerCompilerStub(CiTargetMethod targetMethod, String name);
+    Object registerCompilerStub(CiTargetMethod targetMethod, String name, RiCodeInfo info);
 
     /**
      * Returns the RiType object representing the base type for the given kind.
@@ -185,8 +176,9 @@
      *
      * @param method a method whose executable code is being modified
      * @param code the code to be executed when {@code method} is called
+     * @param info the object into which details of the installed code will be written (ignored if null)
      */
-    void installMethod(RiResolvedMethod method, CiTargetMethod code);
+    void installMethod(RiResolvedMethod method, CiTargetMethod code, RiCodeInfo info);
 
     /**
      * Adds the given machine code as an implementation of the given method without making it the default implementation.
--- a/src/share/vm/classfile/systemDictionary.hpp	Mon Apr 23 15:42:30 2012 +0200
+++ b/src/share/vm/classfile/systemDictionary.hpp	Mon Apr 23 15:49:11 2012 +0200
@@ -192,6 +192,7 @@
   template(HotSpotType_klass,                     com_oracle_graal_hotspot_HotSpotType,                         Opt) \
   template(HotSpotField_klass,                    com_oracle_graal_hotspot_HotSpotField,                        Opt) \
   template(HotSpotCompiledMethod_klass,           com_oracle_graal_hotspot_HotSpotCompiledMethod,               Opt) \
+  template(HotSpotCodeInfo_klass,                 com_oracle_graal_hotspot_HotSpotCodeInfo,                     Opt) \
   template(HotSpotMethodResolved_klass,           com_oracle_graal_hotspot_ri_HotSpotMethodResolved,            Opt) \
   template(HotSpotMethodData_klass,               com_oracle_graal_hotspot_ri_HotSpotMethodData,                Opt) \
   template(HotSpotTargetMethod_klass,             com_oracle_graal_hotspot_HotSpotTargetMethod,                 Opt) \
--- a/src/share/vm/classfile/vmSymbols.hpp	Mon Apr 23 15:42:30 2012 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Mon Apr 23 15:49:11 2012 +0200
@@ -273,6 +273,7 @@
   template(com_oracle_graal_hotspot_ri_HotSpotMethodResolved,     "com/oracle/graal/hotspot/ri/HotSpotMethodResolvedImpl")        \
   template(com_oracle_graal_hotspot_HotSpotTargetMethod,          "com/oracle/graal/hotspot/HotSpotTargetMethod")                 \
   template(com_oracle_graal_hotspot_ri_HotSpotMethodData,         "com/oracle/graal/hotspot/ri/HotSpotMethodData")                \
+  template(com_oracle_graal_hotspot_HotSpotCodeInfo,              "com/oracle/graal/hotspot/ri/HotSpotCodeInfo")                  \
   template(com_oracle_graal_hotspot_HotSpotField,                 "com/oracle/graal/hotspot/ri/HotSpotField")                     \
   template(com_oracle_graal_hotspot_HotSpotCompiledMethod,        "com/oracle/graal/hotspot/ri/HotSpotCompiledMethod")            \
   template(com_oracle_graal_hotspot_HotSpotOptions,               "com/oracle/graal/hotspot/HotSpotOptions")                      \
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Mon Apr 23 15:42:30 2012 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Mon Apr 23 15:49:11 2012 +0200
@@ -297,7 +297,7 @@
 }
 
 // constructor used to create a stub
-CodeInstaller::CodeInstaller(Handle& target_method, jlong& id) {
+CodeInstaller::CodeInstaller(Handle& target_method, BufferBlob*& blob, jlong& id) {
   No_Safepoint_Verifier no_safepoint;
   _env = CURRENT_ENV;
   
@@ -312,7 +312,7 @@
   initialize_buffer(buffer);
 
   const char* cname = java_lang_String::as_utf8_string(_name);
-  BufferBlob* blob = BufferBlob::create(strdup(cname), &buffer); // this is leaking strings... but only a limited number of stubs will be created
+  blob = BufferBlob::create(strdup(cname), &buffer); // this is leaking strings... but only a limited number of stubs will be created
   IF_TRACE_graal_3 Disassembler::decode((CodeBlob*) blob);
   id = VmIds::addStub(blob->code_begin());
 }
--- a/src/share/vm/graal/graalCodeInstaller.hpp	Mon Apr 23 15:42:30 2012 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.hpp	Mon Apr 23 15:49:11 2012 +0200
@@ -85,7 +85,7 @@
   CodeInstaller(Handle& target_method, nmethod*& nm, bool install_code);
 
   // constructor used to create a stub
-  CodeInstaller(Handle& target_method, jlong& id);
+  CodeInstaller(Handle& target_method, BufferBlob*& blob, jlong& id);
 
   static address runtime_call_target_address(oop runtime_call);
 
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Mon Apr 23 15:42:30 2012 +0200
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Mon Apr 23 15:49:11 2012 +0200
@@ -877,7 +877,7 @@
 }
 
 // public HotSpotCompiledMethod installMethod(HotSpotTargetMethod targetMethod, boolean installCode);
-JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_installMethod(JNIEnv *jniEnv, jobject, jobject targetMethod, jboolean install_code) {
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_installMethod(JNIEnv *jniEnv, jobject, jobject targetMethod, jboolean install_code, jobject info) {
   VM_ENTRY_MARK;
   ResourceMark rm;
   HandleMark hm;
@@ -887,6 +887,13 @@
   ciEnv env(&arena);
   CodeInstaller installer(targetMethodHandle, nm, install_code != 0);
 
+  if (info != NULL) {
+    arrayOop codeCopy = oopFactory::new_byteArray(nm->code_size(), CHECK_0);
+    memcpy(codeCopy->base(T_BYTE), nm->code_begin(), nm->code_size());
+    HotSpotCodeInfo::set_code(info, codeCopy);
+    HotSpotCodeInfo::set_start(info, (jlong) nm->code_begin());
+  }
+
   // if install_code is true then we installed the code into the given method, no need to return an RiCompiledMethod
   if (!install_code && nm != NULL) {
     instanceKlass::cast(HotSpotCompiledMethod::klass())->initialize(CHECK_NULL);
@@ -903,7 +910,7 @@
 }
 
 // public long installStub(HotSpotTargetMethod targetMethod, String name);
-JNIEXPORT jlong JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_installStub(JNIEnv *jniEnv, jobject, jobject targetMethod) {
+JNIEXPORT jlong JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_installStub(JNIEnv *jniEnv, jobject, jobject targetMethod, jobject info) {
   VM_ENTRY_MARK;
   ResourceMark rm;
   HandleMark hm;
@@ -911,7 +918,16 @@
   jlong id;
   Arena arena;
   ciEnv env(&arena);
-  CodeInstaller installer(targetMethodHandle, id);
+  BufferBlob* blob;
+  CodeInstaller installer(targetMethodHandle, blob, id);
+
+  if (info != NULL) {
+    arrayOop codeCopy = oopFactory::new_byteArray(blob->code_size(), CHECK_0);
+    memcpy(codeCopy->base(T_BYTE), blob->code_begin(), blob->code_size());
+    HotSpotCodeInfo::set_code(info, codeCopy);
+    HotSpotCodeInfo::set_start(info, (jlong) blob->code_begin());
+  }
+
   return id;
 }
 
@@ -1114,6 +1130,7 @@
 #define CONFIG          "Lcom/oracle/graal/hotspot/HotSpotVMConfig;"
 #define HS_METHOD       "Lcom/oracle/graal/hotspot/ri/HotSpotMethod;"
 #define HS_COMP_METHOD  "Lcom/oracle/graal/hotspot/ri/HotSpotCompiledMethod;"
+#define HS_CODE_INFO    "Lcom/oracle/graal/hotspot/ri/HotSpotCodeInfo;"
 #define METHOD_DATA     "Lcom/oracle/graal/hotspot/ri/HotSpotMethodData;"
 #define CI_CONSTANT     "Lcom/oracle/max/cri/ci/CiConstant;"
 #define CI_KIND         "Lcom/oracle/max/cri/ci/CiKind;"
@@ -1153,8 +1170,8 @@
   {CC"getMaxCallTargetOffset",            CC"("CI_RUNTIME_CALL")J",                             FN_PTR(getMaxCallTargetOffset)},
   {CC"getType",                           CC"("CLASS")"TYPE,                                    FN_PTR(getType)},
   {CC"getConfiguration",                  CC"()"CONFIG,                                         FN_PTR(getConfiguration)},
-  {CC"installMethod",                     CC"("TARGET_METHOD"Z)"HS_COMP_METHOD,                 FN_PTR(installMethod)},
-  {CC"installStub",                       CC"("TARGET_METHOD")"PROXY,                           FN_PTR(installStub)},
+  {CC"installMethod",                     CC"("TARGET_METHOD"Z"HS_CODE_INFO")"HS_COMP_METHOD,   FN_PTR(installMethod)},
+  {CC"installStub",                       CC"("TARGET_METHOD HS_CODE_INFO")"PROXY,              FN_PTR(installStub)},
   {CC"disassembleNative",                 CC"([BJ)"STRING,                                      FN_PTR(disassembleNative)},
   {CC"disassembleJava",                   CC"("RESOLVED_METHOD")"STRING,                        FN_PTR(disassembleJava)},
   {CC"RiMethod_toStackTraceElement",      CC"("RESOLVED_METHOD"I)"STACK_TRACE_ELEMENT,          FN_PTR(RiMethod_1toStackTraceElement)},
--- a/src/share/vm/graal/graalJavaAccess.hpp	Mon Apr 23 15:42:30 2012 +0200
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Mon Apr 23 15:49:11 2012 +0200
@@ -46,7 +46,7 @@
 
 #define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, float_field, oop_field, static_oop_field)   \
   start_class(HotSpotTypeResolved)                                                      \
-    oop_field(HotSpotTypeResolved, compiler, "Lcom/oracle/graal/hotspot/Compiler;") \
+    oop_field(HotSpotTypeResolved, compiler, "Lcom/oracle/graal/hotspot/Compiler;")     \
     oop_field(HotSpotTypeResolved, javaMirror, "Ljava/lang/Class;")                     \
     oop_field(HotSpotTypeResolved, simpleName, "Ljava/lang/String;")                    \
     int_field(HotSpotTypeResolved, accessFlags)                                         \
@@ -59,7 +59,7 @@
     int_field(HotSpotTypeResolved, instanceSize)                                        \
   end_class                                                                             \
   start_class(HotSpotMethodResolved)                                                    \
-    oop_field(HotSpotMethodResolved, compiler, "Lcom/oracle/graal/hotspot/Compiler;") \
+    oop_field(HotSpotMethodResolved, compiler, "Lcom/oracle/graal/hotspot/Compiler;")   \
     oop_field(HotSpotMethodResolved, name, "Ljava/lang/String;")                        \
     oop_field(HotSpotMethodResolved, holder, "Lcom/oracle/max/cri/ri/RiResolvedType;")  \
     oop_field(HotSpotMethodResolved, javaMirror, "Ljava/lang/Object;")                  \
@@ -70,7 +70,7 @@
     boolean_field(HotSpotMethodResolved, canBeInlined)                                  \
   end_class                                                                             \
   start_class(HotSpotMethodData)                                                        \
-    oop_field(HotSpotMethodData, compiler, "Lcom/oracle/graal/hotspot/Compiler;")   \
+    oop_field(HotSpotMethodData, compiler, "Lcom/oracle/graal/hotspot/Compiler;")       \
     oop_field(HotSpotMethodData, hotspotMirror, "Ljava/lang/Object;")                   \
     int_field(HotSpotMethodData, normalDataSize)                                        \
     int_field(HotSpotMethodData, extraDataSize)                                         \
@@ -84,9 +84,13 @@
     int_field(HotSpotField, accessFlags)                                                \
   end_class                                                                             \
   start_class(HotSpotCompiledMethod)                                                    \
-    oop_field(HotSpotCompiledMethod, compiler, "Lcom/oracle/graal/hotspot/Compiler;") \
+    oop_field(HotSpotCompiledMethod, compiler, "Lcom/oracle/graal/hotspot/Compiler;")   \
     long_field(HotSpotCompiledMethod, nmethod)                                          \
-    oop_field(HotSpotCompiledMethod, method, "Lcom/oracle/max/cri/ri/RiResolvedMethod;") \
+    oop_field(HotSpotCompiledMethod, method, "Lcom/oracle/max/cri/ri/RiResolvedMethod;")\
+  end_class                                                                             \
+  start_class(HotSpotCodeInfo)                                                          \
+    long_field(HotSpotCodeInfo, start)                                                  \
+    oop_field(HotSpotCodeInfo, code, "[B")                                              \
   end_class                                                                             \
   start_class(HotSpotProxy)                                                             \
     static_oop_field(HotSpotProxy, DUMMY_CONSTANT_OBJ, "Ljava/lang/Long;")              \