Mercurial > hg > graal-jvmci-8
annotate jvmci/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationResult.java @ 22740:22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Thu, 26 Nov 2015 00:47:01 +0100 |
parents | f41ed1d87d68 |
children |
rev | line source |
---|---|
22054 | 1 /* |
2 * Copyright (c) 2009, 2014, 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 */ | |
22672
1bbd4a7c274b
Rename jdk.internal.jvmci to jdk.vm.ci
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
22663
diff
changeset
|
23 package jdk.vm.ci.code; |
22054 | 24 |
22569
ec96f33a101d
updated imports to be explicit and added checkstyle rule to forbid * imports
Doug Simon <doug.simon@oracle.com>
parents:
22113
diff
changeset
|
25 import static java.util.Collections.emptyList; |
ec96f33a101d
updated imports to be explicit and added checkstyle rule to forbid * imports
Doug Simon <doug.simon@oracle.com>
parents:
22113
diff
changeset
|
26 import static java.util.Collections.unmodifiableList; |
22672
1bbd4a7c274b
Rename jdk.internal.jvmci to jdk.vm.ci
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
22663
diff
changeset
|
27 import static jdk.vm.ci.meta.MetaUtil.identityHashCodeString; |
22054 | 28 |
22569
ec96f33a101d
updated imports to be explicit and added checkstyle rule to forbid * imports
Doug Simon <doug.simon@oracle.com>
parents:
22113
diff
changeset
|
29 import java.util.ArrayList; |
ec96f33a101d
updated imports to be explicit and added checkstyle rule to forbid * imports
Doug Simon <doug.simon@oracle.com>
parents:
22113
diff
changeset
|
30 import java.util.Arrays; |
ec96f33a101d
updated imports to be explicit and added checkstyle rule to forbid * imports
Doug Simon <doug.simon@oracle.com>
parents:
22113
diff
changeset
|
31 import java.util.Collection; |
ec96f33a101d
updated imports to be explicit and added checkstyle rule to forbid * imports
Doug Simon <doug.simon@oracle.com>
parents:
22113
diff
changeset
|
32 import java.util.Collections; |
ec96f33a101d
updated imports to be explicit and added checkstyle rule to forbid * imports
Doug Simon <doug.simon@oracle.com>
parents:
22113
diff
changeset
|
33 import java.util.List; |
ec96f33a101d
updated imports to be explicit and added checkstyle rule to forbid * imports
Doug Simon <doug.simon@oracle.com>
parents:
22113
diff
changeset
|
34 import java.util.Map; |
ec96f33a101d
updated imports to be explicit and added checkstyle rule to forbid * imports
Doug Simon <doug.simon@oracle.com>
parents:
22113
diff
changeset
|
35 import java.util.Objects; |
22054 | 36 |
22672
1bbd4a7c274b
Rename jdk.internal.jvmci to jdk.vm.ci
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
22663
diff
changeset
|
37 import jdk.vm.ci.meta.Assumptions.Assumption; |
1bbd4a7c274b
Rename jdk.internal.jvmci to jdk.vm.ci
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
22663
diff
changeset
|
38 import jdk.vm.ci.meta.InvokeTarget; |
1bbd4a7c274b
Rename jdk.internal.jvmci to jdk.vm.ci
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
22663
diff
changeset
|
39 import jdk.vm.ci.meta.JavaConstant; |
1bbd4a7c274b
Rename jdk.internal.jvmci to jdk.vm.ci
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
22663
diff
changeset
|
40 import jdk.vm.ci.meta.MetaUtil; |
1bbd4a7c274b
Rename jdk.internal.jvmci to jdk.vm.ci
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
22663
diff
changeset
|
41 import jdk.vm.ci.meta.ResolvedJavaMethod; |
1bbd4a7c274b
Rename jdk.internal.jvmci to jdk.vm.ci
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
22663
diff
changeset
|
42 import jdk.vm.ci.meta.VMConstant; |
22054 | 43 |
44 /** | |
45 * Represents the output from compiling a method, including the compiled machine code, associated | |
46 * data and references, relocation information, deoptimization information, etc. | |
47 */ | |
48 public class CompilationResult { | |
49 | |
50 /** | |
51 * Represents a code position with associated additional information. | |
52 */ | |
53 public abstract static class Site { | |
54 | |
55 /** | |
56 * The position (or offset) of this site with respect to the start of the target method. | |
57 */ | |
58 public final int pcOffset; | |
59 | |
60 public Site(int pos) { | |
61 this.pcOffset = pos; | |
62 } | |
63 | |
64 @Override | |
65 public final int hashCode() { | |
66 throw new UnsupportedOperationException("hashCode"); | |
67 } | |
68 | |
69 @Override | |
70 public String toString() { | |
71 return identityHashCodeString(this); | |
72 } | |
73 | |
74 @Override | |
75 public abstract boolean equals(Object obj); | |
76 } | |
77 | |
78 /** | |
79 * Represents an infopoint with associated debug info. Note that safepoints are also infopoints. | |
80 */ | |
81 public static class Infopoint extends Site implements Comparable<Infopoint> { | |
82 | |
83 public final DebugInfo debugInfo; | |
84 | |
85 public final InfopointReason reason; | |
86 | |
87 public Infopoint(int pcOffset, DebugInfo debugInfo, InfopointReason reason) { | |
88 super(pcOffset); | |
89 this.debugInfo = debugInfo; | |
90 this.reason = reason; | |
91 } | |
92 | |
93 @Override | |
94 public String toString() { | |
95 StringBuilder sb = new StringBuilder(); | |
96 sb.append(pcOffset); | |
97 sb.append("[<infopoint>]"); | |
98 appendDebugInfo(sb, debugInfo); | |
99 return sb.toString(); | |
100 } | |
101 | |
102 @Override | |
103 public int compareTo(Infopoint o) { | |
104 if (pcOffset < o.pcOffset) { | |
105 return -1; | |
106 } else if (pcOffset > o.pcOffset) { | |
107 return 1; | |
108 } | |
109 return this.reason.compareTo(o.reason); | |
110 } | |
111 | |
112 @Override | |
113 public boolean equals(Object obj) { | |
114 if (this == obj) { | |
115 return true; | |
116 } | |
117 if (obj != null && obj.getClass() == getClass()) { | |
118 Infopoint that = (Infopoint) obj; | |
119 if (this.pcOffset == that.pcOffset && Objects.equals(this.debugInfo, that.debugInfo) && Objects.equals(this.reason, that.reason)) { | |
120 return true; | |
121 } | |
122 } | |
123 return false; | |
124 } | |
125 } | |
126 | |
127 /** | |
128 * Represents a call in the code. | |
129 */ | |
130 public static final class Call extends Infopoint { | |
131 | |
132 /** | |
133 * The target of the call. | |
134 */ | |
135 public final InvokeTarget target; | |
136 | |
137 /** | |
138 * The size of the call instruction. | |
139 */ | |
140 public final int size; | |
141 | |
142 /** | |
143 * Specifies if this call is direct or indirect. A direct call has an immediate operand | |
144 * encoding the absolute or relative (to the call itself) address of the target. An indirect | |
145 * call has a register or memory operand specifying the target address of the call. | |
146 */ | |
147 public final boolean direct; | |
148 | |
149 public Call(InvokeTarget target, int pcOffset, int size, boolean direct, DebugInfo debugInfo) { | |
150 super(pcOffset, debugInfo, InfopointReason.CALL); | |
151 this.size = size; | |
152 this.target = target; | |
153 this.direct = direct; | |
154 } | |
155 | |
156 @Override | |
157 public boolean equals(Object obj) { | |
158 if (this == obj) { | |
159 return true; | |
160 } | |
161 if (obj instanceof Call && super.equals(obj)) { | |
162 Call that = (Call) obj; | |
163 if (this.size == that.size && this.direct == that.direct && Objects.equals(this.target, that.target)) { | |
164 return true; | |
165 } | |
166 } | |
167 return false; | |
168 } | |
169 | |
170 @Override | |
171 public String toString() { | |
172 StringBuilder sb = new StringBuilder(); | |
173 sb.append(pcOffset); | |
174 sb.append('['); | |
175 sb.append(target); | |
176 sb.append(']'); | |
177 | |
178 if (debugInfo != null) { | |
179 appendDebugInfo(sb, debugInfo); | |
180 } | |
181 | |
182 return sb.toString(); | |
183 } | |
184 } | |
185 | |
186 /** | |
187 * Represents some external data that is referenced by the code. | |
188 */ | |
189 public abstract static class Reference { | |
190 | |
191 @Override | |
192 public abstract int hashCode(); | |
193 | |
194 @Override | |
195 public abstract boolean equals(Object obj); | |
196 } | |
197 | |
198 public static final class ConstantReference extends Reference { | |
199 | |
200 private final VMConstant constant; | |
201 | |
202 public ConstantReference(VMConstant constant) { | |
203 this.constant = constant; | |
204 } | |
205 | |
206 public VMConstant getConstant() { | |
207 return constant; | |
208 } | |
209 | |
210 @Override | |
211 public String toString() { | |
212 return constant.toString(); | |
213 } | |
214 | |
215 @Override | |
216 public int hashCode() { | |
217 return constant.hashCode(); | |
218 } | |
219 | |
220 @Override | |
221 public boolean equals(Object obj) { | |
222 if (this == obj) { | |
223 return true; | |
224 } | |
225 if (obj instanceof ConstantReference) { | |
226 ConstantReference that = (ConstantReference) obj; | |
227 return Objects.equals(this.constant, that.constant); | |
228 } | |
229 return false; | |
230 } | |
231 } | |
232 | |
233 public static final class DataSectionReference extends Reference { | |
234 | |
235 private boolean initialized; | |
236 private int offset; | |
237 | |
238 public DataSectionReference() { | |
239 // will be set after the data section layout is fixed | |
240 offset = 0xDEADDEAD; | |
241 } | |
242 | |
243 public int getOffset() { | |
244 assert initialized; | |
245 | |
246 return offset; | |
247 } | |
248 | |
249 public void setOffset(int offset) { | |
250 assert !initialized; | |
251 initialized = true; | |
252 | |
253 this.offset = offset; | |
254 } | |
255 | |
256 @Override | |
257 public int hashCode() { | |
258 return offset; | |
259 } | |
260 | |
261 @Override | |
262 public boolean equals(Object obj) { | |
263 if (this == obj) { | |
264 return true; | |
265 } | |
266 if (obj instanceof DataSectionReference) { | |
267 DataSectionReference that = (DataSectionReference) obj; | |
268 return this.offset == that.offset; | |
269 } | |
270 return false; | |
271 } | |
22663
41b97852175d
Implement DataSectionReference.toString.
Roland Schatz <roland.schatz@oracle.com>
parents:
22625
diff
changeset
|
272 |
41b97852175d
Implement DataSectionReference.toString.
Roland Schatz <roland.schatz@oracle.com>
parents:
22625
diff
changeset
|
273 @Override |
41b97852175d
Implement DataSectionReference.toString.
Roland Schatz <roland.schatz@oracle.com>
parents:
22625
diff
changeset
|
274 public String toString() { |
41b97852175d
Implement DataSectionReference.toString.
Roland Schatz <roland.schatz@oracle.com>
parents:
22625
diff
changeset
|
275 if (initialized) { |
41b97852175d
Implement DataSectionReference.toString.
Roland Schatz <roland.schatz@oracle.com>
parents:
22625
diff
changeset
|
276 return String.format("DataSection[0x%x]", offset); |
41b97852175d
Implement DataSectionReference.toString.
Roland Schatz <roland.schatz@oracle.com>
parents:
22625
diff
changeset
|
277 } else { |
41b97852175d
Implement DataSectionReference.toString.
Roland Schatz <roland.schatz@oracle.com>
parents:
22625
diff
changeset
|
278 return "DataSection[?]"; |
41b97852175d
Implement DataSectionReference.toString.
Roland Schatz <roland.schatz@oracle.com>
parents:
22625
diff
changeset
|
279 } |
41b97852175d
Implement DataSectionReference.toString.
Roland Schatz <roland.schatz@oracle.com>
parents:
22625
diff
changeset
|
280 } |
22054 | 281 } |
282 | |
283 /** | |
284 * Represents a code site that references some data. The associated data can be either a | |
285 * {@link DataSectionReference reference} to the data section, or it may be an inlined | |
286 * {@link JavaConstant} that needs to be patched. | |
287 */ | |
288 public static final class DataPatch extends Site { | |
289 | |
290 public Reference reference; | |
291 | |
292 public DataPatch(int pcOffset, Reference reference) { | |
293 super(pcOffset); | |
294 this.reference = reference; | |
295 } | |
296 | |
297 @Override | |
298 public String toString() { | |
299 return String.format("%d[<data patch referring to %s>]", pcOffset, reference.toString()); | |
300 } | |
301 | |
302 @Override | |
303 public boolean equals(Object obj) { | |
304 if (this == obj) { | |
305 return true; | |
306 } | |
307 if (obj instanceof DataPatch) { | |
308 DataPatch that = (DataPatch) obj; | |
309 if (this.pcOffset == that.pcOffset && Objects.equals(this.reference, that.reference)) { | |
310 return true; | |
311 } | |
312 } | |
313 return false; | |
314 } | |
315 } | |
316 | |
317 /** | |
318 * Provides extra information about instructions or data at specific positions in | |
319 * {@link CompilationResult#getTargetCode()}. This is optional information that can be used to | |
320 * enhance a disassembly of the code. | |
321 */ | |
322 public abstract static class CodeAnnotation { | |
323 | |
324 public final int position; | |
325 | |
326 public CodeAnnotation(int position) { | |
327 this.position = position; | |
328 } | |
329 | |
330 @Override | |
331 public final int hashCode() { | |
332 throw new UnsupportedOperationException("hashCode"); | |
333 } | |
334 | |
335 @Override | |
336 public String toString() { | |
337 return identityHashCodeString(this); | |
338 } | |
339 | |
340 @Override | |
341 public abstract boolean equals(Object obj); | |
342 } | |
343 | |
344 /** | |
345 * A string comment about one or more instructions at a specific position in the code. | |
346 */ | |
347 public static final class CodeComment extends CodeAnnotation { | |
348 | |
349 public final String value; | |
350 | |
351 public CodeComment(int position, String comment) { | |
352 super(position); | |
353 this.value = comment; | |
354 } | |
355 | |
356 @Override | |
357 public boolean equals(Object obj) { | |
358 if (this == obj) { | |
359 return true; | |
360 } | |
361 if (obj instanceof CodeComment) { | |
362 CodeComment that = (CodeComment) obj; | |
363 if (this.position == that.position && this.value.equals(that.value)) { | |
364 return true; | |
365 } | |
366 } | |
367 return false; | |
368 } | |
369 | |
370 @Override | |
371 public String toString() { | |
372 return getClass().getSimpleName() + "@" + position + ": " + value; | |
373 } | |
374 } | |
375 | |
376 /** | |
377 * Describes a table of signed offsets embedded in the code. The offsets are relative to the | |
378 * starting address of the table. This type of table maybe generated when translating a | |
379 * multi-way branch based on a key value from a dense value set (e.g. the {@code tableswitch} | |
380 * JVM instruction). | |
381 * | |
382 * The table is indexed by the contiguous range of integers from {@link #low} to {@link #high} | |
383 * inclusive. | |
384 */ | |
385 public static final class JumpTable extends CodeAnnotation { | |
386 | |
387 /** | |
388 * The low value in the key range (inclusive). | |
389 */ | |
390 public final int low; | |
391 | |
392 /** | |
393 * The high value in the key range (inclusive). | |
394 */ | |
395 public final int high; | |
396 | |
397 /** | |
398 * The size (in bytes) of each table entry. | |
399 */ | |
400 public final int entrySize; | |
401 | |
402 public JumpTable(int position, int low, int high, int entrySize) { | |
403 super(position); | |
404 this.low = low; | |
405 this.high = high; | |
406 this.entrySize = entrySize; | |
407 } | |
408 | |
409 @Override | |
410 public boolean equals(Object obj) { | |
411 if (this == obj) { | |
412 return true; | |
413 } | |
414 if (obj instanceof JumpTable) { | |
415 JumpTable that = (JumpTable) obj; | |
416 if (this.position == that.position && this.entrySize == that.entrySize && this.low == that.low && this.high == that.high) { | |
417 return true; | |
418 } | |
419 } | |
420 return false; | |
421 } | |
422 | |
423 @Override | |
424 public String toString() { | |
425 return getClass().getSimpleName() + "@" + position + ": [" + low + " .. " + high + "]"; | |
426 } | |
427 } | |
428 | |
429 /** | |
430 * Represents exception handler information for a specific code position. It includes the catch | |
431 * code position as well as the caught exception type. | |
432 */ | |
433 public static final class ExceptionHandler extends Site { | |
434 | |
435 public final int handlerPos; | |
436 | |
437 ExceptionHandler(int pcOffset, int handlerPos) { | |
438 super(pcOffset); | |
439 this.handlerPos = handlerPos; | |
440 } | |
441 | |
442 @Override | |
443 public String toString() { | |
444 return String.format("%d[<exception edge to %d>]", pcOffset, handlerPos); | |
445 } | |
446 | |
447 @Override | |
448 public boolean equals(Object obj) { | |
449 if (this == obj) { | |
450 return true; | |
451 } | |
452 if (obj instanceof ExceptionHandler) { | |
453 ExceptionHandler that = (ExceptionHandler) obj; | |
454 if (this.pcOffset == that.pcOffset && this.handlerPos == that.handlerPos) { | |
455 return true; | |
456 } | |
457 } | |
458 return false; | |
459 } | |
460 } | |
461 | |
462 /** | |
463 * Represents a mark in the machine code that can be used by the runtime for its own purposes. A | |
464 * mark can reference other marks. | |
465 */ | |
466 public static final class Mark extends Site { | |
467 | |
468 public final Object id; | |
469 | |
470 public Mark(int pcOffset, Object id) { | |
471 super(pcOffset); | |
472 this.id = id; | |
473 } | |
474 | |
475 @Override | |
476 public String toString() { | |
477 if (id == null) { | |
478 return String.format("%d[<mar>]", pcOffset); | |
479 } else if (id instanceof Integer) { | |
480 return String.format("%d[<mark with id %s>]", pcOffset, Integer.toHexString((Integer) id)); | |
481 } else { | |
482 return String.format("%d[<mark with id %s>]", pcOffset, id.toString()); | |
483 } | |
484 } | |
485 | |
486 @Override | |
487 public boolean equals(Object obj) { | |
488 if (this == obj) { | |
489 return true; | |
490 } | |
491 if (obj instanceof Mark) { | |
492 Mark that = (Mark) obj; | |
493 if (this.pcOffset == that.pcOffset && Objects.equals(this.id, that.id)) { | |
494 return true; | |
495 } | |
496 } | |
497 return false; | |
498 } | |
499 } | |
500 | |
22740
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
501 private boolean closed; |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
502 |
22054 | 503 private int entryBCI = -1; |
504 | |
505 private final DataSection dataSection = new DataSection(); | |
506 | |
507 private final List<Infopoint> infopoints = new ArrayList<>(); | |
508 private final List<DataPatch> dataPatches = new ArrayList<>(); | |
509 private final List<ExceptionHandler> exceptionHandlers = new ArrayList<>(); | |
510 private final List<Mark> marks = new ArrayList<>(); | |
511 | |
512 private int totalFrameSize = -1; | |
513 private int customStackAreaOffset = -1; | |
514 | |
515 private final String name; | |
516 | |
517 /** | |
518 * The buffer containing the emitted machine code. | |
519 */ | |
520 private byte[] targetCode; | |
521 | |
522 /** | |
523 * The leading number of bytes in {@link #targetCode} containing the emitted machine code. | |
524 */ | |
525 private int targetCodeSize; | |
526 | |
527 private ArrayList<CodeAnnotation> annotations; | |
528 | |
529 private Assumption[] assumptions; | |
530 | |
531 /** | |
532 * The list of the methods whose bytecodes were used as input to the compilation. If | |
533 * {@code null}, then the compilation did not record method dependencies. Otherwise, the first | |
534 * element of this array is the root method of the compilation. | |
535 */ | |
536 private ResolvedJavaMethod[] methods; | |
537 | |
538 private int bytecodeSize; | |
539 | |
540 private boolean hasUnsafeAccess; | |
541 | |
542 public CompilationResult() { | |
543 this(null); | |
544 } | |
545 | |
546 public CompilationResult(String name) { | |
547 this.name = name; | |
548 } | |
549 | |
550 @Override | |
551 public int hashCode() { | |
552 // CompilationResult instances should not be used as hash map keys | |
553 throw new UnsupportedOperationException("hashCode"); | |
554 } | |
555 | |
556 @Override | |
557 public String toString() { | |
558 if (methods != null) { | |
559 return getClass().getName() + "[" + methods[0].format("%H.%n(%p)%r") + "]"; | |
560 } | |
561 return identityHashCodeString(this); | |
562 } | |
563 | |
564 @Override | |
565 public boolean equals(Object obj) { | |
566 if (this == obj) { | |
567 return true; | |
568 } | |
569 if (obj != null && obj.getClass() == getClass()) { | |
570 CompilationResult that = (CompilationResult) obj; | |
571 // @formatter:off | |
572 if (this.entryBCI == that.entryBCI && | |
573 this.customStackAreaOffset == that.customStackAreaOffset && | |
574 this.totalFrameSize == that.totalFrameSize && | |
575 this.targetCodeSize == that.targetCodeSize && | |
576 Objects.equals(this.name, that.name) && | |
577 Objects.equals(this.annotations, that.annotations) && | |
578 Objects.equals(this.dataSection, that.dataSection) && | |
579 Objects.equals(this.exceptionHandlers, that.exceptionHandlers) && | |
580 Objects.equals(this.dataPatches, that.dataPatches) && | |
581 Objects.equals(this.infopoints, that.infopoints) && | |
582 Objects.equals(this.marks, that.marks) && | |
583 Arrays.equals(this.assumptions, that.assumptions) && | |
584 Arrays.equals(targetCode, that.targetCode)) { | |
585 return true; | |
586 } | |
587 // @formatter:on | |
588 } | |
589 return false; | |
590 } | |
591 | |
592 /** | |
593 * @return the entryBCI | |
594 */ | |
595 public int getEntryBCI() { | |
596 return entryBCI; | |
597 } | |
598 | |
599 /** | |
600 * @param entryBCI the entryBCI to set | |
601 */ | |
602 public void setEntryBCI(int entryBCI) { | |
22740
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
603 checkOpen(); |
22054 | 604 this.entryBCI = entryBCI; |
605 } | |
606 | |
607 /** | |
608 * Sets the assumptions made during compilation. | |
609 */ | |
610 public void setAssumptions(Assumption[] assumptions) { | |
22740
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
611 checkOpen(); |
22054 | 612 this.assumptions = assumptions; |
613 } | |
614 | |
615 /** | |
616 * Gets the assumptions made during compilation. | |
22740
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
617 * |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
618 * The caller must not modify the contents of the returned array. |
22054 | 619 */ |
620 public Assumption[] getAssumptions() { | |
621 return assumptions; | |
622 } | |
623 | |
624 /** | |
625 * Sets the methods whose bytecodes were used as input to the compilation. | |
626 * | |
627 * @param rootMethod the root method of the compilation | |
628 * @param inlinedMethods the methods inlined during compilation | |
629 */ | |
630 public void setMethods(ResolvedJavaMethod rootMethod, Collection<ResolvedJavaMethod> inlinedMethods) { | |
22740
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
631 checkOpen(); |
22054 | 632 assert rootMethod != null; |
633 assert inlinedMethods != null; | |
634 if (inlinedMethods.contains(rootMethod)) { | |
635 methods = inlinedMethods.toArray(new ResolvedJavaMethod[inlinedMethods.size()]); | |
636 for (int i = 0; i < methods.length; i++) { | |
637 if (methods[i].equals(rootMethod)) { | |
638 if (i != 0) { | |
639 ResolvedJavaMethod tmp = methods[0]; | |
640 methods[0] = methods[i]; | |
641 methods[i] = tmp; | |
642 } | |
643 break; | |
644 } | |
645 } | |
646 } else { | |
647 methods = new ResolvedJavaMethod[1 + inlinedMethods.size()]; | |
648 methods[0] = rootMethod; | |
649 int i = 1; | |
650 for (ResolvedJavaMethod m : inlinedMethods) { | |
651 methods[i++] = m; | |
652 } | |
653 } | |
654 } | |
655 | |
656 /** | |
657 * Gets the methods whose bytecodes were used as input to the compilation. | |
658 * | |
22740
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
659 * The caller must not modify the contents of the returned array. |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
660 * |
22054 | 661 * @return {@code null} if the compilation did not record method dependencies otherwise the |
662 * methods whose bytecodes were used as input to the compilation with the first element | |
663 * being the root method of the compilation | |
664 */ | |
665 public ResolvedJavaMethod[] getMethods() { | |
666 return methods; | |
667 } | |
668 | |
669 public void setBytecodeSize(int bytecodeSize) { | |
22740
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
670 checkOpen(); |
22054 | 671 this.bytecodeSize = bytecodeSize; |
672 } | |
673 | |
674 public int getBytecodeSize() { | |
675 return bytecodeSize; | |
676 } | |
677 | |
678 public DataSection getDataSection() { | |
679 return dataSection; | |
680 } | |
681 | |
682 /** | |
683 * The total frame size of the method in bytes. This includes the return address pushed onto the | |
684 * stack, if any. | |
685 * | |
686 * @return the frame size | |
687 */ | |
688 public int getTotalFrameSize() { | |
689 assert totalFrameSize != -1 : "frame size not yet initialized!"; | |
690 return totalFrameSize; | |
691 } | |
692 | |
693 /** | |
694 * Sets the total frame size in bytes. This includes the return address pushed onto the stack, | |
695 * if any. | |
696 * | |
697 * @param size the size of the frame in bytes | |
698 */ | |
699 public void setTotalFrameSize(int size) { | |
22740
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
700 checkOpen(); |
22054 | 701 totalFrameSize = size; |
702 } | |
703 | |
704 /** | |
705 * Sets the machine that has been generated by the compiler. | |
706 * | |
707 * @param code the machine code generated | |
708 * @param size the size of the machine code | |
709 */ | |
710 public void setTargetCode(byte[] code, int size) { | |
22740
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
711 checkOpen(); |
22054 | 712 targetCode = code; |
713 targetCodeSize = size; | |
714 } | |
715 | |
716 /** | |
717 * Records a data patch in the code section. The data patch can refer to something in the | |
718 * {@link DataSectionReference data section} or directly to an {@link ConstantReference inlined | |
719 * constant}. | |
720 * | |
721 * @param codePos The position in the code that needs to be patched. | |
722 * @param ref The reference that should be inserted in the code. | |
723 */ | |
724 public void recordDataPatch(int codePos, Reference ref) { | |
22740
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
725 checkOpen(); |
22054 | 726 assert codePos >= 0 && ref != null; |
727 dataPatches.add(new DataPatch(codePos, ref)); | |
728 } | |
729 | |
730 /** | |
731 * Records a call in the code array. | |
732 * | |
733 * @param codePos the position of the call in the code array | |
734 * @param size the size of the call instruction | |
735 * @param target the being called | |
736 * @param debugInfo the debug info for the call | |
737 * @param direct specifies if this is a {@linkplain Call#direct direct} call | |
738 */ | |
739 public void recordCall(int codePos, int size, InvokeTarget target, DebugInfo debugInfo, boolean direct) { | |
22740
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
740 checkOpen(); |
22054 | 741 final Call call = new Call(target, codePos, size, direct, debugInfo); |
742 addInfopoint(call); | |
743 } | |
744 | |
745 /** | |
746 * Records an exception handler for this method. | |
747 * | |
748 * @param codePos the position in the code that is covered by the handler | |
749 * @param handlerPos the position of the handler | |
750 */ | |
751 public void recordExceptionHandler(int codePos, int handlerPos) { | |
22740
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
752 checkOpen(); |
22054 | 753 assert validateExceptionHandlerAdd(codePos, handlerPos) : String.format("Duplicate exception handler for pc 0x%x handlerPos 0x%x", codePos, handlerPos); |
754 exceptionHandlers.add(new ExceptionHandler(codePos, handlerPos)); | |
755 } | |
756 | |
757 /** | |
758 * Validate if the exception handler for codePos already exists and handlerPos is different. | |
759 * | |
760 * @param codePos | |
761 * @param handlerPos | |
762 * @return true if the validation is successful | |
763 */ | |
764 private boolean validateExceptionHandlerAdd(int codePos, int handlerPos) { | |
765 ExceptionHandler exHandler = getExceptionHandlerForCodePos(codePos); | |
766 return exHandler == null || exHandler.handlerPos == handlerPos; | |
767 } | |
768 | |
769 /** | |
770 * Returns the first ExceptionHandler which matches codePos. | |
771 * | |
772 * @param codePos position to search for | |
773 * @return first matching ExceptionHandler | |
774 */ | |
775 private ExceptionHandler getExceptionHandlerForCodePos(int codePos) { | |
776 for (ExceptionHandler h : exceptionHandlers) { | |
777 if (h.pcOffset == codePos) { | |
778 return h; | |
779 } | |
780 } | |
781 return null; | |
782 } | |
783 | |
784 /** | |
785 * Records an infopoint in the code array. | |
786 * | |
787 * @param codePos the position of the infopoint in the code array | |
788 * @param debugInfo the debug info for the infopoint | |
789 */ | |
790 public void recordInfopoint(int codePos, DebugInfo debugInfo, InfopointReason reason) { | |
791 addInfopoint(new Infopoint(codePos, debugInfo, reason)); | |
792 } | |
793 | |
794 /** | |
795 * Records a custom infopoint in the code section. | |
796 * | |
797 * Compiler implementations can use this method to record non-standard infopoints, which are not | |
22739
f41ed1d87d68
8143730 [JVMCI] infopoint recording is too restrictive
Doug Simon <doug.simon@oracle.com>
parents:
22737
diff
changeset
|
798 * handled by dedicated methods like {@link #recordCall}. |
22054 | 799 * |
800 * @param infopoint the infopoint to record, usually a derived class from {@link Infopoint} | |
801 */ | |
802 public void addInfopoint(Infopoint infopoint) { | |
22740
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
803 checkOpen(); |
22054 | 804 infopoints.add(infopoint); |
805 } | |
806 | |
807 /** | |
808 * Records an instruction mark within this method. | |
809 * | |
810 * @param codePos the position in the code that is covered by the handler | |
811 * @param markId the identifier for this mark | |
812 */ | |
813 public Mark recordMark(int codePos, Object markId) { | |
22740
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
814 checkOpen(); |
22054 | 815 Mark mark = new Mark(codePos, markId); |
816 marks.add(mark); | |
817 return mark; | |
818 } | |
819 | |
820 /** | |
821 * Offset in bytes for the custom stack area (relative to sp). | |
822 * | |
823 * @return the offset in bytes | |
824 */ | |
825 public int getCustomStackAreaOffset() { | |
826 return customStackAreaOffset; | |
827 } | |
828 | |
829 /** | |
830 * @see #getCustomStackAreaOffset() | |
831 * @param offset | |
832 */ | |
833 public void setCustomStackAreaOffset(int offset) { | |
22740
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
834 checkOpen(); |
22054 | 835 customStackAreaOffset = offset; |
836 } | |
837 | |
838 /** | |
839 * @return the machine code generated for this method | |
840 */ | |
841 public byte[] getTargetCode() { | |
842 return targetCode; | |
843 } | |
844 | |
845 /** | |
846 * @return the size of the machine code generated for this method | |
847 */ | |
848 public int getTargetCodeSize() { | |
849 return targetCodeSize; | |
850 } | |
851 | |
852 /** | |
853 * @return the code annotations or {@code null} if there are none | |
854 */ | |
855 public List<CodeAnnotation> getAnnotations() { | |
856 if (annotations == null) { | |
857 return Collections.emptyList(); | |
858 } | |
859 return annotations; | |
860 } | |
861 | |
862 public void addAnnotation(CodeAnnotation annotation) { | |
22740
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
863 checkOpen(); |
22054 | 864 assert annotation != null; |
865 if (annotations == null) { | |
866 annotations = new ArrayList<>(); | |
867 } | |
868 annotations.add(annotation); | |
869 } | |
870 | |
871 private static void appendDebugInfo(StringBuilder sb, DebugInfo info) { | |
872 if (info != null) { | |
873 ReferenceMap refMap = info.getReferenceMap(); | |
874 if (refMap != null) { | |
875 sb.append(refMap.toString()); | |
876 sb.append(']'); | |
877 } | |
878 RegisterSaveLayout calleeSaveInfo = info.getCalleeSaveInfo(); | |
879 if (calleeSaveInfo != null) { | |
880 sb.append(" callee-save-info["); | |
881 String sep = ""; | |
882 for (Map.Entry<Register, Integer> e : calleeSaveInfo.registersToSlots(true).entrySet()) { | |
883 sb.append(sep).append(e.getKey()).append("->").append(e.getValue()); | |
884 sep = ", "; | |
885 } | |
886 sb.append(']'); | |
887 } | |
888 BytecodePosition codePos = info.getBytecodePosition(); | |
889 if (codePos != null) { | |
890 MetaUtil.appendLocation(sb.append(" "), codePos.getMethod(), codePos.getBCI()); | |
891 if (info.hasFrame()) { | |
892 sb.append(" #locals=").append(info.frame().numLocals).append(" #expr=").append(info.frame().numStack); | |
893 if (info.frame().numLocks > 0) { | |
894 sb.append(" #locks=").append(info.frame().numLocks); | |
895 } | |
896 } | |
897 } | |
898 } | |
899 } | |
900 | |
901 /** | |
902 * @return the list of infopoints, sorted by {@link Site#pcOffset} | |
903 */ | |
904 public List<Infopoint> getInfopoints() { | |
905 if (infopoints.isEmpty()) { | |
906 return emptyList(); | |
907 } | |
908 return unmodifiableList(infopoints); | |
909 } | |
910 | |
911 /** | |
912 * @return the list of data references | |
913 */ | |
914 public List<DataPatch> getDataPatches() { | |
915 if (dataPatches.isEmpty()) { | |
916 return emptyList(); | |
917 } | |
918 return unmodifiableList(dataPatches); | |
919 } | |
920 | |
921 /** | |
922 * @return the list of exception handlers | |
923 */ | |
924 public List<ExceptionHandler> getExceptionHandlers() { | |
925 if (exceptionHandlers.isEmpty()) { | |
926 return emptyList(); | |
927 } | |
928 return unmodifiableList(exceptionHandlers); | |
929 } | |
930 | |
931 /** | |
932 * @return the list of marks | |
933 */ | |
934 public List<Mark> getMarks() { | |
935 if (marks.isEmpty()) { | |
936 return emptyList(); | |
937 } | |
938 return unmodifiableList(marks); | |
939 } | |
940 | |
941 public String getName() { | |
942 return name; | |
943 } | |
944 | |
945 public void setHasUnsafeAccess(boolean hasUnsafeAccess) { | |
22740
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
946 checkOpen(); |
22054 | 947 this.hasUnsafeAccess = hasUnsafeAccess; |
948 } | |
949 | |
950 public boolean hasUnsafeAccess() { | |
951 return hasUnsafeAccess; | |
952 } | |
22740
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
953 |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
954 /** |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
955 * Clears the information in this object pertaining to generating code. That is, the |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
956 * {@linkplain #getMarks() marks}, {@linkplain #getInfopoints() infopoints}, |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
957 * {@linkplain #getExceptionHandlers() exception handlers}, {@linkplain #getDataPatches() data |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
958 * patches} and {@linkplain #getAnnotations() annotations} recorded in this object are cleared. |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
959 */ |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
960 public void resetForEmittingCode() { |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
961 checkOpen(); |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
962 infopoints.clear(); |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
963 dataPatches.clear(); |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
964 exceptionHandlers.clear(); |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
965 marks.clear(); |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
966 dataSection.clear(); |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
967 if (annotations != null) { |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
968 annotations.clear(); |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
969 } |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
970 } |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
971 |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
972 private void checkOpen() { |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
973 if (closed) { |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
974 throw new IllegalStateException(); |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
975 } |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
976 } |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
977 |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
978 /** |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
979 * Closes this compilation result to future updates. |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
980 */ |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
981 public void close() { |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
982 if (closed) { |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
983 throw new IllegalStateException("Cannot re-close compilation result " + this); |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
984 } |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
985 dataSection.close(); |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
986 closed = true; |
22110ef74a40
8144083 [JVMCI] CompilationResult should be finalized by JVMCI compiler and made effectively final
Doug Simon <doug.simon@oracle.com>
parents:
22739
diff
changeset
|
987 } |
22054 | 988 } |