Mercurial > hg > graal-jvmci-8
comparison graal/Compiler/src/com/sun/c1x/asm/AbstractAssembler.java @ 2507:9ec15d6914ca
Pull over of compiler from maxine repository.
author | Thomas Wuerthinger <thomas@wuerthinger.net> |
---|---|
date | Wed, 27 Apr 2011 11:43:22 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2506:4a3bf8a5bf41 | 2507:9ec15d6914ca |
---|---|
1 /* | |
2 * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 */ | |
23 package com.sun.c1x.asm; | |
24 | |
25 import java.util.*; | |
26 | |
27 import com.sun.c1x.*; | |
28 import com.sun.c1x.debug.*; | |
29 import com.sun.c1x.ir.*; | |
30 import com.sun.c1x.lir.*; | |
31 import com.sun.c1x.util.*; | |
32 import com.sun.cri.ci.*; | |
33 import com.sun.cri.ci.CiTargetMethod.CodeComment; | |
34 import com.sun.cri.ci.CiTargetMethod.Mark; | |
35 import com.sun.cri.ri.*; | |
36 | |
37 /** | |
38 * @author Marcelo Cintra | |
39 * @author Thomas Wuerthinger | |
40 */ | |
41 public abstract class AbstractAssembler { | |
42 | |
43 public final Buffer codeBuffer; | |
44 public final CiTarget target; | |
45 public final CiTargetMethod targetMethod; | |
46 public List<ExceptionInfo> exceptionInfoList; | |
47 | |
48 public AbstractAssembler(CiTarget target) { | |
49 this.target = target; | |
50 this.targetMethod = new CiTargetMethod(); | |
51 this.codeBuffer = new Buffer(target.arch.byteOrder); | |
52 } | |
53 | |
54 public final void bind(Label l) { | |
55 assert !l.isBound() : "can bind label only once"; | |
56 l.bind(codeBuffer.position()); | |
57 l.patchInstructions(this); | |
58 } | |
59 | |
60 public void setFrameSize(int frameSize) { | |
61 targetMethod.setFrameSize(frameSize); | |
62 } | |
63 | |
64 public CiTargetMethod finishTargetMethod(Object name, RiRuntime runtime, int registerRestoreEpilogueOffset, boolean isStub) { | |
65 // Install code, data and frame size | |
66 targetMethod.setTargetCode(codeBuffer.close(false), codeBuffer.position()); | |
67 targetMethod.setRegisterRestoreEpilogueOffset(registerRestoreEpilogueOffset); | |
68 | |
69 // Record exception handlers if they exist | |
70 if (exceptionInfoList != null) { | |
71 for (ExceptionInfo ei : exceptionInfoList) { | |
72 int codeOffset = ei.codeOffset; | |
73 for (ExceptionHandler handler : ei.exceptionHandlers) { | |
74 int entryOffset = handler.entryCodeOffset(); | |
75 RiType caughtType = handler.handler.catchType(); | |
76 targetMethod.recordExceptionHandler(codeOffset, ei.bci, handler.scopeCount(), entryOffset, handler.handlerBCI(), caughtType); | |
77 } | |
78 } | |
79 } | |
80 | |
81 if (C1XOptions.PrintMetrics) { | |
82 C1XMetrics.TargetMethods++; | |
83 C1XMetrics.CodeBytesEmitted += targetMethod.targetCodeSize(); | |
84 C1XMetrics.SafepointsEmitted += targetMethod.safepoints.size(); | |
85 C1XMetrics.DirectCallSitesEmitted += targetMethod.directCalls.size(); | |
86 C1XMetrics.IndirectCallSitesEmitted += targetMethod.indirectCalls.size(); | |
87 C1XMetrics.DataPatches += targetMethod.dataReferences.size(); | |
88 C1XMetrics.ExceptionHandlersEmitted += targetMethod.exceptionHandlers.size(); | |
89 } | |
90 | |
91 if (C1XOptions.PrintAssembly && !TTY.isSuppressed() && !isStub) { | |
92 Util.printSection("Target Method", Util.SECTION_CHARACTER); | |
93 TTY.println("Name: " + name); | |
94 TTY.println("Frame size: " + targetMethod.frameSize()); | |
95 TTY.println("Register size: " + target.arch.registerReferenceMapBitCount); | |
96 | |
97 if (C1XOptions.PrintCodeBytes) { | |
98 Util.printSection("Code", Util.SUB_SECTION_CHARACTER); | |
99 TTY.println("Code: %d bytes", targetMethod.targetCodeSize()); | |
100 Util.printBytes(0L, targetMethod.targetCode(), 0, targetMethod.targetCodeSize(), C1XOptions.PrintAssemblyBytesPerLine); | |
101 } | |
102 | |
103 Util.printSection("Disassembly", Util.SUB_SECTION_CHARACTER); | |
104 String disassembly = runtime.disassemble(targetMethod); | |
105 TTY.println(disassembly); | |
106 boolean noDis = disassembly == null || disassembly.length() == 0; | |
107 | |
108 Util.printSection("Safepoints", Util.SUB_SECTION_CHARACTER); | |
109 for (CiTargetMethod.Safepoint x : targetMethod.safepoints) { | |
110 TTY.println(x.toString()); | |
111 if (noDis && x.debugInfo != null) { | |
112 TTY.println(CiUtil.indent(x.debugInfo.toString(), " ")); | |
113 } | |
114 } | |
115 | |
116 Util.printSection("Direct Call Sites", Util.SUB_SECTION_CHARACTER); | |
117 for (CiTargetMethod.Call x : targetMethod.directCalls) { | |
118 TTY.println(x.toString()); | |
119 if (noDis && x.debugInfo != null) { | |
120 TTY.println(CiUtil.indent(x.debugInfo.toString(), " ")); | |
121 } | |
122 } | |
123 | |
124 Util.printSection("Indirect Call Sites", Util.SUB_SECTION_CHARACTER); | |
125 for (CiTargetMethod.Call x : targetMethod.indirectCalls) { | |
126 TTY.println(x.toString()); | |
127 if (noDis && x.debugInfo != null) { | |
128 TTY.println(CiUtil.indent(x.debugInfo.toString(), " ")); | |
129 } | |
130 } | |
131 | |
132 Util.printSection("Data Patches", Util.SUB_SECTION_CHARACTER); | |
133 for (CiTargetMethod.DataPatch x : targetMethod.dataReferences) { | |
134 TTY.println(x.toString()); | |
135 } | |
136 | |
137 Util.printSection("Marks", Util.SUB_SECTION_CHARACTER); | |
138 for (CiTargetMethod.Mark x : targetMethod.marks) { | |
139 TTY.println(x.toString()); | |
140 } | |
141 | |
142 Util.printSection("Exception Handlers", Util.SUB_SECTION_CHARACTER); | |
143 for (CiTargetMethod.ExceptionHandler x : targetMethod.exceptionHandlers) { | |
144 TTY.println(x.toString()); | |
145 } | |
146 } | |
147 | |
148 return targetMethod; | |
149 } | |
150 | |
151 public void recordExceptionHandlers(int pcOffset, LIRDebugInfo info) { | |
152 if (info != null) { | |
153 if (info.exceptionHandlers != null) { | |
154 if (exceptionInfoList == null) { | |
155 exceptionInfoList = new ArrayList<ExceptionInfo>(4); | |
156 } | |
157 exceptionInfoList.add(new ExceptionInfo(pcOffset, info.exceptionHandlers, info.state.bci)); | |
158 } | |
159 } | |
160 } | |
161 | |
162 public void recordImplicitException(int pcOffset, LIRDebugInfo info) { | |
163 // record an implicit exception point | |
164 if (info != null) { | |
165 targetMethod.recordSafepoint(pcOffset, info.debugInfo()); | |
166 recordExceptionHandlers(pcOffset, info); | |
167 } | |
168 } | |
169 | |
170 protected void recordDirectCall(int posBefore, int posAfter, Object target, LIRDebugInfo info) { | |
171 CiDebugInfo debugInfo = info != null ? info.debugInfo() : null; | |
172 targetMethod.recordCall(posBefore, target, debugInfo, true); | |
173 } | |
174 | |
175 protected void recordIndirectCall(int posBefore, int posAfter, Object target, LIRDebugInfo info) { | |
176 CiDebugInfo debugInfo = info != null ? info.debugInfo() : null; | |
177 targetMethod.recordCall(posBefore, target, debugInfo, false); | |
178 } | |
179 | |
180 public void recordSafepoint(int pos, LIRDebugInfo info) { | |
181 // safepoints always need debug info | |
182 CiDebugInfo debugInfo = info.debugInfo(); | |
183 targetMethod.recordSafepoint(pos, debugInfo); | |
184 } | |
185 | |
186 public CiAddress recordDataReferenceInCode(CiConstant data) { | |
187 assert data != null; | |
188 | |
189 int pos = codeBuffer.position(); | |
190 | |
191 if (C1XOptions.TraceRelocation) { | |
192 TTY.print("Data reference in code: pos = %d, data = %s", pos, data.toString()); | |
193 } | |
194 | |
195 targetMethod.recordDataReference(pos, data); | |
196 return CiAddress.Placeholder; | |
197 } | |
198 | |
199 public Mark recordMark(Object id, Mark[] references) { | |
200 return targetMethod.recordMark(codeBuffer.position(), id, references); | |
201 } | |
202 | |
203 public abstract void nop(); | |
204 | |
205 public abstract void nullCheck(CiRegister r); | |
206 | |
207 public abstract void align(int codeEntryAlignment); | |
208 | |
209 public abstract void patchJumpTarget(int branch, int target); | |
210 | |
211 public final void emitByte(int x) { | |
212 codeBuffer.emitByte(x); | |
213 } | |
214 | |
215 public final void emitShort(int x) { | |
216 codeBuffer.emitShort(x); | |
217 } | |
218 | |
219 public final void emitInt(int x) { | |
220 codeBuffer.emitInt(x); | |
221 } | |
222 | |
223 public final void emitLong(long x) { | |
224 codeBuffer.emitLong(x); | |
225 } | |
226 | |
227 public void blockComment(String s) { | |
228 targetMethod.addAnnotation(new CodeComment(codeBuffer.position(), s)); | |
229 } | |
230 } |