--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/DataPatchProcessor.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/DataPatchProcessor.java Thu Mar 28 19:39:14 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -47,6 +47,7 @@
import jdk.vm.ci.hotspot.HotSpotObjectConstant;
import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
import jdk.vm.ci.hotspot.HotSpotSentinelConstant;
+import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.VMConstant;
final class DataPatchProcessor {
@@ -95,21 +96,24 @@
gotName = "got." + targetSymbol;
binaryContainer.addCountersSymbol(targetSymbol);
}
- } else if (constant instanceof HotSpotObjectConstant) {
- HotSpotObjectConstant oopConstant = (HotSpotObjectConstant) constant;
- if (oopConstant instanceof HotSpotConstantPoolObject) {
- HotSpotConstantPoolObject cpo = (HotSpotConstantPoolObject) oopConstant;
+ } else if (constant instanceof JavaConstant) {
+ JavaConstant jConstant = (JavaConstant) constant;
+ if (jConstant instanceof HotSpotConstantPoolObject) {
+ HotSpotConstantPoolObject cpo = (HotSpotConstantPoolObject) jConstant;
// Even if two locations use the same object, resolve separately
- targetSymbol = "ldc." + cpo.getCpType().getName() + cpo.getCpi();
- } else {
+ targetSymbol = "ldc." + cpo.toValueString();
+ Integer offset = binaryContainer.addOopSymbol(targetSymbol);
+ gotName = "got.ldc." + offset;
+ } else if (jConstant instanceof HotSpotObjectConstant) {
+ HotSpotObjectConstant oopConstant = (HotSpotObjectConstant) jConstant;
// String constant.
targetSymbol = "ldc." + oopConstant.toValueString();
+ Integer offset = binaryContainer.addOopSymbol(targetSymbol);
+ gotName = "got.ldc." + offset;
+ } else if (jConstant instanceof HotSpotSentinelConstant) {
+ targetSymbol = "state.M" + methodInfo.getCodeId();
+ gotName = "got." + targetSymbol;
}
- Integer offset = binaryContainer.addOopSymbol(targetSymbol);
- gotName = "got.ldc." + offset;
- } else if (constant instanceof HotSpotSentinelConstant) {
- targetSymbol = "state.M" + methodInfo.getCodeId();
- gotName = "got." + targetSymbol;
}
assert gotName != null : "Unknown constant type: " + constant;
--- a/src/jdk.internal.vm.ci/share/classes/module-info.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.ci/share/classes/module-info.java Thu Mar 28 19:39:14 2019 +0100
@@ -24,7 +24,9 @@
*/
module jdk.internal.vm.ci {
- exports jdk.vm.ci.services to jdk.internal.vm.compiler;
+ exports jdk.vm.ci.services to
+ jdk.internal.vm.compiler,
+ jdk.internal.vm.compiler.management;
exports jdk.vm.ci.runtime to
jdk.internal.vm.compiler,
jdk.internal.vm.compiler.management;
--- a/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalRuntimeMBean.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalRuntimeMBean.java Thu Mar 28 19:39:14 2019 +0100
@@ -52,6 +52,8 @@
import org.graalvm.compiler.options.OptionsParser;
import org.graalvm.compiler.serviceprovider.GraalServices;
+import jdk.vm.ci.services.Services;
+
/**
* MBean used to access properties and operations of a {@link HotSpotGraalRuntime} instance.
*/
@@ -84,7 +86,7 @@
private static boolean initDebug() {
try {
- return Boolean.getBoolean(HotSpotGraalRuntimeMBean.class.getSimpleName() + ".debug");
+ return Boolean.parseBoolean(Services.getSavedProperties().get(HotSpotGraalRuntimeMBean.class.getSimpleName() + ".debug"));
} catch (SecurityException e) {
// Swallow the exception
return false;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64Assembler.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64Assembler.java Thu Mar 28 19:39:14 2019 +0100
@@ -40,6 +40,7 @@
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BR;
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.BRK;
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CAS;
+import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CCMP;
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CLREX;
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CLS;
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CLZ;
@@ -86,6 +87,7 @@
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.MOVK;
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.MOVN;
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.MOVZ;
+import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.MRS;
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.MSUB;
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.ORN;
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.ORR;
@@ -436,6 +438,7 @@
private static final int FpImmOffset = 13;
private static final int FpCmpOp = 0x1E202000;
+ private static final int FpCmpeOp = 0x1E202010;
private static final int PcRelImmHiOffset = 5;
private static final int PcRelImmLoOffset = 29;
@@ -532,6 +535,8 @@
SUB(0x40000000),
SUBS(SUB.encoding | AddSubSetFlag),
+ CCMP(0x7A400000),
+
NOT(0x00200000),
AND(0x00000000),
BIC(AND.encoding | NOT.encoding),
@@ -618,6 +623,9 @@
HINT(0xD503201F),
DMB(0x000000A0),
+ MRS(0xD5300000),
+ MSR(0xD5100000),
+
BLR_NATIVE(0xc0000000);
public final int encoding;
@@ -628,6 +636,29 @@
}
+ public enum SystemRegister {
+ FPCR(0b11, 0b011, 0b0100, 0b0100, 0b000),
+ FPSR(0b11, 0b011, 0b0100, 0b0100, 0b001);
+
+ SystemRegister(int op0, int op1, int crn, int crm, int op2) {
+ this.op0 = op0;
+ this.op1 = op1;
+ this.crn = crn;
+ this.crm = crm;
+ this.op2 = op2;
+ }
+
+ public int encoding() {
+ return op0 << 19 | op1 << 16 | crn << 12 | crm << 8 | op2 << 5;
+ }
+
+ private final int op0;
+ private final int op1;
+ private final int crn;
+ private final int crm;
+ private final int op2;
+ }
+
public enum ShiftType {
LSL(0),
LSR(1),
@@ -971,8 +1002,10 @@
int imm = (imm28 & NumUtil.getNbitNumberInt(28)) >> 2;
int instrEncoding = instr.encoding | UnconditionalBranchImmOp;
if (pos == -1) {
+ annotatePatchingImmediate(position(), instr, 26, 0, 2);
emitInt(instrEncoding | imm);
} else {
+ annotatePatchingImmediate(pos, instr, 26, 0, 2);
emitInt(instrEncoding | imm, pos);
}
}
@@ -1011,6 +1044,7 @@
assert !reg.equals(zr);
assert !reg.equals(sp);
emitInt(instr.encoding | UnconditionalBranchRegOp | rs1(reg));
+
}
/* Load-Store Single Register (5.3.1) */
@@ -1161,9 +1195,11 @@
int memop = instr.encoding | transferSizeEncoding | is32Bit | isFloat | rt(reg);
switch (address.getAddressingMode()) {
case IMMEDIATE_SCALED:
+ annotatePatchingImmediate(position(), instr, 12, LoadStoreScaledImmOffset, log2TransferSize);
emitInt(memop | LoadStoreScaledOp | address.getImmediate() << LoadStoreScaledImmOffset | rs1(address.getBase()));
break;
case IMMEDIATE_UNSCALED:
+ annotatePatchingImmediate(position(), instr, 9, LoadStoreUnscaledImmOffset, 0);
emitInt(memop | LoadStoreUnscaledOp | address.getImmediate() << LoadStoreUnscaledImmOffset | rs1(address.getBase()));
break;
case BASE_REGISTER_ONLY:
@@ -1178,12 +1214,15 @@
case PC_LITERAL:
assert log2TransferSize >= 2 : "PC literal loads only works for load/stores of 32-bit and larger";
transferSizeEncoding = (log2TransferSize - 2) << LoadStoreTransferSizeOffset;
+ annotatePatchingImmediate(position(), instr, 21, LoadLiteralImmeOffset, 2);
emitInt(transferSizeEncoding | isFloat | LoadLiteralOp | rd(reg) | address.getImmediate() << LoadLiteralImmeOffset);
break;
case IMMEDIATE_POST_INDEXED:
+ annotatePatchingImmediate(position(), instr, 9, LoadStoreIndexedImmOffset, 0);
emitInt(memop | LoadStorePostIndexedOp | rs1(address.getBase()) | address.getImmediate() << LoadStoreIndexedImmOffset);
break;
case IMMEDIATE_PRE_INDEXED:
+ annotatePatchingImmediate(position(), instr, 9, LoadStoreIndexedImmOffset, 0);
emitInt(memop | LoadStorePreIndexedOp | rs1(address.getBase()) | address.getImmediate() << LoadStoreIndexedImmOffset);
break;
default:
@@ -1529,6 +1568,10 @@
emitInt(type.encoding | instr.encoding | AddSubImmOp | encodeAimm(aimm) | rd(dst) | rs1(src));
}
+ public void ccmp(int size, Register x, Register y, int aimm, ConditionFlag condition) {
+ emitInt(generalFromSize(size).encoding | CCMP.encoding | rs1(x) | rs2(y) | encodeAimm(aimm) | condition.encoding << ConditionalConditionOffset);
+ }
+
/**
* Encodes arithmetic immediate.
*
@@ -2414,7 +2457,8 @@
return false;
}
// bits[62] and bits[61] are opposites.
- return ((bits ^ (bits << 1)) & (1L << 62)) != 0;
+ boolean result = ((bits ^ (bits << 1)) & (1L << 62)) != 0;
+ return result;
}
private static int getFloatImmediate(float imm) {
@@ -2694,6 +2738,20 @@
}
/**
+ * Signalling compares src1 to src2.
+ *
+ * @param size register size.
+ * @param src1 floating point register. May not be null.
+ * @param src2 floating point register. May not be null.
+ */
+ public void fcmpe(int size, Register src1, Register src2) {
+ assert src1.getRegisterCategory().equals(SIMD);
+ assert src2.getRegisterCategory().equals(SIMD);
+ InstructionType type = floatFromSize(size);
+ emitInt(type.encoding | FCMP.encoding | FpCmpeOp | rs1(src1) | rs2(src2));
+ }
+
+ /**
* Conditional compare. NZCV = fcmp(src1, src2) if condition else uimm4.
*
* @param size register size.
@@ -2722,6 +2780,18 @@
emitInt(type.encoding | FCMPZERO.encoding | FpCmpOp | rs1(src));
}
+ /**
+ * Signalling compare register to 0.0 .
+ *
+ * @param size register size.
+ * @param src floating point register. May not be null.
+ */
+ public void fcmpeZero(int size, Register src) {
+ assert src.getRegisterCategory().equals(SIMD);
+ InstructionType type = floatFromSize(size);
+ emitInt(type.encoding | FCMPZERO.encoding | FpCmpeOp | rs1(src));
+ }
+
/* Floating-point Conditional Select (5.7.11) */
/**
@@ -2833,4 +2903,58 @@
emitInt(DMB.encoding | BarrierOp | barrierKind.encoding << BarrierKindOffset);
}
+ public void mrs(Register dst, SystemRegister systemRegister) {
+ emitInt(MRS.encoding | systemRegister.encoding() | rt(dst));
+ }
+
+ public void msr(SystemRegister systemRegister, Register src) {
+ emitInt(MRS.encoding | systemRegister.encoding() | rt(src));
+ }
+
+ public void annotatePatchingImmediate(int pos, Instruction instruction, int operandSizeBits, int offsetBits, int shift) {
+ if (codePatchingAnnotationConsumer != null) {
+ codePatchingAnnotationConsumer.accept(new OperandDataAnnotation(pos, instruction, operandSizeBits, offsetBits, shift));
+ }
+ }
+
+ void annotatePatchingImmediateNativeAddress(int pos, int operandSizeBits, int numInstrs) {
+ if (codePatchingAnnotationConsumer != null) {
+ codePatchingAnnotationConsumer.accept(new MovSequenceAnnotation(pos, operandSizeBits, numInstrs));
+ }
+ }
+
+ public static class OperandDataAnnotation extends CodeAnnotation {
+
+ /**
+ * The size of the operand, in bytes.
+ */
+ public final int operandSizeBits;
+ public final int offsetBits;
+ public final Instruction instruction;
+ public final int shift;
+
+ OperandDataAnnotation(int instructionPosition, Instruction instruction, int operandSizeBits, int offsetBits, int shift) {
+ super(instructionPosition);
+ this.operandSizeBits = operandSizeBits;
+ this.offsetBits = offsetBits;
+ this.shift = shift;
+ this.instruction = instruction;
+ }
+ }
+
+ public static class MovSequenceAnnotation extends CodeAnnotation {
+
+ /**
+ * The size of the operand, in bytes.
+ */
+ public final int operandSizeBits;
+ public final int numInstrs;
+
+ MovSequenceAnnotation(int instructionPosition, int operandSizeBits, int numInstrs) {
+ super(instructionPosition);
+ this.operandSizeBits = operandSizeBits;
+ this.numInstrs = numInstrs;
+ }
+ }
+
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64MacroAssembler.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64MacroAssembler.java Thu Mar 28 19:39:14 2019 +0100
@@ -266,7 +266,8 @@
* @return AArch64Address pointing to memory at {@code base + displacement}.
*/
public AArch64Address makeAddress(Register base, long displacement, int transferSize) {
- return makeAddress(base, displacement, zr, /* signExtend */false, transferSize, zr, /* allowOverwrite */false);
+ return makeAddress(base, displacement, zr, /* signExtend */false, //
+ transferSize, zr, /* allowOverwrite */false);
}
/**
@@ -365,7 +366,19 @@
* @param imm immediate loaded into register.
*/
public void mov(Register dst, long imm) {
+ mov(dst, imm, false);
+ }
+
+ /**
+ * Loads immediate into register.
+ *
+ * @param dst general purpose register. May not be null, zero-register or stackpointer.
+ * @param imm immediate loaded into register.
+ * @param annotateImm Flag to signal of the immediate value should be annotated.
+ */
+ public void mov(Register dst, long imm, boolean annotateImm) {
assert dst.getRegisterCategory().equals(CPU);
+ int pos = position();
if (imm == 0L) {
movx(dst, zr);
} else if (LogicalImmediateTable.isRepresentable(true, imm) != LogicalImmediateTable.Representable.NO) {
@@ -379,6 +392,9 @@
sxt(64, 32, dst, dst);
} else {
mov64(dst, imm);
+ if (annotateImm) {
+ annotatePatchingImmediateNativeAddress(pos, 64, 4);
+ }
}
}
@@ -403,9 +419,25 @@
* @param imm
*/
public void movNativeAddress(Register dst, long imm) {
+ movNativeAddress(dst, imm, false);
+ }
+
+ /**
+ * Generates a 48-bit immediate move code sequence. The immediate may later be updated by
+ * HotSpot.
+ *
+ * In AArch64 mode the virtual address space is 48-bits in size, so we only need three
+ * instructions to create a patchable instruction sequence that can reach anywhere.
+ *
+ * @param dst general purpose register. May not be null, stackpointer or zero-register.
+ * @param imm The immediate address
+ * @param annotateImm Flag to signal of the immediate value should be annotated.
+ */
+ public void movNativeAddress(Register dst, long imm, boolean annotateImm) {
assert (imm & 0xFFFF_0000_0000_0000L) == 0;
// We have to move all non zero parts of the immediate in 16-bit chunks
boolean firstMove = true;
+ int pos = position();
for (int offset = 0; offset < 48; offset += 16) {
int chunk = (int) (imm >> offset) & NumUtil.getNbitNumberInt(16);
if (firstMove) {
@@ -415,6 +447,9 @@
movk(64, dst, chunk, offset);
}
}
+ if (annotateImm) {
+ annotatePatchingImmediateNativeAddress(pos, 48, 3);
+ }
assert !firstMove;
}
@@ -1597,7 +1632,7 @@
}
public void pause() {
- throw GraalError.unimplemented();
+ super.hint(SystemHint.YIELD);
}
/**
@@ -1721,7 +1756,8 @@
*/
@Override
public AArch64Address makeAddress(Register base, int displacement) {
- return makeAddress(base, displacement, zr, /* signExtend */false, /* transferSize */0, zr, /* allowOverwrite */false);
+ return makeAddress(base, displacement, zr, /* signExtend */false, /* transferSize */0, //
+ zr, /* allowOverwrite */false);
}
@Override
@@ -1730,7 +1766,9 @@
}
public void addressOf(Register dst) {
- // This will be fixed up later.
+ if (codePatchingAnnotationConsumer != null) {
+ codePatchingAnnotationConsumer.accept(new AdrpAddMacroInstruction(position()));
+ }
super.adrp(dst);
super.add(64, dst, dst, 0);
}
@@ -1744,4 +1782,51 @@
public void lea(Register d, AArch64Address a) {
a.lea(this, d);
}
+
+ public interface MacroInstruction {
+ void patch(int codePos, int relative, byte[] code);
+ }
+
+ /**
+ * Emits elf patchable adrp add sequence.
+ */
+ public void adrAddRel(int srcSize, Register result, AArch64Address a) {
+ if (codePatchingAnnotationConsumer != null) {
+ codePatchingAnnotationConsumer.accept(new ADRADDPRELMacroInstruction(position()));
+ }
+ super.adrp(a.getBase());
+ this.ldr(srcSize, result, a);
+ }
+
+ public static class ADRADDPRELMacroInstruction extends CodeAnnotation implements MacroInstruction {
+ public ADRADDPRELMacroInstruction(int position) {
+ super(position);
+ }
+
+ @Override
+ public String toString() {
+ return "ADR_PREL_PG";
+ }
+
+ @Override
+ public void patch(int codePos, int relative, byte[] code) {
+ throw GraalError.unimplemented();
+ }
+ }
+
+ public static class AdrpAddMacroInstruction extends CodeAnnotation implements MacroInstruction {
+ public AdrpAddMacroInstruction(int position) {
+ super(position);
+ }
+
+ @Override
+ public String toString() {
+ return "ADRP_ADD";
+ }
+
+ @Override
+ public void patch(int codePos, int relative, byte[] code) {
+ throw GraalError.unimplemented();
+ }
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/Assembler.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/Assembler.java Thu Mar 28 19:39:14 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -123,7 +123,7 @@
return codeBuffer.getInt(pos);
}
- private static final String NEWLINE = System.getProperty("line.separator");
+ private static final String NEWLINE = System.lineSeparator();
/**
* Some GPU architectures have a text based encoding.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ArithmeticLIRGenerator.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ArithmeticLIRGenerator.java Thu Mar 28 19:39:14 2019 +0100
@@ -62,11 +62,26 @@
public class AArch64ArithmeticLIRGenerator extends ArithmeticLIRGenerator implements AArch64ArithmeticLIRGeneratorTool {
+ public AArch64ArithmeticLIRGenerator(AllocatableValue nullRegisterValue) {
+ this.nullRegisterValue = nullRegisterValue;
+ }
+
+ private final AllocatableValue nullRegisterValue;
+
@Override
public AArch64LIRGenerator getLIRGen() {
return (AArch64LIRGenerator) super.getLIRGen();
}
+ public boolean mustReplaceNullWithNullRegister(JavaConstant nullConstant) {
+ /* Uncompressed null pointers only */
+ return nullRegisterValue != null && JavaConstant.NULL_POINTER.equals(nullConstant);
+ }
+
+ public AllocatableValue getNullRegisterValue() {
+ return nullRegisterValue;
+ }
+
@Override
protected boolean isNumericInteger(PlatformKind kind) {
return ((AArch64Kind) kind).isInteger();
@@ -485,11 +500,6 @@
}
@Override
- public void emitCompareOp(AArch64Kind cmpKind, Variable left, Value right) {
- throw GraalError.unimplemented();
- }
-
- @Override
public Value emitRound(Value value, RoundingMode mode) {
AArch64ArithmeticOp op;
switch (mode) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LIRGenerator.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LIRGenerator.java Thu Mar 28 19:39:14 2019 +0100
@@ -164,7 +164,7 @@
public Variable emitValueCompareAndSwap(LIRKind accessKind, Value address, Value expectedValue, Value newValue) {
Variable result = newVariable(newValue.getValueKind());
Variable scratch = newVariable(LIRKind.value(AArch64Kind.WORD));
- append(new CompareAndSwapOp(result, loadNonCompareConst(expectedValue), loadReg(newValue), asAllocatable(address), scratch));
+ append(new CompareAndSwapOp(result, loadReg(expectedValue), loadReg(newValue), asAllocatable(address), scratch));
return result;
}
@@ -238,8 +238,13 @@
* null.
*/
@Override
- public Variable emitConditionalMove(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
- boolean mirrored = emitCompare(cmpKind, left, right, cond, unorderedIsTrue);
+ public Variable emitConditionalMove(PlatformKind cmpKind, Value left, final Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
+ AArch64ArithmeticLIRGenerator arithLir = ((AArch64ArithmeticLIRGenerator) arithmeticLIRGen);
+ Value actualRight = right;
+ if (isJavaConstant(actualRight) && arithLir.mustReplaceNullWithNullRegister((asJavaConstant(actualRight)))) {
+ actualRight = arithLir.getNullRegisterValue();
+ }
+ boolean mirrored = emitCompare(cmpKind, left, actualRight, cond, unorderedIsTrue);
Condition finalCondition = mirrored ? cond.mirror() : cond;
boolean finalUnorderedIsTrue = mirrored ? !unorderedIsTrue : unorderedIsTrue;
ConditionFlag cmpCondition = toConditionFlag(((AArch64Kind) cmpKind).isInteger(), finalCondition, finalUnorderedIsTrue);
@@ -256,30 +261,38 @@
}
@Override
- public void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination,
+ public void emitCompareBranch(PlatformKind cmpKind, Value left, final Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination,
double trueDestinationProbability) {
+ Value actualRight = right;
if (cond == Condition.EQ) {
// emit cbz instruction for IsNullNode.
assert !LIRValueUtil.isNullConstant(left) : "emitNullCheckBranch()'s null input should be in right.";
- if (LIRValueUtil.isNullConstant(right)) {
- append(new CompareBranchZeroOp(asAllocatable(left), trueDestination, falseDestination, trueDestinationProbability));
- return;
+ AArch64ArithmeticLIRGenerator arithLir = ((AArch64ArithmeticLIRGenerator) arithmeticLIRGen);
+ if (LIRValueUtil.isNullConstant(actualRight)) {
+ JavaConstant rightConstant = asJavaConstant(actualRight);
+ if (arithLir.mustReplaceNullWithNullRegister(rightConstant)) {
+ actualRight = arithLir.getNullRegisterValue();
+ } else {
+ append(new CompareBranchZeroOp(asAllocatable(left), trueDestination, falseDestination,
+ trueDestinationProbability));
+ return;
+ }
}
// emit cbz instruction for IntegerEquals when any of the inputs is zero.
AArch64Kind kind = (AArch64Kind) cmpKind;
if (kind.isInteger()) {
if (isIntConstant(left, 0)) {
- append(new CompareBranchZeroOp(asAllocatable(right), trueDestination, falseDestination, trueDestinationProbability));
+ append(new CompareBranchZeroOp(asAllocatable(actualRight), trueDestination, falseDestination, trueDestinationProbability));
return;
- } else if (isIntConstant(right, 0)) {
+ } else if (isIntConstant(actualRight, 0)) {
append(new CompareBranchZeroOp(asAllocatable(left), trueDestination, falseDestination, trueDestinationProbability));
return;
}
}
}
- boolean mirrored = emitCompare(cmpKind, left, right, cond, unorderedIsTrue);
+ boolean mirrored = emitCompare(cmpKind, left, actualRight, cond, unorderedIsTrue);
Condition finalCondition = mirrored ? cond.mirror() : cond;
boolean finalUnorderedIsTrue = mirrored ? !unorderedIsTrue : unorderedIsTrue;
ConditionFlag cmpCondition = toConditionFlag(((AArch64Kind) cmpKind).isInteger(), finalCondition, finalUnorderedIsTrue);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64.test/src/org/graalvm/compiler/core/amd64/test/AMD64MatchRuleTest.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64.test/src/org/graalvm/compiler/core/amd64/test/AMD64MatchRuleTest.java Thu Mar 28 19:39:14 2019 +0100
@@ -26,14 +26,19 @@
import static org.junit.Assume.assumeTrue;
+import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
import org.graalvm.compiler.core.test.MatchRuleTest;
import org.graalvm.compiler.lir.LIR;
import org.graalvm.compiler.lir.LIRInstruction;
+import org.graalvm.compiler.lir.amd64.AMD64Binary;
import org.graalvm.compiler.lir.amd64.AMD64BinaryConsumer.MemoryConstOp;
+import org.graalvm.compiler.lir.amd64.AMD64BinaryConsumer.ConstOp;
+import org.graalvm.compiler.lir.amd64.AMD64Unary;
import org.junit.Before;
import org.junit.Test;
import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.amd64.AMD64Kind;
public class AMD64MatchRuleTest extends MatchRuleTest {
@Before
@@ -77,4 +82,182 @@
this.x = x;
}
}
+
+ static volatile short shortValue;
+
+ public static long testVolatileExtensionSnippet() {
+ return shortValue;
+ }
+
+ @Test
+ public void testVolatileExtension() {
+ compile(getResolvedJavaMethod("testVolatileExtensionSnippet"), null);
+ LIR lir = getLIR();
+ boolean found = false;
+ for (LIRInstruction ins : lir.getLIRforBlock(lir.codeEmittingOrder()[0])) {
+ if (ins instanceof AMD64Unary.MemoryOp) {
+ ins.visitEachOutput((value, mode, flags) -> assertTrue(value.getPlatformKind().toString(), value.getPlatformKind().equals(AMD64Kind.QWORD)));
+ assertFalse("MemoryOp expected only once in first block", found);
+ found = true;
+ }
+ }
+ assertTrue("sign extending load must be in the LIR", found);
+ }
+
+ static int intValue;
+ static volatile int volatileIntValue;
+
+ /**
+ * Can't match test and load of input because of volatile store in between.
+ */
+ public static short testLoadTestNoMatchSnippet() {
+ int v = intValue;
+ volatileIntValue = 42;
+ if (v == 42) {
+ return shortValue;
+ }
+ return 0;
+ }
+
+ @Test
+ public void testLoadTestNoMatch() {
+ compile(getResolvedJavaMethod("testLoadTestNoMatchSnippet"), null);
+ LIR lir = getLIR();
+ boolean found = false;
+ for (LIRInstruction ins : lir.getLIRforBlock(lir.codeEmittingOrder()[0])) {
+ if (ins instanceof ConstOp && ((ConstOp) ins).getOpcode().toString().equals("CMP")) {
+ assertFalse("CMP expected only once in first block", found);
+ found = true;
+ }
+ }
+ assertTrue("CMP must be in the LIR", found);
+ }
+
+ /**
+ * Should match as an add with a memory operand.
+ */
+ public static int testAddLoadSnippet() {
+ int v1 = volatileIntValue;
+ int v2 = intValue;
+ return v2 + (2 * v1);
+ }
+
+ @Test
+ public void testAddLoad() {
+ compile(getResolvedJavaMethod("testAddLoadSnippet"), null);
+ LIR lir = getLIR();
+ boolean found = false;
+ for (LIRInstruction ins : lir.getLIRforBlock(lir.codeEmittingOrder()[0])) {
+ if (ins instanceof AMD64Binary.MemoryTwoOp && ((AMD64Binary.MemoryTwoOp) ins).getOpcode().toString().equals("ADD")) {
+ assertFalse("MemoryTwoOp expected only once in first block", found);
+ found = true;
+ }
+ }
+ assertTrue("ADD with memory argument must be in the LIR", found);
+ }
+
+ /**
+ * Can't match as an add with a memory operand because the other add input is too late.
+ */
+ public static int testAddLoadNoMatchSnippet() {
+ int v1 = volatileIntValue;
+ int v2 = intValue;
+ return v1 + (2 * v2);
+ }
+
+ @Test
+ public void testAddLoadNoMatch() {
+ compile(getResolvedJavaMethod("testAddLoadNoMatchSnippet"), null);
+ LIR lir = getLIR();
+ boolean found = false;
+ for (LIRInstruction ins : lir.getLIRforBlock(lir.codeEmittingOrder()[0])) {
+ if (ins instanceof AMD64Binary.CommutativeTwoOp && ((AMD64Binary.CommutativeTwoOp) ins).getOpcode().toString().equals("ADD")) {
+ assertFalse("CommutativeTwoOp expected only once in first block", found);
+ found = true;
+ }
+ }
+ assertTrue("ADD with memory argument must not be in the LIR", found);
+ }
+
+ /**
+ * sign extension and load are in different blocks but can still be matched as a single
+ * instruction.
+ */
+ public static long testVolatileExtensionDifferentBlocksSnippet(boolean flag) {
+ short v = shortValue;
+ if (flag) {
+ return v;
+ }
+ return 0;
+ }
+
+ @Test
+ public void testVolatileExtensionDifferentBlocks() {
+ compile(getResolvedJavaMethod("testVolatileExtensionDifferentBlocksSnippet"), null);
+ LIR lir = getLIR();
+ boolean found = false;
+ for (LIRInstruction ins : lir.getLIRforBlock(lir.codeEmittingOrder()[0])) {
+ if (ins instanceof AMD64Unary.MemoryOp) {
+ ins.visitEachOutput((value, mode, flags) -> assertTrue(value.getPlatformKind().toString(), value.getPlatformKind().equals(AMD64Kind.QWORD)));
+ assertFalse("MemoryOp expected only once in first block", found);
+ found = true;
+ }
+ }
+ assertTrue("sign extending load must be in the LIR", found);
+ }
+
+ /**
+ * Add and load are not in the same block and one input is too late: can't match.
+ */
+ public static int testAddLoadDifferentBlocksNoMatchSnippet(boolean flag) {
+ int v1 = volatileIntValue;
+ if (flag) {
+ int v2 = intValue;
+ return v1 + (2 * v2);
+ }
+ return 0;
+ }
+
+ @Test
+ public void testAddLoadDifferentBlocksNoMatch() {
+ compile(getResolvedJavaMethod("testAddLoadDifferentBlocksNoMatchSnippet"), null);
+ LIR lir = getLIR();
+ boolean found = false;
+ for (AbstractBlockBase<?> b : lir.codeEmittingOrder()) {
+ for (LIRInstruction ins : lir.getLIRforBlock(b)) {
+ if (ins instanceof AMD64Binary.CommutativeTwoOp && ((AMD64Binary.CommutativeTwoOp) ins).getOpcode().toString().equals("ADD")) {
+ assertFalse("CommutativeTwoOp expected only once in first block", found);
+ found = true;
+ }
+ }
+ }
+ assertTrue("ADD with memory argument must not be in the LIR", found);
+ }
+
+ /**
+ * Add and load are in different blocks but can still match.
+ */
+ public static int testAddLoadDifferentBlocksSnippet(boolean flag) {
+ int v2 = intValue;
+ int v1 = volatileIntValue;
+ if (flag) {
+ return v1 + v2;
+ }
+ return 0;
+ }
+
+ @Test
+ public void testAddLoadDifferentBlocks() {
+ compile(getResolvedJavaMethod("testAddLoadDifferentBlocksSnippet"), null);
+ LIR lir = getLIR();
+ boolean found = false;
+ for (LIRInstruction ins : lir.getLIRforBlock(lir.codeEmittingOrder()[0])) {
+ if (ins instanceof AMD64Binary.MemoryTwoOp && ((AMD64Binary.MemoryTwoOp) ins).getOpcode().toString().equals("ADD")) {
+ assertFalse("MemoryTwoOp expected only once in first block", found);
+ found = true;
+ }
+ }
+ assertTrue("ADD with memory argument must be in the LIR", found);
+ }
+
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java Thu Mar 28 19:39:14 2019 +0100
@@ -689,10 +689,9 @@
getLIRGen().append(new AMD64Unary.MOp(op.m1Op, size, result, input));
} else {
/*
- * c is implicitly masked to 5 or 6 bits by the CPU, so casting it to (int) is
- * always correct, even without the NumUtil.is32bit() test.
+ * c needs to be masked here, because shifts with immediate expect a byte.
*/
- getLIRGen().append(new AMD64Binary.ConstOp(op.miOp, size, result, input, (int) c.asLong()));
+ getLIRGen().append(new AMD64Binary.ConstOp(op.miOp, size, result, input, (byte) c.asLong()));
}
} else {
getLIRGen().emitMove(RCX_I, b);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/Fields.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/Fields.java Thu Mar 28 19:39:14 2019 +0100
@@ -24,7 +24,7 @@
package org.graalvm.compiler.core.common;
-import static org.graalvm.compiler.core.common.UnsafeAccess.UNSAFE;
+import static org.graalvm.compiler.serviceprovider.GraalUnsafeAccess.getUnsafe;
import java.util.ArrayList;
import java.util.Collections;
@@ -38,6 +38,8 @@
*/
public class Fields {
+ private static final Unsafe UNSAFE = getUnsafe();
+
/**
* Offsets used with {@link Unsafe} to access the fields.
*/
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/FieldsScanner.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/FieldsScanner.java Thu Mar 28 19:39:14 2019 +0100
@@ -24,7 +24,7 @@
package org.graalvm.compiler.core.common;
-import static org.graalvm.compiler.core.common.UnsafeAccess.UNSAFE;
+import static org.graalvm.compiler.serviceprovider.GraalUnsafeAccess.getUnsafe;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
@@ -50,6 +50,8 @@
*/
public static class DefaultCalcOffset implements CalcOffset {
+ private static final Unsafe UNSAFE = getUnsafe();
+
@Override
public long getOffset(Field field) {
return UNSAFE.objectFieldOffset(field);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java Thu Mar 28 19:39:14 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -278,4 +278,8 @@
@Option(help = "Enable inlining decision tracing in stubs and snippets.", type = OptionType.Debug)
public static final OptionKey<Boolean> TraceInliningForStubsAndSnippets = new OptionKey<>(false);
+
+ @Option(help = "Use Graal-generated stubs for complicated LIR operations instead of embedding all the emitted code.")
+ public static final OptionKey<Boolean> UseGraalStubs = new OptionKey<>(true);
+
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/UnsafeAccess.java Thu Mar 28 11:06:00 2019 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2012, 2018, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.core.common;
-
-import java.lang.reflect.Field;
-
-import sun.misc.Unsafe;
-
-/**
- * Package private access to the {@link Unsafe} capability.
- */
-class UnsafeAccess {
-
- static final Unsafe UNSAFE = initUnsafe();
-
- private static Unsafe initUnsafe() {
- try {
- // Fast path when we are trusted.
- return Unsafe.getUnsafe();
- } catch (SecurityException se) {
- // Slow path when we are not trusted.
- try {
- Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
- theUnsafe.setAccessible(true);
- return (Unsafe) theUnsafe.get(Unsafe.class);
- } catch (Exception e) {
- throw new RuntimeException("exception while trying to get Unsafe", e);
- }
- }
- }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/UnsafeAccess.java Thu Mar 28 11:06:00 2019 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2012, 2018, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.core.common.util;
-
-import java.lang.reflect.Field;
-
-import sun.misc.Unsafe;
-
-/**
- * Package private access to the {@link Unsafe} capability.
- */
-class UnsafeAccess {
-
- static final Unsafe UNSAFE = initUnsafe();
-
- private static Unsafe initUnsafe() {
- try {
- // Fast path when we are trusted.
- return Unsafe.getUnsafe();
- } catch (SecurityException se) {
- // Slow path when we are not trusted.
- try {
- Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
- theUnsafe.setAccessible(true);
- return (Unsafe) theUnsafe.get(Unsafe.class);
- } catch (Exception e) {
- throw new RuntimeException("exception while trying to get Unsafe", e);
- }
- }
- }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/UnsafeArrayTypeReader.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/UnsafeArrayTypeReader.java Thu Mar 28 19:39:14 2019 +0100
@@ -24,7 +24,8 @@
package org.graalvm.compiler.core.common.util;
-import static org.graalvm.compiler.core.common.util.UnsafeAccess.UNSAFE;
+import static org.graalvm.compiler.serviceprovider.GraalUnsafeAccess.getUnsafe;
+
import sun.misc.Unsafe;
/**
@@ -41,6 +42,8 @@
*/
public abstract class UnsafeArrayTypeReader implements TypeReader {
+ private static final Unsafe UNSAFE = getUnsafe();
+
public static int getS1(byte[] data, long byteIndex) {
return UNSAFE.getByte(data, readOffset(data, byteIndex, Byte.BYTES));
}
@@ -142,6 +145,8 @@
}
final class UnalignedUnsafeArrayTypeReader extends UnsafeArrayTypeReader {
+ private static final Unsafe UNSAFE = getUnsafe();
+
protected static int getS2(byte[] data, long byteIndex) {
return UNSAFE.getShort(data, readOffset(data, byteIndex, Short.BYTES));
}
@@ -181,6 +186,8 @@
}
class AlignedUnsafeArrayTypeReader extends UnsafeArrayTypeReader {
+ private static final Unsafe UNSAFE = getUnsafe();
+
protected static int getS2(byte[] data, long byteIndex) {
long offset = readOffset(data, byteIndex, Short.BYTES);
return ((UNSAFE.getByte(data, offset + 0) & 0xFF) << 0) | //
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/UnsafeArrayTypeWriter.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/UnsafeArrayTypeWriter.java Thu Mar 28 19:39:14 2019 +0100
@@ -30,6 +30,8 @@
import static org.graalvm.compiler.core.common.util.TypeConversion.asU1;
import static org.graalvm.compiler.core.common.util.TypeConversion.asU2;
import static org.graalvm.compiler.core.common.util.TypeConversion.asU4;
+import static org.graalvm.compiler.serviceprovider.GraalUnsafeAccess.getUnsafe;
+
import sun.misc.Unsafe;
/**
@@ -44,6 +46,7 @@
*/
public abstract class UnsafeArrayTypeWriter implements TypeWriter {
+ private static final Unsafe UNSAFE = getUnsafe();
private static final int MIN_CHUNK_LENGTH = 200;
private static final int MAX_CHUNK_LENGTH = 16000;
@@ -96,13 +99,13 @@
@Override
public final void putS1(long value) {
long offset = writeOffset(Byte.BYTES);
- UnsafeAccess.UNSAFE.putByte(writeChunk.data, offset, asS1(value));
+ UNSAFE.putByte(writeChunk.data, offset, asS1(value));
}
@Override
public final void putU1(long value) {
long offset = writeOffset(Byte.BYTES);
- UnsafeAccess.UNSAFE.putByte(writeChunk.data, offset, asU1(value));
+ UNSAFE.putByte(writeChunk.data, offset, asU1(value));
}
@Override
@@ -134,52 +137,56 @@
}
final class UnalignedUnsafeArrayTypeWriter extends UnsafeArrayTypeWriter {
+ private static final Unsafe UNSAFE = getUnsafe();
+
@Override
public void putS2(long value) {
long offset = writeOffset(Short.BYTES);
- UnsafeAccess.UNSAFE.putShort(writeChunk.data, offset, asS2(value));
+ UNSAFE.putShort(writeChunk.data, offset, asS2(value));
}
@Override
public void putS4(long value) {
long offset = writeOffset(Integer.BYTES);
- UnsafeAccess.UNSAFE.putInt(writeChunk.data, offset, asS4(value));
+ UNSAFE.putInt(writeChunk.data, offset, asS4(value));
}
@Override
public void putS8(long value) {
long offset = writeOffset(Long.BYTES);
- UnsafeAccess.UNSAFE.putLong(writeChunk.data, offset, value);
+ UNSAFE.putLong(writeChunk.data, offset, value);
}
}
final class AlignedUnsafeArrayTypeWriter extends UnsafeArrayTypeWriter {
+ private static final Unsafe UNSAFE = getUnsafe();
+
@Override
public void putS2(long value) {
long offset = writeOffset(Short.BYTES);
- UnsafeAccess.UNSAFE.putByte(writeChunk.data, offset + 0, (byte) (value >> 0));
- UnsafeAccess.UNSAFE.putByte(writeChunk.data, offset + 1, (byte) (value >> 8));
+ UNSAFE.putByte(writeChunk.data, offset + 0, (byte) (value >> 0));
+ UNSAFE.putByte(writeChunk.data, offset + 1, (byte) (value >> 8));
}
@Override
public void putS4(long value) {
long offset = writeOffset(Integer.BYTES);
- UnsafeAccess.UNSAFE.putByte(writeChunk.data, offset + 0, (byte) (value >> 0));
- UnsafeAccess.UNSAFE.putByte(writeChunk.data, offset + 1, (byte) (value >> 8));
- UnsafeAccess.UNSAFE.putByte(writeChunk.data, offset + 2, (byte) (value >> 16));
- UnsafeAccess.UNSAFE.putByte(writeChunk.data, offset + 3, (byte) (value >> 24));
+ UNSAFE.putByte(writeChunk.data, offset + 0, (byte) (value >> 0));
+ UNSAFE.putByte(writeChunk.data, offset + 1, (byte) (value >> 8));
+ UNSAFE.putByte(writeChunk.data, offset + 2, (byte) (value >> 16));
+ UNSAFE.putByte(writeChunk.data, offset + 3, (byte) (value >> 24));
}
@Override
public void putS8(long value) {
long offset = writeOffset(Long.BYTES);
- UnsafeAccess.UNSAFE.putByte(writeChunk.data, offset + 0, (byte) (value >> 0));
- UnsafeAccess.UNSAFE.putByte(writeChunk.data, offset + 1, (byte) (value >> 8));
- UnsafeAccess.UNSAFE.putByte(writeChunk.data, offset + 2, (byte) (value >> 16));
- UnsafeAccess.UNSAFE.putByte(writeChunk.data, offset + 3, (byte) (value >> 24));
- UnsafeAccess.UNSAFE.putByte(writeChunk.data, offset + 4, (byte) (value >> 32));
- UnsafeAccess.UNSAFE.putByte(writeChunk.data, offset + 5, (byte) (value >> 40));
- UnsafeAccess.UNSAFE.putByte(writeChunk.data, offset + 6, (byte) (value >> 48));
- UnsafeAccess.UNSAFE.putByte(writeChunk.data, offset + 7, (byte) (value >> 56));
+ UNSAFE.putByte(writeChunk.data, offset + 0, (byte) (value >> 0));
+ UNSAFE.putByte(writeChunk.data, offset + 1, (byte) (value >> 8));
+ UNSAFE.putByte(writeChunk.data, offset + 2, (byte) (value >> 16));
+ UNSAFE.putByte(writeChunk.data, offset + 3, (byte) (value >> 24));
+ UNSAFE.putByte(writeChunk.data, offset + 4, (byte) (value >> 32));
+ UNSAFE.putByte(writeChunk.data, offset + 5, (byte) (value >> 40));
+ UNSAFE.putByte(writeChunk.data, offset + 6, (byte) (value >> 48));
+ UNSAFE.putByte(writeChunk.data, offset + 7, (byte) (value >> 56));
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.match.processor/src/org/graalvm/compiler/core/match/processor/MatchProcessor.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.match.processor/src/org/graalvm/compiler/core/match/processor/MatchProcessor.java Thu Mar 28 19:39:14 2019 +0100
@@ -348,9 +348,15 @@
*/
final boolean shareable;
+ /**
+ * Can this node be subsumed into a match even if there are side effecting nodes between
+ * this node and the match.
+ */
+ final boolean ignoresSideEffects;
+
final Set<Element> originatingElements = new HashSet<>();
- TypeDescriptor(TypeMirror mirror, String shortName, String nodeClass, String nodePackage, List<String> inputs, boolean commutative, boolean shareable) {
+ TypeDescriptor(TypeMirror mirror, String shortName, String nodeClass, String nodePackage, List<String> inputs, boolean commutative, boolean shareable, boolean ignoresSideEffects) {
this.mirror = mirror;
this.shortName = shortName;
this.nodeClass = nodeClass;
@@ -358,6 +364,7 @@
this.inputs = inputs;
this.commutative = commutative;
this.shareable = shareable;
+ this.ignoresSideEffects = ignoresSideEffects;
assert !commutative || inputs.size() == 2;
}
}
@@ -369,8 +376,9 @@
private TypeDescriptor valueType;
- private void declareType(TypeMirror mirror, String shortName, String nodeClass, String nodePackage, List<String> inputs, boolean commutative, boolean shareable, Element element) {
- TypeDescriptor descriptor = new TypeDescriptor(mirror, shortName, nodeClass, nodePackage, inputs, commutative, shareable);
+ private void declareType(TypeMirror mirror, String shortName, String nodeClass, String nodePackage, List<String> inputs, boolean commutative, boolean shareable, boolean ignoresSideEffects,
+ Element element) {
+ TypeDescriptor descriptor = new TypeDescriptor(mirror, shortName, nodeClass, nodePackage, inputs, commutative, shareable, ignoresSideEffects);
descriptor.originatingElements.add(element);
knownTypes.put(shortName, descriptor);
}
@@ -453,7 +461,7 @@
private String formatPrefix() {
if (nodeType == valueType) {
- return String.format("new MatchPattern(%s, false", name != null ? ("\"" + name + "\"") : "null");
+ return String.format("new MatchPattern(%s, false, false", name != null ? ("\"" + name + "\"") : "null");
} else {
return String.format("new MatchPattern(%s.class, %s", nodeType.nodeClass, name != null ? ("\"" + name + "\"") : "null");
}
@@ -462,13 +470,13 @@
private String formatSuffix() {
if (nodeType != null) {
if (inputs.length != nodeType.inputs.size()) {
- return ", true)";
+ return ", true, " + nodeType.ignoresSideEffects + ")";
} else {
if (nodeType.inputs.size() > 0) {
- return ", " + nodeType.nodeClass + "_positions, " + !nodeType.shareable + ")";
+ return ", " + nodeType.nodeClass + "_positions, " + !nodeType.shareable + ", " + nodeType.ignoresSideEffects + ")";
}
if (nodeType.shareable) {
- return ", false)";
+ return ", false, " + nodeType.ignoresSideEffects + ")";
}
}
}
@@ -721,7 +729,7 @@
// Define a TypeDescriptor for the generic node but don't enter it into the nodeTypes
// table since it shouldn't be mentioned in match rules.
TypeMirror valueTypeMirror = getTypeElement(VALUE_NODE_CLASS_NAME).asType();
- valueType = new TypeDescriptor(valueTypeMirror, "Value", "ValueNode", "org.graalvm.compiler.nodes", Collections.emptyList(), false, false);
+ valueType = new TypeDescriptor(valueTypeMirror, "Value", "ValueNode", "org.graalvm.compiler.nodes", Collections.emptyList(), false, false, false);
Map<TypeElement, MatchRuleDescriptor> map = new HashMap<>();
@@ -831,7 +839,8 @@
boolean commutative = getAnnotationValue(matchable, "commutative", Boolean.class);
boolean shareable = getAnnotationValue(matchable, "shareable", Boolean.class);
- declareType(nodeClassMirror, shortName, nodeClass, nodePackage, inputs, commutative, shareable, element);
+ boolean ignoresSideEffects = getAnnotationValue(matchable, "ignoresSideEffects", Boolean.class);
+ declareType(nodeClassMirror, shortName, nodeClass, nodePackage, inputs, commutative, shareable, ignoresSideEffects, element);
}
private void processMatchRules(Map<TypeElement, MatchRuleDescriptor> map, Element element, List<AnnotationMirror> matchRules) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java Thu Mar 28 19:39:14 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -32,6 +32,7 @@
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
@@ -266,9 +267,11 @@
verifiers.add(new VerifyVirtualizableUsage());
verifiers.add(new VerifyUpdateUsages());
verifiers.add(new VerifyBailoutUsage());
+ verifiers.add(new VerifySystemPropertyUsage());
verifiers.add(new VerifyInstanceOfUsage());
verifiers.add(new VerifyGraphAddUsage());
verifiers.add(new VerifyGetOptionsUsage());
+ verifiers.add(new VerifyUnsafeAccess());
VerifyFoldableMethods foldableMethodsVerifier = new VerifyFoldableMethods();
if (tool.shouldVerifyFoldableMethods()) {
@@ -301,21 +304,29 @@
String className = c.getName();
executor.execute(() -> {
try {
- checkClass(c, metaAccess);
+ checkClass(c, metaAccess, verifiers);
} catch (Throwable e) {
errors.add(String.format("Error while checking %s:%n%s", className, printStackTraceToString(e)));
}
});
- for (Method m : c.getDeclaredMethods()) {
- if (Modifier.isNative(m.getModifiers()) || Modifier.isAbstract(m.getModifiers())) {
+ ResolvedJavaType type = metaAccess.lookupJavaType(c);
+ List<ResolvedJavaMethod> methods = new ArrayList<>();
+ methods.addAll(Arrays.asList(type.getDeclaredMethods()));
+ methods.addAll(Arrays.asList(type.getDeclaredConstructors()));
+ ResolvedJavaMethod clinit = type.getClassInitializer();
+ if (clinit != null) {
+ methods.add(clinit);
+ }
+
+ for (ResolvedJavaMethod method : methods) {
+ if (Modifier.isNative(method.getModifiers()) || Modifier.isAbstract(method.getModifiers())) {
// ignore
} else {
- String methodName = className + "." + m.getName();
+ String methodName = className + "." + method.getName();
if (matches(filters, methodName)) {
executor.execute(() -> {
try (DebugContext debug = DebugContext.create(options, DebugHandlersFactory.LOADER)) {
- ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m);
boolean isSubstitution = method.getAnnotation(Snippet.class) != null || method.getAnnotation(MethodSubstitution.class) != null;
StructuredGraph graph = new StructuredGraph.Builder(options, debug).method(method).setIsSubstitution(isSubstitution).build();
try (DebugCloseable s = debug.disableIntercept(); DebugContext.Scope ds = debug.scope("CheckingGraph", graph, method)) {
@@ -400,14 +411,18 @@
/**
* @param metaAccess
+ * @param verifiers
*/
- private static void checkClass(Class<?> c, MetaAccessProvider metaAccess) {
+ private static void checkClass(Class<?> c, MetaAccessProvider metaAccess, List<VerifyPhase<PhaseContext>> verifiers) {
if (Node.class.isAssignableFrom(c)) {
if (c.getAnnotation(NodeInfo.class) == null) {
throw new AssertionError(String.format("Node subclass %s requires %s annotation", c.getName(), NodeClass.class.getSimpleName()));
}
VerifyNodeCosts.verifyNodeClass(c);
}
+ for (VerifyPhase<PhaseContext> verifier : verifiers) {
+ verifier.verifyClass(c, metaAccess);
+ }
}
private static void checkMethod(ResolvedJavaMethod method) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/FinalizableSubclassTest.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/FinalizableSubclassTest.java Thu Mar 28 19:39:14 2019 +0100
@@ -77,8 +77,7 @@
StructuredGraph graph = new StructuredGraph.Builder(options, getDebugContext(options, null, javaMethod), allowAssumptions).method(javaMethod).build();
GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(getDefaultGraphBuilderPlugins());
- new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), getProviders().getConstantReflection(), getProviders().getConstantFieldProvider(), conf,
- OptimisticOptimizations.ALL, null).apply(graph);
+ new GraphBuilderPhase.Instance(getProviders(), conf, OptimisticOptimizations.ALL, null).apply(graph);
HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
createInliningPhase().apply(graph, context);
new CanonicalizerPhase().apply(graph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/NewInstanceTest.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/NewInstanceTest.java Thu Mar 28 19:39:14 2019 +0100
@@ -76,8 +76,7 @@
StructuredGraph graph = new StructuredGraph.Builder(options, getDebugContext(options, null, javaMethod), AllowAssumptions.YES).method(javaMethod).build();
GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(getDefaultGraphBuilderPlugins()).withUnresolvedIsError(false);
- new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), getProviders().getConstantReflection(), getProviders().getConstantFieldProvider(), conf,
- OptimisticOptimizations.ALL, null).apply(graph);
+ new GraphBuilderPhase.Instance(getProviders(), conf, OptimisticOptimizations.ALL, null).apply(graph);
return graph;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SwitchTest.java Thu Mar 28 19:39:14 2019 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.core.test;
+
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import org.junit.Test;
+
+// Regression test for JDK-8220643 (GR-14583)
+public class SwitchTest extends GraalCompilerTest {
+ public static boolean test1(int arg) {
+ switch (arg) {
+ case -2139290527:
+ case -1466249004:
+ case -1063407861:
+ case 125135499:
+ case 425995464:
+ case 786490581:
+ case 1180611932:
+ case 1790655921:
+ case 1970660086:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ @Test
+ public void run1() throws Throwable {
+ ResolvedJavaMethod method = getResolvedJavaMethod("test1");
+ Result compiled = executeActual(method, null, -2139290527);
+ assertEquals(new Result(true, null), compiled);
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnbalancedMonitorsTest.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnbalancedMonitorsTest.java Thu Mar 28 19:39:14 2019 +0100
@@ -94,7 +94,7 @@
GraphBuilderConfiguration graphBuilderConfig = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true).withUnresolvedIsError(true);
OptimisticOptimizations optimisticOpts = OptimisticOptimizations.NONE;
- GraphBuilderPhase.Instance graphBuilder = new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), null, null, graphBuilderConfig, optimisticOpts, null);
+ GraphBuilderPhase.Instance graphBuilder = new GraphBuilderPhase.Instance(getProviders(), graphBuilderConfig, optimisticOpts, null);
graphBuilder.apply(graph);
} catch (BailoutException e) {
if (e.getMessage().contains("unbalanced monitors")) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyBailoutUsage.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyBailoutUsage.java Thu Mar 28 19:39:14 2019 +0100
@@ -73,7 +73,7 @@
}
@Override
- protected boolean verify(StructuredGraph graph, PhaseContext context) {
+ protected void verify(StructuredGraph graph, PhaseContext context) {
final ResolvedJavaType bailoutType = context.getMetaAccess().lookupJavaType(BailoutException.class);
ResolvedJavaMethod caller = graph.method();
String holderQualified = caller.format("%H");
@@ -92,7 +92,6 @@
}
}
}
- return true;
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyCallerSensitiveMethods.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyCallerSensitiveMethods.java Thu Mar 28 19:39:14 2019 +0100
@@ -67,7 +67,7 @@
}
@Override
- protected boolean verify(StructuredGraph graph, PhaseContext context) {
+ protected void verify(StructuredGraph graph, PhaseContext context) {
Invoke invoke = callsReflectionGetCallerClass(graph, context);
Annotation annotation = graph.method().getAnnotation(callerSensitiveClass);
if (invoke != null) {
@@ -79,7 +79,6 @@
} else if (annotation != null) {
throw new VerificationError(String.format("%s: method annotated with @CallerSensitive does not call Reflection.getCallerClass()", graph.method().format("%H.%n(%p)")));
}
- return true;
}
private Invoke callsReflectionGetCallerClass(StructuredGraph graph, PhaseContext context) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyDebugUsage.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyDebugUsage.java Thu Mar 28 19:39:14 2019 +0100
@@ -78,7 +78,7 @@
MetaAccessProvider metaAccess;
@Override
- protected boolean verify(StructuredGraph graph, PhaseContext context) {
+ protected void verify(StructuredGraph graph, PhaseContext context) {
metaAccess = context.getMetaAccess();
ResolvedJavaType debugType = metaAccess.lookupJavaType(DebugContext.class);
ResolvedJavaType nodeType = metaAccess.lookupJavaType(Node.class);
@@ -108,7 +108,6 @@
}
}
}
- return true;
}
private void verifyParameters(MethodCallTargetNode callTarget, StructuredGraph callerGraph, NodeInputList<? extends ValueNode> args, ResolvedJavaType stringType, int startArgIdx) {
@@ -167,6 +166,7 @@
"org.graalvm.compiler.phases.BasePhase.dumpAfter",
"org.graalvm.compiler.replacements.ReplacementsImpl$GraphMaker.makeGraph",
"org.graalvm.compiler.replacements.SnippetTemplate.instantiate",
+ "org.graalvm.compiler.replacements.SnippetTemplate.<init>",
"org.graalvm.compiler.hotspot.SymbolicSnippetEncoder.verifySnippetEncodeDecode"));
private void verifyParameters(StructuredGraph callerGraph, MethodCallTargetNode debugCallTarget, List<? extends ValueNode> args, ResolvedJavaType stringType, int startArgIdx,
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyFoldableMethods.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyFoldableMethods.java Thu Mar 28 19:39:14 2019 +0100
@@ -52,7 +52,7 @@
ResolvedJavaType generatedInvocationPluginType;
@Override
- protected boolean verify(StructuredGraph graph, PhaseContext context) {
+ protected void verify(StructuredGraph graph, PhaseContext context) {
ResolvedJavaMethod method = graph.method();
if (method.getAnnotation(Fold.class) != null) {
foldables.putIfAbsent(method, false);
@@ -69,7 +69,6 @@
}
}
}
- return true;
}
public void finish() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyGetOptionsUsage.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyGetOptionsUsage.java Thu Mar 28 19:39:14 2019 +0100
@@ -36,6 +36,7 @@
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaMethod.Parameter;
import jdk.vm.ci.meta.ResolvedJavaType;
/**
@@ -55,15 +56,19 @@
}
@Override
- protected boolean verify(StructuredGraph graph, PhaseContext context) {
+ protected void verify(StructuredGraph graph, PhaseContext context) {
MetaAccessProvider metaAccess = context.getMetaAccess();
ResolvedJavaType canonicalizerToolClass = metaAccess.lookupJavaType(CanonicalizerTool.class);
boolean hasTool = false;
+ ResolvedJavaMethod method = graph.method();
try {
- for (ResolvedJavaMethod.Parameter parameter : graph.method().getParameters()) {
- if (parameter.getType().getName().equals(canonicalizerToolClass.getName())) {
- hasTool = true;
- break;
+ Parameter[] parameters = method.getParameters();
+ if (parameters != null) {
+ for (ResolvedJavaMethod.Parameter parameter : parameters) {
+ if (parameter.getType().getName().equals(canonicalizerToolClass.getName())) {
+ hasTool = true;
+ break;
+ }
}
}
} catch (MalformedParametersException e) {
@@ -76,13 +81,11 @@
if (callee.equals(getOptionsMethod)) {
if (hasTool) {
throw new VerificationError("Must use CanonicalizerTool.getOptions() instead of Node.getOptions() in method '%s' of class '%s'.",
- graph.method().getName(), graph.method().getDeclaringClass().getName());
+ method.getName(), method.getDeclaringClass().getName());
}
}
}
}
-
- return true;
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyGraphAddUsage.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyGraphAddUsage.java Thu Mar 28 19:39:14 2019 +0100
@@ -66,7 +66,7 @@
}
@Override
- protected boolean verify(StructuredGraph graph, PhaseContext context) {
+ protected void verify(StructuredGraph graph, PhaseContext context) {
boolean allowed = false;
for (Class<?> cls : ALLOWED_CLASSES) {
ResolvedJavaType declaringClass = graph.method().getDeclaringClass();
@@ -85,8 +85,6 @@
}
}
}
-
- return true;
}
private void checkNonFactory(StructuredGraph graph, EconomicSet<Node> seen, PhaseContext context, ValueNode node) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyInstanceOfUsage.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyInstanceOfUsage.java Thu Mar 28 19:39:14 2019 +0100
@@ -53,7 +53,7 @@
}
@Override
- protected boolean verify(StructuredGraph graph, PhaseContext context) {
+ protected void verify(StructuredGraph graph, PhaseContext context) {
final ResolvedJavaType[] bailoutType = new ResolvedJavaType[FORBIDDEN_INSTANCE_OF_CHECKS.length];
for (int i = 0; i < FORBIDDEN_INSTANCE_OF_CHECKS.length; i++) {
bailoutType[i] = context.getMetaAccess().lookupJavaType(FORBIDDEN_INSTANCE_OF_CHECKS[i]);
@@ -77,7 +77,6 @@
}
}
}
- return true;
}
private static boolean isTrustedInterface(ResolvedJavaType declaringClass, MetaAccessProvider metaAccess) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifySystemPropertyUsage.java Thu Mar 28 19:39:14 2019 +0100
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.core.test;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+import org.graalvm.compiler.phases.VerifyPhase;
+import org.graalvm.compiler.phases.tiers.PhaseContext;
+
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.services.Services;
+
+/**
+ * Checks against calls to {@link System#getProperty(String)},
+ * {@link System#getProperty(String, String)} and {@link System#getProperties()}. System properties
+ * can be modified by application code so {@link Services#getSavedProperties()} should be used
+ * instead.
+ */
+public class VerifySystemPropertyUsage extends VerifyPhase<PhaseContext> {
+
+ static final Class<?>[] BOXES = {Integer.class, Long.class, Boolean.class, Float.class, Double.class};
+ static final int JVMCI_VERSION_MAJOR;
+ static final int JVMCI_VERSION_MINOR;
+ static {
+ int major = -1;
+ int minor = -1;
+ String vmVersion = System.getProperty("java.vm.version");
+ if (System.getProperty("java.specification.version").compareTo("1.9") < 0) {
+ Pattern re = Pattern.compile(".*-jvmci-(\\d+)\\.(\\d+).*");
+ Matcher matcher = re.matcher(vmVersion);
+ if (matcher.matches()) {
+ major = Integer.parseInt(matcher.group(1));
+ minor = Integer.parseInt(matcher.group(2));
+ }
+ }
+ JVMCI_VERSION_MAJOR = major;
+ JVMCI_VERSION_MINOR = minor;
+ }
+
+ @Override
+ protected void verify(StructuredGraph graph, PhaseContext context) {
+ MetaAccessProvider metaAccess = context.getMetaAccess();
+ final ResolvedJavaType systemType = metaAccess.lookupJavaType(System.class);
+ final ResolvedJavaType[] boxTypes = new ResolvedJavaType[BOXES.length];
+ for (int i = 0; i < boxTypes.length; i++) {
+ boxTypes[i] = metaAccess.lookupJavaType(BOXES[i]);
+ }
+
+ ResolvedJavaMethod caller = graph.method();
+ String holderQualified = caller.format("%H");
+ String holderUnqualified = caller.format("%h");
+ String packageName = holderQualified.equals(holderUnqualified) ? "" : holderQualified.substring(0, holderQualified.length() - holderUnqualified.length() - 1);
+ if (packageName.startsWith("jdk.vm.ci")) {
+ if (JVMCI_VERSION_MAJOR >= 0 && JVMCI_VERSION_MINOR > 56) {
+ // This JVMCI version should not use non-saved system properties
+ } else {
+ // This JVMCI version still has some calls that need to be removed
+ return;
+ }
+ } else if (holderQualified.equals("org.graalvm.compiler.hotspot.JVMCIVersionCheck") && caller.getName().equals("main")) {
+ // The main method in JVMCIVersionCheck is only called from the shell
+ return;
+ } else if (packageName.startsWith("com.oracle.truffle") || packageName.startsWith("org.graalvm.polyglot")) {
+ // Truffle and Polyglot do not depend on JVMCI so cannot use
+ // Services.getSavedProperties()
+ return;
+ } else if (packageName.startsWith("com.oracle.svm")) {
+ // SVM must read system properties in:
+ // * its JDK substitutions to mimic required JDK semantics
+ // * native-image for config info
+ return;
+ }
+ for (MethodCallTargetNode t : graph.getNodes(MethodCallTargetNode.TYPE)) {
+ ResolvedJavaMethod callee = t.targetMethod();
+ if (callee.getDeclaringClass().equals(systemType)) {
+ if (callee.getName().equals("getProperty") || callee.getName().equals("getProperties")) {
+ throw new VerificationError("Call to %s at callsite %s is prohibited. Call Services.getSavedProperties().get(String) instead.",
+ callee.format("%H.%n(%p)"),
+ caller.format("%H.%n(%p)"));
+ }
+ } else {
+ for (int i = 0; i < boxTypes.length; i++) {
+ ResolvedJavaType boxType = boxTypes[i];
+ if (callee.getDeclaringClass().equals(boxType)) {
+ String simpleName = boxType.toJavaName(false);
+ if (callee.getName().equals("get" + simpleName)) {
+ throw new VerificationError("Call to %s at callsite %s is prohibited. Call %s.parse%s(Services.getSavedProperties().get(String)) instead.",
+ callee.format("%H.%n(%p)"),
+ caller.format("%H.%n(%p)"),
+ simpleName, simpleName);
+ }
+ }
+ }
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyUnsafeAccess.java Thu Mar 28 19:39:14 2019 +0100
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.core.test;
+
+import static java.lang.reflect.Modifier.isProtected;
+import static java.lang.reflect.Modifier.isPublic;
+
+import java.lang.reflect.Field;
+
+import org.graalvm.compiler.core.common.type.TypeReference;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.java.InstanceOfNode;
+import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+import org.graalvm.compiler.phases.VerifyPhase;
+import org.graalvm.compiler.phases.tiers.PhaseContext;
+import org.graalvm.compiler.serviceprovider.GraalUnsafeAccess;
+
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import sun.misc.Unsafe;
+
+/**
+ * Checks that the {@link Unsafe} singleton instance is only accessed via well known classes such as
+ * {@link GraalUnsafeAccess}.
+ */
+public class VerifyUnsafeAccess extends VerifyPhase<PhaseContext> {
+
+ @Override
+ protected void verify(StructuredGraph graph, PhaseContext context) {
+ MetaAccessProvider metaAccess = context.getMetaAccess();
+ final ResolvedJavaType unsafeType = metaAccess.lookupJavaType(Unsafe.class);
+
+ ResolvedJavaMethod caller = graph.method();
+ String holderQualified = caller.format("%H");
+ String holderUnqualified = caller.format("%h");
+ String packageName = holderQualified.equals(holderUnqualified) ? "" : holderQualified.substring(0, holderQualified.length() - holderUnqualified.length() - 1);
+ if ((holderQualified.equals(GraalUnsafeAccess.class.getName()) ||
+ holderQualified.equals("jdk.vm.ci.hotspot.UnsafeAccess")) &&
+ caller.getName().equals("initUnsafe")) {
+ // This is the blessed way access Unsafe in Graal and JVMCI
+ return;
+ } else if (packageName.startsWith("com.oracle.truffle") || packageName.startsWith("org.graalvm.compiler.truffle.runtime")) {
+ // Truffle and GraalTruffleRuntime do not depend on Graal and so cannot use
+ // GraalUnsafeAccess
+ return;
+ }
+
+ if (caller.getSignature().getReturnType(caller.getDeclaringClass()).equals(unsafeType)) {
+ if (caller.isPublic()) {
+ if (holderQualified.equals(GraalUnsafeAccess.class.getName()) && caller.getName().equals("getUnsafe")) {
+ // pass
+ } else {
+ throw new VerificationError("Cannot leak Unsafe from public method %s",
+ caller.format("%H.%n(%p)"));
+ }
+ }
+ }
+
+ for (InstanceOfNode node : graph.getNodes().filter(InstanceOfNode.class)) {
+ TypeReference typeRef = node.type();
+ if (typeRef != null) {
+ if (unsafeType.isAssignableFrom(typeRef.getType())) {
+ throw new VerificationError("Cast to %s in %s is prohibited as it implies accessing Unsafe.theUnsafe via reflection. Use %s.getUnsafe() instead.",
+ unsafeType.toJavaName(),
+ caller.format("%H.%n(%p)"),
+ GraalUnsafeAccess.class.getName());
+
+ }
+ }
+ }
+ for (MethodCallTargetNode t : graph.getNodes(MethodCallTargetNode.TYPE)) {
+ ResolvedJavaMethod callee = t.targetMethod();
+ if (callee.getDeclaringClass().equals(unsafeType)) {
+ if (callee.getName().equals("getUnsafe")) {
+ throw new VerificationError("Call to %s at callsite %s is prohibited. Use %s.getUnsafe() instead.",
+ callee.format("%H.%n(%p)"),
+ caller.format("%H.%n(%p)"),
+ GraalUnsafeAccess.class.getName());
+ }
+ }
+ }
+ }
+
+ @Override
+ public void verifyClass(Class<?> c, MetaAccessProvider metaAccess) {
+ for (Field field : c.getDeclaredFields()) {
+ int modifiers = field.getModifiers();
+ if (field.getType() == Unsafe.class && (isPublic(modifiers) || isProtected(modifiers))) {
+ throw new VerificationError("Field of type %s must be private or package-private: %s", Unsafe.class.getName(), field);
+ }
+ }
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyUpdateUsages.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyUpdateUsages.java Thu Mar 28 19:39:14 2019 +0100
@@ -56,9 +56,9 @@
}
@Override
- protected boolean verify(StructuredGraph graph, PhaseContext context) {
+ protected void verify(StructuredGraph graph, PhaseContext context) {
if (graph.method().isConstructor()) {
- return true;
+ return;
}
/*
* There are only two acceptable patterns for methods which update Node inputs, either a
@@ -78,35 +78,51 @@
} else if (storeField2 == null) {
storeField2 = store;
} else {
- return false;
+ throw new VerificationError("More than 2 stores to %s or %s fields found in %s",
+ Input.class.getSimpleName(),
+ OptionalInput.class.getSimpleName(),
+ graph.method().format("%H.%n(%p)"));
}
}
}
if (storeField1 == null) {
- return true;
+ return;
}
if (storeField2 == null) {
- // Single input field update so just check for updateUsages or updateUsagesInterface
- // call
- ResolvedJavaType node = context.getMetaAccess().lookupJavaType(Node.class);
+ // Single input field update so just check for updateUsages
+ // or updateUsagesInterface call
+ ResolvedJavaType nodeType = context.getMetaAccess().lookupJavaType(Node.class);
for (MethodCallTargetNode call : graph.getNodes().filter(MethodCallTargetNode.class)) {
ResolvedJavaMethod callee = call.targetMethod();
- if (callee.getDeclaringClass().equals(node) && (callee.getName().equals("updateUsages") || callee.getName().equals("updateUsagesInterface"))) {
- return true;
+ if (callee.getDeclaringClass().equals(nodeType) && (callee.getName().equals("updateUsages") || callee.getName().equals("updateUsagesInterface"))) {
+ return;
}
}
+ throw new VerificationError("%s updates field '%s' without calling %s.updateUsages() or %s.updateUsagesInterface()",
+ graph.method().format("%H.%n(%p)"),
+ storeField1.field().getName(),
+ Node.class.getName(),
+ Node.class.getName());
} else {
if (storeField1.value() instanceof LoadFieldNode && storeField2.value() instanceof LoadFieldNode) {
LoadFieldNode load1 = (LoadFieldNode) storeField1.value();
LoadFieldNode load2 = (LoadFieldNode) storeField2.value();
// Check for swapping values within the same object
- if (load1.object() == storeField1.object() && load2.object() == storeField2.object() && storeField1.object() == storeField2.object() &&
- load1.field().equals(storeField2.field()) && load2.field().equals(storeField1.field())) {
- return true;
+ if (load1.object() == storeField1.object() &&
+ load2.object() == storeField2.object() &&
+ storeField1.object() == storeField2.object() &&
+ load1.field().equals(storeField2.field()) &&
+ load2.field().equals(storeField1.field())) {
+ return;
}
}
+ throw new VerificationError("%s performs non-swap update to fields '%s' and '%s' without calling %s.updateUsages() or %s.updateUsagesInterface()",
+ graph.method().format("%H.%n(%p)"),
+ storeField1.field().getName(),
+ storeField2.field().getName(),
+ Node.class.getName(),
+ Node.class.getName());
}
- return false;
}
boolean isNodeInput(ResolvedJavaField field, ResolvedJavaType declaringClass, ResolvedJavaType nodeInputList) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyUsageWithEquals.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyUsageWithEquals.java Thu Mar 28 19:39:14 2019 +0100
@@ -143,7 +143,7 @@
}
@Override
- protected boolean verify(StructuredGraph graph, PhaseContext context) {
+ protected void verify(StructuredGraph graph, PhaseContext context) {
for (ObjectEqualsNode cn : graph.getNodes().filter(ObjectEqualsNode.class)) {
// bail out if we compare an object of type klass with == or != (except null checks)
ResolvedJavaMethod method = graph.method();
@@ -156,6 +156,5 @@
" must use .equals() for object equality, not '==' or '!='");
}
}
- return true;
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyVirtualizableUsage.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyVirtualizableUsage.java Thu Mar 28 19:39:14 2019 +0100
@@ -53,7 +53,7 @@
}
@Override
- protected boolean verify(StructuredGraph graph, PhaseContext context) {
+ protected void verify(StructuredGraph graph, PhaseContext context) {
final ResolvedJavaType graphType = context.getMetaAccess().lookupJavaType(Graph.class);
final ResolvedJavaType virtualizableType = context.getMetaAccess().lookupJavaType(Virtualizable.class);
final ResolvedJavaType constantNodeType = context.getMetaAccess().lookupJavaType(ConstantNode.class);
@@ -70,7 +70,6 @@
}
}
}
- return true;
}
private static void verifyVirtualizableEffectArguments(ResolvedJavaType constantNodeType, ResolvedJavaMethod caller, ResolvedJavaMethod callee, int bciCaller,
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EATestBase.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EATestBase.java Thu Mar 28 19:39:14 2019 +0100
@@ -152,13 +152,17 @@
Assert.assertEquals(expectedConstantResult, returnNode.result().asConstant());
}
}
- int newInstanceCount = graph.getNodes().filter(isA(NewInstanceNode.class).or(NewArrayNode.class).or(AllocatedObjectNode.class)).count();
+ int newInstanceCount = getAllocationCount();
Assert.assertEquals("Expected allocation count does not match", expectedAllocationCount, newInstanceCount);
if (expectedAllocationCount == 0) {
Assert.assertTrue("Unexpected CommitAllocationNode", graph.getNodes().filter(CommitAllocationNode.class).isEmpty());
}
}
+ protected int getAllocationCount() {
+ return graph.getNodes().filter(isA(NewInstanceNode.class).or(NewArrayNode.class).or(AllocatedObjectNode.class)).count();
+ }
+
@SuppressWarnings("try")
protected void prepareGraph(String snippet, boolean iterativeEscapeAnalysis) {
ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/StaticAnalysis.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/StaticAnalysis.java Thu Mar 28 19:39:14 2019 +0100
@@ -34,8 +34,8 @@
import java.util.Map;
import java.util.Set;
+import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugHandlersFactory;
-import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeMap;
@@ -58,7 +58,7 @@
import org.graalvm.compiler.nodes.java.NewArrayNode;
import org.graalvm.compiler.nodes.java.NewInstanceNode;
import org.graalvm.compiler.nodes.java.StoreFieldNode;
-import org.graalvm.compiler.nodes.spi.StampProvider;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
import org.graalvm.compiler.nodes.util.GraphUtil;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.OptimisticOptimizations;
@@ -66,7 +66,6 @@
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
@@ -89,18 +88,21 @@
* {@link MethodState#formalReturn return value}.
*/
public class StaticAnalysis {
- /** Access to type, method, and fields using the Graal API. */
- private final MetaAccessProvider metaAccess;
- /** Access to platform dependent stamps. */
- private final StampProvider stampProvider;
- /** The results of the static analysis. */
+ /**
+ * Access to various builtin providers.
+ */
+ private final CoreProviders providers;
+ /**
+ * The results of the static analysis.
+ */
private final Results results;
- /** Worklist for fixpoint iteration. */
+ /**
+ * Worklist for fixpoint iteration.
+ */
private final Deque<WorklistEntry> worklist;
- public StaticAnalysis(MetaAccessProvider metaAccess, StampProvider stampProvider) {
- this.metaAccess = metaAccess;
- this.stampProvider = stampProvider;
+ public StaticAnalysis(CoreProviders providers) {
+ this.providers = providers;
this.results = new Results();
this.worklist = new ArrayDeque<>();
}
@@ -273,7 +275,7 @@
*/
OptimisticOptimizations optimisticOpts = OptimisticOptimizations.NONE;
- GraphBuilderPhase.Instance graphBuilder = new GraphBuilderPhase.Instance(metaAccess, stampProvider, null, null, graphBuilderConfig, optimisticOpts, null);
+ GraphBuilderPhase.Instance graphBuilder = new GraphBuilderPhase.Instance(providers, graphBuilderConfig, optimisticOpts, null);
graphBuilder.apply(graph);
} catch (Throwable ex) {
debug.handle(ex);
@@ -304,7 +306,9 @@
uses = new HashSet<>();
}
- /** Returns the types of this element. */
+ /**
+ * Returns the types of this element.
+ */
public Set<ResolvedJavaType> getTypes() {
return types;
}
@@ -349,7 +353,7 @@
* Adding a new callee means linking the type flow of the actual parameters with the formal
* parameters of the callee, and linking the return value of the callee with the return value
* state of the invocation.
- *
+ * <p>
* Statically bindable methods calls ({@link InvokeKind#Static static} and
* {@link InvokeKind#Special special} calls) have only one callee, but use the same code for
* simplicity.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/StaticAnalysisTests.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/StaticAnalysisTests.java Thu Mar 28 19:39:14 2019 +0100
@@ -29,21 +29,18 @@
import java.util.Arrays;
import java.util.Collection;
-import jdk.vm.ci.meta.MetaAccessProvider;
-import jdk.vm.ci.meta.ResolvedJavaField;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.vm.ci.meta.ResolvedJavaType;
-
-import org.junit.Assert;
-import org.junit.Test;
-
import org.graalvm.compiler.api.test.Graal;
import org.graalvm.compiler.core.target.Backend;
import org.graalvm.compiler.core.test.tutorial.StaticAnalysis.MethodState;
import org.graalvm.compiler.core.test.tutorial.StaticAnalysis.TypeFlow;
-import org.graalvm.compiler.nodes.spi.StampProvider;
-import org.graalvm.compiler.phases.util.Providers;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
import org.graalvm.compiler.runtime.RuntimeProvider;
+import org.junit.Assert;
+import org.junit.Test;
+
+import jdk.vm.ci.meta.ResolvedJavaField;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
public class StaticAnalysisTests {
@@ -68,14 +65,11 @@
Object f;
}
- private final MetaAccessProvider metaAccess;
- private final StampProvider stampProvider;
+ private final CoreProviders providers;
public StaticAnalysisTests() {
Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend();
- Providers providers = backend.getProviders();
- this.metaAccess = providers.getMetaAccess();
- this.stampProvider = providers.getStampProvider();
+ providers = backend.getProviders();
}
static void test01Entry() {
@@ -85,7 +79,7 @@
@Test
public void test01() {
- StaticAnalysis sa = new StaticAnalysis(metaAccess, stampProvider);
+ StaticAnalysis sa = new StaticAnalysis(providers);
sa.addMethod(findMethod(StaticAnalysisTests.class, "test01Entry"));
sa.finish();
@@ -106,7 +100,7 @@
@Test
public void test02() {
- StaticAnalysis sa = new StaticAnalysis(metaAccess, stampProvider);
+ StaticAnalysis sa = new StaticAnalysis(providers);
sa.addMethod(findMethod(StaticAnalysisTests.class, "test02Entry"));
sa.finish();
@@ -134,7 +128,7 @@
@Test
public void test03() {
- StaticAnalysis sa = new StaticAnalysis(metaAccess, stampProvider);
+ StaticAnalysis sa = new StaticAnalysis(providers);
sa.addMethod(findMethod(StaticAnalysisTests.class, "test03Entry"));
sa.finish();
@@ -165,7 +159,7 @@
@Test
public void test04() {
- StaticAnalysis sa = new StaticAnalysis(metaAccess, stampProvider);
+ StaticAnalysis sa = new StaticAnalysis(providers);
sa.addMethod(findMethod(StaticAnalysisTests.class, "test04Entry"));
sa.finish();
@@ -192,7 +186,7 @@
}
private ResolvedJavaType t(Class<?> clazz) {
- return metaAccess.lookupJavaType(clazz);
+ return providers.getMetaAccess().lookupJavaType(clazz);
}
private ResolvedJavaMethod findMethod(Class<?> declaringClass, String name) {
@@ -204,7 +198,7 @@
}
}
assert reflectionMethod != null : "No method with name " + name + " in class " + declaringClass.getName();
- return metaAccess.lookupJavaMethod(reflectionMethod);
+ return providers.getMetaAccess().lookupJavaMethod(reflectionMethod);
}
private ResolvedJavaField findField(Class<?> declaringClass, String name) {
@@ -214,6 +208,6 @@
} catch (NoSuchFieldException | SecurityException ex) {
throw new AssertionError(ex);
}
- return metaAccess.lookupJavaField(reflectionField);
+ return providers.getMetaAccess().lookupJavaField(reflectionField);
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/LIRGenerationPhase.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/LIRGenerationPhase.java Thu Mar 28 19:39:14 2019 +0100
@@ -67,7 +67,11 @@
NodeLIRBuilderTool nodeLirBuilder = context.nodeLirBuilder;
StructuredGraph graph = context.graph;
ScheduleResult schedule = context.schedule;
- for (AbstractBlockBase<?> b : lirGenRes.getLIR().getControlFlowGraph().getBlocks()) {
+ AbstractBlockBase<?>[] blocks = lirGenRes.getLIR().getControlFlowGraph().getBlocks();
+ for (AbstractBlockBase<?> b : blocks) {
+ matchBlock(nodeLirBuilder, (Block) b, graph, schedule);
+ }
+ for (AbstractBlockBase<?> b : blocks) {
emitBlock(nodeLirBuilder, lirGenRes, (Block) b, graph, schedule.getBlockToNodesMap());
}
context.lirGen.beforeRegisterAllocation();
@@ -84,6 +88,10 @@
instructionCounter.add(debug, lir.getLIRforBlock(b).size());
}
+ private static void matchBlock(NodeLIRBuilderTool nodeLirGen, Block b, StructuredGraph graph, ScheduleResult schedule) {
+ nodeLirGen.matchBlock(b, graph, schedule);
+ }
+
private static boolean verifyPredecessors(LIRGenerationResult lirGenRes, Block block) {
for (Block pred : block.getPredecessors()) {
if (!block.isLoopHeader() || !pred.isLoopEnd()) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java Thu Mar 28 19:39:14 2019 +0100
@@ -48,6 +48,7 @@
import org.graalvm.compiler.core.match.MatchPattern;
import org.graalvm.compiler.core.match.MatchRuleRegistry;
import org.graalvm.compiler.core.match.MatchStatement;
+import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.debug.TTY;
@@ -255,7 +256,7 @@
// get ValueKind for input
final LIRKind valueKind;
- if (value != null) {
+ if (value != null && !(value instanceof ComplexMatchValue)) {
valueKind = value.getValueKind(LIRKind.class);
} else {
assert isPhiInputFromBackedge(phi, i) : String.format("Input %s to phi node %s is not yet available although it is not coming from a loop back edge", node, phi);
@@ -358,10 +359,6 @@
List<Node> nodes = blockMap.get(block);
- // Allow NodeLIRBuilder subclass to specialize code generation of any interesting groups
- // of instructions
- matchComplexExpressions(nodes);
-
boolean trace = traceLIRGeneratorLevel >= 3;
for (int i = 0; i < nodes.size(); i++) {
Node node = nodes.get(i);
@@ -419,11 +416,23 @@
}
}
+ @Override
@SuppressWarnings("try")
- protected void matchComplexExpressions(List<Node> nodes) {
+ public void matchBlock(Block block, StructuredGraph graph, StructuredGraph.ScheduleResult schedule) {
+ try (DebugCloseable matchScope = gen.getMatchScope(block)) {
+ // Allow NodeLIRBuilder subclass to specialize code generation of any interesting groups
+ // of instructions
+ matchComplexExpressions(block, schedule);
+ }
+ }
+
+ @SuppressWarnings("try")
+ protected void matchComplexExpressions(Block block, StructuredGraph.ScheduleResult schedule) {
+
if (matchRules != null) {
DebugContext debug = gen.getResult().getLIR().getDebug();
try (DebugContext.Scope s = debug.scope("MatchComplexExpressions")) {
+ List<Node> nodes = schedule.getBlockToNodesMap().get(block);
if (LogVerbose.getValue(nodeOperands.graph().getOptions())) {
int i = 0;
for (Node node : nodes) {
@@ -441,7 +450,7 @@
List<MatchStatement> statements = matchRules.get(node.getClass());
if (statements != null) {
for (MatchStatement statement : statements) {
- if (statement.generate(this, index, node, nodes)) {
+ if (statement.generate(this, index, node, block, schedule)) {
// Found a match so skip to the next
break;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeMatchRules.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeMatchRules.java Thu Mar 28 19:39:14 2019 +0100
@@ -67,38 +67,38 @@
import jdk.vm.ci.meta.Value;
-@MatchableNode(nodeClass = ConstantNode.class, shareable = true)
-@MatchableNode(nodeClass = FloatConvertNode.class, inputs = {"value"})
+@MatchableNode(nodeClass = ConstantNode.class, shareable = true, ignoresSideEffects = true)
+@MatchableNode(nodeClass = FloatConvertNode.class, inputs = {"value"}, ignoresSideEffects = true)
@MatchableNode(nodeClass = FloatingReadNode.class, inputs = {"address"})
@MatchableNode(nodeClass = IfNode.class, inputs = {"condition"})
-@MatchableNode(nodeClass = SubNode.class, inputs = {"x", "y"})
-@MatchableNode(nodeClass = LeftShiftNode.class, inputs = {"x", "y"})
-@MatchableNode(nodeClass = NarrowNode.class, inputs = {"value"})
+@MatchableNode(nodeClass = SubNode.class, inputs = {"x", "y"}, ignoresSideEffects = true)
+@MatchableNode(nodeClass = LeftShiftNode.class, inputs = {"x", "y"}, ignoresSideEffects = true)
+@MatchableNode(nodeClass = NarrowNode.class, inputs = {"value"}, ignoresSideEffects = true)
@MatchableNode(nodeClass = ReadNode.class, inputs = {"address"})
-@MatchableNode(nodeClass = ReinterpretNode.class, inputs = {"value"})
-@MatchableNode(nodeClass = SignExtendNode.class, inputs = {"value"})
-@MatchableNode(nodeClass = UnsignedRightShiftNode.class, inputs = {"x", "y"})
+@MatchableNode(nodeClass = ReinterpretNode.class, inputs = {"value"}, ignoresSideEffects = true)
+@MatchableNode(nodeClass = SignExtendNode.class, inputs = {"value"}, ignoresSideEffects = true)
+@MatchableNode(nodeClass = UnsignedRightShiftNode.class, inputs = {"x", "y"}, ignoresSideEffects = true)
@MatchableNode(nodeClass = WriteNode.class, inputs = {"address", "value"})
-@MatchableNode(nodeClass = ZeroExtendNode.class, inputs = {"value"})
-@MatchableNode(nodeClass = AndNode.class, inputs = {"x", "y"}, commutative = true)
-@MatchableNode(nodeClass = NegateNode.class, inputs = {"value"})
-@MatchableNode(nodeClass = NotNode.class, inputs = {"value"})
-@MatchableNode(nodeClass = FloatEqualsNode.class, inputs = {"x", "y"}, commutative = true)
-@MatchableNode(nodeClass = FloatLessThanNode.class, inputs = {"x", "y"}, commutative = true)
-@MatchableNode(nodeClass = PointerEqualsNode.class, inputs = {"x", "y"}, commutative = true)
-@MatchableNode(nodeClass = AddNode.class, inputs = {"x", "y"}, commutative = true)
-@MatchableNode(nodeClass = IntegerBelowNode.class, inputs = {"x", "y"}, commutative = true)
-@MatchableNode(nodeClass = IntegerEqualsNode.class, inputs = {"x", "y"}, commutative = true)
-@MatchableNode(nodeClass = IntegerLessThanNode.class, inputs = {"x", "y"}, commutative = true)
-@MatchableNode(nodeClass = MulNode.class, inputs = {"x", "y"}, commutative = true)
-@MatchableNode(nodeClass = IntegerTestNode.class, inputs = {"x", "y"}, commutative = true)
-@MatchableNode(nodeClass = ObjectEqualsNode.class, inputs = {"x", "y"}, commutative = true)
-@MatchableNode(nodeClass = OrNode.class, inputs = {"x", "y"}, commutative = true)
-@MatchableNode(nodeClass = XorNode.class, inputs = {"x", "y"}, commutative = true)
-@MatchableNode(nodeClass = PiNode.class, inputs = {"object"})
+@MatchableNode(nodeClass = ZeroExtendNode.class, inputs = {"value"}, ignoresSideEffects = true)
+@MatchableNode(nodeClass = AndNode.class, inputs = {"x", "y"}, commutative = true, ignoresSideEffects = true)
+@MatchableNode(nodeClass = NegateNode.class, inputs = {"value"}, ignoresSideEffects = true)
+@MatchableNode(nodeClass = NotNode.class, inputs = {"value"}, ignoresSideEffects = true)
+@MatchableNode(nodeClass = FloatEqualsNode.class, inputs = {"x", "y"}, commutative = true, ignoresSideEffects = true)
+@MatchableNode(nodeClass = FloatLessThanNode.class, inputs = {"x", "y"}, commutative = true, ignoresSideEffects = true)
+@MatchableNode(nodeClass = PointerEqualsNode.class, inputs = {"x", "y"}, commutative = true, ignoresSideEffects = true)
+@MatchableNode(nodeClass = AddNode.class, inputs = {"x", "y"}, commutative = true, ignoresSideEffects = true)
+@MatchableNode(nodeClass = IntegerBelowNode.class, inputs = {"x", "y"}, commutative = true, ignoresSideEffects = true)
+@MatchableNode(nodeClass = IntegerEqualsNode.class, inputs = {"x", "y"}, commutative = true, ignoresSideEffects = true)
+@MatchableNode(nodeClass = IntegerLessThanNode.class, inputs = {"x", "y"}, commutative = true, ignoresSideEffects = true)
+@MatchableNode(nodeClass = MulNode.class, inputs = {"x", "y"}, commutative = true, ignoresSideEffects = true)
+@MatchableNode(nodeClass = IntegerTestNode.class, inputs = {"x", "y"}, commutative = true, ignoresSideEffects = true)
+@MatchableNode(nodeClass = ObjectEqualsNode.class, inputs = {"x", "y"}, commutative = true, ignoresSideEffects = true)
+@MatchableNode(nodeClass = OrNode.class, inputs = {"x", "y"}, commutative = true, ignoresSideEffects = true)
+@MatchableNode(nodeClass = XorNode.class, inputs = {"x", "y"}, commutative = true, ignoresSideEffects = true)
+@MatchableNode(nodeClass = PiNode.class, inputs = {"object"}, ignoresSideEffects = true)
@MatchableNode(nodeClass = LogicCompareAndSwapNode.class, inputs = {"address", "expectedValue", "newValue"})
@MatchableNode(nodeClass = ValueCompareAndSwapNode.class, inputs = {"address", "expectedValue", "newValue"})
-@MatchableNode(nodeClass = RightShiftNode.class, inputs = {"x", "y"})
+@MatchableNode(nodeClass = RightShiftNode.class, inputs = {"x", "y"}, ignoresSideEffects = true)
public abstract class NodeMatchRules {
NodeLIRBuilder lirBuilder;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/match/MatchContext.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/match/MatchContext.java Thu Mar 28 19:39:14 2019 +0100
@@ -24,40 +24,120 @@
package org.graalvm.compiler.core.match;
+import static org.graalvm.compiler.core.common.cfg.AbstractControlFlowGraph.dominates;
+import static org.graalvm.compiler.core.common.cfg.AbstractControlFlowGraph.strictlyDominates;
import static org.graalvm.compiler.debug.DebugOptions.LogVerbose;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Iterator;
import java.util.List;
import jdk.internal.vm.compiler.collections.EconomicMap;
import jdk.internal.vm.compiler.collections.Equivalence;
+import org.graalvm.compiler.core.common.cfg.BlockMap;
import org.graalvm.compiler.core.gen.NodeLIRBuilder;
import org.graalvm.compiler.core.match.MatchPattern.Result;
+import org.graalvm.compiler.debug.CounterKey;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.graph.NodeMap;
+import org.graalvm.compiler.nodes.PhiNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.calc.FloatingNode;
+import org.graalvm.compiler.nodes.cfg.Block;
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
/**
* Container for state captured during a match.
*/
public class MatchContext {
+ private static final CounterKey MatchContextSuccessDifferentBlocks = DebugContext.counter("MatchContextSuccessDifferentBlocks");
private final Node root;
- private final List<Node> nodes;
-
private final MatchStatement rule;
+ private final StructuredGraph.ScheduleResult schedule;
private EconomicMap<String, NamedNode> namedNodes;
- private ArrayList<Node> consumed;
+ /**
+ * A node consumed by a match. Keeps track of whether side effects can be ignored.
+ */
+ static final class ConsumedNode {
+ final Node node;
+ final boolean ignoresSideEffects;
+
+ ConsumedNode(Node node, boolean ignoresSideEffects) {
+ this.node = node;
+ this.ignoresSideEffects = ignoresSideEffects;
+ }
+ }
+
+ /**
+ * The collection of nodes consumed by this match.
+ */
+ static final class ConsumedNodes implements Iterable<ConsumedNode> {
+ private ArrayList<ConsumedNode> nodes;
+
+ ConsumedNodes() {
+ this.nodes = null;
+ }
+
+ public void add(Node node, boolean ignoresSideEffects) {
+ if (nodes == null) {
+ nodes = new ArrayList<>(2);
+ }
+ nodes.add(new ConsumedNode(node, ignoresSideEffects));
+ }
- private int startIndex;
+ public boolean contains(Node node) {
+ for (ConsumedNode c : nodes) {
+ if (c.node == node) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public ConsumedNode find(Node node) {
+ for (ConsumedNode c : nodes) {
+ if (c.node == node) {
+ return c;
+ }
+ }
+ return null;
+ }
- private int endIndex;
+ @Override
+ public String toString() {
+ Node[] arr = new Node[nodes.size()];
+ int i = 0;
+ for (ConsumedNode c : nodes) {
+ arr[i++] = c.node;
+ }
+ return Arrays.toString(arr);
+ }
+
+ @Override
+ public Iterator<ConsumedNode> iterator() {
+ return nodes.iterator();
+ }
+ }
+
+ private ConsumedNodes consumed = new ConsumedNodes();
+
+ private Block rootBlock;
+ private int rootIndex;
+
+ /**
+ * Block and index in the block at which the match should be emitted. Differs from
+ * rootBlock/rootIndex for (ZeroExtend Read=access) for instance: match should be emitted where
+ * the Read is.
+ */
+ private int emitIndex;
+ private Block emitBlock;
private final NodeLIRBuilder builder;
@@ -71,14 +151,15 @@
}
}
- public MatchContext(NodeLIRBuilder builder, MatchStatement rule, int index, Node node, List<Node> nodes) {
+ public MatchContext(NodeLIRBuilder builder, MatchStatement rule, int index, Node node, Block rootBlock, StructuredGraph.ScheduleResult schedule) {
this.builder = builder;
this.rule = rule;
this.root = node;
- this.nodes = nodes;
- assert index == nodes.indexOf(node);
+ assert index == schedule.getBlockToNodesMap().get(rootBlock).indexOf(node);
+ this.schedule = schedule;
// The root should be the last index since all the inputs must be scheduled before it.
- startIndex = endIndex = index;
+ this.rootBlock = rootBlock;
+ rootIndex = index;
}
public Node getRoot() {
@@ -103,28 +184,177 @@
}
public Result validate() {
- // Ensure that there's no unsafe work in between these operations.
- for (int i = startIndex; i <= endIndex; i++) {
+ Result result = findEarlyPosition();
+ if (result != Result.OK) {
+ return result;
+ }
+ findLatePosition();
+ assert emitIndex == rootIndex || consumed.find(root).ignoresSideEffects;
+ return verifyInputs();
+ }
+
+ private Result findEarlyPosition() {
+ int startIndexSideEffect = -1;
+ int endIndexSideEffect = -1;
+ final NodeMap<Block> nodeToBlockMap = schedule.getNodeToBlockMap();
+ final BlockMap<List<Node>> blockToNodesMap = schedule.getBlockToNodesMap();
+
+ // Nodes affected by side effects must be in the same block
+ for (ConsumedNode cn : consumed) {
+ if (!cn.ignoresSideEffects) {
+ Block b = nodeToBlockMap.get(cn.node);
+ if (emitBlock == null) {
+ emitBlock = b;
+ startIndexSideEffect = endIndexSideEffect = blockToNodesMap.get(b).indexOf(cn.node);
+ } else if (emitBlock == b) {
+ int index = blockToNodesMap.get(b).indexOf(cn.node);
+ startIndexSideEffect = Math.min(startIndexSideEffect, index);
+ endIndexSideEffect = Math.max(endIndexSideEffect, index);
+ } else {
+ logFailedMatch("nodes affected by side effects in different blocks %s", cn.node);
+ return Result.notInBlock(cn.node, rule.getPattern());
+ }
+ }
+ }
+ if (emitBlock != null) {
+ // There must be no side effects between nodes that are affected by side effects
+ assert startIndexSideEffect != -1 && endIndexSideEffect != -1;
+ final List<Node> nodes = blockToNodesMap.get(emitBlock);
+ for (int i = startIndexSideEffect; i <= endIndexSideEffect; i++) {
+ Node node = nodes.get(i);
+ if (!sideEffectFree(node) && !consumed.contains(node)) {
+ logFailedMatch("unexpected side effect %s", node);
+ return Result.notSafe(node, rule.getPattern());
+ }
+ }
+ // early position is at the node affected by side effects the closest to the root
+ emitIndex = endIndexSideEffect;
+ } else {
+ // Nodes not affected by side effect: early position is at the root
+ emitBlock = nodeToBlockMap.get(root);
+ emitIndex = rootIndex;
+ }
+ return Result.OK;
+ }
+
+ private static boolean sideEffectFree(Node node) {
+ // The order of evaluation of these nodes controlled by data dependence so they
+ // don't interfere with this match.
+ return node instanceof VirtualObjectNode || node instanceof FloatingNode;
+ }
+
+ private void findLatePosition() {
+ // If emit position is at a node affected by side effects that's followed by side effect
+ // free nodes, the node can be emitted later. This helps when the match has inputs that are
+ // late in the block.
+ int index = rootIndex;
+ if (emitBlock != rootBlock) {
+ index = schedule.getBlockToNodesMap().get(emitBlock).size() - 1;
+ }
+ final List<Node> emitBlockNodes = schedule.getBlockToNodesMap().get(emitBlock);
+ for (int i = emitIndex + 1; i <= index; i++) {
+ Node node = emitBlockNodes.get(i);
+ ConsumedNode cn = consumed.find(node);
+ if (cn == null) {
+ if (!sideEffectFree(node)) {
+ return;
+ }
+ } else {
+ assert cn.ignoresSideEffects;
+ emitIndex = i;
+ }
+ }
+ }
+
+ private Result verifyInputs() {
+ DebugContext debug = root.getDebug();
+ if (emitBlock != rootBlock) {
+ assert consumed.find(root).ignoresSideEffects;
+ Result result = verifyInputsDifferentBlock(root);
+ if (result == Result.OK) {
+ MatchContextSuccessDifferentBlocks.increment(debug);
+ }
+ return result;
+ }
+ // We are going to emit the match at emitIndex. We need to make sure nodes of the match
+ // between emitIndex and rootIndex don't have inputs after position emitIndex that would
+ // make emitIndex an illegal position.
+ final List<Node> nodes = schedule.getBlockToNodesMap().get(rootBlock);
+ for (int i = emitIndex + 1; i <= rootIndex; i++) {
Node node = nodes.get(i);
- if (node instanceof VirtualObjectNode || node instanceof FloatingNode) {
- // The order of evaluation of these nodes controlled by data dependence so they
- // don't interfere with this match.
- continue;
- } else if ((consumed == null || !consumed.contains(node)) && node != root) {
- if (LogVerbose.getValue(root.getOptions())) {
- DebugContext debug = root.getDebug();
- debug.log("unexpected node %s", node);
- for (int j = startIndex; j <= endIndex; j++) {
- Node theNode = nodes.get(j);
- debug.log("%s(%s) %1s", (consumed != null && consumed.contains(theNode) || theNode == root) ? "*" : " ", theNode.getUsageCount(), theNode);
+ ConsumedNode cn = consumed.find(node);
+ if (cn != null) {
+ assert cn.ignoresSideEffects;
+ for (Node in : node.inputs()) {
+ if (!consumed.contains(in)) {
+ for (int j = emitIndex + 1; j < i; j++) {
+ if (nodes.get(j) == in) {
+ logFailedMatch("Earliest position in block is too late %s", in);
+ assert consumed.find(root).ignoresSideEffects;
+ assert verifyInputsDifferentBlock(root) != Result.OK;
+ return Result.tooLate(node, rule.getPattern());
+ }
+ }
}
}
- return Result.notSafe(node, rule.getPattern());
+ }
+ }
+ assert verifyInputsDifferentBlock(root) == Result.OK;
+ return Result.OK;
+ }
+
+ private Result verifyInputsDifferentBlock(Node node) {
+ // Is there an input that's not part of the match that's after the emit position?
+ for (Node in : node.inputs()) {
+ if (in instanceof PhiNode) {
+ Block b = schedule.getNodeToBlockMap().get(((PhiNode) in).merge());
+ if (dominates(b, emitBlock)) {
+ continue;
+ }
+ } else {
+ Block b = schedule.getNodeToBlockMap().get(in);
+ if (strictlyDominates(b, emitBlock) || (b == emitBlock && schedule.getBlockToNodesMap().get(emitBlock).indexOf(in) <= emitIndex)) {
+ continue;
+ }
+ }
+ ConsumedNode cn = consumed.find(in);
+ if (cn == null) {
+ logFailedMatch("Earliest position in block is too late %s", in);
+ return Result.tooLate(node, rule.getPattern());
+ }
+ assert cn.ignoresSideEffects;
+ Result res = verifyInputsDifferentBlock(in);
+ if (res != Result.OK) {
+ return res;
}
}
return Result.OK;
}
+ private void logFailedMatch(String s, Node node) {
+ if (LogVerbose.getValue(root.getOptions())) {
+ DebugContext debug = root.getDebug();
+ debug.log(s, node);
+ int startIndex = emitIndex;
+ if (emitBlock != rootBlock) {
+ int endIndex = schedule.getBlockToNodesMap().get(emitBlock).size() - 1;
+ final List<Node> emitBlockNodes = schedule.getBlockToNodesMap().get(emitBlock);
+ debug.log("%s:", emitBlock);
+ for (int j = startIndex; j <= endIndex; j++) {
+ Node theNode = emitBlockNodes.get(j);
+ debug.log("%s(%s) %1s", consumed.contains(theNode) ? "*" : " ", theNode.getUsageCount(), theNode);
+ }
+ startIndex = 0;
+ }
+ debug.log("%s:", rootBlock);
+ final List<Node> nodes = schedule.getBlockToNodesMap().get(rootBlock);
+ for (int j = startIndex; j <= rootIndex; j++) {
+ Node theNode = nodes.get(j);
+ debug.log("%s(%s) %1s", consumed.contains(theNode) ? "*" : " ", theNode.getUsageCount(), theNode);
+ }
+ }
+ }
+
/**
* Mark the interior nodes with INTERIOR_MATCH and set the Value of the root to be the result.
* During final LIR generation it will be evaluated to produce the actual LIR value.
@@ -133,20 +363,28 @@
*/
public void setResult(ComplexMatchResult result) {
ComplexMatchValue value = new ComplexMatchValue(result);
+ Node emitNode = schedule.getBlockToNodesMap().get(emitBlock).get(emitIndex);
DebugContext debug = root.getDebug();
if (debug.isLogEnabled()) {
- debug.log("matched %s %s", rule.getName(), rule.getPattern());
+ debug.log("matched %s %s%s", rule.getName(), rule.getPattern(), emitIndex != rootIndex ? " skipping side effects" : "");
debug.log("with nodes %s", rule.formatMatch(root));
}
- if (consumed != null) {
- for (Node node : consumed) {
- // All the interior nodes should be skipped during the normal doRoot calls in
- // NodeLIRBuilder so mark them as interior matches. The root of the match will get a
- // closure which will be evaluated to produce the final LIR.
- builder.setMatchResult(node, ComplexMatchValue.INTERIOR_MATCH);
+ for (ConsumedNode cn : consumed) {
+ if (cn.node == root || cn.node == emitNode) {
+ continue;
}
+ // All the interior nodes should be skipped during the normal doRoot calls in
+ // NodeLIRBuilder so mark them as interior matches. The root of the match will get a
+ // closure which will be evaluated to produce the final LIR.
+ builder.setMatchResult(cn.node, ComplexMatchValue.INTERIOR_MATCH);
}
- builder.setMatchResult(root, value);
+ builder.setMatchResult(emitNode, value);
+ if (root != emitNode) {
+ // Match is not emitted at the position of root in the block but the uses of root needs
+ // the result of the match so add a ComplexMatchValue that will simply return the result
+ // of the actual match above.
+ builder.setMatchResult(root, new ComplexMatchValue(gen -> gen.operand(emitNode)));
+ }
}
/**
@@ -154,24 +392,18 @@
*
* @return Result.OK if the node can be safely consumed.
*/
- public Result consume(Node node) {
+ public Result consume(Node node, boolean ignoresSideEffects, boolean atRoot) {
+ if (atRoot) {
+ consumed.add(node, ignoresSideEffects);
+ return Result.OK;
+ }
assert MatchPattern.isSingleValueUser(node) : "should have already been checked";
- // Check NOT_IN_BLOCK first since that usually implies ALREADY_USED
- int index = nodes.indexOf(node);
- if (index == -1) {
- return Result.notInBlock(node, rule.getPattern());
- }
-
if (builder.hasOperand(node)) {
return Result.alreadyUsed(node, rule.getPattern());
}
- startIndex = Math.min(startIndex, index);
- if (consumed == null) {
- consumed = new ArrayList<>(2);
- }
- consumed.add(node);
+ consumed.add(node, ignoresSideEffects);
return Result.OK;
}
@@ -194,6 +426,6 @@
@Override
public String toString() {
- return String.format("%s %s (%d, %d) consumed %s", rule, root, startIndex, endIndex, consumed != null ? Arrays.toString(consumed.toArray()) : "");
+ return String.format("%s %s (%s/%d, %s/%d) consumed %s", rule, root, rootBlock, rootIndex, emitBlock, emitIndex, consumed);
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/match/MatchPattern.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/match/MatchPattern.java Thu Mar 28 19:39:14 2019 +0100
@@ -30,6 +30,7 @@
import org.graalvm.compiler.graph.Position;
import org.graalvm.compiler.nodeinfo.InputType;
import org.graalvm.compiler.nodeinfo.Verbosity;
+import org.graalvm.compiler.nodes.calc.FloatingNode;
/**
* A simple recursive pattern matcher for a DAG of nodes.
@@ -45,6 +46,7 @@
NOT_IN_BLOCK,
NOT_SAFE,
ALREADY_USED,
+ TOO_LATE,
}
/**
@@ -70,6 +72,7 @@
private static final CounterKey MatchResult_NOT_IN_BLOCK = DebugContext.counter("MatchResult_NOT_IN_BLOCK");
private static final CounterKey MatchResult_NOT_SAFE = DebugContext.counter("MatchResult_NOT_SAFE");
private static final CounterKey MatchResult_ALREADY_USED = DebugContext.counter("MatchResult_ALREADY_USED");
+ private static final CounterKey MatchResult_TOO_LATE = DebugContext.counter("MatchResult_TOO_LATE");
static final Result OK = new Result(MatchResultCode.OK, null, null);
private static final Result CACHED_WRONG_CLASS = new Result(MatchResultCode.WRONG_CLASS, null, null);
@@ -78,6 +81,7 @@
private static final Result CACHED_NOT_IN_BLOCK = new Result(MatchResultCode.NOT_IN_BLOCK, null, null);
private static final Result CACHED_NOT_SAFE = new Result(MatchResultCode.NOT_SAFE, null, null);
private static final Result CACHED_ALREADY_USED = new Result(MatchResultCode.ALREADY_USED, null, null);
+ private static final Result CACHED_TOO_LATE = new Result(MatchResultCode.TOO_LATE, null, null);
static Result wrongClass(Node node, MatchPattern matcher) {
MatchResult_WRONG_CLASS.increment(node.getDebug());
@@ -109,6 +113,11 @@
return node.getDebug().isLogEnabled() ? new Result(MatchResultCode.ALREADY_USED, node, matcher) : CACHED_ALREADY_USED;
}
+ static Result tooLate(Node node, MatchPattern matcher) {
+ MatchResult_TOO_LATE.increment(node.getDebug());
+ return node.getDebug().isLogEnabled() ? new Result(MatchResultCode.TOO_LATE, node, matcher) : CACHED_TOO_LATE;
+ }
+
@Override
public String toString() {
if (code == MatchResultCode.OK) {
@@ -149,39 +158,49 @@
*/
private final boolean singleUser;
+ /**
+ * Can this node be subsumed into a match even if there are side effecting nodes between this
+ * node and the match.
+ */
+ private final boolean ignoresSideEffects;
+
private static final MatchPattern[] EMPTY_PATTERNS = new MatchPattern[0];
- public MatchPattern(String name, boolean singleUser) {
- this(null, name, singleUser);
+ public MatchPattern(String name, boolean singleUser, boolean ignoresSideEffects) {
+ this(null, name, singleUser, ignoresSideEffects);
}
- public MatchPattern(Class<? extends Node> nodeClass, String name, boolean singleUser) {
+ public MatchPattern(Class<? extends Node> nodeClass, String name, boolean singleUser, boolean ignoresSideEffects) {
this.nodeClass = nodeClass;
this.name = name;
this.singleUser = singleUser;
+ this.ignoresSideEffects = ignoresSideEffects;
this.patterns = EMPTY_PATTERNS;
this.inputs = null;
+ assert !ignoresSideEffects || FloatingNode.class.isAssignableFrom(nodeClass);
}
- private MatchPattern(Class<? extends Node> nodeClass, String name, boolean singleUser, MatchPattern[] patterns, Position[] inputs) {
+ private MatchPattern(Class<? extends Node> nodeClass, String name, boolean singleUser, boolean ignoresSideEffects, MatchPattern[] patterns, Position[] inputs) {
assert inputs == null || inputs.length == patterns.length;
this.nodeClass = nodeClass;
this.name = name;
this.singleUser = singleUser;
+ this.ignoresSideEffects = ignoresSideEffects;
this.patterns = patterns;
this.inputs = inputs;
+ assert !ignoresSideEffects || FloatingNode.class.isAssignableFrom(nodeClass);
}
- public MatchPattern(Class<? extends Node> nodeClass, String name, MatchPattern first, Position[] inputs, boolean singleUser) {
- this(nodeClass, name, singleUser, new MatchPattern[]{first}, inputs);
+ public MatchPattern(Class<? extends Node> nodeClass, String name, MatchPattern first, Position[] inputs, boolean singleUser, boolean ignoresSideEffects) {
+ this(nodeClass, name, singleUser, ignoresSideEffects, new MatchPattern[]{first}, inputs);
}
- public MatchPattern(Class<? extends Node> nodeClass, String name, MatchPattern first, MatchPattern second, Position[] inputs, boolean singleUser) {
- this(nodeClass, name, singleUser, new MatchPattern[]{first, second}, inputs);
+ public MatchPattern(Class<? extends Node> nodeClass, String name, MatchPattern first, MatchPattern second, Position[] inputs, boolean singleUser, boolean ignoresSideEffects) {
+ this(nodeClass, name, singleUser, ignoresSideEffects, new MatchPattern[]{first, second}, inputs);
}
- public MatchPattern(Class<? extends Node> nodeClass, String name, MatchPattern first, MatchPattern second, MatchPattern third, Position[] inputs, boolean singleUser) {
- this(nodeClass, name, singleUser, new MatchPattern[]{first, second, third}, inputs);
+ public MatchPattern(Class<? extends Node> nodeClass, String name, MatchPattern first, MatchPattern second, MatchPattern third, Position[] inputs, boolean singleUser, boolean ignoresSideEffects) {
+ this(nodeClass, name, singleUser, ignoresSideEffects, new MatchPattern[]{first, second, third}, inputs);
}
Class<? extends Node> nodeClass() {
@@ -215,8 +234,8 @@
if (result != Result.OK) {
return result;
}
- if (singleUser && !atRoot) {
- result = context.consume(node);
+ if (singleUser) {
+ result = context.consume(node, ignoresSideEffects, atRoot);
if (result != Result.OK) {
return result;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/match/MatchStatement.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/match/MatchStatement.java Thu Mar 28 19:39:14 2019 +0100
@@ -26,8 +26,6 @@
import static org.graalvm.compiler.debug.DebugOptions.LogVerbose;
-import java.util.List;
-
import org.graalvm.compiler.core.gen.NodeLIRBuilder;
import org.graalvm.compiler.core.match.MatchPattern.MatchResultCode;
import org.graalvm.compiler.core.match.MatchPattern.Result;
@@ -38,6 +36,8 @@
import org.graalvm.compiler.nodeinfo.Verbosity;
import jdk.vm.ci.meta.Value;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.cfg.Block;
/**
* A named {@link MatchPattern} along with a {@link MatchGenerator} that can be evaluated to replace
@@ -80,20 +80,21 @@
*
* @param builder the current builder instance.
* @param node the node to be matched
- * @param nodes the nodes in the current block
+ * @param block the current block
+ * @param schedule the schedule that's being used
* @return true if the statement matched something and set a {@link ComplexMatchResult} to be
* evaluated by the NodeLIRBuilder.
*/
- public boolean generate(NodeLIRBuilder builder, int index, Node node, List<Node> nodes) {
+ public boolean generate(NodeLIRBuilder builder, int index, Node node, Block block, StructuredGraph.ScheduleResult schedule) {
DebugContext debug = node.getDebug();
- assert index == nodes.indexOf(node);
+ assert index == schedule.getBlockToNodesMap().get(block).indexOf(node);
// Check that the basic shape matches
Result result = pattern.matchShape(node, this);
if (result != Result.OK) {
return false;
}
// Now ensure that the other safety constraints are matched.
- MatchContext context = new MatchContext(builder, this, index, node, nodes);
+ MatchContext context = new MatchContext(builder, this, index, node, block, schedule);
result = pattern.matchUsage(node, context);
if (result == Result.OK) {
// Invoke the generator method and set the result if it's non null.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/match/MatchableNode.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/match/MatchableNode.java Thu Mar 28 19:39:14 2019 +0100
@@ -64,4 +64,6 @@
* Can a node with multiple uses be safely matched by a rule.
*/
boolean shareable() default false;
+
+ boolean ignoresSideEffects() default false;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java Thu Mar 28 19:39:14 2019 +0100
@@ -239,15 +239,9 @@
this.unscopedTimers = parseUnscopedMetricSpec(Timers.getValue(options), "".equals(timeValue), true);
this.unscopedMemUseTrackers = parseUnscopedMetricSpec(MemUseTrackers.getValue(options), "".equals(trackMemUseValue), true);
- if (unscopedTimers != null || timeValue != null) {
- if (!GraalServices.isCurrentThreadCpuTimeSupported()) {
- throw new IllegalArgumentException("Time and Timers options require VM support for querying CPU time");
- }
- }
-
if (unscopedMemUseTrackers != null || trackMemUseValue != null) {
if (!GraalServices.isThreadAllocatedMemorySupported()) {
- throw new IllegalArgumentException("MemUseTrackers and TrackMemUse options require VM support for querying thread allocated memory");
+ TTY.println("WARNING: Missing VM support for MemUseTrackers and TrackMemUse options so all reported memory usage will be 0");
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/LogStream.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/LogStream.java Thu Mar 28 19:39:14 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -87,7 +87,7 @@
/**
* The system dependent line separator.
*/
- public static final String LINE_SEPARATOR = System.getProperty("line.separator");
+ public static final String LINE_SEPARATOR = System.lineSeparator();
/**
* Creates a new log stream.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/MemUseTrackerKey.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/MemUseTrackerKey.java Thu Mar 28 19:39:14 2019 +0100
@@ -56,6 +56,6 @@
MemUseTrackerKey doc(String string);
static long getCurrentThreadAllocatedBytes() {
- return GraalServices.getCurrentThreadAllocatedBytes();
+ return GraalServices.isThreadAllocatedMemorySupported() ? GraalServices.getCurrentThreadAllocatedBytes() : 0;
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/Versions.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/Versions.java Thu Mar 28 19:39:14 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -32,11 +32,13 @@
import java.util.HashMap;
import java.util.Map;
+import jdk.vm.ci.services.Services;
+
/** Avoid using directly. Only public for the needs of unit testing. */
public final class Versions {
static final Versions VERSIONS;
static {
- String home = System.getProperty("java.home");
+ String home = Services.getSavedProperties().get("java.home");
VERSIONS = new Versions(home == null ? null : new File(home).toPath());
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Edges.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Edges.java Thu Mar 28 19:39:14 2019 +0100
@@ -26,7 +26,6 @@
import static org.graalvm.compiler.graph.Graph.isModificationCountsEnabled;
import static org.graalvm.compiler.graph.Node.NOT_ITERABLE;
-import static org.graalvm.compiler.graph.UnsafeAccess.UNSAFE;
import java.util.ArrayList;
import java.util.Iterator;
@@ -34,6 +33,9 @@
import org.graalvm.compiler.core.common.Fields;
import org.graalvm.compiler.core.common.FieldsScanner;
import org.graalvm.compiler.graph.NodeClass.EdgeInfo;
+import org.graalvm.compiler.serviceprovider.GraalUnsafeAccess;
+
+import sun.misc.Unsafe;
/**
* Describes {@link Node} fields representing the set of inputs for the node or the set of the
@@ -41,6 +43,8 @@
*/
public abstract class Edges extends Fields {
+ private static final Unsafe UNSAFE = GraalUnsafeAccess.getUnsafe();
+
/**
* Constants denoting whether a set of edges are inputs or successors.
*/
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java Thu Mar 28 19:39:14 2019 +0100
@@ -27,7 +27,7 @@
import static org.graalvm.compiler.graph.Edges.Type.Inputs;
import static org.graalvm.compiler.graph.Edges.Type.Successors;
import static org.graalvm.compiler.graph.Graph.isModificationCountsEnabled;
-import static org.graalvm.compiler.graph.UnsafeAccess.UNSAFE;
+import static org.graalvm.compiler.serviceprovider.GraalUnsafeAccess.getUnsafe;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
@@ -61,6 +61,7 @@
import org.graalvm.compiler.nodeinfo.Verbosity;
import org.graalvm.compiler.options.OptionValues;
+import jdk.vm.ci.services.Services;
import sun.misc.Unsafe;
/**
@@ -86,9 +87,11 @@
@NodeInfo
public abstract class Node implements Cloneable, Formattable, NodeInterface {
+ private static final Unsafe UNSAFE = getUnsafe();
+
public static final NodeClass<?> TYPE = null;
- public static final boolean TRACK_CREATION_POSITION = Boolean.getBoolean("debug.graal.TrackNodeCreationPosition");
+ public static final boolean TRACK_CREATION_POSITION = Boolean.parseBoolean(Services.getSavedProperties().get("debug.graal.TrackNodeCreationPosition"));
static final int DELETED_ID_START = -1000000000;
static final int INITIAL_ID = -1;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java Thu Mar 28 19:39:14 2019 +0100
@@ -24,11 +24,13 @@
package org.graalvm.compiler.graph;
+import static org.graalvm.compiler.core.common.Fields.translateInto;
import static org.graalvm.compiler.debug.GraalError.shouldNotReachHere;
+import static org.graalvm.compiler.graph.Edges.translateInto;
import static org.graalvm.compiler.graph.Graph.isModificationCountsEnabled;
import static org.graalvm.compiler.graph.InputEdges.translateInto;
import static org.graalvm.compiler.graph.Node.WithAllEdges;
-import static org.graalvm.compiler.graph.UnsafeAccess.UNSAFE;
+import static org.graalvm.compiler.serviceprovider.GraalUnsafeAccess.getUnsafe;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
@@ -69,6 +71,8 @@
import org.graalvm.compiler.nodeinfo.NodeSize;
import org.graalvm.compiler.nodeinfo.Verbosity;
+import sun.misc.Unsafe;
+
/**
* Metadata for every {@link Node} type. The metadata includes:
* <ul>
@@ -79,6 +83,7 @@
*/
public final class NodeClass<T> extends FieldIntrospection<T> {
+ private static final Unsafe UNSAFE = getUnsafe();
// Timers for creation of a NodeClass instance
private static final TimerKey Init_FieldScanning = DebugContext.timer("NodeClass.Init.FieldScanning");
private static final TimerKey Init_FieldScanningInner = DebugContext.timer("NodeClass.Init.FieldScanning.Inner");
@@ -128,7 +133,7 @@
public static <T> NodeClass<T> get(Class<T> clazz) {
int numTries = 0;
while (true) {
- boolean shouldBeInitializedBefore = UnsafeAccess.UNSAFE.shouldBeInitialized(clazz);
+ boolean shouldBeInitializedBefore = UNSAFE.shouldBeInitialized(clazz);
NodeClass<T> result = getUnchecked(clazz);
if (result != null || clazz == NODE_CLASS) {
@@ -141,13 +146,13 @@
* information without failing gates.
*/
numTries++;
- boolean shouldBeInitializedAfter = UnsafeAccess.UNSAFE.shouldBeInitialized(clazz);
+ boolean shouldBeInitializedAfter = UNSAFE.shouldBeInitialized(clazz);
String msg = "GR-9537 Reflective field access of TYPE field returned null. This is probably a bug in HotSpot class initialization. " +
" clazz: " + clazz.getTypeName() + ", numTries: " + numTries +
", shouldBeInitializedBefore: " + shouldBeInitializedBefore + ", shouldBeInitializedAfter: " + shouldBeInitializedAfter;
if (numTries <= 100) {
TTY.println(msg);
- UnsafeAccess.UNSAFE.ensureClassInitialized(clazz);
+ UNSAFE.ensureClassInitialized(clazz);
} else {
throw GraalError.shouldNotReachHere(msg);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeSourcePosition.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeSourcePosition.java Thu Mar 28 19:39:14 2019 +0100
@@ -40,11 +40,12 @@
import jdk.vm.ci.meta.JavaMethod;
import jdk.vm.ci.meta.MetaUtil;
import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.services.Services;
public class NodeSourcePosition extends BytecodePosition implements Iterable<NodeSourcePosition> {
- private static final boolean STRICT_SOURCE_POSITION = Boolean.getBoolean("debug.graal.SourcePositionStrictChecks");
- private static final boolean SOURCE_POSITION_BYTECODES = Boolean.getBoolean("debug.graal.SourcePositionDisassemble");
+ private static final boolean STRICT_SOURCE_POSITION = Boolean.parseBoolean(Services.getSavedProperties().get("debug.graal.SourcePositionStrictChecks"));
+ private static final boolean SOURCE_POSITION_BYTECODES = Boolean.parseBoolean(Services.getSavedProperties().get("debug.graal.SourcePositionDisassemble"));
private final int hashCode;
private final Marker marker;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/UnsafeAccess.java Thu Mar 28 11:06:00 2019 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2012, 2018, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.graph;
-
-import java.lang.reflect.Field;
-
-import sun.misc.Unsafe;
-
-/**
- * Package private access to the {@link Unsafe} capability.
- */
-class UnsafeAccess {
-
- static final Unsafe UNSAFE = initUnsafe();
-
- private static Unsafe initUnsafe() {
- try {
- // Fast path when we are trusted.
- return Unsafe.getUnsafe();
- } catch (SecurityException se) {
- // Slow path when we are not trusted.
- try {
- Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
- theUnsafe.setAccessible(true);
- return (Unsafe) theUnsafe.get(Unsafe.class);
- } catch (Exception e) {
- throw new RuntimeException("exception while trying to get Unsafe", e);
- }
- }
- }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java Thu Mar 28 19:39:14 2019 +0100
@@ -166,7 +166,8 @@
HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection,
HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes) {
Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, replacements);
- AArch64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), false);
+ AArch64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), false, //
+ /* registerMathPlugins */true);
return plugins;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java Thu Mar 28 19:39:14 2019 +0100
@@ -113,7 +113,7 @@
private HotSpotDebugInfoBuilder debugInfoBuilder;
protected AArch64HotSpotLIRGenerator(HotSpotProviders providers, GraalHotSpotVMConfig config, LIRGenerationResult lirGenRes) {
- this(new AArch64LIRKindTool(), new AArch64ArithmeticLIRGenerator(), new AArch64HotSpotMoveFactory(), providers, config, lirGenRes);
+ this(new AArch64LIRKindTool(), new AArch64ArithmeticLIRGenerator(null), new AArch64HotSpotMoveFactory(), providers, config, lirGenRes);
}
protected AArch64HotSpotLIRGenerator(LIRKindTool lirKindTool, AArch64ArithmeticLIRGenerator arithmeticLIRGen, MoveFactory moveFactory, HotSpotProviders providers, GraalHotSpotVMConfig config,
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64IndirectCallOp.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64IndirectCallOp.java Thu Mar 28 19:39:14 2019 +0100
@@ -73,7 +73,9 @@
crb.recordMark(config.MARKID_INLINE_INVOKE);
Register callReg = asRegister(targetAddress);
assert !callReg.equals(METHOD);
+ int pcOffset = masm.position();
AArch64Call.indirectCall(crb, masm, callReg, callTarget, state);
+ crb.recordInlineInvokeCallOp(pcOffset, getPosition());
}
@Override
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayCompareToStub.java Thu Mar 28 19:39:14 2019 +0100
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.hotspot.amd64;
+
+import org.graalvm.compiler.api.replacements.Snippet;
+import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
+import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
+import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
+import org.graalvm.compiler.hotspot.stubs.SnippetStub;
+import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.replacements.nodes.ArrayCompareToNode;
+import jdk.internal.vm.compiler.word.Pointer;
+
+import jdk.vm.ci.meta.JavaKind;
+
+public final class AMD64ArrayCompareToStub extends SnippetStub {
+
+ public static final ForeignCallDescriptor STUB_BYTE_ARRAY_COMPARE_TO_BYTE_ARRAY = new ForeignCallDescriptor(
+ "byteArrayCompareToByteArray", int.class, Pointer.class, Pointer.class, int.class, int.class);
+ public static final ForeignCallDescriptor STUB_BYTE_ARRAY_COMPARE_TO_CHAR_ARRAY = new ForeignCallDescriptor(
+ "byteArrayCompareToCharArray", int.class, Pointer.class, Pointer.class, int.class, int.class);
+ public static final ForeignCallDescriptor STUB_CHAR_ARRAY_COMPARE_TO_BYTE_ARRAY = new ForeignCallDescriptor(
+ "charArrayCompareToByteArray", int.class, Pointer.class, Pointer.class, int.class, int.class);
+ public static final ForeignCallDescriptor STUB_CHAR_ARRAY_COMPARE_TO_CHAR_ARRAY = new ForeignCallDescriptor(
+ "charArrayCompareToCharArray", int.class, Pointer.class, Pointer.class, int.class, int.class);
+
+ public AMD64ArrayCompareToStub(ForeignCallDescriptor foreignCallDescriptor, OptionValues options, HotSpotProviders providers, HotSpotForeignCallLinkage linkage) {
+ super(foreignCallDescriptor.getName(), options, providers, linkage);
+ }
+
+ @Snippet
+ private static int byteArrayCompareToByteArray(Pointer array1, Pointer array2, int length1, int length2) {
+ return ArrayCompareToNode.compareTo(array1, array2, length1, length2, JavaKind.Byte, JavaKind.Byte);
+ }
+
+ @Snippet
+ private static int byteArrayCompareToCharArray(Pointer array1, Pointer array2, int length1, int length2) {
+ return ArrayCompareToNode.compareTo(array1, array2, length1, length2, JavaKind.Byte, JavaKind.Char);
+ }
+
+ @Snippet
+ private static int charArrayCompareToByteArray(Pointer array1, Pointer array2, int length1, int length2) {
+ return ArrayCompareToNode.compareTo(array1, array2, length1, length2, JavaKind.Char, JavaKind.Byte);
+ }
+
+ @Snippet
+ private static int charArrayCompareToCharArray(Pointer array1, Pointer array2, int length1, int length2) {
+ return ArrayCompareToNode.compareTo(array1, array2, length1, length2, JavaKind.Char, JavaKind.Char);
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayEqualsStub.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayEqualsStub.java Thu Mar 28 19:39:14 2019 +0100
@@ -31,6 +31,7 @@
import org.graalvm.compiler.hotspot.stubs.SnippetStub;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.replacements.nodes.ArrayEqualsNode;
+import org.graalvm.compiler.replacements.nodes.ArrayRegionEqualsNode;
import jdk.internal.vm.compiler.word.Pointer;
import jdk.vm.ci.meta.JavaKind;
@@ -54,6 +55,13 @@
public static final ForeignCallDescriptor STUB_DOUBLE_ARRAY_EQUALS = new ForeignCallDescriptor(
"doubleArraysEquals", boolean.class, Pointer.class, Pointer.class, int.class);
+ public static final ForeignCallDescriptor STUB_BYTE_ARRAY_EQUALS_DIRECT = new ForeignCallDescriptor(
+ "byteArraysEqualsDirect", boolean.class, Pointer.class, Pointer.class, int.class);
+ public static final ForeignCallDescriptor STUB_CHAR_ARRAY_EQUALS_DIRECT = new ForeignCallDescriptor(
+ "charArraysEqualsDirect", boolean.class, Pointer.class, Pointer.class, int.class);
+ public static final ForeignCallDescriptor STUB_CHAR_ARRAY_EQUALS_BYTE_ARRAY = new ForeignCallDescriptor(
+ "charArrayEqualsByteArray", boolean.class, Pointer.class, Pointer.class, int.class);
+
public AMD64ArrayEqualsStub(ForeignCallDescriptor foreignCallDescriptor, OptionValues options, HotSpotProviders providers, HotSpotForeignCallLinkage linkage) {
super(foreignCallDescriptor.getName(), options, providers, linkage);
}
@@ -97,4 +105,19 @@
private static boolean doubleArraysEquals(Pointer array1, Pointer array2, int length) {
return ArrayEqualsNode.equals(array1, array2, length, JavaKind.Double);
}
+
+ @Snippet
+ private static boolean byteArraysEqualsDirect(Pointer array1, Pointer array2, int length) {
+ return ArrayRegionEqualsNode.regionEquals(array1, array2, length, JavaKind.Byte, JavaKind.Byte);
+ }
+
+ @Snippet
+ private static boolean charArraysEqualsDirect(Pointer array1, Pointer array2, int length) {
+ return ArrayRegionEqualsNode.regionEquals(array1, array2, length, JavaKind.Char, JavaKind.Char);
+ }
+
+ @Snippet
+ private static boolean charArrayEqualsByteArray(Pointer array1, Pointer array2, int length) {
+ return ArrayRegionEqualsNode.regionEquals(array1, array2, length, JavaKind.Char, JavaKind.Byte);
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java Thu Mar 28 19:39:14 2019 +0100
@@ -137,6 +137,22 @@
registerStubCall(AMD64ArrayEqualsStub.STUB_FLOAT_ARRAY_EQUALS, LEAF, REEXECUTABLE, NO_LOCATIONS)));
link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_DOUBLE_ARRAY_EQUALS, options, providers,
registerStubCall(AMD64ArrayEqualsStub.STUB_DOUBLE_ARRAY_EQUALS, LEAF, REEXECUTABLE, NO_LOCATIONS)));
+ link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_BYTE_ARRAY_EQUALS_DIRECT, options, providers,
+ registerStubCall(AMD64ArrayEqualsStub.STUB_BYTE_ARRAY_EQUALS_DIRECT, LEAF, REEXECUTABLE, NO_LOCATIONS)));
+ link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_CHAR_ARRAY_EQUALS_DIRECT, options, providers,
+ registerStubCall(AMD64ArrayEqualsStub.STUB_CHAR_ARRAY_EQUALS_DIRECT, LEAF, REEXECUTABLE, NO_LOCATIONS)));
+ link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_CHAR_ARRAY_EQUALS_BYTE_ARRAY, options, providers,
+ registerStubCall(AMD64ArrayEqualsStub.STUB_CHAR_ARRAY_EQUALS_BYTE_ARRAY, LEAF, REEXECUTABLE, NO_LOCATIONS)));
+
+ link(new AMD64ArrayCompareToStub(AMD64ArrayCompareToStub.STUB_BYTE_ARRAY_COMPARE_TO_BYTE_ARRAY, options, providers,
+ registerStubCall(AMD64ArrayCompareToStub.STUB_BYTE_ARRAY_COMPARE_TO_BYTE_ARRAY, LEAF, REEXECUTABLE, NO_LOCATIONS)));
+ link(new AMD64ArrayCompareToStub(AMD64ArrayCompareToStub.STUB_BYTE_ARRAY_COMPARE_TO_CHAR_ARRAY, options, providers,
+ registerStubCall(AMD64ArrayCompareToStub.STUB_BYTE_ARRAY_COMPARE_TO_CHAR_ARRAY, LEAF, REEXECUTABLE, NO_LOCATIONS)));
+ link(new AMD64ArrayCompareToStub(AMD64ArrayCompareToStub.STUB_CHAR_ARRAY_COMPARE_TO_BYTE_ARRAY, options, providers,
+ registerStubCall(AMD64ArrayCompareToStub.STUB_CHAR_ARRAY_COMPARE_TO_BYTE_ARRAY, LEAF, REEXECUTABLE, NO_LOCATIONS)));
+ link(new AMD64ArrayCompareToStub(AMD64ArrayCompareToStub.STUB_CHAR_ARRAY_COMPARE_TO_CHAR_ARRAY, options, providers,
+ registerStubCall(AMD64ArrayCompareToStub.STUB_CHAR_ARRAY_COMPARE_TO_CHAR_ARRAY, LEAF, REEXECUTABLE, NO_LOCATIONS)));
+
super.initialize(providers, options);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java Thu Mar 28 19:39:14 2019 +0100
@@ -676,32 +676,4 @@
protected StrategySwitchOp createStrategySwitchOp(SwitchStrategy strategy, LabelRef[] keyTargets, LabelRef defaultTarget, Variable key, AllocatableValue temp) {
return new AMD64HotSpotStrategySwitchOp(strategy, keyTargets, defaultTarget, key, temp);
}
-
- @Override
- public ForeignCallLinkage lookupArrayEqualsStub(JavaKind kind, int constantLength) {
- if (constantLength >= 0 && constantLength * kind.getByteCount() < 2 * getMaxVectorSize()) {
- // Yield constant-length arrays comparison assembly
- return null;
- }
- switch (kind) {
- case Boolean:
- return getForeignCalls().lookupForeignCall(AMD64ArrayEqualsStub.STUB_BOOLEAN_ARRAY_EQUALS);
- case Byte:
- return getForeignCalls().lookupForeignCall(AMD64ArrayEqualsStub.STUB_BYTE_ARRAY_EQUALS);
- case Char:
- return getForeignCalls().lookupForeignCall(AMD64ArrayEqualsStub.STUB_CHAR_ARRAY_EQUALS);
- case Short:
- return getForeignCalls().lookupForeignCall(AMD64ArrayEqualsStub.STUB_SHORT_ARRAY_EQUALS);
- case Int:
- return getForeignCalls().lookupForeignCall(AMD64ArrayEqualsStub.STUB_INT_ARRAY_EQUALS);
- case Long:
- return getForeignCalls().lookupForeignCall(AMD64ArrayEqualsStub.STUB_LONG_ARRAY_EQUALS);
- case Float:
- return getForeignCalls().lookupForeignCall(AMD64ArrayEqualsStub.STUB_FLOAT_ARRAY_EQUALS);
- case Double:
- return getForeignCalls().lookupForeignCall(AMD64ArrayEqualsStub.STUB_DOUBLE_ARRAY_EQUALS);
- default:
- return null;
- }
- }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java Thu Mar 28 19:39:14 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -28,9 +28,11 @@
import static jdk.vm.ci.code.ValueUtil.isStackSlot;
import static org.graalvm.compiler.hotspot.HotSpotBackend.EXCEPTION_HANDLER_IN_CALLER;
+import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.core.amd64.AMD64NodeLIRBuilder;
import org.graalvm.compiler.core.amd64.AMD64NodeMatchRules;
import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
import org.graalvm.compiler.core.gen.DebugInfoBuilder;
import org.graalvm.compiler.hotspot.HotSpotDebugInfoBuilder;
@@ -54,6 +56,8 @@
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.spi.NodeValueMap;
+import org.graalvm.compiler.replacements.nodes.ArrayCompareToNode;
+import org.graalvm.compiler.replacements.nodes.ArrayEqualsNode;
import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.amd64.AMD64Kind;
@@ -66,8 +70,11 @@
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.Value;
+import org.graalvm.compiler.replacements.nodes.ArrayRegionEqualsNode;
/**
* LIR generator specialized for AMD64 HotSpot.
@@ -196,4 +203,98 @@
Value[] parameters = visitInvokeArguments(gen.getRegisterConfig().getCallingConvention(HotSpotCallingConventionType.JavaCall, null, sig, gen), node.arguments());
append(new AMD64BreakpointOp(parameters));
}
+
+ private ForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor) {
+ return getGen().getForeignCalls().lookupForeignCall(descriptor);
+ }
+
+ @Override
+ public ForeignCallLinkage lookupGraalStub(ValueNode valueNode) {
+ ResolvedJavaMethod method = valueNode.graph().method();
+ if (method == null || method.getAnnotation(Snippet.class) != null) {
+ // Emit assembly for snippet stubs
+ return null;
+ }
+
+ if (valueNode instanceof ArrayEqualsNode) {
+ ArrayEqualsNode arrayEqualsNode = (ArrayEqualsNode) valueNode;
+ JavaKind kind = arrayEqualsNode.getKind();
+ ValueNode length = arrayEqualsNode.getLength();
+
+ if (length.isConstant()) {
+ int constantLength = length.asJavaConstant().asInt();
+ if (constantLength >= 0 && constantLength * kind.getByteCount() < 2 * getGen().getMaxVectorSize()) {
+ // Yield constant-length arrays comparison assembly
+ return null;
+ }
+ }
+
+ switch (kind) {
+ case Boolean:
+ return lookupForeignCall(AMD64ArrayEqualsStub.STUB_BOOLEAN_ARRAY_EQUALS);
+ case Byte:
+ return lookupForeignCall(AMD64ArrayEqualsStub.STUB_BYTE_ARRAY_EQUALS);
+ case Char:
+ return lookupForeignCall(AMD64ArrayEqualsStub.STUB_CHAR_ARRAY_EQUALS);
+ case Short:
+ return lookupForeignCall(AMD64ArrayEqualsStub.STUB_SHORT_ARRAY_EQUALS);
+ case Int:
+ return lookupForeignCall(AMD64ArrayEqualsStub.STUB_INT_ARRAY_EQUALS);
+ case Long:
+ return lookupForeignCall(AMD64ArrayEqualsStub.STUB_LONG_ARRAY_EQUALS);
+ case Float:
+ return lookupForeignCall(AMD64ArrayEqualsStub.STUB_FLOAT_ARRAY_EQUALS);
+ case Double:
+ return lookupForeignCall(AMD64ArrayEqualsStub.STUB_DOUBLE_ARRAY_EQUALS);
+ default:
+ return null;
+ }
+ } else if (valueNode instanceof ArrayCompareToNode) {
+ ArrayCompareToNode arrayCompareToNode = (ArrayCompareToNode) valueNode;
+ JavaKind kind1 = arrayCompareToNode.getKind1();
+ JavaKind kind2 = arrayCompareToNode.getKind2();
+
+ if (kind1 == JavaKind.Byte) {
+ if (kind2 == JavaKind.Byte) {
+ return lookupForeignCall(AMD64ArrayCompareToStub.STUB_BYTE_ARRAY_COMPARE_TO_BYTE_ARRAY);
+ } else if (kind2 == JavaKind.Char) {
+ return lookupForeignCall(AMD64ArrayCompareToStub.STUB_BYTE_ARRAY_COMPARE_TO_CHAR_ARRAY);
+ }
+ } else if (kind1 == JavaKind.Char) {
+ if (kind2 == JavaKind.Byte) {
+ return lookupForeignCall(AMD64ArrayCompareToStub.STUB_CHAR_ARRAY_COMPARE_TO_BYTE_ARRAY);
+ } else if (kind2 == JavaKind.Char) {
+ return lookupForeignCall(AMD64ArrayCompareToStub.STUB_CHAR_ARRAY_COMPARE_TO_CHAR_ARRAY);
+ }
+ }
+ } else if (valueNode instanceof ArrayRegionEqualsNode) {
+ ArrayRegionEqualsNode arrayRegionEqualsNode = (ArrayRegionEqualsNode) valueNode;
+ JavaKind kind1 = arrayRegionEqualsNode.getKind1();
+ JavaKind kind2 = arrayRegionEqualsNode.getKind2();
+ ValueNode length = arrayRegionEqualsNode.getLength();
+
+ if (length.isConstant()) {
+ int constantLength = length.asJavaConstant().asInt();
+ if (constantLength >= 0 && constantLength * (Math.max(kind1.getByteCount(), kind2.getByteCount())) < 2 * getGen().getMaxVectorSize()) {
+ // Yield constant-length arrays comparison assembly
+ return null;
+ }
+ }
+
+ if (kind1 == kind2) {
+ switch (kind1) {
+ case Byte:
+ return lookupForeignCall(AMD64ArrayEqualsStub.STUB_BYTE_ARRAY_EQUALS_DIRECT);
+ case Char:
+ return lookupForeignCall(AMD64ArrayEqualsStub.STUB_CHAR_ARRAY_EQUALS_DIRECT);
+ default:
+ return null;
+ }
+ } else if (kind1 == JavaKind.Char && kind2 == JavaKind.Byte) {
+ return lookupForeignCall(AMD64ArrayEqualsStub.STUB_CHAR_ARRAY_EQUALS_BYTE_ARRAY);
+ }
+ }
+
+ return null;
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/NodeCostDumpUtil.java Thu Mar 28 19:39:14 2019 +0100
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.hotspot.test;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+import java.util.stream.Collectors;
+
+import org.graalvm.compiler.debug.CSVUtil;
+import org.graalvm.compiler.debug.GraalError;
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.graph.spi.Canonicalizable;
+import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
+import org.graalvm.compiler.nodes.spi.Virtualizable;
+
+public class NodeCostDumpUtil {
+
+ private static final String prefix1 = "com.oracle.";
+ private static final String prefix2 = "org.graalvm.";
+ private static final String FMT = CSVUtil.buildFormatString("%s", "%s", "%s", "%s", "%s", "%s", "%s", "%s");
+
+ private static String getArgumentRegex(String arg) {
+ if (arg.length() == 0) {
+ return null;
+ }
+ try {
+ Pattern.compile(arg);
+ return arg;
+ } catch (PatternSyntaxException e) {
+ // silently ignore
+ System.err.println("Invalid regex given, defaulting to \".*\" regex..");
+ return null;
+ }
+ }
+
+ public static void main(String[] args) {
+ if (args.length != 1) {
+ System.err.println("NodeCostDumpUtil expects exactly one argument, the node name regex to match against.");
+ System.exit(-1);
+ }
+ final String pattern = getArgumentRegex(args[0]);
+ String version = System.getProperty("java.specification.version");
+ if (version.compareTo("1.9") >= 0) {
+ System.err.printf("NodeCostDumpUtil does not support JDK versions greater than 1.8, current version is %s.\n", version);
+ System.exit(-1);
+ }
+ String[] jvmciCP = System.getProperty("jvmci.class.path.append").split(File.pathSeparator);
+ String[] primarySuiteCP = System.getProperty("primary.suite.cp").split(File.pathSeparator);
+ ClassLoader applicationClassLoader = Thread.currentThread().getContextClassLoader();
+ HashSet<Class<?>> classes = new HashSet<>();
+ try {
+ Set<String> uniquePaths = new HashSet<>(Arrays.asList(primarySuiteCP));
+ uniquePaths.addAll(Arrays.asList(jvmciCP));
+ for (String path : uniquePaths) {
+ if (new File(path).exists()) {
+ if (path.endsWith(".jar")) {
+ try (FileSystem jarFileSystem = FileSystems.newFileSystem(URI.create("jar:file:" + path), Collections.emptyMap())) {
+ initAllClasses(jarFileSystem.getPath("/"), applicationClassLoader, classes);
+ }
+ } else {
+ initAllClasses(FileSystems.getDefault().getPath(path), applicationClassLoader, classes);
+ }
+ }
+ }
+ } catch (IOException ex) {
+ GraalError.shouldNotReachHere();
+ }
+ System.err.printf("Loaded %d classes...\n", classes.size());
+ List<Class<?>> nodeClasses = new ArrayList<>();
+ for (Class<?> loaded : classes) {
+ if (Node.class.isAssignableFrom(loaded) && !loaded.isArray()) {
+ nodeClasses.add(loaded);
+ }
+ }
+ System.err.printf("Loaded %s node classes...\n", nodeClasses.size());
+ List<NodeClass<?>> nc = new ArrayList<>();
+ for (Class<?> c : nodeClasses) {
+ try {
+ nc.add(NodeClass.get(c));
+ } catch (Throwable t) {
+ // Silently ignore problems here
+ }
+ }
+ System.err.printf("Read TYPE field from %s node classes...\n", nc.size());
+ nc = nc.stream().filter(x -> x != null).collect(Collectors.toList());
+ nc.sort((x, y) -> {
+ String a = x.getJavaClass().getName();
+ String b = y.getJavaClass().getName();
+ return a.compareTo(b);
+ });
+ CSVUtil.Escape.println(System.out, FMT, "NodeName", "Size", "Overrides Size Method", "Cycles", "Overrides Cycles Method", "Canonicalizable", "MemoryCheckPoint", "Virtualizable");
+ for (NodeClass<?> nodeclass : nc) {
+ String packageStrippedName = null;
+ try {
+ packageStrippedName = nodeclass.getJavaClass().getCanonicalName().replace(prefix1, "").replace(prefix2, "");
+ } catch (Throwable t) {
+ // do nothing
+ continue;
+ }
+ if (pattern != null && !packageStrippedName.matches(pattern)) {
+ continue;
+ }
+ boolean overridesSizeMethod = false;
+ boolean overridesCyclesMethod = false;
+ Class<?> c = nodeclass.getJavaClass();
+ try {
+ c.getDeclaredMethod("estimatedNodeSize");
+ overridesSizeMethod = true;
+ } catch (Throwable t) {
+ // do nothing
+ }
+ try {
+ c.getDeclaredMethod("estimatedNodeCycles");
+ overridesCyclesMethod = true;
+ } catch (Throwable t) {
+ // do nothing
+ }
+ CSVUtil.Escape.println(System.out, FMT, packageStrippedName, nodeclass.size(), overridesSizeMethod, nodeclass.cycles(), overridesCyclesMethod, canonicalizable(c), memoryCheckPoint(c),
+ virtualizable(c));
+ }
+ }
+
+ private static boolean canonicalizable(Class<?> c) {
+ return Canonicalizable.class.isAssignableFrom(c);
+ }
+
+ private static boolean virtualizable(Class<?> c) {
+ return Virtualizable.class.isAssignableFrom(c);
+ }
+
+ private static boolean memoryCheckPoint(Class<?> c) {
+ return MemoryCheckpoint.class.isAssignableFrom(c);
+ }
+
+ private static void initAllClasses(final Path root, ClassLoader classLoader, HashSet<Class<?>> classes) {
+ try {
+ Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+ String className = root.relativize(file).toString();
+ ClassLoader c = classLoader;
+ if (className.endsWith(".class")) {
+ String prefix = prefixed(className);
+ if (prefix != null) {
+ String stripped = stripClassName(className);
+ c = new URLClassLoader(new URL[]{new File(constructURLPart(stripped, className, prefix)).toURI().toURL()}, classLoader);
+ className = constructClazzPart(stripped, prefix);
+ } else {
+ String clazzPart = className.replace('/', '.');
+ className = clazzPart.substring(0, clazzPart.length() - ".class".length());
+ }
+ try {
+ Class<?> systemClass = Class.forName(className, false, c);
+ if (systemClass.getEnclosingClass() != null) {
+ try {
+ classes.add(systemClass.getEnclosingClass());
+ } catch (Throwable t) {
+ // do nothing
+ }
+ }
+ classes.add(systemClass);
+ } catch (Throwable ignored) {
+ }
+ }
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ } catch (IOException ex) {
+ GraalError.shouldNotReachHere();
+ }
+ }
+
+ private static String prefixed(String className) {
+ if (className.contains(prefix1) && className.indexOf(prefix1) > 0) {
+ return prefix1;
+ } else if (className.contains(prefix2) && className.indexOf(prefix2) > 0) {
+ return prefix2;
+ }
+ return null;
+ }
+
+ private static String stripClassName(String className) {
+ return className.replace('/', '.');
+ }
+
+ private static String constructClazzPart(String stripped, String prefix) {
+ String clazzPart = stripped.substring(stripped.lastIndexOf(prefix), stripped.length());
+ return clazzPart.substring(0, clazzPart.length() - ".class".length());
+ }
+
+ private static String constructURLPart(String stripped, String className, String prefix) {
+ return className.substring(0, stripped.lastIndexOf(prefix));
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/StringInternConstantTest.java Thu Mar 28 19:39:14 2019 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.hotspot.test;
+
+import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.FixedNode;
+import org.graalvm.compiler.nodes.ReturnNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.junit.Test;
+
+import jdk.vm.ci.hotspot.HotSpotObjectConstant;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import org.junit.Assert;
+
+/**
+ * Tests constant folding of {@link String#intern()}.
+ */
+public class StringInternConstantTest extends GraalCompilerTest {
+
+ private static final String A_CONSTANT_STRING = "a constant string";
+
+ @Test
+ public void test1() {
+ ResolvedJavaMethod method = getResolvedJavaMethod("constantIntern");
+ StructuredGraph graph = parseForCompile(method);
+
+ FixedNode firstFixed = graph.start().next();
+ Assert.assertThat(firstFixed, instanceOf(ReturnNode.class));
+
+ ReturnNode ret = (ReturnNode) firstFixed;
+ if (ret.result() instanceof ConstantNode) {
+ String expected = A_CONSTANT_STRING.intern();
+ Constant constant = ((ConstantNode) ret.result()).getValue();
+ if (constant instanceof HotSpotObjectConstant) {
+ String returnedString = ((HotSpotObjectConstant) constant).asObject(String.class);
+ Assert.assertSame("result", expected, returnedString);
+ } else {
+ Assert.fail("expected HotSpotObjectConstant, got: " + constant.getClass());
+ }
+ } else {
+ Assert.fail("result not constant: " + ret.result());
+ }
+ }
+
+ public static String constantIntern() {
+ return A_CONSTANT_STRING.intern();
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/BootstrapWatchDog.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/BootstrapWatchDog.java Thu Mar 28 19:39:14 2019 +0100
@@ -39,6 +39,7 @@
import org.graalvm.compiler.options.OptionValues;
import jdk.vm.ci.code.CompilationRequest;
+import jdk.vm.ci.services.Services;
/**
* A watch dog that monitors the duration and compilation rate during a
@@ -108,7 +109,7 @@
/**
* Set to true to debug the watch dog.
*/
- private static final boolean DEBUG = Boolean.getBoolean("debug.graal.BootstrapWatchDog");
+ private static final boolean DEBUG = Boolean.parseBoolean(Services.getSavedProperties().get("debug.graal.BootstrapWatchDog"));
/**
* Seconds to delay before starting to measure the compilation rate.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationStatistics.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationStatistics.java Thu Mar 28 19:39:14 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -48,6 +48,7 @@
import jdk.vm.ci.hotspot.HotSpotInstalledCode;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
+import jdk.vm.ci.services.Services;
@SuppressWarnings("unused")
public final class CompilationStatistics {
@@ -189,7 +190,7 @@
timeLeft = RESOLUTION;
}
}
- String timelineName = System.getProperty("stats.timeline.name");
+ String timelineName = Services.getSavedProperties().get("stats.timeline.name");
if (timelineName != null && !timelineName.isEmpty()) {
out.printf("%s%c", CSVUtil.Escape.escape(timelineName), CSVUtil.SEPARATOR);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java Thu Mar 28 19:39:14 2019 +0100
@@ -57,7 +57,6 @@
import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
import jdk.vm.ci.hotspot.HotSpotCompilationRequestResult;
import jdk.vm.ci.hotspot.HotSpotInstalledCode;
-import jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
import jdk.vm.ci.hotspot.HotSpotNmethod;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
@@ -93,6 +92,7 @@
private final boolean installAsDefault;
private final boolean useProfilingInfo;
+ private final boolean shouldRetainLocalVariables;
private final OptionValues options;
final class HotSpotCompilationWrapper extends CompilationWrapper<HotSpotCompilationRequestResult> {
@@ -187,7 +187,7 @@
try (DebugContext.Scope s = debug.scope("Compiling", new DebugDumpScope(getIdString(), true))) {
// Begin the compilation event.
compilationEvent.begin();
- result = compiler.compile(method, entryBCI, useProfilingInfo, compilationId, options, debug);
+ result = compiler.compile(method, entryBCI, useProfilingInfo, shouldRetainLocalVariables, compilationId, options, debug);
} catch (Throwable e) {
throw debug.handle(e);
} finally {
@@ -213,10 +213,16 @@
public CompilationTask(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalCompiler compiler, HotSpotCompilationRequest request, boolean useProfilingInfo, boolean installAsDefault,
OptionValues options) {
+ this(jvmciRuntime, compiler, request, useProfilingInfo, false, installAsDefault, options);
+ }
+
+ public CompilationTask(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalCompiler compiler, HotSpotCompilationRequest request, boolean useProfilingInfo, boolean shouldRetainLocalVariables,
+ boolean installAsDefault, OptionValues options) {
this.jvmciRuntime = jvmciRuntime;
this.compiler = compiler;
this.compilationId = new HotSpotCompilationIdentifier(request);
this.useProfilingInfo = useProfilingInfo;
+ this.shouldRetainLocalVariables = shouldRetainLocalVariables;
this.installAsDefault = installAsDefault;
/*
@@ -321,15 +327,14 @@
// Log a compilation event.
EventProvider.CompilationEvent compilationEvent = eventProvider.newCompilationEvent();
- if (installAsDefault) {
+ if (installAsDefault || isOSR) {
// If there is already compiled code for this method on our level we simply return.
// JVMCI compiles are always at the highest compile level, even in non-tiered mode so we
// only need to check for that value.
if (method.hasCodeAtLevel(entryBCI, config.compilationLevelFullOptimization)) {
return HotSpotCompilationRequestResult.failure("Already compiled", false);
}
- if (HotSpotGraalCompilerFactory.checkGraalCompileOnlyFilter(method.getDeclaringClass().toJavaName(), method.getName(), method.getSignature().toString(),
- HotSpotJVMCICompilerFactory.CompilationLevel.FullOptimization) != HotSpotJVMCICompilerFactory.CompilationLevel.FullOptimization) {
+ if (HotSpotGraalCompilerFactory.shouldExclude(method)) {
return HotSpotCompilationRequestResult.failure("GraalCompileOnly excluded", false);
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationWatchDog.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationWatchDog.java Thu Mar 28 19:39:14 2019 +0100
@@ -35,6 +35,7 @@
import org.graalvm.compiler.options.OptionValues;
import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.services.Services;
/**
* A watch dog for reporting long running compilations. This is designed to be an always on
@@ -166,7 +167,7 @@
/**
* Set to true to debug the watch dog.
*/
- private static final boolean DEBUG = Boolean.getBoolean("debug.graal.CompilationWatchDog");
+ private static final boolean DEBUG = Boolean.parseBoolean(Services.getSavedProperties().get("debug.graal.CompilationWatchDog"));
private void trace(String format, Object... args) {
if (DEBUG) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Thu Mar 28 19:39:14 2019 +0100
@@ -316,14 +316,16 @@
public final int jvmAccWrittenFlags = getConstant("JVM_ACC_WRITTEN_FLAGS", Integer.class);
public final int jvmAccSynthetic = getConstant("JVM_ACC_SYNTHETIC", Integer.class);
- public final int jvmciCompileStateCanPostOnExceptionsOffset = getJvmciCompileStateCanPostOnExceptionsOffset();
+ public final int jvmciCompileStateCanPostOnExceptionsOffset = getJvmciJvmtiCapabilityOffset("_jvmti_can_post_on_exceptions");
+ public final int jvmciCompileStateCanPopFrameOffset = getJvmciJvmtiCapabilityOffset("_jvmti_can_pop_frame");
+ public final int jvmciCompileStateCanAccessLocalVariablesOffset = getJvmciJvmtiCapabilityOffset("_jvmti_can_access_local_variables");
// Integer.MIN_VALUE if not available
- private int getJvmciCompileStateCanPostOnExceptionsOffset() {
- int offset = getFieldOffset("JVMCICompileState::_jvmti_can_post_on_exceptions", Integer.class, "jbyte", Integer.MIN_VALUE);
+ private int getJvmciJvmtiCapabilityOffset(String name) {
+ int offset = getFieldOffset("JVMCICompileState::" + name, Integer.class, "jbyte", Integer.MIN_VALUE);
if (offset == Integer.MIN_VALUE) {
// JDK 12
- offset = getFieldOffset("JVMCIEnv::_jvmti_can_post_on_exceptions", Integer.class, "jbyte", Integer.MIN_VALUE);
+ offset = getFieldOffset("JVMCIEnv::" + name, Integer.class, "jbyte", Integer.MIN_VALUE);
}
return offset;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigBase.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigBase.java Thu Mar 28 19:39:14 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -36,9 +36,10 @@
import jdk.vm.ci.hotspot.HotSpotVMConfigAccess;
import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.services.Services;
/**
- * This is a source with different versions for various JDKs.
+ * Base class of class hierarchy for accessing HotSpot VM configuration.
*/
public abstract class GraalHotSpotVMConfigBase extends HotSpotVMConfigAccess {
@@ -62,6 +63,18 @@
return true;
}
+ private static String getProperty(String name, String def) {
+ String value = Services.getSavedProperties().get(name);
+ if (value == null) {
+ return def;
+ }
+ return value;
+ }
+
+ private static String getProperty(String name) {
+ return getProperty(name, null);
+ }
+
/**
* Contains values that are different between JDK versions.
*/
@@ -78,14 +91,14 @@
public final String osName = getHostOSName();
public final String osArch = getHostArchitectureName();
- public final boolean windowsOs = System.getProperty("os.name", "").startsWith("Windows");
- public final boolean linuxOs = System.getProperty("os.name", "").startsWith("Linux");
+ public final boolean windowsOs = getProperty("os.name", "").startsWith("Windows");
+ public final boolean linuxOs = getProperty("os.name", "").startsWith("Linux");
/**
* Gets the host operating system name.
*/
private static String getHostOSName() {
- String osName = System.getProperty("os.name");
+ String osName = getProperty("os.name");
switch (osName) {
case "Linux":
osName = "linux";
@@ -108,7 +121,7 @@
}
private static String getHostArchitectureName() {
- String arch = System.getProperty("os.arch");
+ String arch = getProperty("os.arch");
switch (arch) {
case "x86_64":
arch = "amd64";
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java Thu Mar 28 19:39:14 2019 +0100
@@ -25,6 +25,7 @@
package org.graalvm.compiler.hotspot;
import static org.graalvm.compiler.core.common.GraalOptions.OptAssumptions;
+import org.graalvm.compiler.serviceprovider.GraalUnsafeAccess;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
@@ -71,9 +72,11 @@
import jdk.vm.ci.meta.SpeculationLog;
import jdk.vm.ci.meta.TriState;
import jdk.vm.ci.runtime.JVMCICompiler;
+import sun.misc.Unsafe;
public class HotSpotGraalCompiler implements GraalJVMCICompiler {
+ private static final Unsafe UNSAFE = GraalUnsafeAccess.getUnsafe();
private final HotSpotJVMCIRuntime jvmciRuntime;
private final HotSpotGraalRuntimeProvider graalRuntime;
private final CompilationCounters compilationCounters;
@@ -131,7 +134,7 @@
if (compilationCounters != null) {
compilationCounters.countCompilation(method);
}
- CompilationTask task = new CompilationTask(jvmciRuntime, this, hsRequest, true, installAsDefault, options);
+ CompilationTask task = new CompilationTask(jvmciRuntime, this, hsRequest, true, shouldRetainLocalVariables(hsRequest.getJvmciEnv()), installAsDefault, options);
CompilationRequestResult r = null;
try (DebugContext debug = graalRuntime.openDebugContext(options, task.getCompilationIdentifier(), method, getDebugHandlersFactories(), DebugContext.DEFAULT_LOG_STREAM);
Activation a = debug.activate()) {
@@ -142,6 +145,24 @@
}
}
+ private boolean shouldRetainLocalVariables(long envAddress) {
+ GraalHotSpotVMConfig config = graalRuntime.getVMConfig();
+ if (envAddress == 0) {
+ return false;
+ }
+ if (config.jvmciCompileStateCanPopFrameOffset != Integer.MIN_VALUE) {
+ if ((UNSAFE.getByte(envAddress + config.jvmciCompileStateCanPopFrameOffset) & 0xFF) != 0) {
+ return true;
+ }
+ }
+ if (config.jvmciCompileStateCanAccessLocalVariablesOffset != Integer.MIN_VALUE) {
+ if ((UNSAFE.getByte(envAddress + config.jvmciCompileStateCanAccessLocalVariablesOffset) & 0xFF) != 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public StructuredGraph createGraph(ResolvedJavaMethod method, int entryBCI, boolean useProfilingInfo, CompilationIdentifier compilationId, OptionValues options, DebugContext debug) {
HotSpotBackend backend = graalRuntime.getHostBackend();
HotSpotProviders providers = backend.getProviders();
@@ -161,6 +182,11 @@
public CompilationResult compileHelper(CompilationResultBuilderFactory crbf, CompilationResult result, StructuredGraph graph, ResolvedJavaMethod method, int entryBCI, boolean useProfilingInfo,
OptionValues options) {
+ return compileHelper(crbf, result, graph, method, entryBCI, useProfilingInfo, false, options);
+ }
+
+ public CompilationResult compileHelper(CompilationResultBuilderFactory crbf, CompilationResult result, StructuredGraph graph, ResolvedJavaMethod method, int entryBCI, boolean useProfilingInfo,
+ boolean shouldRetainLocalVariables, OptionValues options) {
HotSpotBackend backend = graalRuntime.getHostBackend();
HotSpotProviders providers = backend.getProviders();
@@ -181,7 +207,7 @@
result.setEntryBCI(entryBCI);
boolean shouldDebugNonSafepoints = providers.getCodeCache().shouldDebugNonSafepoints();
- PhaseSuite<HighTierContext> graphBuilderSuite = configGraphBuilderSuite(providers.getSuites().getDefaultGraphBuilderSuite(), shouldDebugNonSafepoints, isOSR);
+ PhaseSuite<HighTierContext> graphBuilderSuite = configGraphBuilderSuite(providers.getSuites().getDefaultGraphBuilderSuite(), shouldDebugNonSafepoints, shouldRetainLocalVariables, isOSR);
GraalCompiler.compileGraph(graph, method, providers, backend, graphBuilderSuite, optimisticOpts, profilingInfo, suites, lirSuites, result, crbf, true);
if (!isOSR && useProfilingInfo) {
@@ -193,9 +219,14 @@
}
public CompilationResult compile(ResolvedJavaMethod method, int entryBCI, boolean useProfilingInfo, CompilationIdentifier compilationId, OptionValues options, DebugContext debug) {
+ return compile(method, entryBCI, useProfilingInfo, false, compilationId, options, debug);
+ }
+
+ public CompilationResult compile(ResolvedJavaMethod method, int entryBCI, boolean useProfilingInfo, boolean shouldRetainLocalVariables, CompilationIdentifier compilationId, OptionValues options,
+ DebugContext debug) {
StructuredGraph graph = createGraph(method, entryBCI, useProfilingInfo, compilationId, options, debug);
CompilationResult result = new CompilationResult(compilationId);
- return compileHelper(CompilationResultBuilderFactory.Default, result, graph, method, entryBCI, useProfilingInfo, options);
+ return compileHelper(CompilationResultBuilderFactory.Default, result, graph, method, entryBCI, useProfilingInfo, shouldRetainLocalVariables, options);
}
protected OptimisticOptimizations getOptimisticOpts(ProfilingInfo profilingInfo, OptionValues options) {
@@ -217,27 +248,26 @@
* @param suite the graph builder suite
* @param shouldDebugNonSafepoints specifies if extra debug info should be generated (default is
* false)
+ * @param shouldRetainLocalVariables specifies if local variables should be retained for
+ * debugging purposes (default is false)
* @param isOSR specifies if extra OSR-specific post-processing is required (default is false)
* @return a new suite derived from {@code suite} if any of the GBS parameters did not have a
* default value otherwise {@code suite}
*/
- protected PhaseSuite<HighTierContext> configGraphBuilderSuite(PhaseSuite<HighTierContext> suite, boolean shouldDebugNonSafepoints, boolean isOSR) {
- if (shouldDebugNonSafepoints || isOSR) {
+ protected PhaseSuite<HighTierContext> configGraphBuilderSuite(PhaseSuite<HighTierContext> suite, boolean shouldDebugNonSafepoints, boolean shouldRetainLocalVariables, boolean isOSR) {
+ if (shouldDebugNonSafepoints || shouldRetainLocalVariables || isOSR) {
PhaseSuite<HighTierContext> newGbs = suite.copy();
-
+ GraphBuilderPhase graphBuilderPhase = (GraphBuilderPhase) newGbs.findPhase(GraphBuilderPhase.class).previous();
+ GraphBuilderConfiguration graphBuilderConfig = graphBuilderPhase.getGraphBuilderConfig();
if (shouldDebugNonSafepoints) {
- GraphBuilderPhase graphBuilderPhase = (GraphBuilderPhase) newGbs.findPhase(GraphBuilderPhase.class).previous();
- GraphBuilderConfiguration graphBuilderConfig = graphBuilderPhase.getGraphBuilderConfig();
graphBuilderConfig = graphBuilderConfig.withNodeSourcePosition(true);
- GraphBuilderPhase newGraphBuilderPhase = new GraphBuilderPhase(graphBuilderConfig);
- newGbs.findPhase(GraphBuilderPhase.class).set(newGraphBuilderPhase);
}
+ if (shouldRetainLocalVariables) {
+ graphBuilderConfig = graphBuilderConfig.withRetainLocalVariables(true);
+ }
+ GraphBuilderPhase newGraphBuilderPhase = new GraphBuilderPhase(graphBuilderConfig);
+ newGbs.findPhase(GraphBuilderPhase.class).set(newGraphBuilderPhase);
if (isOSR) {
- // We must not clear non liveness for OSR compilations.
- GraphBuilderPhase graphBuilderPhase = (GraphBuilderPhase) newGbs.findPhase(GraphBuilderPhase.class).previous();
- GraphBuilderConfiguration graphBuilderConfig = graphBuilderPhase.getGraphBuilderConfig();
- GraphBuilderPhase newGraphBuilderPhase = new GraphBuilderPhase(graphBuilderConfig);
- newGbs.findPhase(GraphBuilderPhase.class).set(newGraphBuilderPhase);
newGbs.appendPhase(new OnStackReplacementPhase());
}
return newGbs;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java Thu Mar 28 19:39:14 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -25,7 +25,9 @@
package org.graalvm.compiler.hotspot;
import static jdk.vm.ci.common.InitTimer.timer;
+import static jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory.CompilationLevelAdjustment.None;
import static jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE;
+import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE;
import static org.graalvm.compiler.hotspot.HotSpotGraalOptionValues.GRAAL_OPTION_PROPERTY_PREFIX;
import java.io.PrintStream;
@@ -42,8 +44,10 @@
import jdk.vm.ci.common.InitTimer;
import jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
-import jdk.vm.ci.hotspot.HotSpotSignature;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
+import jdk.vm.ci.meta.Signature;
import jdk.vm.ci.runtime.JVMCIRuntime;
+import jdk.vm.ci.services.Services;
public final class HotSpotGraalCompilerFactory extends HotSpotJVMCICompilerFactory {
@@ -70,7 +74,7 @@
@Override
public void onSelection() {
- JVMCIVersionCheck.check(false);
+ JVMCIVersionCheck.check(Services.getSavedProperties(), false);
assert options == null : "cannot select " + getClass() + " service more than once";
options = HotSpotGraalOptionValues.defaultOptions();
initializeGraalCompilePolicyFields(options);
@@ -79,8 +83,10 @@
* Exercise this code path early to encourage loading now. This doesn't solve problem of
* deadlock during class loading but seems to eliminate it in practice.
*/
- adjustCompilationLevelInternal(Object.class, "hashCode", "()I", CompilationLevel.FullOptimization);
- adjustCompilationLevelInternal(Object.class, "hashCode", "()I", CompilationLevel.Simple);
+ if (isGraalPredicate != null && isGraalPredicate.getCompilationLevelAdjustment() != None) {
+ adjustCompilationLevelInternal(Object.class, CompilationLevel.FullOptimization);
+ adjustCompilationLevelInternal(Object.class, CompilationLevel.Simple);
+ }
if (IS_BUILDING_NATIVE_IMAGE) {
// Triggers initialization of all option descriptors
Options.CompileGraalWithC1Only.getName();
@@ -88,7 +94,7 @@
}
private static void initializeGraalCompilePolicyFields(OptionValues options) {
- compileGraalWithC1Only = Options.CompileGraalWithC1Only.getValue(options);
+ compileGraalWithC1Only = Options.CompileGraalWithC1Only.getValue(options) && !IS_IN_NATIVE_IMAGE;
String optionValue = Options.GraalCompileOnly.getValue(options);
if (optionValue != null) {
MethodFilter[] filter = MethodFilter.parse(optionValue);
@@ -123,7 +129,7 @@
public HotSpotGraalCompiler createCompiler(JVMCIRuntime runtime) {
CompilerConfigurationFactory factory = CompilerConfigurationFactory.selectFactory(null, options);
if (isGraalPredicate != null) {
- isGraalPredicate.onCompilerConfigurationFactorySelection(factory);
+ isGraalPredicate.onCompilerConfigurationFactorySelection((HotSpotJVMCIRuntime) runtime, factory);
}
HotSpotGraalCompiler compiler = createCompiler("VM", runtime, options, factory);
// Only the HotSpotGraalRuntime associated with the compiler created via
@@ -154,27 +160,13 @@
@Override
public CompilationLevelAdjustment getCompilationLevelAdjustment() {
- if (graalCompileOnlyFilter != null) {
- return CompilationLevelAdjustment.ByFullSignature;
- }
- if (compileGraalWithC1Only) {
- // We only decide using the class declaring the method
- // so no need to have the method name and signature
- // symbols converted to a String.
- return CompilationLevelAdjustment.ByHolder;
- }
- return CompilationLevelAdjustment.None;
+ return isGraalPredicate != null ? isGraalPredicate.getCompilationLevelAdjustment() : None;
}
@Override
public CompilationLevel adjustCompilationLevel(Object declaringClassObject, String name, String signature, boolean isOsr, CompilationLevel level) {
- if (declaringClassObject instanceof String) {
- // This must be SVM mode in which case only GraalCompileC1Only matters since Graal and
- // JVMCI are already compiled.
- return checkGraalCompileOnlyFilter((String) declaringClassObject, name, signature, level);
- }
Class<?> declaringClass = (Class<?>) declaringClassObject;
- return adjustCompilationLevelInternal(declaringClass, name, signature, level);
+ return adjustCompilationLevelInternal(declaringClass, level);
}
static {
@@ -184,32 +176,28 @@
assert HotSpotGraalCompilerFactory.class.getName().equals("org.graalvm.compiler.hotspot.HotSpotGraalCompilerFactory");
}
- private CompilationLevel adjustCompilationLevelInternal(Class<?> declaringClass, String name, String signature, CompilationLevel level) {
- if (compileGraalWithC1Only) {
- if (level.ordinal() > CompilationLevel.Simple.ordinal()) {
- if (isGraalPredicate.apply(declaringClass)) {
- return CompilationLevel.Simple;
- }
- }
- }
- return checkGraalCompileOnlyFilter(declaringClass.getName(), name, signature, level);
- }
-
- public static CompilationLevel checkGraalCompileOnlyFilter(String declaringClassName, String name, String signature, CompilationLevel level) {
- if (graalCompileOnlyFilter != null) {
- if (level == CompilationLevel.FullOptimization) {
- HotSpotSignature sig = null;
- for (MethodFilter filter : graalCompileOnlyFilter) {
- if (filter.hasSignature() && sig == null) {
- sig = new HotSpotSignature(HotSpotJVMCIRuntime.runtime(), signature);
- }
- if (filter.matches(declaringClassName, name, sig)) {
- return level;
- }
- }
+ private CompilationLevel adjustCompilationLevelInternal(Class<?> declaringClass, CompilationLevel level) {
+ assert isGraalPredicate != null;
+ if (level.ordinal() > CompilationLevel.Simple.ordinal()) {
+ if (isGraalPredicate.apply(declaringClass)) {
return CompilationLevel.Simple;
}
}
return level;
}
+
+ static boolean shouldExclude(HotSpotResolvedJavaMethod method) {
+ if (graalCompileOnlyFilter != null) {
+ String javaClassName = method.getDeclaringClass().toJavaName();
+ String name = method.getName();
+ Signature signature = method.getSignature();
+ for (MethodFilter filter : graalCompileOnlyFilter) {
+ if (filter.matches(javaClassName, name, signature)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java Thu Mar 28 19:39:14 2019 +0100
@@ -87,6 +87,7 @@
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.runtime.JVMCI;
import jdk.vm.ci.runtime.JVMCIBackend;
+import jdk.vm.ci.services.Services;
//JaCoCo Exclude
@@ -95,7 +96,7 @@
*/
public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider {
- private static final boolean IS_AOT = Boolean.getBoolean("com.oracle.graalvm.isaot");
+ private static final boolean IS_AOT = Boolean.parseBoolean(Services.getSavedProperties().get("com.oracle.graalvm.isaot"));
private static boolean checkArrayIndexScaleInvariants(MetaAccessProvider metaAccess) {
assert metaAccess.getArrayIndexScale(JavaKind.Byte) == 1;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotTTYStreamProvider.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotTTYStreamProvider.java Thu Mar 28 19:39:14 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -44,6 +44,7 @@
import org.graalvm.compiler.serviceprovider.ServiceProvider;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
+import jdk.vm.ci.services.Services;
@ServiceProvider(TTYStreamProvider.class)
public class HotSpotTTYStreamProvider implements TTYStreamProvider {
@@ -151,7 +152,7 @@
if (inputArguments != null) {
ps.println("VM Arguments: " + String.join(" ", inputArguments));
}
- String cmd = System.getProperty("sun.java.command");
+ String cmd = Services.getSavedProperties().get("sun.java.command");
if (cmd != null) {
ps.println("sun.java.command=" + cmd);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/IsGraalPredicate.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/IsGraalPredicate.java Thu Mar 28 19:39:14 2019 +0100
@@ -25,12 +25,13 @@
package org.graalvm.compiler.hotspot;
import jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory;
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
/**
* Determines if a given class is a JVMCI or Graal class for the purpose of
* {@link HotSpotGraalCompilerFactory.Options#CompileGraalWithC1Only}.
*/
-public class IsGraalPredicate {
+class IsGraalPredicate extends IsGraalPredicateBase {
/**
* Module containing {@link HotSpotJVMCICompilerFactory}.
*/
@@ -47,15 +48,17 @@
*/
private Module compilerConfigurationModule;
- public IsGraalPredicate() {
+ IsGraalPredicate() {
jvmciModule = HotSpotJVMCICompilerFactory.class.getModule();
graalModule = HotSpotGraalCompilerFactory.class.getModule();
}
- void onCompilerConfigurationFactorySelection(CompilerConfigurationFactory factory) {
+ @Override
+ void onCompilerConfigurationFactorySelection(HotSpotJVMCIRuntime runtime, CompilerConfigurationFactory factory) {
compilerConfigurationModule = factory.getClass().getModule();
}
+ @Override
boolean apply(Class<?> declaringClass) {
Module module = declaringClass.getModule();
return jvmciModule == module || graalModule == module || compilerConfigurationModule == module;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/IsGraalPredicateBase.java Thu Mar 28 19:39:14 2019 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2018, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.hotspot;
+
+import jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory;
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
+
+/**
+ * Determines if a given class is a JVMCI or Graal class for the purpose of
+ * {@link HotSpotGraalCompilerFactory.Options#CompileGraalWithC1Only}.
+ */
+abstract class IsGraalPredicateBase {
+
+ @SuppressWarnings("unused")
+ void onCompilerConfigurationFactorySelection(HotSpotJVMCIRuntime runtime, CompilerConfigurationFactory factory) {
+ }
+
+ abstract boolean apply(Class<?> declaringClass);
+
+ HotSpotJVMCICompilerFactory.CompilationLevelAdjustment getCompilationLevelAdjustment() {
+ return HotSpotJVMCICompilerFactory.CompilationLevelAdjustment.ByHolder;
+ }
+}
+
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java Thu Mar 28 19:39:14 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -25,6 +25,9 @@
package org.graalvm.compiler.hotspot;
import java.util.Formatter;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
/**
* Mechanism for checking that the current Java runtime environment supports the minimum JVMCI API
@@ -38,20 +41,22 @@
*/
class JVMCIVersionCheck {
- // 0.55 introduces new HotSpotSpeculationLog API
+ // 0.57 introduces HotSpotJVMCIRuntime.excludeFromJVMCICompilation
private static final int JVMCI8_MIN_MAJOR_VERSION = 0;
- private static final int JVMCI8_MIN_MINOR_VERSION = 55;
+ private static final int JVMCI8_MIN_MINOR_VERSION = 57;
- private static void failVersionCheck(boolean exit, String reason, Object... args) {
+ private static void failVersionCheck(Map<String, String> props, boolean exit, String reason, Object... args) {
Formatter errorMessage = new Formatter().format(reason, args);
- String javaHome = System.getProperty("java.home");
- String vmName = System.getProperty("java.vm.name");
+ String javaHome = props.get("java.home");
+ String vmName = props.get("java.vm.name");
errorMessage.format("Set the JVMCI_VERSION_CHECK environment variable to \"ignore\" to suppress ");
errorMessage.format("this error or to \"warn\" to emit a warning and continue execution.%n");
errorMessage.format("Currently used Java home directory is %s.%n", javaHome);
errorMessage.format("Currently used VM configuration is: %s%n", vmName);
- if (System.getProperty("java.specification.version").compareTo("1.9") < 0) {
- errorMessage.format("Download the latest JVMCI JDK 8 from http://www.oracle.com/technetwork/oracle-labs/program-languages/downloads/index.html");
+ if (props.get("java.specification.version").compareTo("1.9") < 0) {
+ errorMessage.format("Download the latest JVMCI JDK 8 from " +
+ "http://www.oracle.com/technetwork/oracle-labs/program-languages/downloads/index.html or " +
+ "https://github.com/graalvm/openjdk8-jvmci-builder/releases");
} else {
errorMessage.format("Download JDK 11 or later.");
}
@@ -68,10 +73,10 @@
}
}
- static void check(boolean exitOnFailure) {
+ static void check(Map<String, String> props, boolean exitOnFailure) {
// Don't use regular expressions to minimize Graal startup time
- String javaSpecVersion = System.getProperty("java.specification.version");
- String vmVersion = System.getProperty("java.vm.version");
+ String javaSpecVersion = props.get("java.specification.version");
+ String vmVersion = props.get("java.vm.version");
if (javaSpecVersion.compareTo("1.9") < 0) {
int start = vmVersion.indexOf("-jvmci-");
if (start >= 0) {
@@ -82,7 +87,7 @@
try {
major = Integer.parseInt(vmVersion.substring(start, end));
} catch (NumberFormatException e) {
- failVersionCheck(exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
+ failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
"Cannot read JVMCI major version from java.vm.version property: %s.%n", vmVersion);
return;
}
@@ -95,22 +100,22 @@
try {
minor = Integer.parseInt(vmVersion.substring(start, end));
} catch (NumberFormatException e) {
- failVersionCheck(exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
+ failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
"Cannot read JVMCI minor version from java.vm.version property: %s.%n", vmVersion);
return;
}
if (major >= JVMCI8_MIN_MAJOR_VERSION && minor >= JVMCI8_MIN_MINOR_VERSION) {
return;
}
- failVersionCheck(exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal: %d.%d < %d.%d.%n",
+ failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal: %d.%d < %d.%d.%n",
major, minor, JVMCI8_MIN_MAJOR_VERSION, JVMCI8_MIN_MINOR_VERSION);
return;
}
}
- failVersionCheck(exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
+ failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
"Cannot read JVMCI version from java.vm.version property: %s.%n", vmVersion);
} else if (javaSpecVersion.compareTo("11") < 0) {
- failVersionCheck(exitOnFailure, "Graal is not compatible with the JVMCI API in JDK 9 and 10.%n");
+ failVersionCheck(props, exitOnFailure, "Graal is not compatible with the JVMCI API in JDK 9 and 10.%n");
} else {
if (vmVersion.contains("SNAPSHOT")) {
return;
@@ -124,11 +129,11 @@
try {
int build = Integer.parseInt(buildString);
if (build < 20) {
- failVersionCheck(exitOnFailure, "Graal requires build 20 or later of JDK 11 early access binary, got build %d.%n", build);
+ failVersionCheck(props, exitOnFailure, "Graal requires build 20 or later of JDK 11 early access binary, got build %d.%n", build);
return;
}
} catch (NumberFormatException e) {
- failVersionCheck(exitOnFailure, "Could not parse the JDK 11 early access build number from java.vm.version property: %s.%n", vmVersion);
+ failVersionCheck(props, exitOnFailure, "Could not parse the JDK 11 early access build number from java.vm.version property: %s.%n", vmVersion);
return;
}
} else {
@@ -141,6 +146,11 @@
* Command line interface for performing the check.
*/
public static void main(String[] args) {
- check(true);
+ Properties sprops = System.getProperties();
+ Map<String, String> props = new HashMap<>(sprops.size());
+ for (String name : sprops.stringPropertyNames()) {
+ props.put(name, sprops.getProperty(name));
+ }
+ check(props, true);
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/NodeCostDumpUtil.java Thu Mar 28 11:06:00 2019 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,236 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.hotspot;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.nio.file.FileSystem;
-import java.nio.file.FileSystems;
-import java.nio.file.FileVisitResult;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-import java.util.stream.Collectors;
-
-import org.graalvm.compiler.debug.CSVUtil;
-import org.graalvm.compiler.debug.GraalError;
-import org.graalvm.compiler.graph.Node;
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.graph.spi.Canonicalizable;
-import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
-import org.graalvm.compiler.nodes.spi.Virtualizable;
-
-public class NodeCostDumpUtil {
-
- private static final String prefix1 = "com.oracle.";
- private static final String prefix2 = "org.graalvm.";
- private static final String FMT = CSVUtil.buildFormatString("%s", "%s", "%s", "%s", "%s", "%s", "%s", "%s");
-
- private static String getArgumentRegex(String arg) {
- if (arg.length() == 0) {
- return null;
- }
- try {
- Pattern.compile(arg);
- return arg;
- } catch (PatternSyntaxException e) {
- // silently ignore
- System.err.println("Invalid regex given, defaulting to \".*\" regex..");
- return null;
- }
- }
-
- public static void main(String[] args) {
- if (args.length != 1) {
- System.err.println("NodeCostDumpUtil expects exactly one argument, the node name regex to match against.");
- System.exit(-1);
- }
- final String pattern = getArgumentRegex(args[0]);
- String version = System.getProperty("java.specification.version");
- if (version.compareTo("1.9") >= 0) {
- System.err.printf("NodeCostDumpUtil does not support JDK versions greater than 1.8, current version is %s.\n", version);
- System.exit(-1);
- }
- String[] jvmciCP = System.getProperty("jvmci.class.path.append").split(File.pathSeparator);
- String[] primarySuiteCP = System.getProperty("primary.suite.cp").split(File.pathSeparator);
- ClassLoader applicationClassLoader = Thread.currentThread().getContextClassLoader();
- HashSet<Class<?>> classes = new HashSet<>();
- try {
- Set<String> uniquePaths = new HashSet<>(Arrays.asList(primarySuiteCP));
- uniquePaths.addAll(Arrays.asList(jvmciCP));
- for (String path : uniquePaths) {
- if (new File(path).exists()) {
- if (path.endsWith(".jar")) {
- try (FileSystem jarFileSystem = FileSystems.newFileSystem(URI.create("jar:file:" + path), Collections.emptyMap())) {
- initAllClasses(jarFileSystem.getPath("/"), applicationClassLoader, classes);
- }
- } else {
- initAllClasses(FileSystems.getDefault().getPath(path), applicationClassLoader, classes);
- }
- }
- }
- } catch (IOException ex) {
- GraalError.shouldNotReachHere();
- }
- System.err.printf("Loaded %d classes...\n", classes.size());
- List<Class<?>> nodeClasses = new ArrayList<>();
- for (Class<?> loaded : classes) {
- if (Node.class.isAssignableFrom(loaded) && !loaded.isArray()) {
- nodeClasses.add(loaded);
- }
- }
- System.err.printf("Loaded %s node classes...\n", nodeClasses.size());
- List<NodeClass<?>> nc = new ArrayList<>();
- for (Class<?> c : nodeClasses) {
- try {
- nc.add(NodeClass.get(c));
- } catch (Throwable t) {
- // Silently ignore problems here
- }
- }
- System.err.printf("Read TYPE field from %s node classes...\n", nc.size());
- nc = nc.stream().filter(x -> x != null).collect(Collectors.toList());
- nc.sort((x, y) -> {
- String a = x.getJavaClass().getName();
- String b = y.getJavaClass().getName();
- return a.compareTo(b);
- });
- CSVUtil.Escape.println(System.out, FMT, "NodeName", "Size", "Overrides Size Method", "Cycles", "Overrides Cycles Method", "Canonicalizable", "MemoryCheckPoint", "Virtualizable");
- for (NodeClass<?> nodeclass : nc) {
- String packageStrippedName = null;
- try {
- packageStrippedName = nodeclass.getJavaClass().getCanonicalName().replace(prefix1, "").replace(prefix2, "");
- } catch (Throwable t) {
- // do nothing
- continue;
- }
- if (pattern != null && !packageStrippedName.matches(pattern)) {
- continue;
- }
- boolean overridesSizeMethod = false;
- boolean overridesCyclesMethod = false;
- Class<?> c = nodeclass.getJavaClass();
- try {
- c.getDeclaredMethod("estimatedNodeSize");
- overridesSizeMethod = true;
- } catch (Throwable t) {
- // do nothing
- }
- try {
- c.getDeclaredMethod("estimatedNodeCycles");
- overridesCyclesMethod = true;
- } catch (Throwable t) {
- // do nothing
- }
- CSVUtil.Escape.println(System.out, FMT, packageStrippedName, nodeclass.size(), overridesSizeMethod, nodeclass.cycles(), overridesCyclesMethod, canonicalizable(c), memoryCheckPoint(c),
- virtualizable(c));
- }
- }
-
- private static boolean canonicalizable(Class<?> c) {
- return Canonicalizable.class.isAssignableFrom(c);
- }
-
- private static boolean virtualizable(Class<?> c) {
- return Virtualizable.class.isAssignableFrom(c);
- }
-
- private static boolean memoryCheckPoint(Class<?> c) {
- return MemoryCheckpoint.class.isAssignableFrom(c);
- }
-
- private static void initAllClasses(final Path root, ClassLoader classLoader, HashSet<Class<?>> classes) {
- try {
- Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
- String className = root.relativize(file).toString();
- ClassLoader c = classLoader;
- if (className.endsWith(".class")) {
- String prefix = prefixed(className);
- if (prefix != null) {
- String stripped = stripClassName(className);
- c = new URLClassLoader(new URL[]{new File(constructURLPart(stripped, className, prefix)).toURI().toURL()}, classLoader);
- className = constructClazzPart(stripped, prefix);
- } else {
- String clazzPart = className.replace('/', '.');
- className = clazzPart.substring(0, clazzPart.length() - ".class".length());
- }
- try {
- Class<?> systemClass = Class.forName(className, false, c);
- if (systemClass.getEnclosingClass() != null) {
- try {
- classes.add(systemClass.getEnclosingClass());
- } catch (Throwable t) {
- // do nothing
- }
- }
- classes.add(systemClass);
- } catch (Throwable ignored) {
- }
- }
- return FileVisitResult.CONTINUE;
- }
- });
- } catch (IOException ex) {
- GraalError.shouldNotReachHere();
- }
- }
-
- private static String prefixed(String className) {
- if (className.contains(prefix1) && className.indexOf(prefix1) > 0) {
- return prefix1;
- } else if (className.contains(prefix2) && className.indexOf(prefix2) > 0) {
- return prefix2;
- }
- return null;
- }
-
- private static String stripClassName(String className) {
- return className.replace('/', '.');
- }
-
- private static String constructClazzPart(String stripped, String prefix) {
- String clazzPart = stripped.substring(stripped.lastIndexOf(prefix), stripped.length());
- return clazzPart.substring(0, clazzPart.length() - ".class".length());
- }
-
- private static String constructURLPart(String stripped, String className, String prefix) {
- return className.substring(0, stripped.lastIndexOf(prefix));
- }
-
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/SymbolicSnippetEncoder.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/SymbolicSnippetEncoder.java Thu Mar 28 19:39:14 2019 +0100
@@ -48,7 +48,6 @@
import org.graalvm.compiler.api.runtime.GraalJVMCICompiler;
import org.graalvm.compiler.api.runtime.GraalRuntime;
import org.graalvm.compiler.bytecode.BytecodeProvider;
-import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
import org.graalvm.compiler.core.common.type.AbstractObjectStamp;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.core.common.type.StampPair;
@@ -88,7 +87,6 @@
import org.graalvm.compiler.nodes.java.AccessFieldNode;
import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
import org.graalvm.compiler.nodes.spi.DelegatingReplacements;
-import org.graalvm.compiler.nodes.spi.StampProvider;
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.OptimisticOptimizations;
@@ -112,7 +110,6 @@
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.MemoryAccessProvider;
-import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.MethodHandleAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
@@ -311,10 +308,7 @@
PEGraphDecoder graphDecoder = new PEGraphDecoder(
providers.getCodeCache().getTarget().arch,
result,
- providers.getMetaAccess(),
- providers.getConstantReflection(),
- providers.getConstantFieldProvider(),
- providers.getStampProvider(),
+ providers,
null, // loopExplosionPlugin
replacements.getGraphBuilderPlugins().getInvocationPlugins(),
new InlineInvokePlugin[0],
@@ -407,10 +401,7 @@
PEGraphDecoder graphDecoder = new PEGraphDecoder(
architecture,
result,
- providers.getMetaAccess(),
- providers.getConstantReflection(),
- providers.getConstantFieldProvider(),
- providers.getStampProvider(),
+ providers,
null,
replacements.getGraphBuilderPlugins().getInvocationPlugins(),
new InlineInvokePlugin[0],
@@ -993,17 +984,15 @@
}
@Override
- protected GraphBuilderPhase.Instance createGraphBuilder(MetaAccessProvider metaAccess, StampProvider stampProvider, ConstantReflectionProvider constantReflection,
- ConstantFieldProvider constantFieldProvider, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, IntrinsicContext initialIntrinsicContext) {
- return new HotSpotSnippetGraphBuilderPhase(metaAccess, stampProvider, constantReflection, constantFieldProvider, graphBuilderConfig, optimisticOpts,
- initialIntrinsicContext);
+ protected GraphBuilderPhase.Instance createGraphBuilder(Providers providers, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts,
+ IntrinsicContext initialIntrinsicContext) {
+ return new HotSpotSnippetGraphBuilderPhase(providers, graphBuilderConfig, optimisticOpts, initialIntrinsicContext);
}
}
static class HotSpotSnippetGraphBuilderPhase extends GraphBuilderPhase.Instance {
- HotSpotSnippetGraphBuilderPhase(MetaAccessProvider metaAccess, StampProvider stampProvider, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider,
- GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, IntrinsicContext initialIntrinsicContext) {
- super(metaAccess, stampProvider, constantReflection, constantFieldProvider, graphBuilderConfig, optimisticOpts, initialIntrinsicContext);
+ HotSpotSnippetGraphBuilderPhase(Providers theProviders, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, IntrinsicContext initialIntrinsicContext) {
+ super(theProviders, graphBuilderConfig, optimisticOpts, initialIntrinsicContext);
}
@Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/debug/BenchmarkCounters.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/debug/BenchmarkCounters.java Thu Mar 28 19:39:14 2019 +0100
@@ -416,7 +416,9 @@
if (waitingForEnd) {
waitingForEnd = false;
running = false;
- BenchmarkCounters.dump(options, getPrintStream(options), (System.nanoTime() - startTime) / 1000000000d, jvmciRuntime.collectCounters(), 100);
+ try (PrintStreamScope scope = getPrintStream(options)) {
+ BenchmarkCounters.dump(options, scope.out, (System.nanoTime() - startTime) / 1000000000d, jvmciRuntime.collectCounters(), 100);
+ }
}
break;
}
@@ -445,18 +447,19 @@
if (Options.TimedDynamicCounters.getValue(options) > 0) {
Thread thread = new Thread() {
long lastTime = System.nanoTime();
- PrintStream out = getPrintStream(options);
@Override
public void run() {
- while (true) {
- try {
- Thread.sleep(Options.TimedDynamicCounters.getValue(options));
- } catch (InterruptedException e) {
+ try (PrintStreamScope scope = getPrintStream(options)) {
+ while (true) {
+ try {
+ Thread.sleep(Options.TimedDynamicCounters.getValue(options));
+ } catch (InterruptedException e) {
+ }
+ long time = System.nanoTime();
+ dump(options, scope.out, (time - lastTime) / 1000000000d, jvmciRuntime.collectCounters(), 10);
+ lastTime = time;
}
- long time = System.nanoTime();
- dump(options, out, (time - lastTime) / 1000000000d, jvmciRuntime.collectCounters(), 10);
- lastTime = time;
}
}
};
@@ -472,22 +475,39 @@
public static void shutdown(HotSpotJVMCIRuntime jvmciRuntime, OptionValues options, long compilerStartTime) {
if (Options.GenericDynamicCounters.getValue(options)) {
- dump(options, getPrintStream(options), (System.nanoTime() - compilerStartTime) / 1000000000d, jvmciRuntime.collectCounters(), 100);
+ try (PrintStreamScope scope = getPrintStream(options)) {
+ dump(options, scope.out, (System.nanoTime() - compilerStartTime) / 1000000000d, jvmciRuntime.collectCounters(), 100);
+ }
}
}
- private static PrintStream getPrintStream(OptionValues options) {
- if (Options.BenchmarkCountersFile.getValue(options) != null) {
- try {
+ static class PrintStreamScope implements AutoCloseable {
+ final PrintStream out;
- File file = new File(Options.BenchmarkCountersFile.getValue(options));
- TTY.println("Writing benchmark counters to '%s'", file.getAbsolutePath());
- return new PrintStream(file);
- } catch (IOException e) {
- TTY.out().println(e.getMessage());
- TTY.out().println("Fallback to default");
+ PrintStreamScope(OptionValues options) {
+ PrintStream ps = TTY.out;
+ if (Options.BenchmarkCountersFile.getValue(options) != null) {
+ try {
+ File file = new File(Options.BenchmarkCountersFile.getValue(options));
+ TTY.println("Writing benchmark counters to '%s'", file.getAbsolutePath());
+ ps = new PrintStream(file);
+ } catch (IOException e) {
+ TTY.out().println(e.getMessage());
+ TTY.out().println("Fallback to default");
+ }
+ }
+ this.out = ps;
+ }
+
+ @Override
+ public void close() {
+ if (out != TTY.out) {
+ this.out.close();
}
}
- return TTY.out;
+ }
+
+ private static PrintStreamScope getPrintStream(OptionValues options) {
+ return new PrintStreamScope(options);
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotNodePlugin.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotNodePlugin.java Thu Mar 28 19:39:14 2019 +0100
@@ -28,8 +28,6 @@
import static jdk.vm.ci.meta.DeoptimizationReason.TransferToInterpreter;
import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
-import java.lang.reflect.Field;
-
import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.core.common.type.StampPair;
@@ -56,6 +54,7 @@
import org.graalvm.compiler.nodes.memory.address.AddressNode;
import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
import org.graalvm.compiler.nodes.util.ConstantFoldUtil;
+import org.graalvm.compiler.serviceprovider.GraalUnsafeAccess;
import org.graalvm.compiler.word.Word;
import org.graalvm.compiler.word.WordOperationPlugin;
import jdk.internal.vm.compiler.word.LocationIdentity;
@@ -83,6 +82,7 @@
* </ul>
*/
public final class HotSpotNodePlugin implements NodePlugin, TypePlugin {
+ private static final Unsafe UNSAFE = GraalUnsafeAccess.getUnsafe();
protected final WordOperationPlugin wordOperationPlugin;
private final GraalHotSpotVMConfig config;
private final HotSpotWordTypes wordTypes;
@@ -243,21 +243,5 @@
}
private static final LocationIdentity JAVA_THREAD_SHOULD_POST_ON_EXCEPTIONS_FLAG_LOCATION = NamedLocationIdentity.mutable("JavaThread::_should_post_on_exceptions_flag");
- static final Unsafe UNSAFE = initUnsafe();
+}
- static Unsafe initUnsafe() {
- try {
- // Fast path when we are trusted.
- return Unsafe.getUnsafe();
- } catch (SecurityException se) {
- // Slow path when we are not trusted.
- try {
- Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
- theUnsafe.setAccessible(true);
- return (Unsafe) theUnsafe.get(Unsafe.class);
- } catch (Exception e) {
- throw new RuntimeException("exception while trying to get Unsafe", e);
- }
- }
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotObjdumpDisassemblerProvider.java Thu Mar 28 19:39:14 2019 +0100
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.hotspot.meta;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.graalvm.compiler.code.CompilationResult;
+import org.graalvm.compiler.code.CompilationResult.CodeAnnotation;
+import org.graalvm.compiler.code.DisassemblerProvider;
+import org.graalvm.compiler.serviceprovider.ServiceProvider;
+
+import jdk.vm.ci.code.CodeCacheProvider;
+import jdk.vm.ci.code.CodeUtil;
+import jdk.vm.ci.code.CodeUtil.DefaultRefMapFormatter;
+import jdk.vm.ci.code.CodeUtil.RefMapFormatter;
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.RegisterConfig;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.code.site.Call;
+import jdk.vm.ci.code.site.DataPatch;
+import jdk.vm.ci.code.site.Infopoint;
+import jdk.vm.ci.code.site.Mark;
+import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
+import jdk.vm.ci.services.Services;
+
+/**
+ * This disassembles the code immediatly with objdump.
+ */
+@ServiceProvider(DisassemblerProvider.class)
+public class HotSpotObjdumpDisassemblerProvider extends HotSpotDisassemblerProvider {
+
+ /**
+ * Uses objdump to disassemble the compiled code.
+ */
+ @Override
+ public String disassembleCompiledCode(CodeCacheProvider codeCache, CompilationResult compResult) {
+ File tmp = null;
+ try {
+ tmp = File.createTempFile("compiledBinary", ".bin");
+ try (FileOutputStream fos = new FileOutputStream(tmp)) {
+ fos.write(compResult.getTargetCode());
+ }
+ String[] cmdline;
+ String arch = Services.getSavedProperties().get("os.arch");
+ if (arch.equals("amd64")) {
+ cmdline = new String[]{"objdump", "-D", "-b", "binary", "-M", "x86-64", "-m", "i386", tmp.getAbsolutePath()};
+ } else if (arch.equals("aarch64")) {
+ cmdline = new String[]{"objdump", "-D", "-b", "binary", "-m", "aarch64", tmp.getAbsolutePath()};
+ } else {
+ return null;
+ }
+
+ Pattern p = Pattern.compile(" *(([0-9a-fA-F]+):\t.*)");
+
+ TargetDescription target = codeCache.getTarget();
+ RegisterConfig regConfig = codeCache.getRegisterConfig();
+ Register fp = regConfig.getFrameRegister();
+ RefMapFormatter slotFormatter = new DefaultRefMapFormatter(target.wordSize, fp, 0);
+
+ Map<Integer, String> annotations = new HashMap<>();
+ for (DataPatch site : compResult.getDataPatches()) {
+ putAnnotation(annotations, site.pcOffset, "{" + site.reference.toString() + "}");
+ }
+ for (Mark mark : compResult.getMarks()) {
+ putAnnotation(annotations, mark.pcOffset, codeCache.getMarkName(mark));
+ }
+ for (CodeAnnotation a : compResult.getCodeAnnotations()) {
+ putAnnotation(annotations, a.position, a.toString());
+ }
+ for (Infopoint infopoint : compResult.getInfopoints()) {
+ if (infopoint instanceof Call) {
+ Call call = (Call) infopoint;
+ if (call.debugInfo != null) {
+ putAnnotation(annotations, call.pcOffset + call.size, CodeUtil.append(new StringBuilder(100), call.debugInfo, slotFormatter).toString());
+ }
+ putAnnotation(annotations, call.pcOffset, "{" + codeCache.getTargetName(call) + "}");
+ } else {
+ if (infopoint.debugInfo != null) {
+ putAnnotation(annotations, infopoint.pcOffset, CodeUtil.append(new StringBuilder(100), infopoint.debugInfo, slotFormatter).toString());
+ }
+ putAnnotation(annotations, infopoint.pcOffset, "{infopoint: " + infopoint.reason + "}");
+ }
+ }
+
+ Process proc = Runtime.getRuntime().exec(cmdline);
+ InputStream is = proc.getInputStream();
+
+ InputStreamReader isr = new InputStreamReader(is);
+ BufferedReader br = new BufferedReader(isr);
+ String line;
+
+ StringBuilder sb = new StringBuilder();
+ while ((line = br.readLine()) != null) {
+ Matcher m = p.matcher(line);
+ if (m.find()) {
+ int address = Integer.parseInt(m.group(2), 16);
+ String annotation = annotations.get(address);
+ if (annotation != null) {
+ annotation = annotation.replace("\n", "\n; ");
+ sb.append("; ").append(annotation).append('\n');
+ }
+ line = m.replaceAll("0x$1");
+ }
+ sb.append(line).append("\n");
+ }
+ BufferedReader ebr = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
+ while ((line = ebr.readLine()) != null) {
+ System.err.println(line);
+ }
+ ebr.close();
+ return sb.toString();
+ } catch (IOException e) {
+ if (tmp != null) {
+ tmp.delete();
+ }
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ private static void putAnnotation(Map<Integer, String> annotations, int idx, String txt) {
+ String newAnnoation = annotations.getOrDefault(idx, "") + "\n" + txt;
+ annotations.put(idx, newAnnoation);
+ }
+
+ @Override
+ public String disassembleInstalledCode(CodeCacheProvider codeCache, CompilationResult compResult, InstalledCode code) {
+ return ((HotSpotCodeCacheProvider) codeCache).disassemble(code);
+ }
+
+ @Override
+ public String getName() {
+ return "hsdis-objdump";
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotSuitesProvider.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotSuitesProvider.java Thu Mar 28 19:39:14 2019 +0100
@@ -142,8 +142,7 @@
StructuredGraph targetGraph = new StructuredGraph.Builder(graph.getOptions(), graph.getDebug(), AllowAssumptions.YES).method(graph.method()).trackNodeSourcePosition(
graph.trackNodeSourcePosition()).build();
- SimplifyingGraphDecoder graphDecoder = new SimplifyingGraphDecoder(runtime.getTarget().arch, targetGraph, context.getMetaAccess(), context.getConstantReflection(),
- context.getConstantFieldProvider(), context.getStampProvider(), !ImmutableCode.getValue(graph.getOptions()));
+ SimplifyingGraphDecoder graphDecoder = new SimplifyingGraphDecoder(runtime.getTarget().arch, targetGraph, context, !ImmutableCode.getValue(graph.getOptions()));
graphDecoder.decode(encodedGraph);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/AheadOfTimeVerificationPhase.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/AheadOfTimeVerificationPhase.java Thu Mar 28 19:39:14 2019 +0100
@@ -44,17 +44,21 @@
public class AheadOfTimeVerificationPhase extends VerifyPhase<PhaseContext> {
@Override
- protected boolean verify(StructuredGraph graph, PhaseContext context) {
+ protected void verify(StructuredGraph graph, PhaseContext context) {
for (ConstantNode node : getConstantNodes(graph)) {
if (isIllegalObjectConstant(node)) {
throw new VerificationError("illegal object constant: " + node);
}
}
- return true;
}
public static boolean isIllegalObjectConstant(ConstantNode node) {
- return isObject(node) && !isNullReference(node) && !isInternedString(node) && !isDirectMethodHandle(node) && !isBoundMethodHandle(node);
+ return isObject(node) &&
+ !isNullReference(node) &&
+ !isInternedString(node) &&
+ !isDirectMethodHandle(node) &&
+ !isBoundMethodHandle(node) &&
+ !isVarHandle(node);
}
private static boolean isObject(ConstantNode node) {
@@ -79,6 +83,14 @@
return StampTool.typeOrNull(node).getName().startsWith("Ljava/lang/invoke/BoundMethodHandle");
}
+ private static boolean isVarHandle(ConstantNode node) {
+ if (!isObject(node)) {
+ return false;
+ }
+ String name = StampTool.typeOrNull(node).getName();
+ return name.equals("Ljava/lang/invoke/VarHandle$AccessDescriptor;");
+ }
+
private static boolean isInternedString(ConstantNode node) {
if (!isObject(node)) {
return false;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Thu Mar 28 19:39:14 2019 +0100
@@ -420,6 +420,8 @@
import org.graalvm.compiler.nodes.java.RegisterFinalizerNode;
import org.graalvm.compiler.nodes.java.StoreFieldNode;
import org.graalvm.compiler.nodes.java.StoreIndexedNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
+import org.graalvm.compiler.nodes.spi.Replacements;
import org.graalvm.compiler.nodes.spi.StampProvider;
import org.graalvm.compiler.nodes.type.StampTool;
import org.graalvm.compiler.nodes.util.GraphUtil;
@@ -714,10 +716,7 @@
this.debug = graph.getDebug();
this.graphBuilderConfig = graphBuilderInstance.graphBuilderConfig;
this.optimisticOpts = graphBuilderInstance.optimisticOpts;
- this.metaAccess = graphBuilderInstance.metaAccess;
- this.stampProvider = graphBuilderInstance.stampProvider;
- this.constantReflection = graphBuilderInstance.constantReflection;
- this.constantFieldProvider = graphBuilderInstance.constantFieldProvider;
+ this.providers = graphBuilderInstance.providers;
this.stream = new BytecodeStream(code.getCode());
this.profilingInfo = graph.useProfilingInfo() ? code.getProfilingInfo() : null;
this.constantPool = code.getConstantPool();
@@ -778,7 +777,7 @@
@SuppressWarnings("try")
protected void buildRootMethod() {
- FrameStateBuilder startFrameState = new FrameStateBuilder(this, code, graph);
+ FrameStateBuilder startFrameState = new FrameStateBuilder(this, code, graph, graphBuilderConfig.retainLocalVariables());
startFrameState.initializeForMethodStart(graph.getAssumptions(), graphBuilderConfig.eagerResolving() || intrinsicContext != null, graphBuilderConfig.getPlugins());
try (IntrinsicScope s = intrinsicContext != null ? new IntrinsicScope(this) : null) {
@@ -1121,7 +1120,7 @@
AbstractBeginNode dispatchBegin;
if (exceptionObject == null) {
- ExceptionObjectNode newExceptionObject = graph.add(new ExceptionObjectNode(metaAccess));
+ ExceptionObjectNode newExceptionObject = graph.add(new ExceptionObjectNode(getMetaAccess()));
dispatchBegin = newExceptionObject;
dispatchState.push(JavaKind.Object, dispatchBegin);
dispatchState.setRethrowException(true);
@@ -1166,7 +1165,7 @@
}
protected ValueNode genLoadIndexed(ValueNode array, ValueNode index, GuardingNode boundsCheck, JavaKind kind) {
- return LoadIndexedNode.create(graph.getAssumptions(), array, index, boundsCheck, kind, metaAccess, constantReflection);
+ return LoadIndexedNode.create(graph.getAssumptions(), array, index, boundsCheck, kind, getMetaAccess(), getConstantReflection());
}
protected void genStoreIndexed(ValueNode array, ValueNode index, GuardingNode boundsCheck, GuardingNode storeCheck, JavaKind kind, ValueNode value) {
@@ -1242,7 +1241,7 @@
}
protected ValueNode genNormalizeCompare(ValueNode x, ValueNode y, boolean isUnorderedLess) {
- return NormalizeCompareNode.create(x, y, isUnorderedLess, JavaKind.Int, constantReflection);
+ return NormalizeCompareNode.create(x, y, isUnorderedLess, JavaKind.Int, getConstantReflection());
}
protected ValueNode genFloatConvert(FloatConvert op, ValueNode input) {
@@ -1273,15 +1272,15 @@
}
protected LogicNode genObjectEquals(ValueNode x, ValueNode y) {
- return ObjectEqualsNode.create(constantReflection, metaAccess, options, x, y, NodeView.DEFAULT);
+ return ObjectEqualsNode.create(getConstantReflection(), getMetaAccess(), options, x, y, NodeView.DEFAULT);
}
protected LogicNode genIntegerEquals(ValueNode x, ValueNode y) {
- return IntegerEqualsNode.create(constantReflection, metaAccess, options, null, x, y, NodeView.DEFAULT);
+ return IntegerEqualsNode.create(getConstantReflection(), getMetaAccess(), options, null, x, y, NodeView.DEFAULT);
}
protected LogicNode genIntegerLessThan(ValueNode x, ValueNode y) {
- return IntegerLessThanNode.create(constantReflection, metaAccess, options, null, x, y, NodeView.DEFAULT);
+ return IntegerLessThanNode.create(getConstantReflection(), getMetaAccess(), options, null, x, y, NodeView.DEFAULT);
}
protected ValueNode genUnique(ValueNode x) {
@@ -1372,7 +1371,7 @@
return null;
}
ValueNode length = append(genArrayLength(receiver));
- LogicNode condition = genUnique(IntegerBelowNode.create(constantReflection, metaAccess, options, null, index, length, NodeView.DEFAULT));
+ LogicNode condition = genUnique(IntegerBelowNode.create(getConstantReflection(), getMetaAccess(), options, null, index, length, NodeView.DEFAULT));
return emitBytecodeExceptionCheck(condition, true, BytecodeExceptionKind.OUT_OF_BOUNDS, index, length);
}
@@ -1380,8 +1379,8 @@
if (elementKind != JavaKind.Object || StampTool.isPointerAlwaysNull(value) || !needsExplicitStoreCheckException(array, value)) {
return null;
}
- ValueNode arrayClass = genUnique(LoadHubNode.create(array, stampProvider, metaAccess, constantReflection));
- ValueNode componentHub = append(LoadArrayComponentHubNode.create(arrayClass, stampProvider, metaAccess, constantReflection));
+ ValueNode arrayClass = genUnique(LoadHubNode.create(array, getStampProvider(), getMetaAccess(), getConstantReflection()));
+ ValueNode componentHub = append(LoadArrayComponentHubNode.create(arrayClass, getStampProvider(), getMetaAccess(), getConstantReflection()));
LogicNode condition = genUnique(InstanceOfDynamicNode.create(graph.getAssumptions(), getConstantReflection(), componentHub, value, true));
return emitBytecodeExceptionCheck(condition, true, BytecodeExceptionKind.ARRAY_STORE, value);
}
@@ -1391,7 +1390,7 @@
return null;
}
ConstantNode zero = ConstantNode.defaultForKind(y.getStackKind(), graph);
- LogicNode condition = genUnique(IntegerEqualsNode.create(constantReflection, metaAccess, options, null, y, zero, NodeView.DEFAULT));
+ LogicNode condition = genUnique(IntegerEqualsNode.create(getConstantReflection(), getMetaAccess(), options, null, y, zero, NodeView.DEFAULT));
return emitBytecodeExceptionCheck(condition, false, BytecodeExceptionKind.DIVISION_BY_ZERO);
}
@@ -1400,7 +1399,7 @@
return null;
}
- BytecodeExceptionNode exception = graph.add(new BytecodeExceptionNode(metaAccess, exceptionKind, arguments));
+ BytecodeExceptionNode exception = graph.add(new BytecodeExceptionNode(getMetaAccess(), exceptionKind, arguments));
AbstractBeginNode passingSuccessor = graph.add(new BeginNode());
FixedNode trueSuccessor = passingOnTrue ? passingSuccessor : exception;
@@ -1416,7 +1415,7 @@
}
protected ValueNode genArrayLength(ValueNode x) {
- return ArrayLengthNode.create(x, constantReflection);
+ return ArrayLengthNode.create(x, getConstantReflection());
}
protected void genStoreField(ValueNode receiver, ResolvedJavaField field, ValueNode value) {
@@ -1567,7 +1566,7 @@
FrameState stateBefore = createCurrentFrameState();
appendixNode = invokeDynamicPlugin.genAppendixNode(this, cpi, opcode, appendix, stateBefore);
} else {
- appendixNode = ConstantNode.forConstant(appendix, metaAccess, graph);
+ appendixNode = ConstantNode.forConstant(appendix, getMetaAccess(), graph);
}
frameState.push(JavaKind.Object, appendixNode);
@@ -1629,10 +1628,7 @@
protected final ProfilingInfo profilingInfo;
protected final OptimisticOptimizations optimisticOpts;
protected final ConstantPool constantPool;
- protected final MetaAccessProvider metaAccess;
- private final ConstantReflectionProvider constantReflection;
- private final ConstantFieldProvider constantFieldProvider;
- private final StampProvider stampProvider;
+ protected final CoreProviders providers;
protected final IntrinsicContext intrinsicContext;
@Override
@@ -1954,7 +1950,7 @@
}
String error(String format, Object... a) {
- return String.format(format, a) + String.format("%n\tplugin at %s", plugin.getApplySourceLocation(metaAccess));
+ return String.format(format, a) + String.format("%n\tplugin at %s", plugin.getApplySourceLocation(getMetaAccess()));
}
boolean check(boolean pluginResult) {
@@ -2039,11 +2035,12 @@
Mark mark = graph.getMark();
FixedWithNextNode currentLastInstr = lastInstr;
ValueNode nonNullReceiver = pluginReceiver.get();
- Stamp methodStamp = stampProvider.createMethodStamp();
- LoadHubNode hub = graph.unique(new LoadHubNode(stampProvider, nonNullReceiver));
+ Stamp methodStamp = getStampProvider().createMethodStamp();
+ LoadHubNode hub = graph.unique(new LoadHubNode(getStampProvider(), nonNullReceiver));
LoadMethodNode actual = append(new LoadMethodNode(methodStamp, targetMethod, receiverType, method.getDeclaringClass(), hub));
ConstantNode expected = graph.unique(ConstantNode.forConstant(methodStamp, targetMethod.getEncoding(), getMetaAccess()));
- LogicNode compare = graph.addOrUniqueWithInputs(CompareNode.createCompareNode(constantReflection, metaAccess, options, null, CanonicalCondition.EQ, actual, expected, NodeView.DEFAULT));
+ LogicNode compare = graph.addOrUniqueWithInputs(
+ CompareNode.createCompareNode(getConstantReflection(), getMetaAccess(), options, null, CanonicalCondition.EQ, actual, expected, NodeView.DEFAULT));
JavaTypeProfile profile = null;
if (profilingInfo != null && this.optimisticOpts.useTypeCheckHints(getOptions())) {
@@ -2321,7 +2318,7 @@
}
return false;
}
- if (canInlinePartialIntrinsicExit() && InlinePartialIntrinsicExitDuringParsing.getValue(options) && !IS_BUILDING_NATIVE_IMAGE) {
+ if (canInlinePartialIntrinsicExit()) {
// Otherwise inline the original method. Any frame state created
// during the inlining will exclude frame(s) in the
// intrinsic method (see FrameStateBuilder.create(int bci)).
@@ -2384,7 +2381,7 @@
* intrinsic) can be inlined.
*/
protected boolean canInlinePartialIntrinsicExit() {
- return true;
+ return InlinePartialIntrinsicExitDuringParsing.getValue(options) && !IS_BUILDING_NATIVE_IMAGE && method.getAnnotation(Snippet.class) == null;
}
private void printInlining(ResolvedJavaMethod targetMethod, ResolvedJavaMethod inlinedMethod, boolean success, String msg) {
@@ -2446,7 +2443,7 @@
try (IntrinsicScope s = calleeIntrinsicContext != null && !parsingIntrinsic() ? new IntrinsicScope(this, targetMethod.getSignature().toParameterKinds(!targetMethod.isStatic()), args) : null) {
BytecodeParser parser = graphBuilderInstance.createBytecodeParser(graph, this, targetMethod, INVOCATION_ENTRY_BCI, calleeIntrinsicContext);
- FrameStateBuilder startFrameState = new FrameStateBuilder(parser, parser.code, graph);
+ FrameStateBuilder startFrameState = new FrameStateBuilder(parser, parser.code, graph, graphBuilderConfig.retainLocalVariables());
if (!targetMethod.isStatic()) {
args[0] = nullCheckedValue(args[0]);
}
@@ -2679,7 +2676,7 @@
JsrScope scope = currentBlock.getJsrScope();
int retAddress = scope.nextReturnAddress();
ConstantNode returnBciNode = getJsrConstant(retAddress);
- LogicNode guard = IntegerEqualsNode.create(constantReflection, metaAccess, options, null, local, returnBciNode, NodeView.DEFAULT);
+ LogicNode guard = IntegerEqualsNode.create(getConstantReflection(), getMetaAccess(), options, null, local, returnBciNode, NodeView.DEFAULT);
guard = graph.addOrUniqueWithInputs(guard);
append(new FixedGuardNode(guard, JavaSubroutineMismatch, InvalidateReprofile));
if (!successor.getJsrScope().equals(scope.pop())) {
@@ -2731,7 +2728,7 @@
protected ConstantNode appendConstant(JavaConstant constant) {
assert constant != null;
- return ConstantNode.forConstant(constant, metaAccess, graph);
+ return ConstantNode.forConstant(constant, getMetaAccess(), graph);
}
@Override
@@ -3602,12 +3599,17 @@
@Override
public StampProvider getStampProvider() {
- return stampProvider;
+ return providers.getStampProvider();
}
@Override
public MetaAccessProvider getMetaAccess() {
- return metaAccess;
+ return providers.getMetaAccess();
+ }
+
+ @Override
+ public Replacements getReplacements() {
+ return providers.getReplacements();
}
@Override
@@ -3623,12 +3625,12 @@
@Override
public ConstantReflectionProvider getConstantReflection() {
- return constantReflection;
+ return providers.getConstantReflection();
}
@Override
public ConstantFieldProvider getConstantFieldProvider() {
- return constantFieldProvider;
+ return providers.getConstantFieldProvider();
}
/**
@@ -3753,7 +3755,7 @@
private JavaKind refineComponentType(ValueNode array, JavaKind kind) {
if (kind == JavaKind.Byte) {
- JavaType type = array.stamp(NodeView.DEFAULT).javaType(metaAccess);
+ JavaType type = array.stamp(NodeView.DEFAULT).javaType(getMetaAccess());
if (type.isArray()) {
JavaType componentType = type.getComponentType();
if (componentType != null) {
@@ -4308,7 +4310,7 @@
}
private void genNewPrimitiveArray(int typeCode) {
- ResolvedJavaType elementType = metaAccess.lookupJavaType(arrayTypeCodeToClass(typeCode));
+ ResolvedJavaType elementType = getMetaAccess().lookupJavaType(arrayTypeCodeToClass(typeCode));
ValueNode length = frameState.pop(JavaKind.Int);
for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
@@ -4492,7 +4494,7 @@
@Override
public AbstractBeginNode genExplicitExceptionEdge(BytecodeExceptionKind exceptionKind) {
- BytecodeExceptionNode exceptionNode = graph.add(new BytecodeExceptionNode(metaAccess, exceptionKind));
+ BytecodeExceptionNode exceptionNode = graph.add(new BytecodeExceptionNode(getMetaAccess(), exceptionKind));
exceptionNode.setStateAfter(createFrameState(bci(), exceptionNode));
AbstractBeginNode exceptionDispatch = handleException(exceptionNode, bci(), false);
exceptionNode.setNext(exceptionDispatch);
@@ -5113,3 +5115,4 @@
return n == 0 ? "" : format("%" + n + "s", "");
}
}
+
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java Thu Mar 28 19:39:14 2019 +0100
@@ -118,17 +118,18 @@
* @param graph the target graph of Graal nodes created by the builder
*/
public FrameStateBuilder(GraphBuilderTool tool, ResolvedJavaMethod method, StructuredGraph graph) {
- this(tool, new ResolvedJavaMethodBytecode(method), graph);
+ this(tool, new ResolvedJavaMethodBytecode(method), graph, false);
}
/**
* Creates a new frame state builder for the given code attribute, method and the given target
- * graph.
+ * graph. Additionally specifies if nonLiveLocals should be retained.
*
* @param code the bytecode in which the frame exists
* @param graph the target graph of Graal nodes created by the builder
+ * @param shouldRetainLocalVariables specifies if nonLiveLocals should be retained in state.
*/
- public FrameStateBuilder(GraphBuilderTool tool, Bytecode code, StructuredGraph graph) {
+ public FrameStateBuilder(GraphBuilderTool tool, Bytecode code, StructuredGraph graph, boolean shouldRetainLocalVariables) {
this.tool = tool;
if (tool instanceof BytecodeParser) {
this.parser = (BytecodeParser) tool;
@@ -144,7 +145,7 @@
this.monitorIds = EMPTY_MONITOR_ARRAY;
this.graph = graph;
- this.clearNonLiveLocals = GraalOptions.OptClearNonLiveLocals.getValue(graph.getOptions());
+ this.clearNonLiveLocals = GraalOptions.OptClearNonLiveLocals.getValue(graph.getOptions()) && !shouldRetainLocalVariables;
this.canVerifyKind = true;
}
@@ -630,12 +631,12 @@
public void clearNonLiveLocals(BciBlock block, LocalLiveness liveness, boolean liveIn) {
/*
- * (lstadler) if somebody is tempted to remove/disable this clearing code: it's possible to
- * remove it for normal compilations, but not for OSR compilations - otherwise dead object
- * slots at the OSR entry aren't cleared. it is also not enough to rely on PiNodes with
- * Kind.Illegal, because the conflicting branch might not have been parsed.
+ * Non-live local clearing is mandatory for the entry block of an OSR compilation so that
+ * dead object slots at the OSR entry are cleared. It's not sufficient to rely on PiNodes
+ * with Kind.Illegal, because the conflicting branch might not have been parsed.
*/
- if (!clearNonLiveLocals) {
+ boolean isOSREntryBlock = graph.isOSR() && getMethod().equals(graph.method()) && graph.getEntryBCI() == block.startBci;
+ if (!clearNonLiveLocals && !isOSREntryBlock) {
return;
}
if (liveIn) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/GraphBuilderPhase.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/GraphBuilderPhase.java Thu Mar 28 19:39:14 2019 +0100
@@ -24,17 +24,14 @@
package org.graalvm.compiler.java;
-import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext;
-import org.graalvm.compiler.nodes.spi.StampProvider;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
import org.graalvm.compiler.phases.BasePhase;
import org.graalvm.compiler.phases.OptimisticOptimizations;
import org.graalvm.compiler.phases.tiers.HighTierContext;
-import jdk.vm.ci.meta.ConstantReflectionProvider;
-import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
@@ -55,8 +52,7 @@
@Override
protected void run(StructuredGraph graph, HighTierContext context) {
- new Instance(context.getMetaAccess(), context.getStampProvider(), context.getConstantReflection(), context.getConstantFieldProvider(), graphBuilderConfig, context.getOptimisticOptimizations(),
- null).run(graph);
+ new Instance(context, graphBuilderConfig, context.getOptimisticOptimizations(), null).run(graph);
}
public GraphBuilderConfiguration getGraphBuilderConfig() {
@@ -66,22 +62,15 @@
// Fully qualified name is a workaround for JDK-8056066
public static class Instance extends org.graalvm.compiler.phases.Phase {
- protected final MetaAccessProvider metaAccess;
- protected final StampProvider stampProvider;
- protected final ConstantReflectionProvider constantReflection;
- protected final ConstantFieldProvider constantFieldProvider;
+ protected final CoreProviders providers;
protected final GraphBuilderConfiguration graphBuilderConfig;
protected final OptimisticOptimizations optimisticOpts;
private final IntrinsicContext initialIntrinsicContext;
- public Instance(MetaAccessProvider metaAccess, StampProvider stampProvider, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider,
- GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, IntrinsicContext initialIntrinsicContext) {
+ public Instance(CoreProviders providers, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, IntrinsicContext initialIntrinsicContext) {
this.graphBuilderConfig = graphBuilderConfig;
this.optimisticOpts = optimisticOpts;
- this.metaAccess = metaAccess;
- this.stampProvider = stampProvider;
- this.constantReflection = constantReflection;
- this.constantFieldProvider = constantFieldProvider;
+ this.providers = providers;
this.initialIntrinsicContext = initialIntrinsicContext;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ArithmeticLIRGeneratorTool.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ArithmeticLIRGeneratorTool.java Thu Mar 28 19:39:14 2019 +0100
@@ -24,10 +24,8 @@
package org.graalvm.compiler.lir.aarch64;
-import org.graalvm.compiler.lir.Variable;
import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
-import jdk.vm.ci.aarch64.AArch64Kind;
import jdk.vm.ci.meta.Value;
/**
@@ -53,6 +51,4 @@
}
Value emitRound(Value value, RoundingMode mode);
-
- void emitCompareOp(AArch64Kind cmpKind, Variable left, Value right);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64Call.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64Call.java Thu Mar 28 19:39:14 2019 +0100
@@ -215,7 +215,7 @@
* Offset might not fit into a 28-bit immediate, generate an indirect call with a
* 64-bit immediate address which is fixed up by HotSpot.
*/
- masm.movNativeAddress(scratch, 0L);
+ masm.movNativeAddress(scratch, 0L, true);
masm.blr(scratch);
}
} else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64Compare.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64Compare.java Thu Mar 28 19:39:14 2019 +0100
@@ -24,22 +24,21 @@
package org.graalvm.compiler.lir.aarch64;
+import static jdk.vm.ci.code.ValueUtil.asRegister;
+import static jdk.vm.ci.code.ValueUtil.isRegister;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.CONST;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
import static org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant;
import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant;
-import static jdk.vm.ci.code.ValueUtil.asRegister;
-import static jdk.vm.ci.code.ValueUtil.isRegister;
-import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.asm.aarch64.AArch64Assembler;
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
+import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.core.common.calc.Condition;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
-import jdk.vm.ci.aarch64.AArch64Kind;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.Value;
@@ -53,8 +52,7 @@
public CompareOp(Value x, Value y) {
super(TYPE);
- assert ((AArch64Kind) x.getPlatformKind()).isInteger() && ((AArch64Kind) y.getPlatformKind()).isInteger();
- assert x.getPlatformKind() == y.getPlatformKind();
+ assert x.getPlatformKind() == y.getPlatformKind() : x.getPlatformKind() + " " + y.getPlatformKind();
this.x = x;
this.y = y;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ControlFlow.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ControlFlow.java Thu Mar 28 19:39:14 2019 +0100
@@ -24,22 +24,24 @@
package org.graalvm.compiler.lir.aarch64;
+import static jdk.vm.ci.aarch64.AArch64.lr;
import static jdk.vm.ci.code.ValueUtil.asAllocatableValue;
import static jdk.vm.ci.code.ValueUtil.asRegister;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
import java.util.function.Function;
import jdk.vm.ci.meta.AllocatableValue;
import org.graalvm.compiler.asm.Label;
-import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.asm.aarch64.AArch64Assembler;
import org.graalvm.compiler.asm.aarch64.AArch64Assembler.ConditionFlag;
import org.graalvm.compiler.asm.aarch64.AArch64Assembler.ExtendType;
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
import org.graalvm.compiler.code.CompilationResult.JumpTable;
import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.core.common.calc.Condition;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.lir.ConstantValue;
@@ -47,6 +49,7 @@
import org.graalvm.compiler.lir.LabelRef;
import org.graalvm.compiler.lir.Opcode;
import org.graalvm.compiler.lir.StandardOp;
+import org.graalvm.compiler.lir.StandardOp.BlockEndOp;
import org.graalvm.compiler.lir.SwitchStrategy;
import org.graalvm.compiler.lir.SwitchStrategy.BaseSwitchClosure;
import org.graalvm.compiler.lir.Variable;
@@ -59,6 +62,21 @@
import jdk.vm.ci.meta.Value;
public class AArch64ControlFlow {
+ public static final class ReturnOp extends AArch64BlockEndOp implements BlockEndOp {
+ public static final LIRInstructionClass<ReturnOp> TYPE = LIRInstructionClass.create(ReturnOp.class);
+ @Use({REG, ILLEGAL}) protected Value x;
+
+ public ReturnOp(Value x) {
+ super(TYPE);
+ this.x = x;
+ }
+
+ @Override
+ protected void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
+ crb.frameContext.leave(crb);
+ masm.ret(lr);
+ }
+ }
public abstract static class AbstractBranchOp extends AArch64BlockEndOp implements StandardOp.BranchOp {
private final LabelRef trueDestination;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64MathIntrinsicBinaryOp.java Thu Mar 28 19:39:14 2019 +0100
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.lir.aarch64;
+
+import static jdk.vm.ci.aarch64.AArch64.v0;
+import static jdk.vm.ci.aarch64.AArch64.v1;
+
+import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.debug.GraalError;
+import org.graalvm.compiler.lir.LIRInstructionClass;
+import org.graalvm.compiler.lir.Variable;
+import org.graalvm.compiler.lir.gen.LIRGenerator;
+
+import jdk.vm.ci.aarch64.AArch64;
+import jdk.vm.ci.aarch64.AArch64Kind;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.RegisterValue;
+import jdk.vm.ci.meta.Value;
+
+public abstract class AArch64MathIntrinsicBinaryOp extends AArch64LIRInstruction {
+
+ @Def protected Value output;
+ @Use protected Value input0;
+ @Use protected Value input1;
+ @Temp protected Value[] temps;
+
+ public AArch64MathIntrinsicBinaryOp(LIRInstructionClass<? extends AArch64LIRInstruction> type, Register... registers) {
+ super(type);
+ input0 = v0.asValue(LIRKind.value(AArch64Kind.V64_WORD));
+ input1 = v0.asValue(LIRKind.value(AArch64Kind.V64_WORD));
+ output = v0.asValue(LIRKind.value(AArch64Kind.V64_WORD));
+
+ temps = registersToValues(registers);
+ }
+
+ protected static Value[] registersToValues(Register[] registers) {
+ Value[] temps = new Value[registers.length];
+ for (int i = 0; i < registers.length; i++) {
+ Register register = registers[i];
+ if (AArch64.CPU.equals(register.getRegisterCategory())) {
+ temps[i] = register.asValue(LIRKind.value(AArch64Kind.V64_WORD));
+ } else if (AArch64.SIMD.equals(register.getRegisterCategory())) {
+ temps[i] = register.asValue(LIRKind.value(AArch64Kind.V64_WORD));
+ } else {
+ throw GraalError.shouldNotReachHere("Unsupported register type in math stubs.");
+ }
+ }
+ return temps;
+ }
+
+ public final Variable emitLIRWrapper(LIRGenerator gen, Value x, Value y) {
+ LIRKind kind = LIRKind.combine(x, y);
+ RegisterValue v0value = v0.asValue(kind);
+ gen.emitMove(v0value, x);
+ RegisterValue v1value = v1.asValue(kind);
+ gen.emitMove(v1value, y);
+ gen.append(this);
+ Variable result = gen.newVariable(kind);
+ gen.emitMove(result, v0value);
+ return result;
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64Move.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64Move.java Thu Mar 28 19:39:14 2019 +0100
@@ -31,18 +31,25 @@
import static jdk.vm.ci.code.ValueUtil.asStackSlot;
import static jdk.vm.ci.code.ValueUtil.isRegister;
import static jdk.vm.ci.code.ValueUtil.isStackSlot;
+import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.COMPOSITE;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.CONST;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.UNINITIALIZED;
import static org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant;
import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant;
+import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.aarch64.AArch64Address;
+import org.graalvm.compiler.asm.aarch64.AArch64Assembler;
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler.ScratchRegister;
+import org.graalvm.compiler.core.common.CompressEncoding;
import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.core.common.spi.LIRKindTool;
import org.graalvm.compiler.core.common.type.DataPointerConstant;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.lir.LIRFrameState;
@@ -54,6 +61,7 @@
import org.graalvm.compiler.lir.StandardOp.ValueMoveOp;
import org.graalvm.compiler.lir.VirtualStackSlot;
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
+import org.graalvm.compiler.options.OptionValues;
import jdk.vm.ci.aarch64.AArch64Kind;
import jdk.vm.ci.code.MemoryBarriers;
@@ -507,10 +515,14 @@
break;
case Object:
if (input.isNull()) {
- masm.mov(dst, 0);
+ if (crb.mustReplaceWithNullRegister(input)) {
+ masm.mov(64, dst, crb.nullRegister);
+ } else {
+ masm.mov(dst, 0);
+ }
} else if (crb.target.inlineObjects) {
crb.recordInlineDataInCode(input);
- masm.movNativeAddress(dst, 0xDEADDEADDEADDEADL);
+ masm.mov(dst, 0xDEADDEADDEADDEADL, true);
} else {
masm.ldr(64, dst, (AArch64Address) crb.recordDataReferenceInCode(input, 8));
}
@@ -561,4 +573,131 @@
return masm.makeAddress(sp, displacement, scratchReg, transferSize, /* allowOverwrite */false);
}
+ public abstract static class PointerCompressionOp extends AArch64LIRInstruction {
+
+ @Def({REG, HINT}) private AllocatableValue result;
+ @Use({REG, CONST}) private Value input;
+ @Alive({REG, ILLEGAL, UNINITIALIZED}) private AllocatableValue baseRegister;
+
+ protected final CompressEncoding encoding;
+ protected final boolean nonNull;
+ protected final LIRKindTool lirKindTool;
+
+ protected PointerCompressionOp(LIRInstructionClass<? extends PointerCompressionOp> type, AllocatableValue result, Value input,
+ AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull, LIRKindTool lirKindTool) {
+
+ super(type);
+ this.result = result;
+ this.input = input;
+ this.baseRegister = baseRegister;
+ this.encoding = encoding;
+ this.nonNull = nonNull;
+ this.lirKindTool = lirKindTool;
+ }
+
+ public static boolean hasBase(OptionValues options, CompressEncoding encoding) {
+ return GeneratePIC.getValue(options) || encoding.hasBase();
+ }
+
+ public final Value getInput() {
+ return input;
+ }
+
+ public final AllocatableValue getResult() {
+ return result;
+ }
+
+ protected final Register getResultRegister() {
+ return asRegister(result);
+ }
+
+ protected final Register getBaseRegister(CompilationResultBuilder crb) {
+ return hasBase(crb.getOptions(), encoding) ? asRegister(baseRegister) : Register.None;
+ }
+
+ protected final int getShift() {
+ return encoding.getShift();
+ }
+
+ protected final void move(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
+ AArch64Move.move(crb, masm, result, input);
+ }
+ }
+
+ public static class CompressPointerOp extends PointerCompressionOp {
+ public static final LIRInstructionClass<CompressPointerOp> TYPE = LIRInstructionClass.create(CompressPointerOp.class);
+
+ public CompressPointerOp(AllocatableValue result, Value input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull, LIRKindTool lirKindTool) {
+ this(TYPE, result, input, baseRegister, encoding, nonNull, lirKindTool);
+ }
+
+ private CompressPointerOp(LIRInstructionClass<? extends PointerCompressionOp> type, AllocatableValue result, Value input,
+ AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull, LIRKindTool lirKindTool) {
+
+ super(type, result, input, baseRegister, encoding, nonNull, lirKindTool);
+ }
+
+ @Override
+ protected void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
+ Register resultRegister = getResultRegister();
+ Register ptr = asRegister(getInput());
+ Register base = getBaseRegister(crb);
+ // result = (ptr - base) >> shift
+ if (!encoding.hasBase()) {
+ if (encoding.hasShift()) {
+ masm.lshr(64, resultRegister, ptr, encoding.getShift());
+ } else {
+ masm.movx(resultRegister, ptr);
+ }
+ } else if (nonNull) {
+ masm.sub(64, resultRegister, ptr, base);
+ if (encoding.hasShift()) {
+ masm.lshr(64, resultRegister, resultRegister, encoding.getShift());
+ }
+ } else {
+ // if ptr is null it still has to be null after compression
+ masm.cmp(64, ptr, 0);
+ masm.cmov(64, resultRegister, ptr, base, AArch64Assembler.ConditionFlag.NE);
+ masm.sub(64, resultRegister, resultRegister, base);
+ if (encoding.hasShift()) {
+ masm.lshr(64, resultRegister, resultRegister, encoding.getShift());
+ }
+ }
+ }
+ }
+
+ public static class UncompressPointerOp extends PointerCompressionOp {
+ public static final LIRInstructionClass<UncompressPointerOp> TYPE = LIRInstructionClass.create(UncompressPointerOp.class);
+
+ public UncompressPointerOp(AllocatableValue result, Value input, AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull, LIRKindTool lirKindTool) {
+ this(TYPE, result, input, baseRegister, encoding, nonNull, lirKindTool);
+ }
+
+ private UncompressPointerOp(LIRInstructionClass<? extends PointerCompressionOp> type, AllocatableValue result, Value input,
+ AllocatableValue baseRegister, CompressEncoding encoding, boolean nonNull, LIRKindTool lirKindTool) {
+ super(type, result, input, baseRegister, encoding, nonNull, lirKindTool);
+ }
+
+ @Override
+ protected void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
+ Register inputRegister = asRegister(getInput());
+ Register resultRegister = getResultRegister();
+ Register base = encoding.hasBase() ? getBaseRegister(crb) : null;
+
+ // result = base + (ptr << shift)
+ if (nonNull || base == null) {
+ masm.add(64, resultRegister, base == null ? zr : base, inputRegister, AArch64Assembler.ShiftType.LSL, encoding.getShift());
+ } else {
+ // if ptr is null it has to be null after decompression
+ Label done = new Label();
+ if (!resultRegister.equals(inputRegister)) {
+ masm.mov(32, resultRegister, inputRegister);
+ }
+ masm.cbz(32, resultRegister, done);
+ masm.add(64, resultRegister, base, resultRegister, AArch64Assembler.ShiftType.LSL, encoding.getShift());
+ masm.bind(done);
+ }
+ }
+ }
+
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayIndexOfOp.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayIndexOfOp.java Thu Mar 28 19:39:14 2019 +0100
@@ -655,3 +655,4 @@
return ((AMD64) tool.target().arch).getFeatures().contains(cpuFeature);
}
}
+
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Binary.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64Binary.java Thu Mar 28 19:39:14 2019 +0100
@@ -137,6 +137,11 @@
opcode.emit(masm, size, asRegister(result), (AMD64Address) crb.asAddress(input));
}
}
+
+ public AMD64RMOp getOpcode() {
+ return opcode;
+ }
+
}
/**
@@ -263,6 +268,11 @@
}
return false;
}
+
+ public AMD64RMOp getOpcode() {
+ return opcode;
+ }
+
}
/**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64BinaryConsumer.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64BinaryConsumer.java Thu Mar 28 19:39:14 2019 +0100
@@ -131,6 +131,10 @@
protected boolean shouldAnnotate() {
return false;
}
+
+ public AMD64MIOp getOpcode() {
+ return opcode;
+ }
}
/**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGenerator.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGenerator.java Thu Mar 28 19:39:14 2019 +0100
@@ -46,6 +46,7 @@
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
import org.graalvm.compiler.core.common.spi.LIRKindTool;
import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.debug.TTY;
import org.graalvm.compiler.graph.NodeSourcePosition;
@@ -386,6 +387,24 @@
return blockScope;
}
+ private final class MatchScope implements DebugCloseable {
+
+ private MatchScope(AbstractBlockBase<?> block) {
+ currentBlock = block;
+ }
+
+ @Override
+ public void close() {
+ currentBlock = null;
+ }
+
+ }
+
+ public final DebugCloseable getMatchScope(AbstractBlockBase<?> block) {
+ MatchScope matchScope = new MatchScope(block);
+ return matchScope;
+ }
+
@Override
public void emitIncomingValues(Value[] params) {
((LabelOp) res.getLIR().getLIRforBlock(getCurrentBlock()).get(0)).setIncomingValues(params);
@@ -457,7 +476,8 @@
double minDensity = 1 / Math.sqrt(strategy.getAverageEffort());
Optional<Hasher> hasher = hasherFor(keyConstants, minDensity);
double hashTableSwitchDensity = hasher.map(h -> keyCount / (double) h.cardinality()).orElse(0d);
- long valueRange = keyConstants[keyCount - 1].asLong() - keyConstants[0].asLong() + 1;
+ // The value range computation below may overflow, so compute it as a long.
+ long valueRange = (long) keyConstants[keyCount - 1].asInt() - (long) keyConstants[0].asInt() + 1;
double tableSwitchDensity = keyCount / (double) valueRange;
/*
@@ -479,7 +499,7 @@
targets[i] = defaultTarget;
}
for (int i = 0; i < keyCount; i++) {
- int idx = h.hash(keyConstants[i].asLong());
+ int idx = h.hash(keyConstants[i].asInt());
keys[idx] = keyConstants[i];
targets[idx] = keyTargets[i];
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java Thu Mar 28 19:39:14 2019 +0100
@@ -269,11 +269,6 @@
Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length, int constantLength, boolean directPointers);
@SuppressWarnings("unused")
- default ForeignCallLinkage lookupArrayEqualsStub(JavaKind kind, int constantLength) {
- return null;
- }
-
- @SuppressWarnings("unused")
default Variable emitArrayEquals(JavaKind kind1, JavaKind kind2, Value array1, Value array2, Value length, int constantLength, boolean directPointers) {
throw GraalError.unimplemented("Array.equals with different types substitution is not implemented on this architecture");
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/hashing/HashFunction.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/hashing/HashFunction.java Thu Mar 28 19:39:14 2019 +0100
@@ -49,7 +49,7 @@
* @param min {@code value} is guaranteed to be greater or equal to this minimum
* @return the hash value within int range
*/
- public abstract int apply(long value, long min);
+ public abstract int apply(int value, int min);
/**
* Generates LIR that implements the hash function in terms of value and min.
@@ -109,25 +109,25 @@
(gen, prime) -> (val, min) -> gen.emitShr(gen.emitMul(val, prime, false), min));
addWithPrimes("rotateRight(val, prime)", 3,
- prime -> (val, min) -> Long.rotateRight(val, prime),
+ prime -> (val, min) -> Integer.rotateRight(val, prime),
(gen, prime) -> (val, min) -> gen.emitRor(val, prime));
addWithPrimes("rotateRight(val, prime) + val", 4,
- prime -> (val, min) -> Long.rotateRight(val, prime) + val,
+ prime -> (val, min) -> Integer.rotateRight(val, prime) + val,
(gen, prime) -> (val, min) -> gen.emitAdd(gen.emitRor(val, prime), val, false));
addWithPrimes("rotateRight(val, prime) ^ val", 4,
- prime -> (val, min) -> Long.rotateRight(val, prime) ^ val,
+ prime -> (val, min) -> Integer.rotateRight(val, prime) ^ val,
(gen, prime) -> (val, min) -> gen.emitXor(gen.emitRor(val, prime), val));
//@formatter:on
}
- private static void add(String toString, int effort, BiFunction<Long, Long, Long> f, Function<ArithmeticLIRGenerator, BiFunction<Value, Value, Value>> gen) {
+ private static void add(String toString, int effort, BiFunction<Integer, Integer, Integer> f, Function<ArithmeticLIRGenerator, BiFunction<Value, Value, Value>> gen) {
instances.add(new HashFunction() {
@Override
- public int apply(long value, long min) {
- return f.apply(value, min).intValue();
+ public int apply(int value, int min) {
+ return f.apply(value, min);
}
@Override
@@ -147,7 +147,7 @@
});
}
- private static void addWithPrimes(String toString, int effort, Function<Integer, BiFunction<Long, Long, Long>> f,
+ private static void addWithPrimes(String toString, int effort, Function<Integer, BiFunction<Integer, Integer, Integer>> f,
BiFunction<ArithmeticLIRGenerator, Value, BiFunction<Value, Value, Value>> gen) {
for (int p : mersennePrimes) {
add(toString, effort, f.apply(p), g -> gen.apply(g, g.getLIRGen().emitJavaConstant(JavaConstant.forInt(p))));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/hashing/Hasher.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/hashing/Hasher.java Thu Mar 28 19:39:14 2019 +0100
@@ -30,6 +30,7 @@
import java.util.Set;
import java.util.TreeSet;
+import jdk.vm.ci.meta.JavaKind;
import org.graalvm.compiler.lir.gen.ArithmeticLIRGenerator;
import jdk.vm.ci.meta.JavaConstant;
@@ -51,11 +52,12 @@
* @return an optional hasher
*/
public static Optional<Hasher> forKeys(JavaConstant[] keys, double minDensity) {
+ assert checkKeyKind(keys);
if (keys.length <= 2) {
return Optional.empty();
} else {
int maxCardinality = (int) Math.round(keys.length / minDensity);
- assertSorted(keys);
+ assert checkIfSorted(keys);
TreeSet<Hasher> candidates = new TreeSet<>(new Comparator<Hasher>() {
@Override
public int compare(Hasher o1, Hasher o2) {
@@ -67,7 +69,7 @@
}
}
});
- long min = keys[0].asLong();
+ int min = keys[0].asInt();
for (HashFunction f : HashFunction.instances()) {
for (int cardinality = keys.length; cardinality < maxCardinality; cardinality++) {
if (isValid(keys, min, f, cardinality)) {
@@ -84,16 +86,28 @@
}
}
- private static void assertSorted(JavaConstant[] keys) {
- for (int i = 1; i < keys.length; i++) {
- assert keys[i - 1].asLong() < keys[i].asLong();
+ private static boolean checkKeyKind(JavaConstant[] keys) {
+ for (int i = 0; i < keys.length; i++) {
+ if (keys[i].getJavaKind() != JavaKind.Int) {
+ throw new AssertionError(String.format("Key at index %d is not an int: %s", i, keys[i]));
+ }
}
+ return true;
}
- private static boolean isValid(JavaConstant[] keys, long min, HashFunction function, int cardinality) {
+ private static boolean checkIfSorted(JavaConstant[] keys) {
+ for (int i = 1; i < keys.length; i++) {
+ if (keys[i - 1].asInt() >= keys[i].asInt()) {
+ throw new AssertionError("Keys array is not sorted");
+ }
+ }
+ return true;
+ }
+
+ private static boolean isValid(JavaConstant[] keys, int min, HashFunction function, int cardinality) {
Set<Integer> seen = new HashSet<>(keys.length);
for (JavaConstant key : keys) {
- int hash = function.apply(key.asLong(), min) & (cardinality - 1);
+ int hash = function.apply(key.asInt(), min) & (cardinality - 1);
if (!seen.add(hash)) {
return false;
}
@@ -103,9 +117,9 @@
private final HashFunction function;
private final int cardinality;
- private final long min;
+ private final int min;
- private Hasher(HashFunction function, int cardinality, long min) {
+ private Hasher(HashFunction function, int cardinality, int min) {
this.function = function;
this.cardinality = cardinality;
this.min = min;
@@ -117,7 +131,7 @@
* @param value the value to be hashed
* @return the hash value
*/
- public int hash(long value) {
+ public int hash(int value) {
return function.apply(value, min) & (cardinality - 1);
}
@@ -129,7 +143,7 @@
* @return the hashed lir value
*/
public Value hash(Value value, ArithmeticLIRGenerator gen) {
- Value h = function.gen(value, gen.getLIRGen().emitJavaConstant(JavaConstant.forLong(min)), gen);
+ Value h = function.gen(value, gen.getLIRGen().emitJavaConstant(JavaConstant.forInt(min)), gen);
return gen.emitAnd(h, gen.getLIRGen().emitJavaConstant(JavaConstant.forInt(cardinality - 1)));
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/SimplifyingGraphDecoder.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/SimplifyingGraphDecoder.java Thu Mar 28 19:39:14 2019 +0100
@@ -44,7 +44,7 @@
import org.graalvm.compiler.nodes.java.ArrayLengthNode;
import org.graalvm.compiler.nodes.java.LoadFieldNode;
import org.graalvm.compiler.nodes.java.LoadIndexedNode;
-import org.graalvm.compiler.nodes.spi.StampProvider;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
import org.graalvm.compiler.nodes.util.GraphUtil;
import org.graalvm.compiler.options.OptionValues;
@@ -61,10 +61,7 @@
*/
public class SimplifyingGraphDecoder extends GraphDecoder {
- protected final MetaAccessProvider metaAccess;
- protected final ConstantReflectionProvider constantReflection;
- protected final ConstantFieldProvider constantFieldProvider;
- protected final StampProvider stampProvider;
+ protected final CoreProviders providers;
protected final boolean canonicalizeReads;
protected final CanonicalizerTool canonicalizerTool;
@@ -85,17 +82,17 @@
@Override
public MetaAccessProvider getMetaAccess() {
- return metaAccess;
+ return providers.getMetaAccess();
}
@Override
public ConstantReflectionProvider getConstantReflection() {
- return constantReflection;
+ return providers.getConstantReflection();
}
@Override
public ConstantFieldProvider getConstantFieldProvider() {
- return constantFieldProvider;
+ return providers.getConstantFieldProvider();
}
@Override
@@ -135,14 +132,9 @@
}
}
- public SimplifyingGraphDecoder(Architecture architecture, StructuredGraph graph, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection,
- ConstantFieldProvider constantFieldProvider, StampProvider stampProvider,
- boolean canonicalizeReads) {
+ public SimplifyingGraphDecoder(Architecture architecture, StructuredGraph graph, CoreProviders providers, boolean canonicalizeReads) {
super(architecture, graph);
- this.metaAccess = metaAccess;
- this.constantReflection = constantReflection;
- this.constantFieldProvider = constantFieldProvider;
- this.stampProvider = stampProvider;
+ this.providers = providers;
this.canonicalizeReads = canonicalizeReads;
this.canonicalizerTool = new PECanonicalizerTool(graph.getAssumptions(), graph.getOptions());
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/JavaWriteNode.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/JavaWriteNode.java Thu Mar 28 19:39:14 2019 +0100
@@ -24,6 +24,8 @@
package org.graalvm.compiler.nodes.extended;
+import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.StateSplit;
@@ -72,4 +74,9 @@
public boolean isCompressible() {
return compressible;
}
+
+ @Override
+ public Stamp getAccessStamp() {
+ return StampFactory.forKind(writeKind);
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderConfiguration.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderConfiguration.java Thu Mar 28 19:39:14 2019 +0100
@@ -201,6 +201,7 @@
private final List<ResolvedJavaType> skippedExceptionTypes;
private final boolean insertFullInfopoints;
private final boolean trackNodeSourcePosition;
+ private final boolean retainLocalVariables;
private final Plugins plugins;
public enum BytecodeExceptionMode {
@@ -229,6 +230,7 @@
boolean omitAssertions,
boolean insertFullInfopoints,
boolean trackNodeSourcePosition,
+ boolean retainLocalVariables,
List<ResolvedJavaType> skippedExceptionTypes,
Plugins plugins) {
this.eagerResolving = eagerResolving;
@@ -237,6 +239,7 @@
this.omitAssertions = omitAssertions;
this.insertFullInfopoints = insertFullInfopoints;
this.trackNodeSourcePosition = trackNodeSourcePosition;
+ this.retainLocalVariables = retainLocalVariables;
this.skippedExceptionTypes = skippedExceptionTypes;
this.plugins = plugins;
}
@@ -255,6 +258,7 @@
omitAssertions,
insertFullInfopoints,
trackNodeSourcePosition,
+ retainLocalVariables,
skippedExceptionTypes,
newPlugins);
return result;
@@ -274,6 +278,7 @@
omitAssertions,
insertFullInfopoints,
trackNodeSourcePosition,
+ retainLocalVariables,
skippedExceptionTypes,
plugins);
}
@@ -286,6 +291,7 @@
omitAssertions,
insertFullInfopoints,
trackNodeSourcePosition,
+ retainLocalVariables,
skippedExceptionTypes,
plugins);
}
@@ -298,6 +304,7 @@
omitAssertions,
insertFullInfopoints,
trackNodeSourcePosition,
+ retainLocalVariables,
Collections.unmodifiableList(Arrays.asList(newSkippedExceptionTypes)),
plugins);
}
@@ -309,6 +316,7 @@
omitAssertions,
insertFullInfopoints,
trackNodeSourcePosition,
+ retainLocalVariables,
skippedExceptionTypes,
plugins);
}
@@ -321,6 +329,7 @@
newOmitAssertions,
insertFullInfopoints,
trackNodeSourcePosition,
+ retainLocalVariables,
skippedExceptionTypes,
plugins);
}
@@ -333,6 +342,7 @@
omitAssertions,
newInsertFullInfopoints,
trackNodeSourcePosition,
+ retainLocalVariables,
skippedExceptionTypes,
plugins);
}
@@ -345,6 +355,20 @@
omitAssertions,
insertFullInfopoints,
newTrackNodeSourcePosition,
+ retainLocalVariables,
+ skippedExceptionTypes,
+ plugins);
+ }
+
+ public GraphBuilderConfiguration withRetainLocalVariables(boolean newRetainLocalVariables) {
+ return new GraphBuilderConfiguration(
+ eagerResolving,
+ unresolvedIsError,
+ bytecodeExceptionMode,
+ omitAssertions,
+ insertFullInfopoints,
+ trackNodeSourcePosition,
+ newRetainLocalVariables,
skippedExceptionTypes,
plugins);
}
@@ -369,6 +393,10 @@
return trackNodeSourcePosition;
}
+ public boolean retainLocalVariables() {
+ return retainLocalVariables;
+ }
+
public boolean insertFullInfopoints() {
return insertFullInfopoints;
}
@@ -381,6 +409,7 @@
/* omitAssertions: */ false,
/* insertFullInfopoints: */ false,
/* trackNodeSourcePosition: */ false,
+ /* retainLocalVariables */ false,
Collections.emptyList(),
plugins);
}
@@ -393,6 +422,7 @@
/* omitAssertions: */ false,
/* insertFullInfopoints: */ false,
/* trackNodeSourcePosition: */ false,
+ /* retainLocalVariables */ false,
Collections.emptyList(),
plugins);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderTool.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderTool.java Thu Mar 28 19:39:14 2019 +0100
@@ -28,6 +28,7 @@
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.spi.Replacements;
import org.graalvm.compiler.nodes.spi.StampProvider;
import org.graalvm.compiler.options.OptionValues;
@@ -52,6 +53,8 @@
MetaAccessProvider getMetaAccess();
+ Replacements getReplacements();
+
default Assumptions getAssumptions() {
return getGraph().getAssumptions();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/NodePlugin.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/NodePlugin.java Thu Mar 28 19:39:14 2019 +0100
@@ -243,3 +243,4 @@
return false;
}
}
+
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/AbstractWriteNode.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/AbstractWriteNode.java Thu Mar 28 19:39:14 2019 +0100
@@ -27,6 +27,7 @@
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
+import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
@@ -90,4 +91,6 @@
updateUsages(lastLocationAccess, newLla);
lastLocationAccess = newLla;
}
+
+ public abstract Stamp getAccessStamp();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/CoreProviders.java Thu Mar 28 19:39:14 2019 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.nodes.spi;
+
+import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
+import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
+
+import jdk.vm.ci.meta.ConstantReflectionProvider;
+import jdk.vm.ci.meta.MetaAccessProvider;
+
+public interface CoreProviders {
+
+ MetaAccessProvider getMetaAccess();
+
+ ConstantReflectionProvider getConstantReflection();
+
+ ConstantFieldProvider getConstantFieldProvider();
+
+ LoweringProvider getLowerer();
+
+ Replacements getReplacements();
+
+ StampProvider getStampProvider();
+
+ ForeignCallsProvider getForeignCalls();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/CoreProvidersImpl.java Thu Mar 28 19:39:14 2019 +0100
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.nodes.spi;
+
+import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
+import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
+
+import jdk.vm.ci.meta.ConstantReflectionProvider;
+import jdk.vm.ci.meta.MetaAccessProvider;
+
+public class CoreProvidersImpl implements CoreProviders {
+ protected final MetaAccessProvider metaAccess;
+ protected final ConstantReflectionProvider constantReflection;
+ protected final ConstantFieldProvider constantFieldProvider;
+ protected final LoweringProvider lowerer;
+ protected final Replacements replacements;
+ protected final StampProvider stampProvider;
+ protected final ForeignCallsProvider foreignCalls;
+
+ protected CoreProvidersImpl(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider, LoweringProvider lowerer,
+ Replacements replacements, StampProvider stampProvider, ForeignCallsProvider foreignCalls) {
+ this.metaAccess = metaAccess;
+ this.constantReflection = constantReflection;
+ this.constantFieldProvider = constantFieldProvider;
+ this.lowerer = lowerer;
+ this.replacements = replacements;
+ this.stampProvider = stampProvider;
+ this.foreignCalls = foreignCalls;
+ }
+
+ @Override
+ public MetaAccessProvider getMetaAccess() {
+ return metaAccess;
+ }
+
+ @Override
+ public ConstantReflectionProvider getConstantReflection() {
+ return constantReflection;
+ }
+
+ @Override
+ public ConstantFieldProvider getConstantFieldProvider() {
+ return constantFieldProvider;
+ }
+
+ @Override
+ public LoweringProvider getLowerer() {
+ return lowerer;
+ }
+
+ @Override
+ public Replacements getReplacements() {
+ return replacements;
+ }
+
+ @Override
+ public StampProvider getStampProvider() {
+ return stampProvider;
+ }
+
+ @Override
+ public ForeignCallsProvider getForeignCalls() {
+ return foreignCalls;
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringTool.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringTool.java Thu Mar 28 19:39:14 2019 +0100
@@ -40,6 +40,8 @@
public interface LoweringTool {
+ CoreProviders getProviders();
+
MetaAccessProvider getMetaAccess();
LoweringProvider getLowerer();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/NodeLIRBuilderTool.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/NodeLIRBuilderTool.java Thu Mar 28 19:39:14 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -28,6 +28,7 @@
import java.util.List;
import org.graalvm.compiler.core.common.cfg.BlockMap;
+import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeSourcePosition;
@@ -96,4 +97,11 @@
}
void emitReadExceptionObject(ValueNode node);
+
+ @SuppressWarnings("unused")
+ default ForeignCallLinkage lookupGraalStub(ValueNode valueNode) {
+ return null;
+ }
+
+ void matchBlock(Block b, StructuredGraph graph, StructuredGraph.ScheduleResult blockMap);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionsParser.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionsParser.java Thu Mar 28 19:39:14 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -36,6 +36,8 @@
import jdk.internal.vm.compiler.collections.EconomicMap;
import jdk.internal.vm.compiler.collections.MapCursor;
+import jdk.vm.ci.services.Services;
+
/**
* This class contains methods for parsing Graal options and matching them against a set of
* {@link OptionDescriptors}. The {@link OptionDescriptors} are loaded via a {@link ServiceLoader}.
@@ -51,7 +53,7 @@
if (IS_IN_NATIVE_IMAGE || cachedOptionDescriptors != null) {
return cachedOptionDescriptors;
}
- boolean java8OrEarlier = System.getProperty("java.specification.version").compareTo("1.9") < 0;
+ boolean java8OrEarlier = Services.getSavedProperties().get("java.specification.version").compareTo("1.9") < 0;
ClassLoader loader;
if (java8OrEarlier) {
// On JDK 8, Graal and its extensions are loaded by same class loader.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/LoweringPhase.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/LoweringPhase.java Thu Mar 28 19:39:14 2019 +0100
@@ -38,6 +38,7 @@
import java.util.List;
import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
+import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.GraalError;
@@ -68,6 +69,7 @@
import org.graalvm.compiler.nodes.extended.GuardedNode;
import org.graalvm.compiler.nodes.extended.GuardingNode;
import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
import org.graalvm.compiler.nodes.spi.Lowerable;
import org.graalvm.compiler.nodes.spi.LoweringProvider;
import org.graalvm.compiler.nodes.spi.LoweringTool;
@@ -144,6 +146,11 @@
}
@Override
+ public CoreProviders getProviders() {
+ return context;
+ }
+
+ @Override
public ConstantReflectionProvider getConstantReflection() {
return context.getConstantReflection();
}
@@ -168,6 +175,10 @@
return context.getReplacements();
}
+ public ForeignCallsProvider getForeignCalls() {
+ return context.getForeignCalls();
+ }
+
@Override
public AnchoringNode getCurrentGuardAnchor() {
return guardAnchor;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ProfileCompiledMethodsPhase.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ProfileCompiledMethodsPhase.java Thu Mar 28 19:39:14 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -69,6 +69,8 @@
import org.graalvm.compiler.phases.Phase;
import org.graalvm.compiler.phases.schedule.SchedulePhase;
+import jdk.vm.ci.services.Services;
+
/**
* This phase add counters for the dynamically executed number of nodes. Incrementing the counter
* for each node would be too costly, so this phase takes the compromise that it trusts split
@@ -87,9 +89,17 @@
private static final String GROUP_NAME_WITHOUT = "~profiled weight (invoke-free sections)";
private static final String GROUP_NAME_INVOKES = "~profiled invokes";
- private static final boolean WITH_SECTION_HEADER = Boolean.parseBoolean(System.getProperty("ProfileCompiledMethodsPhase.WITH_SECTION_HEADER", "false"));
- private static final boolean WITH_INVOKE_FREE_SECTIONS = Boolean.parseBoolean(System.getProperty("ProfileCompiledMethodsPhase.WITH_FREE_SECTIONS", "false"));
- private static final boolean WITH_INVOKES = Boolean.parseBoolean(System.getProperty("ProfileCompiledMethodsPhase.WITH_INVOKES", "true"));
+ private static String getProperty(String name, String def) {
+ String value = Services.getSavedProperties().get(name);
+ if (value == null) {
+ return def;
+ }
+ return value;
+ }
+
+ private static final boolean WITH_SECTION_HEADER = Boolean.parseBoolean(getProperty("ProfileCompiledMethodsPhase.WITH_SECTION_HEADER", "false"));
+ private static final boolean WITH_INVOKE_FREE_SECTIONS = Boolean.parseBoolean(getProperty("ProfileCompiledMethodsPhase.WITH_FREE_SECTIONS", "false"));
+ private static final boolean WITH_INVOKES = Boolean.parseBoolean(getProperty("ProfileCompiledMethodsPhase.WITH_INVOKES", "true"));
@Override
protected void run(StructuredGraph graph) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/InliningData.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/InliningData.java Thu Mar 28 19:39:14 2019 +0100
@@ -154,6 +154,8 @@
return "it is marked non-inlinable";
} else if (countRecursiveInlining(method) > MaximumRecursiveInlining.getValue(options)) {
return "it exceeds the maximum recursive inlining depth";
+ } else if (!method.hasBytecodes()) {
+ return "it has no bytecodes to inline";
} else {
if (new OptimisticOptimizations(rootGraph.getProfilingInfo(method), options).lessOptimisticThan(context.getOptimisticOptimizations())) {
return "the callee uses less optimistic optimizations than caller";
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/VerifyPhase.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/VerifyPhase.java Thu Mar 28 19:39:14 2019 +0100
@@ -26,11 +26,12 @@
import org.graalvm.compiler.nodes.StructuredGraph;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaType;
+
/***
- * This phase serves as a verification, in order to check the graph for certain properties. The
- * {@link #verify(StructuredGraph, Object)} method will be used as an assertion, and implements the
- * actual check. Instead of returning false, it is also valid to throw an {@link VerificationError}
- * in the implemented {@link #verify(StructuredGraph, Object)} method.
+ * Verifies a {@linkplain #verify graph} or {@linkplain #verifyClass class} against one or more
+ * invariants.
*/
public abstract class VerifyPhase<C> extends BasePhase<C> {
@@ -55,13 +56,23 @@
@Override
protected final void run(StructuredGraph graph, C context) {
- assert verify(graph, context);
+ verify(graph, context);
}
/**
- * Performs the actual verification.
+ * Checks {@code graph} against some invariants.
*
* @throws VerificationError if the verification fails
*/
- protected abstract boolean verify(StructuredGraph graph, C context);
+ protected abstract void verify(StructuredGraph graph, C context);
+
+ /**
+ * Checks {@code clazz} against some invariants.
+ *
+ * @param clazz the class to verify
+ * @param metaAccess an object to get a {@link ResolvedJavaType} for {@code clazz}
+ * @throws VerificationError if the class violates some invariant
+ */
+ public void verifyClass(Class<?> clazz, MetaAccessProvider metaAccess) {
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/PhaseContext.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/PhaseContext.java Thu Mar 28 19:39:14 2019 +0100
@@ -25,66 +25,55 @@
package org.graalvm.compiler.phases.tiers;
import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
+import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
import org.graalvm.compiler.nodes.spi.LoweringProvider;
import org.graalvm.compiler.nodes.spi.Replacements;
import org.graalvm.compiler.nodes.spi.StampProvider;
-import org.graalvm.compiler.phases.util.Providers;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.MetaAccessProvider;
-import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
-public class PhaseContext {
+public class PhaseContext implements CoreProviders {
- private final MetaAccessProvider metaAccess;
- private final ConstantReflectionProvider constantReflection;
- private final ConstantFieldProvider constantFieldProvider;
- private final LoweringProvider lowerer;
- private final Replacements replacements;
- private final StampProvider stampProvider;
- private final ForeignCallsProvider foreignCalls;
+ private final CoreProviders providers;
- public PhaseContext(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider, LoweringProvider lowerer, Replacements replacements,
- StampProvider stampProvider, ForeignCallsProvider foreignCalls) {
- this.metaAccess = metaAccess;
- this.constantReflection = constantReflection;
- this.constantFieldProvider = constantFieldProvider;
- this.lowerer = lowerer;
- this.replacements = replacements;
- this.stampProvider = stampProvider;
- this.foreignCalls = foreignCalls;
+ public PhaseContext(CoreProviders providers) {
+ this.providers = providers;
}
- public PhaseContext(Providers providers) {
- this(providers.getMetaAccess(), providers.getConstantReflection(), providers.getConstantFieldProvider(), providers.getLowerer(), providers.getReplacements(), providers.getStampProvider(),
- providers.getForeignCalls());
+ @Override
+ public MetaAccessProvider getMetaAccess() {
+ return providers.getMetaAccess();
+ }
+
+ @Override
+ public ConstantReflectionProvider getConstantReflection() {
+ return providers.getConstantReflection();
}
- public MetaAccessProvider getMetaAccess() {
- return metaAccess;
+ @Override
+ public ConstantFieldProvider getConstantFieldProvider() {
+ return providers.getConstantFieldProvider();
}
- public ConstantReflectionProvider getConstantReflection() {
- return constantReflection;
- }
-
- public ConstantFieldProvider getConstantFieldProvider() {
- return constantFieldProvider;
+ @Override
+ public LoweringProvider getLowerer() {
+ return providers.getLowerer();
}
- public LoweringProvider getLowerer() {
- return lowerer;
- }
-
+ @Override
public Replacements getReplacements() {
- return replacements;
+ return providers.getReplacements();
}
+ @Override
public StampProvider getStampProvider() {
- return stampProvider;
+ return providers.getStampProvider();
}
+ @Override
public ForeignCallsProvider getForeignCalls() {
- return foreignCalls;
+ return providers.getForeignCalls();
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/Providers.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/Providers.java Thu Mar 28 19:39:14 2019 +0100
@@ -27,6 +27,7 @@
import org.graalvm.compiler.core.common.spi.CodeGenProviders;
import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
+import org.graalvm.compiler.nodes.spi.CoreProvidersImpl;
import org.graalvm.compiler.nodes.spi.LoweringProvider;
import org.graalvm.compiler.nodes.spi.Replacements;
import org.graalvm.compiler.nodes.spi.StampProvider;
@@ -39,27 +40,14 @@
/**
* A set of providers, some of which may not be present (i.e., null).
*/
-public class Providers implements CodeGenProviders {
+public class Providers extends CoreProvidersImpl implements CodeGenProviders {
- private final MetaAccessProvider metaAccess;
private final CodeCacheProvider codeCache;
- private final LoweringProvider lowerer;
- private final ConstantReflectionProvider constantReflection;
- private final ConstantFieldProvider constantFieldProvider;
- private final ForeignCallsProvider foreignCalls;
- private final Replacements replacements;
- private final StampProvider stampProvider;
public Providers(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider,
ForeignCallsProvider foreignCalls, LoweringProvider lowerer, Replacements replacements, StampProvider stampProvider) {
- this.metaAccess = metaAccess;
+ super(metaAccess, constantReflection, constantFieldProvider, lowerer, replacements, stampProvider, foreignCalls);
this.codeCache = codeCache;
- this.constantReflection = constantReflection;
- this.constantFieldProvider = constantFieldProvider;
- this.foreignCalls = foreignCalls;
- this.lowerer = lowerer;
- this.replacements = replacements;
- this.stampProvider = stampProvider;
}
public Providers(Providers copyFrom) {
@@ -73,41 +61,10 @@
}
@Override
- public MetaAccessProvider getMetaAccess() {
- return metaAccess;
- }
-
- @Override
public CodeCacheProvider getCodeCache() {
return codeCache;
}
- @Override
- public ForeignCallsProvider getForeignCalls() {
- return foreignCalls;
- }
-
- public LoweringProvider getLowerer() {
- return lowerer;
- }
-
- @Override
- public ConstantReflectionProvider getConstantReflection() {
- return constantReflection;
- }
-
- public ConstantFieldProvider getConstantFieldProvider() {
- return constantFieldProvider;
- }
-
- public Replacements getReplacements() {
- return replacements;
- }
-
- public StampProvider getStampProvider() {
- return stampProvider;
- }
-
public Providers copyWith(MetaAccessProvider substitution) {
assert this.getClass() == Providers.class : "must override";
return new Providers(substitution, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinterObserver.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/CFGPrinterObserver.java Thu Mar 28 19:39:14 2019 +0100
@@ -64,6 +64,7 @@
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.meta.JavaMethod;
import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.services.Services;
/**
* Observes compilation events and uses {@link CFGPrinter} to produce a control flow graph for the
@@ -256,11 +257,19 @@
static {
DisassemblerProvider selected = null;
+ String arch = Services.getSavedProperties().get("os.arch");
for (DisassemblerProvider d : GraalServices.load(DisassemblerProvider.class)) {
String name = d.getName().toLowerCase();
- if (name.contains("hcf") || name.contains("hexcodefile")) {
- selected = d;
- break;
+ if (arch.equals("aarch64")) {
+ if (name.contains("hsdis-objdump")) {
+ selected = d;
+ break;
+ }
+ } else {
+ if (name.contains("hcf") || name.contains("hexcodefile")) {
+ selected = d;
+ break;
+ }
}
}
if (selected == null) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java Thu Mar 28 19:39:14 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -52,6 +52,7 @@
import jdk.vm.ci.meta.JavaMethod;
import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.services.Services;
//JaCoCo Exclude
@@ -86,7 +87,7 @@
this.printerSupplier = printerSupplier;
/* Add the JVM and Java arguments to the graph properties to help identify it. */
this.jvmArguments = jvmArguments();
- this.sunJavaCommand = System.getProperty("sun.java.command");
+ this.sunJavaCommand = Services.getSavedProperties().get("sun.java.command");
}
private static String jvmArguments() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64GraphBuilderPlugins.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64GraphBuilderPlugins.java Thu Mar 28 19:39:14 2019 +0100
@@ -59,14 +59,16 @@
public class AArch64GraphBuilderPlugins {
- public static void register(Plugins plugins, BytecodeProvider bytecodeProvider, boolean explicitUnsafeNullChecks) {
+ public static void register(Plugins plugins, BytecodeProvider bytecodeProvider, boolean explicitUnsafeNullChecks, boolean registerMathPlugins) {
InvocationPlugins invocationPlugins = plugins.getInvocationPlugins();
invocationPlugins.defer(new Runnable() {
@Override
public void run() {
registerIntegerLongPlugins(invocationPlugins, AArch64IntegerSubstitutions.class, JavaKind.Int, bytecodeProvider);
registerIntegerLongPlugins(invocationPlugins, AArch64LongSubstitutions.class, JavaKind.Long, bytecodeProvider);
- registerMathPlugins(invocationPlugins);
+ if (registerMathPlugins) {
+ registerMathPlugins(invocationPlugins);
+ }
registerStringLatin1Plugins(invocationPlugins, bytecodeProvider);
registerStringUTF16Plugins(invocationPlugins, bytecodeProvider);
registerUnsafePlugins(invocationPlugins, bytecodeProvider);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java Thu Mar 28 19:39:14 2019 +0100
@@ -31,6 +31,7 @@
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.graph.SourceLanguagePositionProvider;
import org.graalvm.compiler.java.GraphBuilderPhase;
+import org.graalvm.compiler.loop.phases.ConvertDeoptimizeToGuardPhase;
import org.graalvm.compiler.nodes.EncodedGraph;
import org.graalvm.compiler.nodes.GraphEncoder;
import org.graalvm.compiler.nodes.StructuredGraph;
@@ -44,7 +45,6 @@
import org.graalvm.compiler.nodes.graphbuilderconf.ParameterPlugin;
import org.graalvm.compiler.phases.OptimisticOptimizations;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.loop.phases.ConvertDeoptimizeToGuardPhase;
import org.graalvm.compiler.phases.tiers.PhaseContext;
import org.graalvm.compiler.phases.util.Providers;
@@ -67,7 +67,7 @@
AllowAssumptions allowAssumptions, LoopExplosionPlugin loopExplosionPlugin, InvocationPlugins invocationPlugins, InlineInvokePlugin[] inlineInvokePlugins,
ParameterPlugin parameterPlugin,
NodePlugin[] nodePlugins, ResolvedJavaMethod callInlinedMethod, SourceLanguagePositionProvider sourceLanguagePositionProvider) {
- super(architecture, graph, providers.getMetaAccess(), providers.getConstantReflection(), providers.getConstantFieldProvider(), providers.getStampProvider(), loopExplosionPlugin,
+ super(architecture, graph, providers, loopExplosionPlugin,
invocationPlugins, inlineInvokePlugins, parameterPlugin, nodePlugins, callInlinedMethod, sourceLanguagePositionProvider);
this.providers = providers;
@@ -78,8 +78,7 @@
}
protected GraphBuilderPhase.Instance createGraphBuilderPhaseInstance(IntrinsicContext initialIntrinsicContext) {
- return new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), providers.getConstantReflection(), providers.getConstantFieldProvider(), graphBuilderConfig,
- optimisticOpts, initialIntrinsicContext);
+ return new GraphBuilderPhase.Instance(providers, graphBuilderConfig, optimisticOpts, initialIntrinsicContext);
}
@SuppressWarnings("try")
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantStringIndexOfSnippets.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantStringIndexOfSnippets.java Thu Mar 28 19:39:14 2019 +0100
@@ -25,6 +25,7 @@
package org.graalvm.compiler.replacements;
import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER;
+import static org.graalvm.compiler.serviceprovider.GraalUnsafeAccess.getUnsafe;
import org.graalvm.compiler.api.replacements.Fold;
import org.graalvm.compiler.api.replacements.Fold.InjectedParameter;
@@ -44,8 +45,11 @@
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.MetaAccessProvider;
+import sun.misc.Unsafe;
public class ConstantStringIndexOfSnippets implements Snippets {
+ private static final Unsafe UNSAFE = getUnsafe();
+
public static class Templates extends AbstractTemplates {
private final SnippetInfo indexOfConstant = snippet(ConstantStringIndexOfSnippets.class, "indexOfConstant");
@@ -157,10 +161,10 @@
return 0;
}
long base = metaAccess.getArrayBaseOffset(JavaKind.Byte);
- char lastChar = UnsafeAccess.UNSAFE.getChar(target, base + (c - 1) * 2);
+ char lastChar = UNSAFE.getChar(target, base + (c - 1) * 2);
int md2 = c;
for (int i = 0; i < c - 1; i++) {
- char currChar = UnsafeAccess.UNSAFE.getChar(target, base + i * 2);
+ char currChar = UNSAFE.getChar(target, base + i * 2);
if (currChar == lastChar) {
md2 = (c - 1) - i;
}
@@ -174,7 +178,7 @@
int i;
long base = metaAccess.getArrayBaseOffset(JavaKind.Byte);
for (i = 0; i < c - 1; i++) {
- char currChar = UnsafeAccess.UNSAFE.getChar(s, base + i * 2);
+ char currChar = UNSAFE.getChar(s, base + i * 2);
cache |= (1 << (currChar & 63));
}
return cache;
@@ -212,10 +216,10 @@
int sourceEnd = sourceCount - targetCountLess1;
long base = charArrayBaseOffset(INJECTED);
- int lastChar = UnsafeAccess.UNSAFE.getChar(target, base + targetCountLess1 * 2);
+ int lastChar = UNSAFE.getChar(target, base + targetCountLess1 * 2);
outer_loop: for (long i = sourceOffset + fromIndex; i < sourceEnd;) {
- int src = UnsafeAccess.UNSAFE.getChar(source, base + (i + targetCountLess1) * 2);
+ int src = UNSAFE.getChar(source, base + (i + targetCountLess1) * 2);
if (src == lastChar) {
// With random strings and a 4-character alphabet,
// reverse matching at this point sets up 0.8% fewer
@@ -229,8 +233,8 @@
ExplodeLoopNode.explodeLoop();
}
for (long j = 0; j < targetCountLess1; j++) {
- char sourceChar = UnsafeAccess.UNSAFE.getChar(source, base + (i + j) * 2);
- if (UnsafeAccess.UNSAFE.getChar(target, base + (targetOffset + j) * 2) != sourceChar) {
+ char sourceChar = UNSAFE.getChar(source, base + (i + j) * 2);
+ if (UNSAFE.getChar(target, base + (targetOffset + j) * 2) != sourceChar) {
if ((cache & (1 << sourceChar)) == 0) {
if (md2 < j + 1) {
i += j + 1;
@@ -270,10 +274,10 @@
int sourceEnd = sourceCount - targetCountLess1;
long base = byteArrayBaseOffset(INJECTED);
- int lastChar = UnsafeAccess.UNSAFE.getChar(target, base + targetCountLess1 * 2);
+ int lastChar = UNSAFE.getChar(target, base + targetCountLess1 * 2);
outer_loop: for (long i = fromIndex; i < sourceEnd;) {
- int src = UnsafeAccess.UNSAFE.getChar(source, base + (i + targetCountLess1) * 2);
+ int src = UNSAFE.getChar(source, base + (i + targetCountLess1) * 2);
if (src == lastChar) {
// With random strings and a 4-character alphabet,
// reverse matching at this point sets up 0.8% fewer
@@ -287,8 +291,8 @@
ExplodeLoopNode.explodeLoop();
}
for (long j = 0; j < targetCountLess1; j++) {
- char sourceChar = UnsafeAccess.UNSAFE.getChar(source, base + (i + j) * 2);
- if (UnsafeAccess.UNSAFE.getChar(target, base + j * 2) != sourceChar) {
+ char sourceChar = UNSAFE.getChar(source, base + (i + j) * 2);
+ if (UNSAFE.getChar(target, base + j * 2) != sourceChar) {
if ((cache & (1 << sourceChar)) == 0) {
if (md2 < j + 1) {
i += j + 1;
@@ -328,10 +332,10 @@
int sourceEnd = sourceCount - targetCountLess1;
long base = byteArrayBaseOffset(INJECTED);
- int lastByte = UnsafeAccess.UNSAFE.getByte(target, base + targetCountLess1);
+ int lastByte = UNSAFE.getByte(target, base + targetCountLess1);
outer_loop: for (long i = fromIndex; i < sourceEnd;) {
- int src = UnsafeAccess.UNSAFE.getByte(source, base + i + targetCountLess1);
+ int src = UNSAFE.getByte(source, base + i + targetCountLess1);
if (src == lastByte) {
// With random strings and a 4-character alphabet,
// reverse matching at this point sets up 0.8% fewer
@@ -345,8 +349,8 @@
ExplodeLoopNode.explodeLoop();
}
for (long j = 0; j < targetCountLess1; j++) {
- byte sourceByte = UnsafeAccess.UNSAFE.getByte(source, base + i + j);
- if (UnsafeAccess.UNSAFE.getByte(target, base + j) != sourceByte) {
+ byte sourceByte = UNSAFE.getByte(source, base + i + j);
+ if (UNSAFE.getByte(target, base + j) != sourceByte) {
if ((cache & (1 << sourceByte)) == 0) {
if (md2 < j + 1) {
i += j + 1;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java Thu Mar 28 19:39:14 2019 +0100
@@ -68,6 +68,7 @@
import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext;
import org.graalvm.compiler.nodes.java.ExceptionObjectNode;
import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+import org.graalvm.compiler.nodes.spi.Replacements;
import org.graalvm.compiler.nodes.spi.StampProvider;
import org.graalvm.compiler.nodes.type.StampTool;
import org.graalvm.compiler.phases.OptimisticOptimizations;
@@ -152,6 +153,11 @@
}
@Override
+ public Replacements getReplacements() {
+ return providers.getReplacements();
+ }
+
+ @Override
public StampProvider getStampProvider() {
return providers.getStampProvider();
}
@@ -355,7 +361,6 @@
public void inline(InvokeNode invoke, String reason, String phase) {
ResolvedJavaMethod method = ((MethodCallTargetNode) invoke.callTarget()).targetMethod();
- MetaAccessProvider metaAccess = providers.getMetaAccess();
Plugins plugins = new Plugins(graphBuilderPlugins);
GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(plugins);
@@ -366,9 +371,7 @@
calleeGraph = new StructuredGraph.Builder(invoke.getOptions(), invoke.getDebug()).method(method).trackNodeSourcePosition(invoke.graph().trackNodeSourcePosition()).setIsSubstitution(
true).build();
IntrinsicContext initialReplacementContext = new IntrinsicContext(method, method, providers.getReplacements().getDefaultReplacementBytecodeProvider(), INLINE_AFTER_PARSING);
- GraphBuilderPhase.Instance instance = createGraphBuilderInstance(metaAccess, providers.getStampProvider(), providers.getConstantReflection(), providers.getConstantFieldProvider(), config,
- OptimisticOptimizations.NONE,
- initialReplacementContext);
+ GraphBuilderPhase.Instance instance = createGraphBuilderInstance(providers, config, OptimisticOptimizations.NONE, initialReplacementContext);
instance.apply(calleeGraph);
}
@@ -379,9 +382,9 @@
InliningUtil.inline(invoke, calleeGraph, false, method, reason, phase);
}
- protected GraphBuilderPhase.Instance createGraphBuilderInstance(MetaAccessProvider metaAccess, StampProvider stampProvider, ConstantReflectionProvider constantReflection,
- ConstantFieldProvider constantFieldProvider, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, IntrinsicContext initialIntrinsicContext) {
- return new GraphBuilderPhase.Instance(metaAccess, stampProvider, constantReflection, constantFieldProvider, graphBuilderConfig, optimisticOpts, initialIntrinsicContext);
+ protected GraphBuilderPhase.Instance createGraphBuilderInstance(Providers theProviders, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts,
+ IntrinsicContext initialIntrinsicContext) {
+ return new GraphBuilderPhase.Instance(theProviders, graphBuilderConfig, optimisticOpts, initialIntrinsicContext);
}
protected void pushStructure(Structure structure) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/InlineDuringParsingPlugin.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/InlineDuringParsingPlugin.java Thu Mar 28 19:39:14 2019 +0100
@@ -35,17 +35,26 @@
import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin;
import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.services.Services;
public final class InlineDuringParsingPlugin implements InlineInvokePlugin {
+ private static int getInteger(String name, int def) {
+ String value = Services.getSavedProperties().get(name);
+ if (value != null) {
+ return Integer.parseInt(value);
+ }
+ return def;
+ }
+
/**
* Budget which when exceeded reduces the effective value of
* {@link BytecodeParserOptions#InlineDuringParsingMaxDepth} to
* {@link #MaxDepthAfterBudgetExceeded}.
*/
- private static final int NodeBudget = Integer.getInteger("InlineDuringParsingPlugin.NodeBudget", 2000);
+ private static final int NodeBudget = getInteger("InlineDuringParsingPlugin.NodeBudget", 2000);
- private static final int MaxDepthAfterBudgetExceeded = Integer.getInteger("InlineDuringParsingPlugin.MaxDepthAfterBudgetExceeded", 3);
+ private static final int MaxDepthAfterBudgetExceeded = getInteger("InlineDuringParsingPlugin.MaxDepthAfterBudgetExceeded", 3);
@Override
public InlineInfo shouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/IntrinsicGraphBuilder.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/IntrinsicGraphBuilder.java Thu Mar 28 19:39:14 2019 +0100
@@ -51,6 +51,8 @@
import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
+import org.graalvm.compiler.nodes.spi.Replacements;
import org.graalvm.compiler.nodes.spi.StampProvider;
import org.graalvm.compiler.options.OptionValues;
@@ -70,10 +72,7 @@
*/
public class IntrinsicGraphBuilder implements GraphBuilderContext, Receiver {
- protected final MetaAccessProvider metaAccess;
- protected final ConstantReflectionProvider constantReflection;
- protected final ConstantFieldProvider constantFieldProvider;
- protected final StampProvider stampProvider;
+ protected final CoreProviders providers;
protected final StructuredGraph graph;
protected final Bytecode code;
protected final ResolvedJavaMethod method;
@@ -82,17 +81,12 @@
protected ValueNode[] arguments;
protected ValueNode returnValue;
- public IntrinsicGraphBuilder(OptionValues options, DebugContext debug, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider,
- StampProvider stampProvider, Bytecode code, int invokeBci) {
- this(options, debug, metaAccess, constantReflection, constantFieldProvider, stampProvider, code, invokeBci, AllowAssumptions.YES);
+ public IntrinsicGraphBuilder(OptionValues options, DebugContext debug, CoreProviders providers, Bytecode code, int invokeBci) {
+ this(options, debug, providers, code, invokeBci, AllowAssumptions.YES);
}
- protected IntrinsicGraphBuilder(OptionValues options, DebugContext debug, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider,
- StampProvider stampProvider, Bytecode code, int invokeBci, AllowAssumptions allowAssumptions) {
- this.metaAccess = metaAccess;
- this.constantReflection = constantReflection;
- this.constantFieldProvider = constantFieldProvider;
- this.stampProvider = stampProvider;
+ protected IntrinsicGraphBuilder(OptionValues options, DebugContext debug, CoreProviders providers, Bytecode code, int invokeBci, AllowAssumptions allowAssumptions) {
+ this.providers = providers;
this.code = code;
this.method = code.getMethod();
this.graph = new StructuredGraph.Builder(options, debug, allowAssumptions).method(method).setIsSubstitution(true).trackNodeSourcePosition(true).build();
@@ -133,7 +127,9 @@
private <T extends ValueNode> void updateLastInstruction(T v) {
if (v instanceof FixedNode) {
FixedNode fixedNode = (FixedNode) v;
- lastInstr.setNext(fixedNode);
+ if (lastInstr != null) {
+ lastInstr.setNext(fixedNode);
+ }
if (fixedNode instanceof FixedWithNextNode) {
FixedWithNextNode fixedWithNextNode = (FixedWithNextNode) fixedNode;
assert fixedWithNextNode.next() == null : "cannot append instruction to instruction which isn't end";
@@ -175,22 +171,27 @@
@Override
public StampProvider getStampProvider() {
- return stampProvider;
+ return providers.getStampProvider();
}
@Override
public MetaAccessProvider getMetaAccess() {
- return metaAccess;
+ return providers.getMetaAccess();
}
@Override
public ConstantReflectionProvider getConstantReflection() {
- return constantReflection;
+ return providers.getConstantReflection();
}
@Override
public ConstantFieldProvider getConstantFieldProvider() {
- return constantFieldProvider;
+ return providers.getConstantFieldProvider();
+ }
+
+ @Override
+ public Replacements getReplacements() {
+ return providers.getReplacements();
}
@Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java Thu Mar 28 19:39:14 2019 +0100
@@ -106,6 +106,8 @@
import org.graalvm.compiler.nodes.java.NewMultiArrayNode;
import org.graalvm.compiler.nodes.java.StoreFieldNode;
import org.graalvm.compiler.nodes.java.StoreIndexedNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
+import org.graalvm.compiler.nodes.spi.Replacements;
import org.graalvm.compiler.nodes.spi.StampProvider;
import org.graalvm.compiler.nodes.type.StampTool;
import org.graalvm.compiler.nodes.util.GraphUtil;
@@ -309,22 +311,27 @@
@Override
public StampProvider getStampProvider() {
- return stampProvider;
+ return providers.getStampProvider();
}
@Override
public MetaAccessProvider getMetaAccess() {
- return metaAccess;
+ return providers.getMetaAccess();
}
@Override
public ConstantReflectionProvider getConstantReflection() {
- return constantReflection;
+ return providers.getConstantReflection();
}
@Override
public ConstantFieldProvider getConstantFieldProvider() {
- return constantFieldProvider;
+ return providers.getConstantFieldProvider();
+ }
+
+ @Override
+ public Replacements getReplacements() {
+ return providers.getReplacements();
}
@Override
@@ -565,11 +572,11 @@
private final ResolvedJavaMethod callInlinedMethod;
protected final SourceLanguagePositionProvider sourceLanguagePositionProvider;
- public PEGraphDecoder(Architecture architecture, StructuredGraph graph, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider,
- StampProvider stampProvider, LoopExplosionPlugin loopExplosionPlugin, InvocationPlugins invocationPlugins, InlineInvokePlugin[] inlineInvokePlugins,
+ public PEGraphDecoder(Architecture architecture, StructuredGraph graph, CoreProviders providers, LoopExplosionPlugin loopExplosionPlugin, InvocationPlugins invocationPlugins,
+ InlineInvokePlugin[] inlineInvokePlugins,
ParameterPlugin parameterPlugin,
NodePlugin[] nodePlugins, ResolvedJavaMethod callInlinedMethod, SourceLanguagePositionProvider sourceLanguagePositionProvider) {
- super(architecture, graph, metaAccess, constantReflection, constantFieldProvider, stampProvider, true);
+ super(architecture, graph, providers, true);
this.loopExplosionPlugin = loopExplosionPlugin;
this.invocationPlugins = invocationPlugins;
this.inlineInvokePlugins = inlineInvokePlugins;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java Thu Mar 28 19:39:14 2019 +0100
@@ -52,7 +52,6 @@
import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode;
import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.core.common.GraalOptions;
-import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugContext.Description;
@@ -64,6 +63,7 @@
import org.graalvm.compiler.graph.NodeSourcePosition;
import org.graalvm.compiler.java.GraphBuilderPhase;
import org.graalvm.compiler.java.GraphBuilderPhase.Instance;
+import org.graalvm.compiler.loop.phases.ConvertDeoptimizeToGuardPhase;
import org.graalvm.compiler.nodes.CallTargetNode;
import org.graalvm.compiler.nodes.Invoke;
import org.graalvm.compiler.nodes.StateSplit;
@@ -80,14 +80,12 @@
import org.graalvm.compiler.nodes.graphbuilderconf.MethodSubstitutionPlugin;
import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
import org.graalvm.compiler.nodes.spi.Replacements;
-import org.graalvm.compiler.nodes.spi.StampProvider;
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 org.graalvm.compiler.phases.OptimisticOptimizations;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.loop.phases.ConvertDeoptimizeToGuardPhase;
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
import org.graalvm.compiler.phases.tiers.PhaseContext;
import org.graalvm.compiler.phases.util.Providers;
@@ -95,7 +93,6 @@
import org.graalvm.compiler.word.WordOperationPlugin;
import jdk.vm.ci.code.TargetDescription;
-import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
@@ -322,11 +319,8 @@
result = graph;
} else {
Bytecode code = new ResolvedJavaMethodBytecode(method);
- ConstantReflectionProvider constantReflection = providers.getConstantReflection();
- ConstantFieldProvider constantFieldProvider = providers.getConstantFieldProvider();
- StampProvider stampProvider = providers.getStampProvider();
try (DebugContext debug = openDebugContext("Substitution_", method)) {
- result = new IntrinsicGraphBuilder(options, debug, metaAccess, constantReflection, constantFieldProvider, stampProvider, code, invokeBci).buildGraph(plugin);
+ result = new IntrinsicGraphBuilder(options, debug, providers, code, invokeBci).buildGraph(plugin);
}
}
} else {
@@ -355,8 +349,7 @@
Plugins plugins = new Plugins(getGraphBuilderPlugins());
GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(plugins);
IntrinsicContext initialReplacementContext = new IntrinsicContext(method, substMethod, bytecodeProvider, ROOT_COMPILATION);
- new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), providers.getConstantReflection(), providers.getConstantFieldProvider(), config,
- OptimisticOptimizations.NONE, initialReplacementContext).apply(graph);
+ new GraphBuilderPhase.Instance(providers, config, OptimisticOptimizations.NONE, initialReplacementContext).apply(graph);
assert !graph.isFrozen();
return graph;
} catch (Throwable e) {
@@ -521,8 +514,7 @@
snippetAnnotation != null ? snippetAnnotation.allowPartialIntrinsicArgumentMismatch() : true);
}
- createGraphBuilder(metaAccess, replacements.providers.getStampProvider(), replacements.providers.getConstantReflection(), replacements.providers.getConstantFieldProvider(), config,
- OptimisticOptimizations.NONE, initialIntrinsicContext).apply(graph);
+ createGraphBuilder(replacements.providers, config, OptimisticOptimizations.NONE, initialIntrinsicContext).apply(graph);
new CanonicalizerPhase().apply(graph, new PhaseContext(replacements.providers));
} catch (Throwable e) {
@@ -531,10 +523,8 @@
return graph;
}
- protected Instance createGraphBuilder(MetaAccessProvider metaAccess, StampProvider stampProvider, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider,
- GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, IntrinsicContext initialIntrinsicContext) {
- return new GraphBuilderPhase.Instance(metaAccess, stampProvider, constantReflection, constantFieldProvider, graphBuilderConfig, optimisticOpts,
- initialIntrinsicContext);
+ protected Instance createGraphBuilder(Providers providers, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, IntrinsicContext initialIntrinsicContext) {
+ return new GraphBuilderPhase.Instance(providers, graphBuilderConfig, optimisticOpts, initialIntrinsicContext);
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounterNode.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounterNode.java Thu Mar 28 19:39:14 2019 +0100
@@ -28,7 +28,6 @@
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED;
import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER;
-import java.lang.reflect.Field;
import java.util.Arrays;
import org.graalvm.compiler.api.replacements.Fold;
@@ -51,6 +50,7 @@
import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates;
import org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
+import org.graalvm.compiler.serviceprovider.GraalUnsafeAccess;
import org.graalvm.compiler.word.ObjectAccess;
import jdk.internal.vm.compiler.word.LocationIdentity;
@@ -129,6 +129,8 @@
static class SnippetCounterSnippets implements Snippets {
+ private static final Unsafe UNSAFE = GraalUnsafeAccess.getUnsafe();
+
@Fold
static int countOffset() {
try {
@@ -162,20 +164,4 @@
}
}
}
-
- private static final Unsafe UNSAFE = initUnsafe();
-
- private static Unsafe initUnsafe() {
- try {
- return Unsafe.getUnsafe();
- } catch (SecurityException se) {
- try {
- Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
- theUnsafe.setAccessible(true);
- return (Unsafe) theUnsafe.get(Unsafe.class);
- } catch (Exception e) {
- throw new RuntimeException("exception while trying to get Unsafe", e);
- }
- }
- }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java Thu Mar 28 19:39:14 2019 +0100
@@ -212,6 +212,20 @@
return false;
}
});
+ r.register1("intern", Receiver.class, new InvocationPlugin() {
+ @Override
+ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
+ if (receiver.isConstant()) {
+ String s = snippetReflection.asObject(String.class, (JavaConstant) receiver.get().asConstant());
+ if (s != null) {
+ JavaConstant interned = snippetReflection.forObject(s.intern());
+ b.addPush(JavaKind.Object, b.add(ConstantNode.forConstant(interned, b.getMetaAccess(), b.getGraph())));
+ return true;
+ }
+ }
+ return false;
+ }
+ });
if (Java8OrEarlier) {
r.registerMethodSubstitution(StringSubstitutions.class, "equals", Receiver.class, Object.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/UnsafeAccess.java Thu Mar 28 11:06:00 2019 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2012, 2018, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.replacements;
-
-import java.lang.reflect.Field;
-
-import sun.misc.Unsafe;
-
-/**
- * Package private access to the {@link Unsafe} capability.
- */
-class UnsafeAccess {
-
- private static final Unsafe THE_UNSAFE = initUnsafe();
-
- static final UnsafeAccess UNSAFE = new UnsafeAccess();
-
- private static Unsafe initUnsafe() {
- try {
- // Fast path when we are trusted.
- return Unsafe.getUnsafe();
- } catch (SecurityException se) {
- // Slow path when we are not trusted.
- try {
- Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
- theUnsafe.setAccessible(true);
- return (Unsafe) theUnsafe.get(Unsafe.class);
- } catch (Exception e) {
- throw new RuntimeException("exception while trying to get Unsafe", e);
- }
- }
- }
-
- public char getChar(Object target, long l) {
- return THE_UNSAFE.getChar(target, l);
- }
-
- public byte getByte(Object target, long l) {
- return THE_UNSAFE.getByte(target, l);
- }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java Thu Mar 28 19:39:14 2019 +0100
@@ -108,12 +108,13 @@
if (classfile == null) {
try {
ResolvedJavaType type = metaAccess.lookupJavaType(c);
- InputStream in = GraalServices.getClassfileAsStream(c);
- if (in != null) {
- DataInputStream stream = new DataInputStream(in);
- classfile = new Classfile(type, stream, this);
- classfiles.put(c, classfile);
- return classfile;
+ try (InputStream in = GraalServices.getClassfileAsStream(c)) {
+ if (in != null) {
+ DataInputStream stream = new DataInputStream(in);
+ classfile = new Classfile(type, stream, this);
+ classfiles.put(c, classfile);
+ return classfile;
+ }
}
throw new NoClassDefFoundError(c.getName());
} catch (IOException e) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayCompareToNode.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayCompareToNode.java Thu Mar 28 19:39:14 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 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
@@ -24,10 +24,12 @@
package org.graalvm.compiler.replacements.nodes;
+import static org.graalvm.compiler.core.common.GraalOptions.UseGraalStubs;
import static org.graalvm.compiler.nodeinfo.InputType.Memory;
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1024;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1024;
+import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
@@ -117,8 +119,25 @@
@NodeIntrinsic
public static native int compareTo(Object array1, Object array2, int length1, int length2, @ConstantNodeParameter JavaKind kind1, @ConstantNodeParameter JavaKind kind2);
+ public JavaKind getKind1() {
+ return kind1;
+ }
+
+ public JavaKind getKind2() {
+ return kind2;
+ }
+
@Override
public void generate(NodeLIRBuilderTool gen) {
+ if (UseGraalStubs.getValue(graph().getOptions())) {
+ ForeignCallLinkage linkage = gen.lookupGraalStub(this);
+ if (linkage != null) {
+ Value result = gen.getLIRGeneratorTool().emitForeignCall(linkage, null, gen.operand(array1), gen.operand(array2), gen.operand(length1), gen.operand(length2));
+ gen.setResult(this, result);
+ return;
+ }
+ }
+
Value result = gen.getLIRGeneratorTool().emitArrayCompareTo(kind1, kind2, gen.operand(array1), gen.operand(array2), gen.operand(length1), gen.operand(length2));
gen.setResult(this, result);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayEqualsNode.java Thu Mar 28 19:39:14 2019 +0100
@@ -24,16 +24,15 @@
package org.graalvm.compiler.replacements.nodes;
+import static org.graalvm.compiler.core.common.GraalOptions.UseGraalStubs;
import static org.graalvm.compiler.nodeinfo.InputType.Memory;
-import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.spi.Canonicalizable;
import org.graalvm.compiler.graph.spi.CanonicalizerTool;
-import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
import org.graalvm.compiler.nodeinfo.NodeCycles;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodeinfo.NodeSize;
@@ -51,14 +50,11 @@
import org.graalvm.compiler.nodes.spi.VirtualizerTool;
import org.graalvm.compiler.nodes.util.GraphUtil;
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
-import org.graalvm.compiler.options.Option;
-import org.graalvm.compiler.options.OptionKey;
import jdk.internal.vm.compiler.word.LocationIdentity;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.Value;
// JaCoCo Exclude
@@ -69,13 +65,6 @@
@NodeInfo(cycles = NodeCycles.CYCLES_UNKNOWN, size = NodeSize.SIZE_128)
public final class ArrayEqualsNode extends FixedWithNextNode implements LIRLowerable, Canonicalizable, Virtualizable, MemoryAccess {
- public static class Options {
- // @formatter:off
- @Option(help = "Use Array equals stubs instead of embedding all the emitted code.")
- public static final OptionKey<Boolean> ArrayEqualsStubs = new OptionKey<>(true);
- // @formatter:on
- }
-
public static final NodeClass<ArrayEqualsNode> TYPE = NodeClass.create(ArrayEqualsNode.class);
/** {@link JavaKind} of the arrays to compare. */
protected final JavaKind kind;
@@ -225,27 +214,30 @@
return equals(array1, array2, length, JavaKind.Double);
}
+ public ValueNode getLength() {
+ return length;
+ }
+
+ public JavaKind getKind() {
+ return kind;
+ }
+
@Override
public void generate(NodeLIRBuilderTool gen) {
- LIRGeneratorTool tool = gen.getLIRGeneratorTool();
+ if (UseGraalStubs.getValue(graph().getOptions())) {
+ ForeignCallLinkage linkage = gen.lookupGraalStub(this);
+ if (linkage != null) {
+ Value result = gen.getLIRGeneratorTool().emitForeignCall(linkage, null, gen.operand(array1), gen.operand(array2), gen.operand(length));
+ gen.setResult(this, result);
+ return;
+ }
+ }
+
int constantLength = -1;
if (length.isConstant()) {
constantLength = length.asJavaConstant().asInt();
}
-
- if (Options.ArrayEqualsStubs.getValue(graph().getOptions())) {
- ResolvedJavaMethod method = graph().method();
- if (method != null && method.getAnnotation(Snippet.class) == null) {
- ForeignCallLinkage linkage = tool.lookupArrayEqualsStub(kind, constantLength);
- if (linkage != null) {
- Value result = tool.emitForeignCall(linkage, null, gen.operand(array1), gen.operand(array2), gen.operand(length));
- gen.setResult(this, result);
- return;
- }
- }
- }
-
- Value result = tool.emitArrayEquals(kind, gen.operand(array1), gen.operand(array2), gen.operand(length), constantLength, false);
+ Value result = gen.getLIRGeneratorTool().emitArrayEquals(kind, gen.operand(array1), gen.operand(array2), gen.operand(length), constantLength, false);
gen.setResult(this, result);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayRegionEqualsNode.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayRegionEqualsNode.java Thu Mar 28 19:39:14 2019 +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
@@ -24,8 +24,10 @@
package org.graalvm.compiler.replacements.nodes;
-import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.Value;
+import static org.graalvm.compiler.core.common.GraalOptions.UseGraalStubs;
+import static org.graalvm.compiler.nodeinfo.InputType.Memory;
+
+import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.nodeinfo.NodeCycles;
@@ -42,7 +44,8 @@
import jdk.internal.vm.compiler.word.LocationIdentity;
import jdk.internal.vm.compiler.word.Pointer;
-import static org.graalvm.compiler.nodeinfo.InputType.Memory;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.Value;
// JaCoCo Exclude
@@ -85,8 +88,29 @@
@NodeIntrinsic
public static native boolean regionEquals(Pointer array1, Pointer array2, int length, @ConstantNodeParameter JavaKind kind1, @ConstantNodeParameter JavaKind kind2);
+ public JavaKind getKind1() {
+ return kind1;
+ }
+
+ public JavaKind getKind2() {
+ return kind2;
+ }
+
+ public ValueNode getLength() {
+ return length;
+ }
+
@Override
public void generate(NodeLIRBuilderTool gen) {
+ if (UseGraalStubs.getValue(graph().getOptions())) {
+ ForeignCallLinkage linkage = gen.lookupGraalStub(this);
+ if (linkage != null) {
+ Value result = gen.getLIRGeneratorTool().emitForeignCall(linkage, null, gen.operand(array1), gen.operand(array2), gen.operand(length));
+ gen.setResult(this, result);
+ return;
+ }
+ }
+
int constantLength = -1;
if (length.isConstant()) {
constantLength = length.asJavaConstant().asInt();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java Thu Mar 28 19:39:14 2019 +0100
@@ -41,9 +41,9 @@
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
import org.graalvm.compiler.nodes.FixedNode;
-import org.graalvm.compiler.nodes.Invokable;
import org.graalvm.compiler.nodes.FixedWithNextNode;
import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.Invokable;
import org.graalvm.compiler.nodes.InvokeNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.GuardsStage;
@@ -58,10 +58,10 @@
import org.graalvm.compiler.phases.common.RemoveValueProxyPhase;
import org.graalvm.compiler.phases.common.inlining.InliningUtil;
import org.graalvm.compiler.phases.tiers.PhaseContext;
+import jdk.internal.vm.compiler.word.LocationIdentity;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.internal.vm.compiler.word.LocationIdentity;
/**
* Macro nodes can be used to temporarily replace an invoke. They can, for example, be used to
@@ -160,8 +160,7 @@
*/
@SuppressWarnings("try")
protected StructuredGraph lowerReplacement(final StructuredGraph replacementGraph, LoweringTool tool) {
- final PhaseContext c = new PhaseContext(tool.getMetaAccess(), tool.getConstantReflection(), tool.getConstantFieldProvider(), tool.getLowerer(), tool.getReplacements(),
- tool.getStampProvider(), null);
+ final PhaseContext c = new PhaseContext(tool.getProviders());
if (!graph().hasValueProxies()) {
new RemoveValueProxyPhase().apply(replacementGraph);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalUnsafeAccess.java Thu Mar 28 19:39:14 2019 +0100
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2012, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.serviceprovider;
+
+import java.lang.reflect.Field;
+
+import sun.misc.Unsafe;
+
+/**
+ * Access to the {@link Unsafe} capability. Care must be taken not to leak the {@link #UNSAFE} value
+ * of out code loaded by the JVMCI class loader or encapsulated in the JVMCI or Graal modules into
+ * other code (e.g. via the Polyglot API).
+ */
+public class GraalUnsafeAccess {
+
+ private static final Unsafe UNSAFE = initUnsafe();
+
+ private static Unsafe initUnsafe() {
+ try {
+ // Fast path when we are trusted.
+ return Unsafe.getUnsafe();
+ } catch (SecurityException se) {
+ // Slow path when we are not trusted.
+ try {
+ Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
+ theUnsafe.setAccessible(true);
+ return (Unsafe) theUnsafe.get(Unsafe.class);
+ } catch (Exception e) {
+ throw new RuntimeException("exception while trying to get Unsafe", e);
+ }
+ }
+ }
+
+ /**
+ * Gets the {@link Unsafe} singleton.
+ *
+ * @throws SecurityException if a security manager is present and it denies
+ * {@link RuntimePermission}("accessUnsafe")
+ */
+ public static Unsafe getUnsafe() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new RuntimePermission("accessUnsafe"));
+ }
+ return UNSAFE;
+ }
+}
+
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/JavaVersionUtil.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/JavaVersionUtil.java Thu Mar 28 19:39:14 2019 +0100
@@ -24,13 +24,15 @@
package org.graalvm.compiler.serviceprovider;
+import jdk.vm.ci.services.Services;
+
/**
* Interface to query which JDK version Graal is running on.
*/
public final class JavaVersionUtil {
private static int getJavaSpecificationVersion() {
- String value = System.getProperty("java.specification.version");
+ String value = Services.getSavedProperties().get("java.specification.version");
if (value.startsWith("1.")) {
value = value.substring(2);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsClosure.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsClosure.java Thu Mar 28 19:39:14 2019 +0100
@@ -428,7 +428,7 @@
protected abstract class MergeProcessor {
private final Block mergeBlock;
- private final AbstractMergeNode merge;
+ protected final AbstractMergeNode merge;
protected final GraphEffectList mergeEffects;
protected final GraphEffectList afterMergeEffects;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java Thu Mar 28 19:39:14 2019 +0100
@@ -59,6 +59,7 @@
import org.graalvm.compiler.nodes.ProxyNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
+import org.graalvm.compiler.nodes.UnwindNode;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.ValuePhiNode;
import org.graalvm.compiler.nodes.ValueProxyNode;
@@ -105,7 +106,6 @@
* The indexes into this array correspond to {@link VirtualObjectNode#getObjectId()}.
*/
public final ArrayList<VirtualObjectNode> virtualObjects = new ArrayList<>();
- public final DebugContext debug;
@Override
public boolean needsApplyEffects() {
@@ -189,7 +189,6 @@
super(schedule, schedule.getCFG());
StructuredGraph graph = schedule.getCFG().graph;
this.hasVirtualInputs = graph.createNodeBitMap();
- this.debug = graph.getDebug();
this.tool = new VirtualizerToolImpl(metaAccess, constantReflection, constantFieldProvider, this, graph.getAssumptions(), graph.getOptions(), debug, loweringProvider);
}
@@ -687,16 +686,44 @@
// calculate the set of virtual objects that exist in all predecessors
int[] virtualObjTemp = intersectVirtualObjects(states);
+ boolean forceMaterialization = false;
+ ValueNode forcedMaterializationValue = null;
+ FrameState frameState = merge.stateAfter();
+ if (frameState != null && frameState.isExceptionHandlingBCI()) {
+ // We can not go below merges with an exception handling bci
+ // it could create allocations whose slow-path has an invalid framestate
+ forceMaterialization = true;
+ // check if we can reduce the scope of forced materialization to one phi node
+ if (frameState.stackSize() == 1 && merge.next() instanceof UnwindNode) {
+ assert frameState.outerFrameState() == null;
+ UnwindNode unwind = (UnwindNode) merge.next();
+ if (unwind.exception() == frameState.stackAt(0)) {
+ boolean nullLocals = true;
+ for (int i = 0; i < frameState.localsSize(); i++) {
+ if (frameState.localAt(i) != null) {
+ nullLocals = false;
+ break;
+ }
+ }
+ if (nullLocals) {
+ // We found that the merge is directly followed by an unwind
+ // the Framestate only has the thrown value on the stack and no locals
+ forcedMaterializationValue = unwind.exception();
+ }
+ }
+ }
+ }
+
boolean materialized;
do {
materialized = false;
- if (PartialEscapeBlockState.identicalObjectStates(states)) {
+ if (!forceMaterialization && PartialEscapeBlockState.identicalObjectStates(states)) {
newState.adoptAddObjectStates(states[0]);
} else {
for (int object : virtualObjTemp) {
- if (PartialEscapeBlockState.identicalObjectStates(states, object)) {
+ if (!forceMaterialization && PartialEscapeBlockState.identicalObjectStates(states, object)) {
newState.addObject(object, states[0].getObjectState(object).share());
continue;
}
@@ -710,6 +737,22 @@
for (int i = 0; i < states.length; i++) {
ObjectState obj = states[i].getObjectState(object);
ensureVirtual &= obj.getEnsureVirtualized();
+ if (forceMaterialization) {
+ if (forcedMaterializationValue == null) {
+ uniqueMaterializedValue = null;
+ continue;
+ } else {
+ ValueNode value = forcedMaterializationValue;
+ if (merge.isPhiAtMerge(value)) {
+ value = ((ValuePhiNode) value).valueAt(i);
+ }
+ ValueNode alias = getAlias(value);
+ if (alias instanceof VirtualObjectNode && ((VirtualObjectNode) alias).getObjectId() == object) {
+ uniqueMaterializedValue = null;
+ continue;
+ }
+ }
+ }
if (obj.isVirtual()) {
virtualCount++;
uniqueMaterializedValue = null;
@@ -1029,6 +1072,7 @@
*/
if (virtual.hasIdentity() && !isSingleUsageAllocation(getPhiValueAt(phi, i), virtualObjs, states[i])) {
compatible = false;
+ break;
}
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/UnsafeAccess.java Thu Mar 28 11:06:00 2019 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2012, 2018, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.word;
-
-import java.lang.reflect.Field;
-
-import sun.misc.Unsafe;
-
-/**
- * Package private access to the {@link Unsafe} capability.
- */
-class UnsafeAccess {
-
- static final Unsafe UNSAFE = initUnsafe();
-
- private static Unsafe initUnsafe() {
- try {
- // Fast path when we are trusted.
- return Unsafe.getUnsafe();
- } catch (SecurityException se) {
- // Slow path when we are not trusted.
- try {
- Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
- theUnsafe.setAccessible(true);
- return (Unsafe) theUnsafe.get(Unsafe.class);
- } catch (Exception e) {
- throw new RuntimeException("exception while trying to get Unsafe", e);
- }
- }
- }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/Word.java Thu Mar 28 11:06:00 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.word/src/org/graalvm/compiler/word/Word.java Thu Mar 28 19:39:14 2019 +0100
@@ -24,7 +24,7 @@
package org.graalvm.compiler.word;
-import static org.graalvm.compiler.word.UnsafeAccess.UNSAFE;
+import static org.graalvm.compiler.serviceprovider.GraalUnsafeAccess.getUnsafe;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -59,8 +59,12 @@
import jdk.internal.vm.compiler.word.WordFactory;
import jdk.internal.vm.compiler.word.impl.WordBoxFactory;
+import sun.misc.Unsafe;
+
public abstract class Word implements SignedWord, UnsignedWord, Pointer {
+ private static final Unsafe UNSAFE = getUnsafe();
+
static {
BoxFactoryImpl.initialize();
}