--- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/asm/CompilationResultBuilder.java 2019-03-12 08:09:32.963556195 +0100 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/asm/CompilationResultBuilder.java 2019-03-12 08:09:32.599553833 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,6 +38,7 @@ import jdk.internal.vm.compiler.collections.Equivalence; import org.graalvm.compiler.asm.AbstractAddress; import org.graalvm.compiler.asm.Assembler; +import org.graalvm.compiler.asm.Label; import org.graalvm.compiler.code.CompilationResult; import org.graalvm.compiler.code.CompilationResult.CodeAnnotation; import org.graalvm.compiler.code.DataSection.Data; @@ -46,7 +47,6 @@ import org.graalvm.compiler.core.common.cfg.AbstractBlockBase; import org.graalvm.compiler.core.common.spi.ForeignCallsProvider; import org.graalvm.compiler.core.common.type.DataPointerConstant; -import org.graalvm.compiler.debug.Assertions; import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.graph.NodeSourcePosition; @@ -54,12 +54,14 @@ import org.graalvm.compiler.lir.LIRFrameState; import org.graalvm.compiler.lir.LIRInstruction; import org.graalvm.compiler.lir.LabelRef; +import org.graalvm.compiler.lir.StandardOp.LabelHoldingOp; import org.graalvm.compiler.lir.framemap.FrameMap; import org.graalvm.compiler.options.Option; import org.graalvm.compiler.options.OptionKey; import org.graalvm.compiler.options.OptionType; import org.graalvm.compiler.options.OptionValues; +import jdk.vm.ci.code.BailoutException; import jdk.vm.ci.code.CodeCacheProvider; import jdk.vm.ci.code.DebugInfo; import jdk.vm.ci.code.Register; @@ -155,6 +157,20 @@ private Consumer beforeOp; private Consumer afterOp; + /** + * These position maps are used for estimating offsets of forward branches. Used for + * architectures where certain branch instructions have limited displacement such as ARM tbz or + * SPARC cbcond. + */ + private EconomicMap labelBindLirPositions; + private EconomicMap lirPositions; + /** + * This flag is for setting the + * {@link CompilationResultBuilder#labelWithinRange(LIRInstruction, Label, int)} into a + * conservative mode and always answering false. + */ + private boolean conservativeLabelOffsets = false; + public final boolean mustReplaceWithNullRegister(JavaConstant nullConstant) { return !nullRegister.equals(Register.None) && JavaConstant.NULL_POINTER.equals(nullConstant); } @@ -179,14 +195,6 @@ this.debug = debug; assert frameContext != null; this.dataCache = dataCache; - - if (dataBuilder.needDetailedPatchingInformation() || Assertions.assertionsEnabled()) { - /* - * Always enabled in debug mode, even when the VM does not request detailed information, - * to increase test coverage. - */ - asm.setCodePatchingAnnotationConsumer(assemblerCodeAnnotation -> compilationResult.addAnnotation(new AssemblerAnnotation(assemblerCodeAnnotation))); - } } public void setTotalFrameSize(int frameSize) { @@ -543,6 +551,8 @@ if (op.getPosition() != null) { crb.recordSourceMapping(start, crb.asm.position(), op.getPosition()); } + } catch (BailoutException e) { + throw e; } catch (AssertionError t) { throw new GraalError(t); } catch (RuntimeException t) { @@ -559,6 +569,8 @@ if (dataCache != null) { dataCache.clear(); } + lir = null; + currentBlockIndex = 0; } public void setOpCallback(Consumer beforeOp, Consumer afterOp) { @@ -570,4 +582,57 @@ return options; } + /** + * Builds up a map for label and LIR instruction positions where labels are or labels pointing + * to. + */ + public void buildLabelOffsets(LIR generatedLIR) { + labelBindLirPositions = EconomicMap.create(Equivalence.IDENTITY); + lirPositions = EconomicMap.create(Equivalence.IDENTITY); + int instructionPosition = 0; + for (AbstractBlockBase block : generatedLIR.codeEmittingOrder()) { + if (block != null) { + for (LIRInstruction op : generatedLIR.getLIRforBlock(block)) { + if (op instanceof LabelHoldingOp) { + Label label = ((LabelHoldingOp) op).getLabel(); + if (label != null) { + labelBindLirPositions.put(label, instructionPosition); + } + lirPositions.put(op, instructionPosition); + } + instructionPosition++; + } + } + } + } + + /** + * Answers the code generator whether the jump from instruction to label is within disp LIR + * instructions. + * + * @param disp Maximum number of LIR instructions between label and instruction + */ + public boolean labelWithinRange(LIRInstruction instruction, Label label, int disp) { + if (conservativeLabelOffsets) { + return false; + } + Integer labelPosition = labelBindLirPositions.get(label); + Integer instructionPosition = lirPositions.get(instruction); + boolean result; + if (labelPosition != null && instructionPosition != null) { + result = Math.abs(labelPosition - instructionPosition) < disp; + } else { + result = false; + } + return result; + } + + /** + * Sets this CompilationResultBuilder into conservative mode. If set, + * {@link CompilationResultBuilder#labelWithinRange(LIRInstruction, Label, int)} always returns + * false. + */ + public void setConservativeLabelRanges() { + this.conservativeLabelOffsets = true; + } }