< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/asm/CompilationResultBuilder.java

Print this page


   1 /*
   2  * Copyright (c) 2013, 2018, 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 
  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.code.CompilationResult;
  42 import org.graalvm.compiler.code.CompilationResult.CodeAnnotation;
  43 import org.graalvm.compiler.code.DataSection.Data;
  44 import org.graalvm.compiler.code.DataSection.RawData;
  45 import org.graalvm.compiler.core.common.NumUtil;
  46 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
  47 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
  48 import org.graalvm.compiler.core.common.type.DataPointerConstant;
  49 import org.graalvm.compiler.debug.Assertions;
  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.framemap.FrameMap;
  58 import org.graalvm.compiler.options.Option;
  59 import org.graalvm.compiler.options.OptionKey;
  60 import org.graalvm.compiler.options.OptionType;
  61 import org.graalvm.compiler.options.OptionValues;
  62 

  63 import jdk.vm.ci.code.CodeCacheProvider;
  64 import jdk.vm.ci.code.DebugInfo;
  65 import jdk.vm.ci.code.Register;
  66 import jdk.vm.ci.code.StackSlot;
  67 import jdk.vm.ci.code.TargetDescription;
  68 import jdk.vm.ci.code.site.ConstantReference;
  69 import jdk.vm.ci.code.site.DataSectionReference;
  70 import jdk.vm.ci.code.site.InfopointReason;
  71 import jdk.vm.ci.code.site.Mark;
  72 import jdk.vm.ci.meta.Constant;
  73 import jdk.vm.ci.meta.InvokeTarget;
  74 import jdk.vm.ci.meta.JavaConstant;
  75 import jdk.vm.ci.meta.JavaKind;
  76 import jdk.vm.ci.meta.VMConstant;
  77 import jdk.vm.ci.meta.Value;
  78 
  79 /**
  80  * Fills in a {@link CompilationResult} as its code is being assembled.
  81  *
  82  * @see CompilationResultBuilderFactory


 138 
 139     /**
 140      * The index of the block currently being emitted.
 141      */
 142     protected int currentBlockIndex;
 143 
 144     /**
 145      * The object that emits code for managing a method's frame.
 146      */
 147     public final FrameContext frameContext;
 148 
 149     private List<ExceptionInfo> exceptionInfoList;
 150 
 151     private final OptionValues options;
 152     private final DebugContext debug;
 153     private final EconomicMap<Constant, Data> dataCache;
 154 
 155     private Consumer<LIRInstruction> beforeOp;
 156     private Consumer<LIRInstruction> afterOp;
 157 














 158     public final boolean mustReplaceWithNullRegister(JavaConstant nullConstant) {
 159         return !nullRegister.equals(Register.None) && JavaConstant.NULL_POINTER.equals(nullConstant);
 160     }
 161 
 162     public CompilationResultBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, Assembler asm, DataBuilder dataBuilder, FrameContext frameContext,
 163                     OptionValues options, DebugContext debug, CompilationResult compilationResult, Register nullRegister) {
 164         this(codeCache, foreignCalls, frameMap, asm, dataBuilder, frameContext, options, debug, compilationResult, nullRegister, EconomicMap.create(Equivalence.DEFAULT));
 165     }
 166 
 167     public CompilationResultBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, Assembler asm, DataBuilder dataBuilder, FrameContext frameContext,
 168                     OptionValues options, DebugContext debug, CompilationResult compilationResult, Register nullRegister, EconomicMap<Constant, Data> dataCache) {
 169         this.target = codeCache.getTarget();
 170         this.codeCache = codeCache;
 171         this.foreignCalls = foreignCalls;
 172         this.frameMap = frameMap;
 173         this.asm = asm;
 174         this.dataBuilder = dataBuilder;
 175         this.compilationResult = compilationResult;
 176         this.nullRegister = nullRegister;
 177         this.frameContext = frameContext;
 178         this.options = options;
 179         this.debug = debug;
 180         assert frameContext != null;
 181         this.dataCache = dataCache;
 182 
 183         if (dataBuilder.needDetailedPatchingInformation() || Assertions.assertionsEnabled()) {
 184             /*
 185              * Always enabled in debug mode, even when the VM does not request detailed information,
 186              * to increase test coverage.
 187              */
 188             asm.setCodePatchingAnnotationConsumer(assemblerCodeAnnotation -> compilationResult.addAnnotation(new AssemblerAnnotation(assemblerCodeAnnotation)));
 189         }
 190     }
 191 
 192     public void setTotalFrameSize(int frameSize) {
 193         compilationResult.setTotalFrameSize(frameSize);
 194     }
 195 
 196     public void setMaxInterpreterFrameSize(int maxInterpreterFrameSize) {
 197         compilationResult.setMaxInterpreterFrameSize(maxInterpreterFrameSize);
 198     }
 199 
 200     public Mark recordMark(Object id) {
 201         return compilationResult.recordMark(asm.position(), id);
 202     }
 203 
 204     public void blockComment(String s) {
 205         compilationResult.addAnnotation(new CompilationResult.CodeComment(asm.position(), s));
 206     }
 207 
 208     /**
 209      * Sets the {@linkplain CompilationResult#setTargetCode(byte[], int) code} and


 526                 if (beforeOp != null) {
 527                     beforeOp.accept(op);
 528                 }
 529                 emitOp(this, op);
 530                 if (afterOp != null) {
 531                     afterOp.accept(op);
 532                 }
 533             } catch (GraalError e) {
 534                 throw e.addContext("lir instruction", block + "@" + op.id() + " " + op.getClass().getName() + " " + op + "\n" + Arrays.toString(lir.codeEmittingOrder()));
 535             }
 536         }
 537     }
 538 
 539     private static void emitOp(CompilationResultBuilder crb, LIRInstruction op) {
 540         try {
 541             int start = crb.asm.position();
 542             op.emitCode(crb);
 543             if (op.getPosition() != null) {
 544                 crb.recordSourceMapping(start, crb.asm.position(), op.getPosition());
 545             }


 546         } catch (AssertionError t) {
 547             throw new GraalError(t);
 548         } catch (RuntimeException t) {
 549             throw new GraalError(t);
 550         }
 551     }
 552 
 553     public void resetForEmittingCode() {
 554         asm.reset();
 555         compilationResult.resetForEmittingCode();
 556         if (exceptionInfoList != null) {
 557             exceptionInfoList.clear();
 558         }
 559         if (dataCache != null) {
 560             dataCache.clear();
 561         }


 562     }
 563 
 564     public void setOpCallback(Consumer<LIRInstruction> beforeOp, Consumer<LIRInstruction> afterOp) {
 565         this.beforeOp = beforeOp;
 566         this.afterOp = afterOp;
 567     }
 568 
 569     public OptionValues getOptions() {
 570         return options;
 571     }
 572 





















































 573 }
   1 /*
   2  * Copyright (c) 2013, 2019, 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 
  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


 140 
 141     /**
 142      * The index of the block currently being emitted.
 143      */
 144     protected int currentBlockIndex;
 145 
 146     /**
 147      * The object that emits code for managing a method's frame.
 148      */
 149     public final FrameContext frameContext;
 150 
 151     private List<ExceptionInfo> exceptionInfoList;
 152 
 153     private final OptionValues options;
 154     private final DebugContext debug;
 155     private final EconomicMap<Constant, Data> dataCache;
 156 
 157     private Consumer<LIRInstruction> beforeOp;
 158     private Consumer<LIRInstruction> afterOp;
 159 
 160     /**
 161      * These position maps are used for estimating offsets of forward branches. Used for
 162      * architectures where certain branch instructions have limited displacement such as ARM tbz or
 163      * SPARC cbcond.
 164      */
 165     private EconomicMap<Label, Integer> labelBindLirPositions;
 166     private EconomicMap<LIRInstruction, Integer> lirPositions;
 167     /**
 168      * This flag is for setting the
 169      * {@link CompilationResultBuilder#labelWithinRange(LIRInstruction, Label, int)} into a
 170      * conservative mode and always answering false.
 171      */
 172     private boolean conservativeLabelOffsets = false;
 173 
 174     public final boolean mustReplaceWithNullRegister(JavaConstant nullConstant) {
 175         return !nullRegister.equals(Register.None) && JavaConstant.NULL_POINTER.equals(nullConstant);
 176     }
 177 
 178     public CompilationResultBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, Assembler asm, DataBuilder dataBuilder, FrameContext frameContext,
 179                     OptionValues options, DebugContext debug, CompilationResult compilationResult, Register nullRegister) {
 180         this(codeCache, foreignCalls, frameMap, asm, dataBuilder, frameContext, options, debug, compilationResult, nullRegister, EconomicMap.create(Equivalence.DEFAULT));
 181     }
 182 
 183     public CompilationResultBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, Assembler asm, DataBuilder dataBuilder, FrameContext frameContext,
 184                     OptionValues options, DebugContext debug, CompilationResult compilationResult, Register nullRegister, EconomicMap<Constant, Data> dataCache) {
 185         this.target = codeCache.getTarget();
 186         this.codeCache = codeCache;
 187         this.foreignCalls = foreignCalls;
 188         this.frameMap = frameMap;
 189         this.asm = asm;
 190         this.dataBuilder = dataBuilder;
 191         this.compilationResult = compilationResult;
 192         this.nullRegister = nullRegister;
 193         this.frameContext = frameContext;
 194         this.options = options;
 195         this.debug = debug;
 196         assert frameContext != null;
 197         this.dataCache = dataCache;








 198     }
 199 
 200     public void setTotalFrameSize(int frameSize) {
 201         compilationResult.setTotalFrameSize(frameSize);
 202     }
 203 
 204     public void setMaxInterpreterFrameSize(int maxInterpreterFrameSize) {
 205         compilationResult.setMaxInterpreterFrameSize(maxInterpreterFrameSize);
 206     }
 207 
 208     public Mark recordMark(Object id) {
 209         return compilationResult.recordMark(asm.position(), id);
 210     }
 211 
 212     public void blockComment(String s) {
 213         compilationResult.addAnnotation(new CompilationResult.CodeComment(asm.position(), s));
 214     }
 215 
 216     /**
 217      * Sets the {@linkplain CompilationResult#setTargetCode(byte[], int) code} and


 534                 if (beforeOp != null) {
 535                     beforeOp.accept(op);
 536                 }
 537                 emitOp(this, op);
 538                 if (afterOp != null) {
 539                     afterOp.accept(op);
 540                 }
 541             } catch (GraalError e) {
 542                 throw e.addContext("lir instruction", block + "@" + op.id() + " " + op.getClass().getName() + " " + op + "\n" + Arrays.toString(lir.codeEmittingOrder()));
 543             }
 544         }
 545     }
 546 
 547     private static void emitOp(CompilationResultBuilder crb, LIRInstruction op) {
 548         try {
 549             int start = crb.asm.position();
 550             op.emitCode(crb);
 551             if (op.getPosition() != null) {
 552                 crb.recordSourceMapping(start, crb.asm.position(), op.getPosition());
 553             }
 554         } catch (BailoutException e) {
 555             throw e;
 556         } catch (AssertionError t) {
 557             throw new GraalError(t);
 558         } catch (RuntimeException t) {
 559             throw new GraalError(t);
 560         }
 561     }
 562 
 563     public void resetForEmittingCode() {
 564         asm.reset();
 565         compilationResult.resetForEmittingCode();
 566         if (exceptionInfoList != null) {
 567             exceptionInfoList.clear();
 568         }
 569         if (dataCache != null) {
 570             dataCache.clear();
 571         }
 572         lir = null;
 573         currentBlockIndex = 0;
 574     }
 575 
 576     public void setOpCallback(Consumer<LIRInstruction> beforeOp, Consumer<LIRInstruction> afterOp) {
 577         this.beforeOp = beforeOp;
 578         this.afterOp = afterOp;
 579     }
 580 
 581     public OptionValues getOptions() {
 582         return options;
 583     }
 584 
 585     /**
 586      * Builds up a map for label and LIR instruction positions where labels are or labels pointing
 587      * to.
 588      */
 589     public void buildLabelOffsets(LIR generatedLIR) {
 590         labelBindLirPositions = EconomicMap.create(Equivalence.IDENTITY);
 591         lirPositions = EconomicMap.create(Equivalence.IDENTITY);
 592         int instructionPosition = 0;
 593         for (AbstractBlockBase<?> block : generatedLIR.codeEmittingOrder()) {
 594             if (block != null) {
 595                 for (LIRInstruction op : generatedLIR.getLIRforBlock(block)) {
 596                     if (op instanceof LabelHoldingOp) {
 597                         Label label = ((LabelHoldingOp) op).getLabel();
 598                         if (label != null) {
 599                             labelBindLirPositions.put(label, instructionPosition);
 600                         }
 601                         lirPositions.put(op, instructionPosition);
 602                     }
 603                     instructionPosition++;
 604                 }
 605             }
 606         }
 607     }
 608 
 609     /**
 610      * Answers the code generator whether the jump from instruction to label is within disp LIR
 611      * instructions.
 612      *
 613      * @param disp Maximum number of LIR instructions between label and instruction
 614      */
 615     public boolean labelWithinRange(LIRInstruction instruction, Label label, int disp) {
 616         if (conservativeLabelOffsets) {
 617             return false;
 618         }
 619         Integer labelPosition = labelBindLirPositions.get(label);
 620         Integer instructionPosition = lirPositions.get(instruction);
 621         boolean result;
 622         if (labelPosition != null && instructionPosition != null) {
 623             result = Math.abs(labelPosition - instructionPosition) < disp;
 624         } else {
 625             result = false;
 626         }
 627         return result;
 628     }
 629 
 630     /**
 631      * Sets this CompilationResultBuilder into conservative mode. If set,
 632      * {@link CompilationResultBuilder#labelWithinRange(LIRInstruction, Label, int)} always returns
 633      * false.
 634      */
 635     public void setConservativeLabelRanges() {
 636         this.conservativeLabelOffsets = true;
 637     }
 638 }
< prev index next >