24
25 package org.graalvm.compiler.lir.asm;
26
27 import static jdk.vm.ci.code.ValueUtil.asStackSlot;
28 import static jdk.vm.ci.code.ValueUtil.isStackSlot;
29 import static org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant;
30 import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant;
31
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.List;
35 import java.util.function.Consumer;
36
37 import jdk.internal.vm.compiler.collections.EconomicMap;
38 import jdk.internal.vm.compiler.collections.Equivalence;
39 import org.graalvm.compiler.asm.AbstractAddress;
40 import org.graalvm.compiler.asm.Assembler;
41 import org.graalvm.compiler.asm.Label;
42 import org.graalvm.compiler.code.CompilationResult;
43 import org.graalvm.compiler.code.CompilationResult.CodeAnnotation;
44 import org.graalvm.compiler.code.DataSection.Data;
45 import org.graalvm.compiler.code.DataSection.RawData;
46 import org.graalvm.compiler.core.common.NumUtil;
47 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
48 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
49 import org.graalvm.compiler.core.common.type.DataPointerConstant;
50 import org.graalvm.compiler.debug.DebugContext;
51 import org.graalvm.compiler.debug.GraalError;
52 import org.graalvm.compiler.graph.NodeSourcePosition;
53 import org.graalvm.compiler.lir.LIR;
54 import org.graalvm.compiler.lir.LIRFrameState;
55 import org.graalvm.compiler.lir.LIRInstruction;
56 import org.graalvm.compiler.lir.LabelRef;
57 import org.graalvm.compiler.lir.StandardOp.LabelHoldingOp;
58 import org.graalvm.compiler.lir.framemap.FrameMap;
59 import org.graalvm.compiler.options.Option;
60 import org.graalvm.compiler.options.OptionKey;
61 import org.graalvm.compiler.options.OptionType;
62 import org.graalvm.compiler.options.OptionValues;
63
64 import jdk.vm.ci.code.BailoutException;
65 import jdk.vm.ci.code.CodeCacheProvider;
66 import jdk.vm.ci.code.DebugInfo;
67 import jdk.vm.ci.code.Register;
68 import jdk.vm.ci.code.StackSlot;
69 import jdk.vm.ci.code.TargetDescription;
70 import jdk.vm.ci.code.site.ConstantReference;
71 import jdk.vm.ci.code.site.DataSectionReference;
72 import jdk.vm.ci.code.site.InfopointReason;
73 import jdk.vm.ci.code.site.Mark;
74 import jdk.vm.ci.meta.Constant;
75 import jdk.vm.ci.meta.InvokeTarget;
76 import jdk.vm.ci.meta.JavaConstant;
77 import jdk.vm.ci.meta.JavaKind;
78 import jdk.vm.ci.meta.VMConstant;
79 import jdk.vm.ci.meta.Value;
80
81 /**
82 * Fills in a {@link CompilationResult} as its code is being assembled.
83 *
84 * @see CompilationResultBuilderFactory
85 */
86 public class CompilationResultBuilder {
87
88 public static class Options {
89 @Option(help = "Include the LIR as comments with the final assembly.", type = OptionType.Debug) //
90 public static final OptionKey<Boolean> PrintLIRWithAssembly = new OptionKey<>(false);
91 }
92
93 private static class ExceptionInfo {
94
95 public final int codeOffset;
96 public final LabelRef exceptionEdge;
97
98 ExceptionInfo(int pcOffset, LabelRef exceptionEdge) {
99 this.codeOffset = pcOffset;
100 this.exceptionEdge = exceptionEdge;
101 }
102 }
103
104 /**
105 * Wrapper for a code annotation that was produced by the {@link Assembler}.
106 */
107 public static final class AssemblerAnnotation extends CodeAnnotation {
544 }
545
546 private void emitBlock(AbstractBlockBase<?> block) {
547 if (block == null) {
548 return;
549 }
550 boolean emitComment = debug.isDumpEnabled(DebugContext.BASIC_LEVEL) || Options.PrintLIRWithAssembly.getValue(getOptions());
551 if (emitComment) {
552 blockComment(String.format("block B%d %s", block.getId(), block.getLoop()));
553 }
554
555 for (LIRInstruction op : lir.getLIRforBlock(block)) {
556 if (emitComment) {
557 blockComment(String.format("%d %s", op.id(), op));
558 }
559
560 try {
561 if (beforeOp != null) {
562 beforeOp.accept(op);
563 }
564 emitOp(this, op);
565 if (afterOp != null) {
566 afterOp.accept(op);
567 }
568 } catch (GraalError e) {
569 throw e.addContext("lir instruction", block + "@" + op.id() + " " + op.getClass().getName() + " " + op + "\n" + Arrays.toString(lir.codeEmittingOrder()));
570 }
571 }
572 }
573
574 private static void emitOp(CompilationResultBuilder crb, LIRInstruction op) {
575 try {
576 int start = crb.asm.position();
577 op.emitCode(crb);
578 if (op.getPosition() != null) {
579 crb.recordSourceMapping(start, crb.asm.position(), op.getPosition());
580 }
581 } catch (BailoutException e) {
582 throw e;
583 } catch (AssertionError t) {
584 throw new GraalError(t);
585 } catch (RuntimeException t) {
586 throw new GraalError(t);
587 }
588 }
589
590 public void resetForEmittingCode() {
591 asm.reset();
592 compilationResult.resetForEmittingCode();
593 if (exceptionInfoList != null) {
594 exceptionInfoList.clear();
595 }
596 if (dataCache != null) {
597 dataCache.clear();
598 }
599 lir = null;
|
24
25 package org.graalvm.compiler.lir.asm;
26
27 import static jdk.vm.ci.code.ValueUtil.asStackSlot;
28 import static jdk.vm.ci.code.ValueUtil.isStackSlot;
29 import static org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant;
30 import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant;
31
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.List;
35 import java.util.function.Consumer;
36
37 import jdk.internal.vm.compiler.collections.EconomicMap;
38 import jdk.internal.vm.compiler.collections.Equivalence;
39 import org.graalvm.compiler.asm.AbstractAddress;
40 import org.graalvm.compiler.asm.Assembler;
41 import org.graalvm.compiler.asm.Label;
42 import org.graalvm.compiler.code.CompilationResult;
43 import org.graalvm.compiler.code.CompilationResult.CodeAnnotation;
44 import org.graalvm.compiler.code.CompilationResult.JumpTable;
45 import org.graalvm.compiler.code.DataSection.Data;
46 import org.graalvm.compiler.code.DataSection.RawData;
47 import org.graalvm.compiler.core.common.NumUtil;
48 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
49 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
50 import org.graalvm.compiler.core.common.type.DataPointerConstant;
51 import org.graalvm.compiler.debug.DebugContext;
52 import org.graalvm.compiler.debug.GraalError;
53 import org.graalvm.compiler.graph.NodeSourcePosition;
54 import org.graalvm.compiler.lir.LIR;
55 import org.graalvm.compiler.lir.LIRFrameState;
56 import org.graalvm.compiler.lir.LIRInstruction;
57 import org.graalvm.compiler.lir.LIRInstructionVerifier;
58 import org.graalvm.compiler.lir.LabelRef;
59 import org.graalvm.compiler.lir.StandardOp.LabelHoldingOp;
60 import org.graalvm.compiler.lir.framemap.FrameMap;
61 import org.graalvm.compiler.options.Option;
62 import org.graalvm.compiler.options.OptionKey;
63 import org.graalvm.compiler.options.OptionType;
64 import org.graalvm.compiler.options.OptionValues;
65 import org.graalvm.compiler.serviceprovider.GraalServices;
66
67 import jdk.vm.ci.code.BailoutException;
68 import jdk.vm.ci.code.CodeCacheProvider;
69 import jdk.vm.ci.code.DebugInfo;
70 import jdk.vm.ci.code.Register;
71 import jdk.vm.ci.code.StackSlot;
72 import jdk.vm.ci.code.TargetDescription;
73 import jdk.vm.ci.code.site.ConstantReference;
74 import jdk.vm.ci.code.site.DataSectionReference;
75 import jdk.vm.ci.code.site.InfopointReason;
76 import jdk.vm.ci.code.site.Mark;
77 import jdk.vm.ci.meta.Constant;
78 import jdk.vm.ci.meta.InvokeTarget;
79 import jdk.vm.ci.meta.JavaConstant;
80 import jdk.vm.ci.meta.JavaKind;
81 import jdk.vm.ci.meta.VMConstant;
82 import jdk.vm.ci.meta.Value;
83
84 /**
85 * Fills in a {@link CompilationResult} as its code is being assembled.
86 *
87 * @see CompilationResultBuilderFactory
88 */
89 public class CompilationResultBuilder {
90
91 private static final List<LIRInstructionVerifier> LIR_INSTRUCTION_VERIFIERS = new ArrayList<>();
92
93 static {
94 for (LIRInstructionVerifier verifier : GraalServices.load(LIRInstructionVerifier.class)) {
95 if (verifier.isEnabled()) {
96 LIR_INSTRUCTION_VERIFIERS.add(verifier);
97 }
98 }
99 }
100
101 public static class Options {
102 @Option(help = "Include the LIR as comments with the final assembly.", type = OptionType.Debug) //
103 public static final OptionKey<Boolean> PrintLIRWithAssembly = new OptionKey<>(false);
104 }
105
106 private static class ExceptionInfo {
107
108 public final int codeOffset;
109 public final LabelRef exceptionEdge;
110
111 ExceptionInfo(int pcOffset, LabelRef exceptionEdge) {
112 this.codeOffset = pcOffset;
113 this.exceptionEdge = exceptionEdge;
114 }
115 }
116
117 /**
118 * Wrapper for a code annotation that was produced by the {@link Assembler}.
119 */
120 public static final class AssemblerAnnotation extends CodeAnnotation {
557 }
558
559 private void emitBlock(AbstractBlockBase<?> block) {
560 if (block == null) {
561 return;
562 }
563 boolean emitComment = debug.isDumpEnabled(DebugContext.BASIC_LEVEL) || Options.PrintLIRWithAssembly.getValue(getOptions());
564 if (emitComment) {
565 blockComment(String.format("block B%d %s", block.getId(), block.getLoop()));
566 }
567
568 for (LIRInstruction op : lir.getLIRforBlock(block)) {
569 if (emitComment) {
570 blockComment(String.format("%d %s", op.id(), op));
571 }
572
573 try {
574 if (beforeOp != null) {
575 beforeOp.accept(op);
576 }
577 emitOp(op);
578 if (afterOp != null) {
579 afterOp.accept(op);
580 }
581 } catch (GraalError e) {
582 throw e.addContext("lir instruction", block + "@" + op.id() + " " + op.getClass().getName() + " " + op + "\n" + Arrays.toString(lir.codeEmittingOrder()));
583 }
584 }
585 }
586
587 private void emitOp(LIRInstruction op) {
588 try {
589 int start = asm.position();
590 op.emitCode(this);
591 if (op.getPosition() != null) {
592 recordSourceMapping(start, asm.position(), op.getPosition());
593 }
594 if (LIR_INSTRUCTION_VERIFIERS.size() > 0 && start < asm.position()) {
595 int end = asm.position();
596 for (CodeAnnotation codeAnnotation : compilationResult.getCodeAnnotations()) {
597 if (codeAnnotation instanceof JumpTable) {
598 // Skip jump table. Here we assume the jump table is at the tail of the
599 // emitted code.
600 int jumpTableStart = codeAnnotation.position;
601 if (jumpTableStart >= start && jumpTableStart < end) {
602 end = jumpTableStart;
603 }
604 }
605 }
606 byte[] emittedCode = asm.copy(start, end);
607 for (LIRInstructionVerifier verifier : LIR_INSTRUCTION_VERIFIERS) {
608 verifier.verify(op, emittedCode);
609 }
610 }
611 } catch (BailoutException e) {
612 throw e;
613 } catch (AssertionError t) {
614 throw new GraalError(t);
615 } catch (RuntimeException t) {
616 throw new GraalError(t);
617 }
618 }
619
620 public void resetForEmittingCode() {
621 asm.reset();
622 compilationResult.resetForEmittingCode();
623 if (exceptionInfoList != null) {
624 exceptionInfoList.clear();
625 }
626 if (dataCache != null) {
627 dataCache.clear();
628 }
629 lir = null;
|