Mercurial > hg > truffle
comparison graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotCodeCacheProvider.java @ 21706:4c00096fc415
moved CodeCacheProvider.disassemble(...) from API to CFGPrinterObserver
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 03 Jun 2015 16:52:41 +0200 |
parents | d563baeca9df |
children |
comparison
equal
deleted
inserted
replaced
21705:729e6acde6c0 | 21706:4c00096fc415 |
---|---|
23 package com.oracle.jvmci.hotspot; | 23 package com.oracle.jvmci.hotspot; |
24 | 24 |
25 import static com.oracle.jvmci.hotspot.HotSpotCompressedNullConstant.*; | 25 import static com.oracle.jvmci.hotspot.HotSpotCompressedNullConstant.*; |
26 | 26 |
27 import java.lang.reflect.*; | 27 import java.lang.reflect.*; |
28 import java.util.*; | |
29 | 28 |
30 import com.oracle.jvmci.code.*; | 29 import com.oracle.jvmci.code.*; |
31 import com.oracle.jvmci.code.CodeUtil.DefaultRefMapFormatter; | |
32 import com.oracle.jvmci.code.CodeUtil.RefMapFormatter; | |
33 import com.oracle.jvmci.code.CompilationResult.Call; | 30 import com.oracle.jvmci.code.CompilationResult.Call; |
34 import com.oracle.jvmci.code.CompilationResult.ConstantReference; | 31 import com.oracle.jvmci.code.CompilationResult.ConstantReference; |
35 import com.oracle.jvmci.code.CompilationResult.DataPatch; | 32 import com.oracle.jvmci.code.CompilationResult.DataPatch; |
36 import com.oracle.jvmci.code.CompilationResult.Infopoint; | |
37 import com.oracle.jvmci.code.CompilationResult.Mark; | 33 import com.oracle.jvmci.code.CompilationResult.Mark; |
38 import com.oracle.jvmci.code.DataSection.Data; | 34 import com.oracle.jvmci.code.DataSection.Data; |
39 import com.oracle.jvmci.code.DataSection.DataBuilder; | 35 import com.oracle.jvmci.code.DataSection.DataBuilder; |
40 import com.oracle.jvmci.common.*; | 36 import com.oracle.jvmci.common.*; |
41 import com.oracle.jvmci.debug.*; | 37 import com.oracle.jvmci.debug.*; |
57 this.target = target; | 53 this.target = target; |
58 this.regConfig = regConfig; | 54 this.regConfig = regConfig; |
59 } | 55 } |
60 | 56 |
61 @Override | 57 @Override |
62 public String disassemble(CompilationResult compResult, InstalledCode installedCode) { | 58 public String getMarkName(Mark mark) { |
63 byte[] code = installedCode == null ? Arrays.copyOf(compResult.getTargetCode(), compResult.getTargetCodeSize()) : installedCode.getCode(); | 59 int markId = (int) mark.id; |
64 if (code == null) { | |
65 // Method was deoptimized/invalidated | |
66 return ""; | |
67 } | |
68 long start = installedCode == null ? 0L : installedCode.getStart(); | |
69 HexCodeFile hcf = new HexCodeFile(code, start, target.arch.getName(), target.wordSize * 8); | |
70 if (compResult != null) { | |
71 HexCodeFile.addAnnotations(hcf, compResult.getAnnotations()); | |
72 addExceptionHandlersComment(compResult, hcf); | |
73 Register fp = regConfig.getFrameRegister(); | |
74 RefMapFormatter slotFormatter = new DefaultRefMapFormatter(target.arch, target.wordSize, fp, 0); | |
75 for (Infopoint infopoint : compResult.getInfopoints()) { | |
76 if (infopoint instanceof Call) { | |
77 Call call = (Call) infopoint; | |
78 if (call.debugInfo != null) { | |
79 hcf.addComment(call.pcOffset + call.size, CodeUtil.append(new StringBuilder(100), call.debugInfo, slotFormatter).toString()); | |
80 } | |
81 addOperandComment(hcf, call.pcOffset, "{" + getTargetName(call) + "}"); | |
82 } else { | |
83 if (infopoint.debugInfo != null) { | |
84 hcf.addComment(infopoint.pcOffset, CodeUtil.append(new StringBuilder(100), infopoint.debugInfo, slotFormatter).toString()); | |
85 } | |
86 addOperandComment(hcf, infopoint.pcOffset, "{infopoint: " + infopoint.reason + "}"); | |
87 } | |
88 } | |
89 for (DataPatch site : compResult.getDataPatches()) { | |
90 hcf.addOperandComment(site.pcOffset, "{" + site.reference.toString() + "}"); | |
91 } | |
92 for (Mark mark : compResult.getMarks()) { | |
93 hcf.addComment(mark.pcOffset, getMarkIdName((int) mark.id)); | |
94 } | |
95 } | |
96 String hcfEmbeddedString = hcf.toEmbeddedString(); | |
97 return HexCodeFileDisTool.tryDisassemble(hcfEmbeddedString); | |
98 } | |
99 | |
100 /** | |
101 * Interface to the tool for disassembling an {@link HexCodeFile#toEmbeddedString() embedded} | |
102 * {@link HexCodeFile}. | |
103 */ | |
104 static class HexCodeFileDisTool { | |
105 static final Method processMethod; | |
106 static { | |
107 Method toolMethod = null; | |
108 try { | |
109 Class<?> toolClass = Class.forName("com.oracle.max.hcfdis.HexCodeFileDis", true, ClassLoader.getSystemClassLoader()); | |
110 toolMethod = toolClass.getDeclaredMethod("processEmbeddedString", String.class); | |
111 } catch (Exception e) { | |
112 // Tool not available on the class path | |
113 } | |
114 processMethod = toolMethod; | |
115 } | |
116 | |
117 public static String tryDisassemble(String hcfEmbeddedString) { | |
118 if (processMethod != null) { | |
119 try { | |
120 return (String) processMethod.invoke(null, hcfEmbeddedString); | |
121 } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { | |
122 // If the tool is available, for now let's be noisy when it fails | |
123 throw new JVMCIError(e); | |
124 } | |
125 } | |
126 return hcfEmbeddedString; | |
127 } | |
128 } | |
129 | |
130 private String getMarkIdName(int markId) { | |
131 Field[] fields = runtime.getConfig().getClass().getDeclaredFields(); | 60 Field[] fields = runtime.getConfig().getClass().getDeclaredFields(); |
132 for (Field f : fields) { | 61 for (Field f : fields) { |
133 if (f.getName().startsWith("MARKID_")) { | 62 if (f.getName().startsWith("MARKID_")) { |
134 f.setAccessible(true); | 63 f.setAccessible(true); |
135 try { | 64 try { |
138 } | 67 } |
139 } catch (Exception e) { | 68 } catch (Exception e) { |
140 } | 69 } |
141 } | 70 } |
142 } | 71 } |
143 return String.valueOf(markId); | 72 return CodeCacheProvider.super.getMarkName(mark); |
144 } | 73 } |
145 | 74 |
146 /** | 75 /** |
147 * Decodes a call target to a mnemonic if possible. | 76 * Decodes a call target to a mnemonic if possible. |
148 */ | 77 */ |
149 private String getTargetName(Call call) { | 78 @Override |
79 public String getTargetName(Call call) { | |
150 Field[] fields = runtime.getConfig().getClass().getDeclaredFields(); | 80 Field[] fields = runtime.getConfig().getClass().getDeclaredFields(); |
151 for (Field f : fields) { | 81 for (Field f : fields) { |
152 if (f.getName().endsWith("Stub")) { | 82 if (f.getName().endsWith("Stub")) { |
153 f.setAccessible(true); | 83 f.setAccessible(true); |
154 try { | 84 try { |
158 } | 88 } |
159 } catch (Exception e) { | 89 } catch (Exception e) { |
160 } | 90 } |
161 } | 91 } |
162 } | 92 } |
163 return String.valueOf(call.target); | 93 return CodeCacheProvider.super.getTargetName(call); |
164 } | |
165 | |
166 private static void addExceptionHandlersComment(CompilationResult compResult, HexCodeFile hcf) { | |
167 if (!compResult.getExceptionHandlers().isEmpty()) { | |
168 String nl = HexCodeFile.NEW_LINE; | |
169 StringBuilder buf = new StringBuilder("------ Exception Handlers ------").append(nl); | |
170 for (CompilationResult.ExceptionHandler e : compResult.getExceptionHandlers()) { | |
171 buf.append(" ").append(e.pcOffset).append(" -> ").append(e.handlerPos).append(nl); | |
172 hcf.addComment(e.pcOffset, "[exception -> " + e.handlerPos + "]"); | |
173 hcf.addComment(e.handlerPos, "[exception handler for " + e.pcOffset + "]"); | |
174 } | |
175 hcf.addComment(0, buf.toString()); | |
176 } | |
177 } | |
178 | |
179 private static void addOperandComment(HexCodeFile hcf, int pos, String comment) { | |
180 String oldValue = hcf.addOperandComment(pos, comment); | |
181 assert oldValue == null : "multiple comments for operand of instruction at " + pos + ": " + comment + ", " + oldValue; | |
182 } | 94 } |
183 | 95 |
184 @Override | 96 @Override |
185 public RegisterConfig getRegisterConfig() { | 97 public RegisterConfig getRegisterConfig() { |
186 return regConfig; | 98 return regConfig; |