From 089f83703aab9172f1e51829aa8adce3a272c4bb Mon Sep 17 00:00:00 2001
From: Igor Veresov
Date: Fri, 16 Mar 2018 22:59:32 -0700
Subject: [PATCH] 8198969: Update Graal
Reviewed-by: kvn
---
make/CompileToolsHotspot.gmk | 1 +
.../compiler/asm/amd64/AMD64Assembler.java | 145 ++++-
.../bytecode/BytecodeDisassembler.java | 57 ++
.../compiler/code/DisassemblerProvider.java | 2 +-
.../compiler/core/amd64/AMD64AddressNode.java | 3 +-
.../amd64/AMD64ArithmeticLIRGenerator.java | 85 ++-
.../core/amd64/AMD64LIRGenerator.java | 20 +
.../core/amd64/AMD64NodeLIRBuilder.java | 31 +
.../compiler/core/common/GraalOptions.java | 8 +-
.../alloc/BiDirectionalTraceBuilder.java | 36 +-
.../alloc/UniDirectionalTraceBuilder.java | 40 +-
.../core/common/type/AbstractObjectStamp.java | 2 -
.../compiler/core/common/type/FloatStamp.java | 98 ++-
.../core/common/type/IntegerStamp.java | 101 ++-
.../core/common/type/StampFactory.java | 4 +
.../core/common/util/UnsignedLong.java | 98 +++
.../core/test/BasePhaseBinaryGraphTest.java | 63 ++
.../core/test/ConditionalNodeTest.java | 107 ++++
.../compiler/core/test/CountedLoopTest.java | 294 +++++++--
.../compiler/core/test/GraalCompilerTest.java | 30 +-
.../compiler/core/test/GraphEncoderTest.java | 3 +-
.../core/test/SwitchDyingLoopTest.java | 90 +++
.../test/TrivialInliningExplosionTest.java | 6 +-
.../compiler/core/test/UnsignedLongTest.java | 139 ++++
.../graalvm/compiler/core/GraalCompiler.java | 1 +
.../compiler/core/gen/NodeLIRBuilder.java | 5 +
.../compiler/core/phases/HighTier.java | 7 +-
.../graalvm/compiler/core/target/Backend.java | 25 +-
.../.checkstyle_checks.xml | 2 +-
.../src/org/graalvm/compiler/graph/Graph.java | 46 +-
.../graph/InlineCacheGuardPosition.java | 79 +++
.../src/org/graalvm/compiler/graph/Node.java | 20 +-
.../org/graalvm/compiler/graph/NodeClass.java | 14 +-
.../compiler/graph/NodeSourcePosition.java | 188 +++++-
.../graph/SourceLanguagePosition.java | 44 ++
.../SourceLanguagePositionProvider.java} | 21 +-
.../aarch64/AArch64HotSpotBackend.java | 28 +-
.../aarch64/AArch64HotSpotDeoptimizeOp.java | 4 +-
.../hotspot/aarch64/AArch64HotSpotMove.java | 24 +-
.../hotspot/amd64/test/StubAVXTest.java | 5 +
.../amd64/AMD64HotSpotAddressLowering.java | 2 +-
.../amd64/AMD64HotSpotLIRGenerator.java | 6 +-
...RGenerator.java => AMD64HotSpotMaths.java} | 48 +-
.../hotspot/sparc/SPARCHotSpotMove.java | 15 +-
.../hotspot/test/CompileTheWorld.java | 3 +-
.../test/HotSpotLazyInitializationTest.java | 75 +++
.../hotspot/CompilerConfigurationFactory.java | 62 ++
.../hotspot/GraalHotSpotVMConfig.java | 14 +-
.../compiler/hotspot/HotSpotBackend.java | 2 +-
.../hotspot/HotSpotCompiledCodeBuilder.java | 48 +-
.../hotspot/HotSpotGraalCompilerFactory.java | 80 ++-
.../compiler/hotspot/NodeCostDumpUtil.java | 10 +-
.../lir/VerifyMaxRegisterSizePhase.java | 77 +++
.../HotSpotClassInitializationPlugin.java | 49 ++
.../meta/HotSpotGraphBuilderPlugins.java | 2 +-
.../meta/HotSpotInvocationPlugins.java | 34 +-
.../hotspot/meta/HotSpotSuitesProvider.java | 11 +-
.../hotspot/phases/aot/AOTInliningPolicy.java | 12 +-
.../replacements/AssertionSnippets.java | 2 +-
.../replacements/HashCodeSnippets.java | 2 +-
.../LoadExceptionObjectSnippets.java | 2 +-
.../hotspot/replacements/MonitorSnippets.java | 8 +-
.../replacements/NewObjectSnippets.java | 12 +-
.../hotspot/replacements/ObjectCloneNode.java | 2 +-
.../replacements/StringToBytesSnippets.java | 2 +-
.../replacements/UnsafeLoadSnippets.java | 2 +-
.../replacements/WriteBarrierSnippets.java | 14 +-
.../aot/ResolveConstantSnippets.java | 12 +-
.../arraycopy/ArrayCopySnippets.java | 2 +-
.../ProbabilisticProfileSnippets.java | 4 +-
.../profiling/ProfileSnippets.java | 4 +-
.../hotspot/stubs/ForeignCallStub.java | 43 +-
.../graalvm/compiler/java/BytecodeParser.java | 364 ++++++-----
.../compiler/java/BytecodeParserOptions.java | 2 +-
.../compiler/java/FrameStateBuilder.java | 28 +-
.../src/org/graalvm/compiler/jtt/JTTTest.java | 59 +-
.../compiler/jtt/hotpath/HP_series.java | 21 +-
.../graalvm/compiler/jtt/lang/Math_abs.java | 11 +-
.../graalvm/compiler/jtt/lang/Math_cos.java | 11 +-
.../graalvm/compiler/jtt/lang/Math_exp.java | 18 +-
.../graalvm/compiler/jtt/lang/Math_log.java | 11 +-
.../graalvm/compiler/jtt/lang/Math_pow.java | 44 +-
.../graalvm/compiler/jtt/lang/Math_sin.java | 11 +-
.../graalvm/compiler/jtt/lang/Math_sqrt.java | 11 +-
.../graalvm/compiler/jtt/lang/Math_tan.java | 11 +-
.../graalvm/compiler/jtt/lang/UnaryMath.java | 68 ++
.../compiler/lir/aarch64/AArch64Call.java | 16 +-
.../lir/amd64/AMD64ArrayCompareToOp.java | 595 ++++++++++++++++++
.../compiler/lir/amd64/AMD64LFenceOp.java | 42 ++
.../graalvm/compiler/lir/amd64/AMD64Move.java | 33 +-
.../compiler/lir/LIRInstructionClass.java | 6 +-
.../lir/alloc/trace/GlobalLivenessInfo.java | 10 +-
.../lir/alloc/trace/TraceAssertions.java | 69 ++
.../trace/TraceGlobalMoveResolutionPhase.java | 72 ++-
.../compiler/lir/alloc/trace/TraceUtil.java | 13 -
.../alloc/trace/TrivialTraceAllocator.java | 76 +--
.../lir/alloc/trace/bu/BottomUpAllocator.java | 13 +-
.../TraceLinearScanLifetimeAnalysisPhase.java | 47 +-
.../compiler/lir/gen/LIRGeneratorTool.java | 7 +-
.../compiler/lir/phases/LIRPhaseSuite.java | 7 +
.../org/graalvm/compiler/lir/ssa/SSAUtil.java | 22 +
.../compiler/loop/BasicInductionVariable.java | 9 +-
.../compiler/loop/CountedLoopInfo.java | 105 ++--
.../compiler/loop/DefaultLoopPolicies.java | 16 +-
.../graalvm/compiler/loop/LoopFragment.java | 60 +-
.../compiler/loop/LoopFragmentInside.java | 52 +-
.../org/graalvm/compiler/loop/MathUtil.java | 23 +-
.../compiler/nodes/test/IntegerStampTest.java | 12 +
.../test/PrimitiveStampBoundaryTest.java | 26 +-
.../nodes/AbstractFixedGuardNode.java | 52 +-
.../org/graalvm/compiler/nodes/BeginNode.java | 14 +-
.../compiler/nodes/DeoptimizeNode.java | 14 +-
.../graalvm/compiler/nodes/DynamicPiNode.java | 40 +-
.../graalvm/compiler/nodes/EncodedGraph.java | 30 +-
.../compiler/nodes/FixedGuardNode.java | 18 +-
.../graalvm/compiler/nodes/FrameState.java | 2 +-
.../graalvm/compiler/nodes/GraphDecoder.java | 20 +-
.../graalvm/compiler/nodes/GraphEncoder.java | 8 +-
.../org/graalvm/compiler/nodes/GuardNode.java | 10 +-
.../graalvm/compiler/nodes/InliningLog.java | 457 ++++++++------
.../org/graalvm/compiler/nodes/Invokable.java | 87 +++
.../org/graalvm/compiler/nodes/Invoke.java | 8 +-
.../graalvm/compiler/nodes/InvokeNode.java | 10 +
.../nodes/InvokeWithExceptionNode.java | 10 +
.../graalvm/compiler/nodes/LoopExitNode.java | 3 +
.../org/graalvm/compiler/nodes/PiNode.java | 2 +-
.../nodes/StaticDeoptimizingNode.java | 15 +
.../compiler/nodes/StructuredGraph.java | 48 +-
.../compiler/nodes/calc/CompareNode.java | 4 +-
.../compiler/nodes/calc/ConditionalNode.java | 6 +-
.../nodes/calc/IntegerConvertNode.java | 9 +
.../nodes/calc/IntegerLowerThanNode.java | 18 +-
.../nodes/extended/IntegerSwitchNode.java | 33 +-
.../ClassInitializationPlugin.java | 6 +
.../GraphBuilderConfiguration.java | 3 +-
.../graphbuilderconf/InlineInvokePlugin.java | 24 +-
.../graphbuilderconf/IntrinsicContext.java | 45 +-
.../nodes/java/InstanceOfDynamicNode.java | 25 +-
.../compiler/nodes/spi/Replacements.java | 15 +-
.../common/ConditionalEliminationPhase.java | 76 ++-
.../common/ConvertDeoptimizeToGuardPhase.java | 58 +-
.../phases/common/NodeCounterPhase.java | 50 ++
.../phases/common/inlining/InliningUtil.java | 257 ++++++--
.../inlining/info/AbstractInlineInfo.java | 2 +-
.../common/inlining/info/elem/Inlineable.java | 4 +-
.../inlining/info/elem/InlineableGraph.java | 16 +-
.../inlining/policy/GreedyInliningPolicy.java | 16 +-
.../InlineMethodSubstitutionsPolicy.java | 2 +-
.../common/inlining/walker/InliningData.java | 22 +-
.../graalvm/compiler/phases/PhaseSuite.java | 7 +
.../phases/contract/VerifyNodeCosts.java | 8 +-
.../compiler/printer/BinaryGraphPrinter.java | 18 +-
.../compiler/printer/GraphPrinter.java | 6 +-
.../printer/GraphPrinterDumpHandler.java | 5 +-
.../AArch64FloatArithmeticSnippets.java | 2 +-
.../AArch64IntegerArithmeticSnippets.java | 2 +-
.../amd64/AMD64ConvertSnippets.java | 2 +-
.../amd64/AMD64GraphBuilderPlugins.java | 31 +-
.../amd64/AMD64StringLatin1Substitutions.java | 59 ++
.../amd64/AMD64StringSubstitutions.java | 15 +
.../amd64/AMD64StringUTF16Substitutions.java | 63 ++
.../test/MethodSubstitutionTest.java | 2 +-
.../replacements/test/PEGraphDecoderTest.java | 4 +-
.../replacements/test/SnippetsTest.java | 2 +-
.../test/StandardMethodSubstitutionsTest.java | 5 +-
.../test/StringCompareToTest.java | 115 ++++
.../test/StringSubstitutionsTest.java | 5 +-
.../compiler/replacements/test/WordTest.java | 2 +-
.../compiler/replacements/BoxingSnippets.java | 6 +-
.../replacements/CachingPEGraphDecoder.java | 16 +-
.../ConstantStringIndexOfSnippets.java | 2 +-
.../compiler/replacements/GraphKit.java | 74 ++-
.../InlineDuringParsingPlugin.java | 21 +-
.../InstanceOfSnippetsTemplates.java | 2 +-
.../replacements/IntrinsicGraphBuilder.java | 19 +-
.../compiler/replacements/PEGraphDecoder.java | 98 ++-
.../replacements/ReplacementsImpl.java | 46 +-
.../replacements/SnippetCounterNode.java | 2 +-
.../replacements/SnippetTemplate.java | 102 +--
.../StandardGraphBuilderPlugins.java | 19 +
.../replacements/StringSubstitutions.java | 2 +-
.../classfile/ClassfileBytecodeProvider.java | 4 +-
.../nodes/ArrayCompareToNode.java | 139 ++++
.../replacements/nodes/MacroNode.java | 29 +-
.../nodes/MacroStateSplitNode.java | 2 +-
.../serviceprovider/GraalServices.java | 14 +-
.../compiler/serviceprovider/JDK9Method.java | 127 ++--
.../src/org/graalvm/graphio/ProtocolImpl.java | 12 +-
.../src/micro/benchmarks/StringBenchmark.java | 7 +
189 files changed, 5747 insertions(+), 1526 deletions(-)
create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/UnsignedLong.java
create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/BasePhaseBinaryGraphTest.java
create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalNodeTest.java
create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SwitchDyingLoopTest.java
create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsignedLongTest.java
create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/InlineCacheGuardPosition.java
create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/SourceLanguagePosition.java
rename src/jdk.internal.vm.compiler/share/classes/{org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/TraceInliningMode.java => org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/SourceLanguagePositionProvider.java} (77%)
rename src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/{AMD64HotSpotArithmeticLIRGenerator.java => AMD64HotSpotMaths.java} (55%)
create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotLazyInitializationTest.java
create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/lir/VerifyMaxRegisterSizePhase.java
create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/lang/UnaryMath.java
create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayCompareToOp.java
create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64LFenceOp.java
create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceAssertions.java
create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/Invokable.java
create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/NodeCounterPhase.java
create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringLatin1Substitutions.java
create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringUTF16Substitutions.java
create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompareToTest.java
create mode 100644 src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayCompareToNode.java
diff --git a/make/CompileToolsHotspot.gmk b/make/CompileToolsHotspot.gmk
index 54ab9ae0dfb..79468ad62b2 100644
--- a/make/CompileToolsHotspot.gmk
+++ b/make/CompileToolsHotspot.gmk
@@ -120,6 +120,7 @@ ifeq ($(INCLUDE_GRAAL), true)
SRC := \
$(SRC_DIR)/org.graalvm.word/src \
$(SRC_DIR)/org.graalvm.collections/src \
+ $(SRC_DIR)/org.graalvm.compiler.bytecode/src \
$(SRC_DIR)/org.graalvm.compiler.replacements.verifier/src \
$(SRC_DIR)/org.graalvm.compiler.api.replacements/src \
$(SRC_DIR)/org.graalvm.compiler.code/src \
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java
index 2bdbabcd46e..6bc4f378dc2 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java
@@ -195,11 +195,6 @@ public class AMD64Assembler extends Assembler {
private static final int VEX_W = 0x80;
}
- private static class AvxVectorLen {
- private static final int AVX_128bit = 0x0;
- private static final int AVX_256bit = 0x1;
- }
-
private static class VexSimdPrefix {
private static final int VEX_SIMD_NONE = 0x0;
private static final int VEX_SIMD_66 = 0x1;
@@ -208,11 +203,44 @@ public class AMD64Assembler extends Assembler {
}
private static class VexOpcode {
+ private static final int VEX_OPCODE_NONE = 0x0;
private static final int VEX_OPCODE_0F = 0x1;
private static final int VEX_OPCODE_0F_38 = 0x2;
private static final int VEX_OPCODE_0F_3A = 0x3;
}
+ public static class AvxVectorLen {
+ public static final int AVX_128bit = 0x0;
+ public static final int AVX_256bit = 0x1;
+ public static final int AVX_512bit = 0x2;
+ public static final int AVX_NoVec = 0x4;
+ }
+
+ public static class EvexTupleType {
+ public static final int EVEX_FV = 0;
+ public static final int EVEX_HV = 4;
+ public static final int EVEX_FVM = 6;
+ public static final int EVEX_T1S = 7;
+ public static final int EVEX_T1F = 11;
+ public static final int EVEX_T2 = 13;
+ public static final int EVEX_T4 = 15;
+ public static final int EVEX_T8 = 17;
+ public static final int EVEX_HVM = 18;
+ public static final int EVEX_QVM = 19;
+ public static final int EVEX_OVM = 20;
+ public static final int EVEX_M128 = 21;
+ public static final int EVEX_DUP = 22;
+ public static final int EVEX_ETUP = 23;
+ }
+
+ public static class EvexInputSizeInBits {
+ public static final int EVEX_8bit = 0;
+ public static final int EVEX_16bit = 1;
+ public static final int EVEX_32bit = 2;
+ public static final int EVEX_64bit = 3;
+ public static final int EVEX_NObit = 4;
+ }
+
private AMD64InstructionAttr curAttributes;
AMD64InstructionAttr getCurAttributes() {
@@ -873,6 +901,7 @@ public class AMD64Assembler extends Assembler {
opc = VexOpcode.VEX_OPCODE_0F_3A;
break;
default:
+ opc = VexOpcode.VEX_OPCODE_NONE;
isSimd = false;
break;
}
@@ -1770,6 +1799,13 @@ public class AMD64Assembler extends Assembler {
emitOperandHelper(dst, src, 0);
}
+ public final void bsfq(Register dst, Register src) {
+ int encode = prefixqAndEncode(dst.encoding(), src.encoding());
+ emitByte(0x0F);
+ emitByte(0xBC);
+ emitByte(0xC0 | encode);
+ }
+
public final void bsrl(Register dst, Register src) {
int encode = prefixAndEncode(dst.encoding(), src.encoding());
emitByte(0x0F);
@@ -1857,6 +1893,26 @@ public class AMD64Assembler extends Assembler {
emitByte(0xC0 | encode);
}
+ public final void evmovdquq(Register dst, AMD64Address src, int vectorLen) {
+ assert supports(CPUFeature.AVX512F);
+ AMD64InstructionAttr attributes = new AMD64InstructionAttr(vectorLen, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true, target);
+ attributes.setAddressAttributes(/* tuple_type */ EvexTupleType.EVEX_FVM, /* input_size_in_bits */ EvexInputSizeInBits.EVEX_NObit);
+ attributes.setIsEvexInstruction();
+ vexPrefix(src, Register.None, dst, VexSimdPrefix.VEX_SIMD_F3, VexOpcode.VEX_OPCODE_0F, attributes);
+ emitByte(0x6F);
+ emitOperandHelper(dst, src, 0);
+ }
+
+ public final void evpcmpeqb(Register kdst, Register nds, AMD64Address src, int vectorLen) {
+ assert supports(CPUFeature.AVX512BW);
+ AMD64InstructionAttr attributes = new AMD64InstructionAttr(vectorLen, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false, target);
+ attributes.setIsEvexInstruction();
+ attributes.setAddressAttributes(/* tuple_type */ EvexTupleType.EVEX_FVM, /* input_size_in_bits */ EvexInputSizeInBits.EVEX_NObit);
+ vexPrefix(src, nds, kdst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes);
+ emitByte(0x74);
+ emitOperandHelper(kdst, src, 0);
+ }
+
public final void hlt() {
emitByte(0xF4);
}
@@ -1982,6 +2038,32 @@ public class AMD64Assembler extends Assembler {
}
}
+ // This instruction produces ZF or CF flags
+ public final void kortestql(Register src1, Register src2) {
+ assert supports(CPUFeature.AVX512BW);
+ AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false, target);
+ int encode = vexPrefixAndEncode(src1, Register.None, src2, VexSimdPrefix.VEX_SIMD_NONE, VexOpcode.VEX_OPCODE_0F, attributes);
+ emitByte(0x98);
+ emitByte(0xC0 | encode);
+ }
+
+ public final void kmovql(Register dst, Register src) {
+ assert supports(CPUFeature.AVX512BW);
+ if (src.getRegisterCategory().equals(AMD64.MASK)) {
+ // kmovql(KRegister dst, KRegister src)
+ AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false, target);
+ int encode = vexPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_NONE, VexOpcode.VEX_OPCODE_0F, attributes);
+ emitByte(0x90);
+ emitByte(0xC0 | encode);
+ } else {
+ // kmovql(KRegister dst, Register src)
+ AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false, target);
+ int encode = vexPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_F2, VexOpcode.VEX_OPCODE_0F, attributes);
+ emitByte(0x92);
+ emitByte(0xC0 | encode);
+ }
+ }
+
public final void lead(Register dst, AMD64Address src) {
prefix(src, dst);
emitByte(0x8D);
@@ -2050,6 +2132,15 @@ public class AMD64Assembler extends Assembler {
emitOperandHelper(dst, src, 0);
}
+ /**
+ * @param wide use 4 byte encoding for displacements that would normally fit in a byte
+ */
+ public final void movl(Register dst, AMD64Address src, boolean wide) {
+ prefix(src, dst);
+ emitByte(0x8B);
+ emitOperandHelper(dst, src, wide, 0);
+ }
+
public final void movl(AMD64Address dst, int imm32) {
prefix(dst);
emitByte(0xC7);
@@ -2291,6 +2382,10 @@ public class AMD64Assembler extends Assembler {
NOT.emit(this, DWORD, dst);
}
+ public final void notq(Register dst) {
+ NOT.emit(this, QWORD, dst);
+ }
+
@Override
public final void ensureUniquePC() {
nop();
@@ -2540,7 +2635,7 @@ public class AMD64Assembler extends Assembler {
emitByte(0xC0 | encode);
}
- void pcmpestri(Register dst, AMD64Address src, int imm8) {
+ public final void pcmpestri(Register dst, AMD64Address src, int imm8) {
assert supports(CPUFeature.SSE4_2);
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target);
simdPrefix(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F_3A, attributes);
@@ -2549,7 +2644,7 @@ public class AMD64Assembler extends Assembler {
emitByte(imm8);
}
- void pcmpestri(Register dst, Register src, int imm8) {
+ public final void pcmpestri(Register dst, Register src, int imm8) {
assert supports(CPUFeature.SSE4_2);
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, target);
int encode = simdPrefixAndEncode(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F_3A, attributes);
@@ -2558,6 +2653,26 @@ public class AMD64Assembler extends Assembler {
emitByte(imm8);
}
+ public final void pmovzxbw(Register dst, AMD64Address src) {
+ assert supports(CPUFeature.SSE4_2);
+ // XXX legacy_mode should be: _legacy_mode_bw
+ AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false, target);
+ attributes.setAddressAttributes(/* tuple_type */ EvexTupleType.EVEX_HVM, /* input_size_in_bits */ EvexInputSizeInBits.EVEX_NObit);
+ simdPrefix(dst, Register.None, src, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F_38, attributes);
+ emitByte(0x30);
+ emitOperandHelper(dst, src, 0);
+ }
+
+ public final void vpmovzxbw(Register dst, AMD64Address src, int vectorLen) {
+ assert supports(CPUFeature.AVX);
+ // XXX legacy_mode should be: _legacy_mode_bw
+ AMD64InstructionAttr attributes = new AMD64InstructionAttr(vectorLen, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false, target);
+ attributes.setAddressAttributes(/* tuple_type */ EvexTupleType.EVEX_HVM, /* input_size_in_bits */ EvexInputSizeInBits.EVEX_NObit);
+ vexPrefix(src, Register.None, dst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F_38, attributes);
+ emitByte(0x30);
+ emitOperandHelper(dst, src, 0);
+ }
+
public final void push(Register src) {
int encode = prefixAndEncode(src.encoding);
emitByte(0x50 | encode);
@@ -2634,6 +2749,15 @@ public class AMD64Assembler extends Assembler {
emitByte(0xC0 | encode);
}
+ public final void vpxor(Register dst, Register nds, AMD64Address src) {
+ assert supports(CPUFeature.AVX);
+ AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_256bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true, target);
+ attributes.setAddressAttributes(/* tuple_type */ EvexTupleType.EVEX_FV, /* input_size_in_bits */ EvexInputSizeInBits.EVEX_32bit);
+ vexPrefix(src, nds, dst, VexSimdPrefix.VEX_SIMD_66, VexOpcode.VEX_OPCODE_0F, attributes);
+ emitByte(0xEF);
+ emitOperandHelper(dst, src, 0);
+ }
+
public final void pslld(Register dst, int imm8) {
assert isUByte(imm8) : "invalid value";
assert dst.getRegisterCategory().equals(AMD64.XMM);
@@ -3843,4 +3967,11 @@ public class AMD64Assembler extends Assembler {
emitByte(0x0f);
emitByte(0x0b);
}
+
+ public void lfence() {
+ emitByte(0x0f);
+ emitByte(0xae);
+ emitByte(0xe8);
+
+ }
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.bytecode/src/org/graalvm/compiler/bytecode/BytecodeDisassembler.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.bytecode/src/org/graalvm/compiler/bytecode/BytecodeDisassembler.java
index 41e52e24482..a50059e2f4c 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.bytecode/src/org/graalvm/compiler/bytecode/BytecodeDisassembler.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.bytecode/src/org/graalvm/compiler/bytecode/BytecodeDisassembler.java
@@ -321,4 +321,61 @@ public class BytecodeDisassembler {
}
// @formatter:on
}
+
+ public static JavaMethod getInvokedMethodAt(ResolvedJavaMethod method, int invokeBci) {
+ if (method.getCode() == null) {
+ return null;
+ }
+ ConstantPool cp = method.getConstantPool();
+ BytecodeStream stream = new BytecodeStream(method.getCode());
+ int opcode = stream.currentBC();
+ while (opcode != Bytecodes.END) {
+ int bci = stream.currentBCI();
+ if (bci == invokeBci) {
+ if (stream.nextBCI() > bci + 1) {
+ switch (opcode) {
+ case INVOKEVIRTUAL:
+ case INVOKESPECIAL:
+ case INVOKESTATIC: {
+ int cpi = stream.readCPI();
+ JavaMethod callee = cp.lookupMethod(cpi, opcode);
+ return callee;
+ }
+ case INVOKEINTERFACE: {
+ int cpi = stream.readCPI();
+ JavaMethod callee = cp.lookupMethod(cpi, opcode);
+ return callee;
+ }
+ case INVOKEDYNAMIC: {
+ int cpi = stream.readCPI4();
+ JavaMethod callee = cp.lookupMethod(cpi, opcode);
+ return callee;
+ }
+ default:
+ throw new InternalError(BytecodeDisassembler.disassembleOne(method, invokeBci));
+ }
+ }
+ }
+ stream.next();
+ opcode = stream.currentBC();
+ }
+ return null;
+ }
+
+ public static int getBytecodeAt(ResolvedJavaMethod method, int invokeBci) {
+ if (method.getCode() == null) {
+ return -1;
+ }
+ BytecodeStream stream = new BytecodeStream(method.getCode());
+ int opcode = stream.currentBC();
+ while (opcode != Bytecodes.END) {
+ int bci = stream.currentBCI();
+ if (bci == invokeBci) {
+ return opcode;
+ }
+ stream.next();
+ opcode = stream.currentBC();
+ }
+ return -1;
+ }
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/DisassemblerProvider.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/DisassemblerProvider.java
index 0b5f6a0d67d..7e71a4082c3 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/DisassemblerProvider.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/DisassemblerProvider.java
@@ -58,7 +58,7 @@ public interface DisassemblerProvider {
}
/**
- * Gets the name denoting the format of the disassmembly return by this object.
+ * Gets the name denoting the format of the disassembly returned by this object.
*/
String getName();
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressNode.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressNode.java
index bd27ef756d3..922413d2698 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressNode.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64AddressNode.java
@@ -25,6 +25,7 @@ package org.graalvm.compiler.core.amd64;
import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.spi.Simplifiable;
import org.graalvm.compiler.graph.spi.SimplifierTool;
@@ -72,7 +73,7 @@ public class AMD64AddressNode extends AddressNode implements Simplifiable, LIRLo
}
public void canonicalizeIndex(SimplifierTool tool) {
- if (index instanceof AddNode) {
+ if (index instanceof AddNode && ((IntegerStamp) index.stamp(NodeView.DEFAULT)).getBits() == 64) {
AddNode add = (AddNode) index;
ValueNode valX = add.getX();
if (valX instanceof PhiNode) {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java
index 5b442b1e3bf..ec2077d8d36 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java
@@ -66,15 +66,14 @@ import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant;
import static org.graalvm.compiler.lir.amd64.AMD64Arithmetic.DREM;
import static org.graalvm.compiler.lir.amd64.AMD64Arithmetic.FREM;
+import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicBinaryOp.BinaryIntrinsicOpcode.POW;
import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp.UnaryIntrinsicOpcode.COS;
+import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp.UnaryIntrinsicOpcode.EXP;
import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp.UnaryIntrinsicOpcode.LOG;
import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp.UnaryIntrinsicOpcode.LOG10;
import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp.UnaryIntrinsicOpcode.SIN;
import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp.UnaryIntrinsicOpcode.TAN;
-import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp.UnaryIntrinsicOpcode.EXP;
-import static org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicBinaryOp.BinaryIntrinsicOpcode.POW;
-import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MOp;
@@ -83,10 +82,11 @@ import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMIOp;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RRMOp;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64Shift;
+import org.graalvm.compiler.asm.amd64.AMD64Assembler.AVXOp;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
-import org.graalvm.compiler.asm.amd64.AMD64Assembler.AVXOp;
import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.core.common.calc.FloatConvert;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.lir.ConstantValue;
@@ -107,6 +107,7 @@ import org.graalvm.compiler.lir.amd64.AMD64ShiftOp;
import org.graalvm.compiler.lir.amd64.AMD64SignExtendOp;
import org.graalvm.compiler.lir.amd64.AMD64Unary;
import org.graalvm.compiler.lir.gen.ArithmeticLIRGenerator;
+import org.graalvm.compiler.lir.gen.LIRGenerator;
import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.amd64.AMD64.CPUFeature;
@@ -114,6 +115,7 @@ import jdk.vm.ci.amd64.AMD64Kind;
import jdk.vm.ci.code.CodeUtil;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.RegisterValue;
+import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.JavaConstant;
@@ -122,7 +124,6 @@ import jdk.vm.ci.meta.PlatformKind;
import jdk.vm.ci.meta.VMConstant;
import jdk.vm.ci.meta.Value;
import jdk.vm.ci.meta.ValueKind;
-import jdk.vm.ci.code.TargetDescription;
/**
* This class implements the AMD64 specific portion of the LIR generator.
@@ -131,6 +132,40 @@ public class AMD64ArithmeticLIRGenerator extends ArithmeticLIRGenerator implemen
private static final RegisterValue RCX_I = AMD64.rcx.asValue(LIRKind.value(AMD64Kind.DWORD));
+ public AMD64ArithmeticLIRGenerator(Maths maths) {
+ this.maths = maths == null ? new Maths() {
+ } : maths;
+ }
+
+ private final Maths maths;
+
+ /**
+ * Interface for emitting LIR for selected {@link Math} routines. A {@code null} return value
+ * for any method in this interface means the caller must emit the LIR itself.
+ */
+ public interface Maths {
+
+ @SuppressWarnings("unused")
+ default Variable emitLog(LIRGenerator gen, Value input, boolean base10) {
+ return null;
+ }
+
+ @SuppressWarnings("unused")
+ default Variable emitCos(LIRGenerator gen, Value input) {
+ return null;
+ }
+
+ @SuppressWarnings("unused")
+ default Variable emitSin(LIRGenerator gen, Value input) {
+ return null;
+ }
+
+ @SuppressWarnings("unused")
+ default Variable emitTan(LIRGenerator gen, Value input) {
+ return null;
+ }
+ }
+
@Override
public Variable emitNegate(Value inputVal) {
AllocatableValue input = getLIRGen().asAllocatable(inputVal);
@@ -1042,33 +1077,49 @@ public class AMD64ArithmeticLIRGenerator extends ArithmeticLIRGenerator implemen
@Override
public Value emitMathLog(Value input, boolean base10) {
- Variable result = getLIRGen().newVariable(LIRKind.combine(input));
- AllocatableValue stackSlot = getLIRGen().getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
- getLIRGen().append(new AMD64MathIntrinsicUnaryOp(getAMD64LIRGen(), base10 ? LOG10 : LOG, result, getLIRGen().asAllocatable(input), stackSlot));
+ LIRGenerator gen = getLIRGen();
+ Variable result = maths.emitLog(gen, input, base10);
+ if (result == null) {
+ result = gen.newVariable(LIRKind.combine(input));
+ AllocatableValue stackSlot = gen.getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
+ gen.append(new AMD64MathIntrinsicUnaryOp(getAMD64LIRGen(), base10 ? LOG10 : LOG, result, gen.asAllocatable(input), stackSlot));
+ }
return result;
}
@Override
public Value emitMathCos(Value input) {
- Variable result = getLIRGen().newVariable(LIRKind.combine(input));
- AllocatableValue stackSlot = getLIRGen().getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
- getLIRGen().append(new AMD64MathIntrinsicUnaryOp(getAMD64LIRGen(), COS, result, getLIRGen().asAllocatable(input), stackSlot));
+ LIRGenerator gen = getLIRGen();
+ Variable result = maths.emitCos(gen, input);
+ if (result == null) {
+ result = gen.newVariable(LIRKind.combine(input));
+ AllocatableValue stackSlot = gen.getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
+ gen.append(new AMD64MathIntrinsicUnaryOp(getAMD64LIRGen(), COS, result, gen.asAllocatable(input), stackSlot));
+ }
return result;
}
@Override
public Value emitMathSin(Value input) {
- Variable result = getLIRGen().newVariable(LIRKind.combine(input));
- AllocatableValue stackSlot = getLIRGen().getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
- getLIRGen().append(new AMD64MathIntrinsicUnaryOp(getAMD64LIRGen(), SIN, result, getLIRGen().asAllocatable(input), stackSlot));
+ LIRGenerator gen = getLIRGen();
+ Variable result = maths.emitSin(gen, input);
+ if (result == null) {
+ result = gen.newVariable(LIRKind.combine(input));
+ AllocatableValue stackSlot = gen.getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
+ gen.append(new AMD64MathIntrinsicUnaryOp(getAMD64LIRGen(), SIN, result, gen.asAllocatable(input), stackSlot));
+ }
return result;
}
@Override
public Value emitMathTan(Value input) {
- Variable result = getLIRGen().newVariable(LIRKind.combine(input));
- AllocatableValue stackSlot = getLIRGen().getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
- getLIRGen().append(new AMD64MathIntrinsicUnaryOp(getAMD64LIRGen(), TAN, result, getLIRGen().asAllocatable(input), stackSlot));
+ LIRGenerator gen = getLIRGen();
+ Variable result = maths.emitTan(gen, input);
+ if (result == null) {
+ result = gen.newVariable(LIRKind.combine(input));
+ AllocatableValue stackSlot = gen.getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(AMD64Kind.QWORD));
+ gen.append(new AMD64MathIntrinsicUnaryOp(getAMD64LIRGen(), TAN, result, gen.asAllocatable(input), stackSlot));
+ }
return result;
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java
index 6e7258ae62f..9abd808ab4b 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java
@@ -59,6 +59,7 @@ import org.graalvm.compiler.lir.SwitchStrategy;
import org.graalvm.compiler.lir.Variable;
import org.graalvm.compiler.lir.amd64.AMD64AddressValue;
import org.graalvm.compiler.lir.amd64.AMD64ArithmeticLIRGeneratorTool;
+import org.graalvm.compiler.lir.amd64.AMD64ArrayCompareToOp;
import org.graalvm.compiler.lir.amd64.AMD64ArrayEqualsOp;
import org.graalvm.compiler.lir.amd64.AMD64Binary;
import org.graalvm.compiler.lir.amd64.AMD64BinaryConsumer;
@@ -74,6 +75,7 @@ import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatCondSetOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.ReturnOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.StrategySwitchOp;
import org.graalvm.compiler.lir.amd64.AMD64ControlFlow.TableSwitchOp;
+import org.graalvm.compiler.lir.amd64.AMD64LFenceOp;
import org.graalvm.compiler.lir.amd64.AMD64Move;
import org.graalvm.compiler.lir.amd64.AMD64Move.CompareAndSwapOp;
import org.graalvm.compiler.lir.amd64.AMD64Move.MembarOp;
@@ -489,6 +491,20 @@ public abstract class AMD64LIRGenerator extends LIRGenerator {
return result;
}
+ @Override
+ public Variable emitArrayCompareTo(JavaKind kind1, JavaKind kind2, Value array1, Value array2, Value length1, Value length2) {
+ LIRKind resultKind = LIRKind.value(AMD64Kind.DWORD);
+ RegisterValue raxRes = AMD64.rax.asValue(resultKind);
+ RegisterValue cnt1 = AMD64.rcx.asValue(length1.getValueKind());
+ RegisterValue cnt2 = AMD64.rdx.asValue(length2.getValueKind());
+ emitMove(cnt1, length1);
+ emitMove(cnt2, length2);
+ append(new AMD64ArrayCompareToOp(this, kind1, kind2, raxRes, array1, array2, cnt1, cnt2));
+ Variable result = newVariable(resultKind);
+ emitMove(result, raxRes);
+ return result;
+ }
+
@Override
public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length) {
Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD));
@@ -554,4 +570,8 @@ public abstract class AMD64LIRGenerator extends LIRGenerator {
public LIRInstruction createZapArgumentSpace(StackSlot[] zappedStack, JavaConstant[] zapValues) {
return new AMD64ZapStackOp(zappedStack, zapValues);
}
+
+ public void emitLFence() {
+ append(new AMD64LFenceOp());
+ }
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeLIRBuilder.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeLIRBuilder.java
index ea5494a0844..efed030fc9d 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeLIRBuilder.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeLIRBuilder.java
@@ -23,6 +23,8 @@
package org.graalvm.compiler.core.amd64;
+import static org.graalvm.compiler.core.amd64.AMD64NodeLIRBuilder.Options.MitigateSpeculativeExecutionAttacks;
+
import org.graalvm.compiler.core.gen.NodeLIRBuilder;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.lir.LIRFrameState;
@@ -37,6 +39,11 @@ import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.IntegerDivRemNode;
import org.graalvm.compiler.nodes.calc.IntegerDivRemNode.Op;
+import org.graalvm.compiler.nodes.cfg.Block;
+import org.graalvm.compiler.options.Option;
+import org.graalvm.compiler.options.OptionKey;
+import org.graalvm.compiler.options.OptionType;
+import org.graalvm.compiler.options.OptionValues;
import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.meta.AllocatableValue;
@@ -44,6 +51,13 @@ import jdk.vm.ci.meta.Value;
public abstract class AMD64NodeLIRBuilder extends NodeLIRBuilder {
+ public static class Options {
+ // @formatter:off
+ @Option(help = "AMD64: Emit lfence instructions at the beginning of basic blocks", type = OptionType.Expert)
+ public static final OptionKey MitigateSpeculativeExecutionAttacks = new OptionKey<>(false);
+ // @formatter:on
+ }
+
public AMD64NodeLIRBuilder(StructuredGraph graph, LIRGeneratorTool gen, AMD64NodeMatchRules nodeMatchRules) {
super(graph, gen, nodeMatchRules);
}
@@ -121,4 +135,21 @@ public abstract class AMD64NodeLIRBuilder extends NodeLIRBuilder {
public AMD64LIRGenerator getLIRGeneratorTool() {
return (AMD64LIRGenerator) gen;
}
+
+ @Override
+ public void doBlockPrologue(Block block, OptionValues options) {
+ if (MitigateSpeculativeExecutionAttacks.getValue(options)) {
+ boolean hasControlSplitPredecessor = false;
+ for (Block b : block.getPredecessors()) {
+ if (b.getSuccessorCount() > 1) {
+ hasControlSplitPredecessor = true;
+ break;
+ }
+ }
+ boolean isStartBlock = block.getPredecessorCount() == 0;
+ if (hasControlSplitPredecessor || isStartBlock) {
+ getLIRGeneratorTool().emitLFence();
+ }
+ }
+ }
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java
index c01737e3d08..713fe7b3fb7 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java
@@ -259,6 +259,9 @@ public final class GraalOptions {
@Option(help = "", type = OptionType.Debug)
public static final OptionKey OptDevirtualizeInvokesOptimistically = new OptionKey<>(true);
+ @Option(help = "Track the NodeSourcePosition.", type = OptionType.Debug)
+ public static final OptionKey TrackNodeSourcePosition = new OptionKey<>(false);
+
@Option(help = "Allow backend to match complex expressions.", type = OptionType.Debug)
public static final OptionKey MatchExpressions = new OptionKey<>(true);
@@ -273,8 +276,7 @@ public final class GraalOptions {
@Option(help = "Enable experimental Trace Register Allocation.", type = OptionType.Debug)
public static final OptionKey TraceRA = new OptionKey<>(false);
-
- @Option(help = "How to trace inlining decisions, one of: None, Linear, Tree", type = OptionType.Debug)
- public static final OptionKey TraceInlining = new OptionKey<>(TraceInliningMode.None);
+ @Option(help = "Enable tracing of inlining decision.", type = OptionType.Debug)
+ public static final OptionKey TraceInlining = new OptionKey<>(false);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/BiDirectionalTraceBuilder.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/BiDirectionalTraceBuilder.java
index f0ad0133f95..d6c1e644032 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/BiDirectionalTraceBuilder.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/BiDirectionalTraceBuilder.java
@@ -84,7 +84,7 @@ public final class BiDirectionalTraceBuilder {
AbstractBlockBase> block = worklist.pollFirst();
assert block != null;
if (!processed(block)) {
- Trace trace = new Trace(startTrace(debug, block));
+ Trace trace = new Trace(findTrace(debug, block));
for (AbstractBlockBase> traceBlock : trace.getBlocks()) {
blockToTrace[traceBlock.getId()] = trace;
}
@@ -101,13 +101,13 @@ public final class BiDirectionalTraceBuilder {
* @param debug
*/
@SuppressWarnings("try")
- private Collection> startTrace(DebugContext debug, AbstractBlockBase> block) {
+ private Collection> findTrace(DebugContext debug, AbstractBlockBase> initBlock) {
ArrayDeque> trace = new ArrayDeque<>();
- try (Indent i = debug.logAndIndent("StartTrace: %s", block)) {
+ try (Indent i = debug.logAndIndent("StartTrace: %s", initBlock)) {
try (Indent indentFront = debug.logAndIndent("Head:")) {
- for (AbstractBlockBase> currentBlock = block; currentBlock != null; currentBlock = selectPredecessor(currentBlock)) {
- addBlockToTrace(debug, currentBlock);
- trace.addFirst(currentBlock);
+ for (AbstractBlockBase> block = initBlock; block != null; block = selectPredecessor(block)) {
+ addBlockToTrace(debug, block);
+ trace.addFirst(block);
}
}
/* Number head blocks. Can not do this in the loop as we go backwards. */
@@ -117,11 +117,11 @@ public final class BiDirectionalTraceBuilder {
}
try (Indent indentBack = debug.logAndIndent("Tail:")) {
- for (AbstractBlockBase> currentBlock = selectSuccessor(block); currentBlock != null; currentBlock = selectSuccessor(currentBlock)) {
- addBlockToTrace(debug, currentBlock);
- trace.addLast(currentBlock);
+ for (AbstractBlockBase> block = selectSuccessor(initBlock); block != null; block = selectSuccessor(block)) {
+ addBlockToTrace(debug, block);
+ trace.addLast(block);
/* This time we can number the blocks immediately as we go forwards. */
- currentBlock.setLinearScanNumber(blockNr++);
+ block.setLinearScanNumber(blockNr++);
}
}
}
@@ -129,18 +129,18 @@ public final class BiDirectionalTraceBuilder {
return trace;
}
- private void addBlockToTrace(DebugContext debug, AbstractBlockBase> currentBlock) {
- debug.log("add %s (prob: %f)", currentBlock, currentBlock.probability());
- processed.set(currentBlock.getId());
+ private void addBlockToTrace(DebugContext debug, AbstractBlockBase> block) {
+ debug.log("add %s (prob: %f)", block, block.probability());
+ processed.set(block.getId());
}
/**
* @return The unprocessed predecessor with the highest probability, or {@code null}.
*/
- private AbstractBlockBase> selectPredecessor(AbstractBlockBase> currentBlock) {
+ private AbstractBlockBase> selectPredecessor(AbstractBlockBase> block) {
AbstractBlockBase> next = null;
- for (AbstractBlockBase> pred : currentBlock.getPredecessors()) {
- if (!processed(pred) && !isBackEdge(pred, currentBlock) && (next == null || pred.probability() > next.probability())) {
+ for (AbstractBlockBase> pred : block.getPredecessors()) {
+ if (!processed(pred) && !isBackEdge(pred, block) && (next == null || pred.probability() > next.probability())) {
next = pred;
}
}
@@ -155,9 +155,9 @@ public final class BiDirectionalTraceBuilder {
/**
* @return The unprocessed successor with the highest probability, or {@code null}.
*/
- private AbstractBlockBase> selectSuccessor(AbstractBlockBase> currentBlock) {
+ private AbstractBlockBase> selectSuccessor(AbstractBlockBase> block) {
AbstractBlockBase> next = null;
- for (AbstractBlockBase> succ : currentBlock.getSuccessors()) {
+ for (AbstractBlockBase> succ : block.getSuccessors()) {
if (!processed(succ) && (next == null || succ.probability() > next.probability())) {
next = succ;
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/UniDirectionalTraceBuilder.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/UniDirectionalTraceBuilder.java
index 42023e1c007..12f1981dafe 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/UniDirectionalTraceBuilder.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/alloc/UniDirectionalTraceBuilder.java
@@ -33,7 +33,7 @@ import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.Indent;
/**
- * Computes traces by starting at a trace head and keep adding predecessors as long as possible.
+ * Computes traces by starting at a trace head and keep adding successors as long as possible.
*/
public final class UniDirectionalTraceBuilder {
@@ -87,7 +87,7 @@ public final class UniDirectionalTraceBuilder {
AbstractBlockBase> block = worklist.poll();
assert block != null;
if (!processed(block)) {
- Trace trace = new Trace(startTrace(debug, block));
+ Trace trace = new Trace(findTrace(debug, block));
for (AbstractBlockBase> traceBlock : trace.getBlocks()) {
blockToTrace[traceBlock.getId()] = trace;
}
@@ -102,17 +102,17 @@ public final class UniDirectionalTraceBuilder {
* Build a new trace starting at {@code block}.
*/
@SuppressWarnings("try")
- private List> startTrace(DebugContext debug, AbstractBlockBase> block) {
- assert checkPredecessorsProcessed(block);
+ private List> findTrace(DebugContext debug, AbstractBlockBase> traceStart) {
+ assert checkPredecessorsProcessed(traceStart);
ArrayList> trace = new ArrayList<>();
int blockNumber = 0;
- try (Indent i = debug.logAndIndent("StartTrace: %s", block)) {
- for (AbstractBlockBase> currentBlock = block; currentBlock != null; currentBlock = selectNext(currentBlock)) {
- debug.log("add %s (prob: %f)", currentBlock, currentBlock.probability());
- processed.set(currentBlock.getId());
- trace.add(currentBlock);
- unblock(currentBlock);
- currentBlock.setLinearScanNumber(blockNumber++);
+ try (Indent i = debug.logAndIndent("StartTrace: %s", traceStart)) {
+ for (AbstractBlockBase> block = traceStart; block != null; block = selectNext(block)) {
+ debug.log("add %s (prob: %f)", block, block.probability());
+ processed.set(block.getId());
+ trace.add(block);
+ unblock(block);
+ block.setLinearScanNumber(blockNumber++);
}
}
return trace;
@@ -120,11 +120,7 @@ public final class UniDirectionalTraceBuilder {
private boolean checkPredecessorsProcessed(AbstractBlockBase> block) {
for (AbstractBlockBase> pred : block.getPredecessors()) {
- if (!processed(pred)) {
- assert false : "Predecessor unscheduled: " + pred;
- return false;
- }
-
+ assert processed(pred) : "Predecessor unscheduled: " + pred;
}
return true;
}
@@ -133,8 +129,8 @@ public final class UniDirectionalTraceBuilder {
* Decrease the {@link #blocked} count for all predecessors and add them to the worklist once
* the count reaches 0.
*/
- private void unblock(AbstractBlockBase> currentBlock) {
- for (AbstractBlockBase> successor : currentBlock.getSuccessors()) {
+ private void unblock(AbstractBlockBase> block) {
+ for (AbstractBlockBase> successor : block.getSuccessors()) {
if (!processed(successor)) {
int blockCount = --blocked[successor.getId()];
assert blockCount >= 0;
@@ -148,11 +144,11 @@ public final class UniDirectionalTraceBuilder {
/**
* @return The unprocessed predecessor with the highest probability, or {@code null}.
*/
- private AbstractBlockBase> selectNext(AbstractBlockBase> currentBlock) {
+ private AbstractBlockBase> selectNext(AbstractBlockBase> block) {
AbstractBlockBase> next = null;
- for (AbstractBlockBase> succ : currentBlock.getSuccessors()) {
- if (!processed(succ) && (next == null || succ.probability() > next.probability())) {
- next = succ;
+ for (AbstractBlockBase> successor : block.getSuccessors()) {
+ if (!processed(successor) && (next == null || successor.probability() > next.probability())) {
+ next = successor;
}
}
return next;
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/AbstractObjectStamp.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/AbstractObjectStamp.java
index b84f2182adf..917cf2b9527 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/AbstractObjectStamp.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/AbstractObjectStamp.java
@@ -191,8 +191,6 @@ public abstract class AbstractObjectStamp extends AbstractPointerStamp {
boolean joinExactType = exactType || other.exactType;
if (Objects.equals(type, other.type)) {
joinType = type;
- } else if (type == null && other.type == null) {
- joinType = null;
} else if (type == null) {
joinType = other.type;
} else if (other.type == null) {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java
index b9e057ef153..5295d7c51d7 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java
@@ -176,11 +176,15 @@ public class FloatStamp extends PrimitiveStamp {
StringBuilder str = new StringBuilder();
str.append('f');
str.append(getBits());
- str.append(nonNaN ? "!" : "");
- if (lowerBound == upperBound) {
- str.append(" [").append(lowerBound).append(']');
- } else if (lowerBound != Double.NEGATIVE_INFINITY || upperBound != Double.POSITIVE_INFINITY) {
- str.append(" [").append(lowerBound).append(" - ").append(upperBound).append(']');
+ if (hasValues()) {
+ str.append(nonNaN ? "!" : "");
+ if (lowerBound == upperBound) {
+ str.append(" [").append(lowerBound).append(']');
+ } else if (lowerBound != Double.NEGATIVE_INFINITY || upperBound != Double.POSITIVE_INFINITY) {
+ str.append(" [").append(lowerBound).append(" - ").append(upperBound).append(']');
+ }
+ } else {
+ str.append("");
}
return str.toString();
}
@@ -200,6 +204,12 @@ public class FloatStamp extends PrimitiveStamp {
if (otherStamp == this) {
return this;
}
+ if (isEmpty()) {
+ return this;
+ }
+ if (otherStamp.isEmpty()) {
+ return otherStamp;
+ }
FloatStamp other = (FloatStamp) otherStamp;
assert getBits() == other.getBits();
double meetUpperBound = meetBounds(upperBound, other.upperBound, Math::max);
@@ -383,6 +393,9 @@ public class FloatStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp s) {
+ if (s.isEmpty()) {
+ return s;
+ }
FloatStamp stamp = (FloatStamp) s;
Stamp folded = maybeFoldConstant(this, stamp);
if (folded != null) {
@@ -412,6 +425,12 @@ public class FloatStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp s1, Stamp s2) {
+ if (s1.isEmpty()) {
+ return s1;
+ }
+ if (s2.isEmpty()) {
+ return s2;
+ }
FloatStamp stamp1 = (FloatStamp) s1;
FloatStamp stamp2 = (FloatStamp) s2;
Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
@@ -454,6 +473,12 @@ public class FloatStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp s1, Stamp s2) {
+ if (s1.isEmpty()) {
+ return s1;
+ }
+ if (s2.isEmpty()) {
+ return s2;
+ }
FloatStamp stamp1 = (FloatStamp) s1;
FloatStamp stamp2 = (FloatStamp) s2;
Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
@@ -496,6 +521,12 @@ public class FloatStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp s1, Stamp s2) {
+ if (s1.isEmpty()) {
+ return s1;
+ }
+ if (s2.isEmpty()) {
+ return s2;
+ }
FloatStamp stamp1 = (FloatStamp) s1;
FloatStamp stamp2 = (FloatStamp) s2;
Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
@@ -544,6 +575,12 @@ public class FloatStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp s1, Stamp s2) {
+ if (s1.isEmpty()) {
+ return s1;
+ }
+ if (s2.isEmpty()) {
+ return s2;
+ }
FloatStamp stamp1 = (FloatStamp) s1;
FloatStamp stamp2 = (FloatStamp) s2;
Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
@@ -586,6 +623,12 @@ public class FloatStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp s1, Stamp s2) {
+ if (s1.isEmpty()) {
+ return s1;
+ }
+ if (s2.isEmpty()) {
+ return s2;
+ }
FloatStamp stamp1 = (FloatStamp) s1;
FloatStamp stamp2 = (FloatStamp) s2;
Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
@@ -615,6 +658,9 @@ public class FloatStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp s) {
+ if (s.isEmpty()) {
+ return s;
+ }
FloatStamp stamp = (FloatStamp) s;
JavaConstant constant = stamp.asConstant();
if (constant != null) {
@@ -653,6 +699,12 @@ public class FloatStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp s1, Stamp s2) {
+ if (s1.isEmpty()) {
+ return s1;
+ }
+ if (s2.isEmpty()) {
+ return s2;
+ }
FloatStamp stamp1 = (FloatStamp) s1;
FloatStamp stamp2 = (FloatStamp) s2;
Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
@@ -701,6 +753,12 @@ public class FloatStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp s1, Stamp s2) {
+ if (s1.isEmpty()) {
+ return s1;
+ }
+ if (s2.isEmpty()) {
+ return s2;
+ }
FloatStamp stamp1 = (FloatStamp) s1;
FloatStamp stamp2 = (FloatStamp) s2;
Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
@@ -747,6 +805,12 @@ public class FloatStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp s1, Stamp s2) {
+ if (s1.isEmpty()) {
+ return s1;
+ }
+ if (s2.isEmpty()) {
+ return s2;
+ }
FloatStamp stamp1 = (FloatStamp) s1;
FloatStamp stamp2 = (FloatStamp) s2;
Stamp folded = maybeFoldConstant(this, stamp1, stamp2);
@@ -789,6 +853,9 @@ public class FloatStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp s) {
+ if (s.isEmpty()) {
+ return s;
+ }
FloatStamp stamp = (FloatStamp) s;
Stamp folded = maybeFoldConstant(this, stamp);
if (folded != null) {
@@ -818,6 +885,9 @@ public class FloatStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp s) {
+ if (s.isEmpty()) {
+ return s;
+ }
FloatStamp stamp = (FloatStamp) s;
Stamp folded = maybeFoldConstant(this, stamp);
if (folded != null) {
@@ -839,6 +909,9 @@ public class FloatStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp stamp) {
+ if (stamp.isEmpty()) {
+ return StampFactory.empty(JavaKind.Int);
+ }
FloatStamp floatStamp = (FloatStamp) stamp;
assert floatStamp.getBits() == 32;
boolean mustHaveZero = !floatStamp.isNonNaN();
@@ -865,6 +938,9 @@ public class FloatStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp stamp) {
+ if (stamp.isEmpty()) {
+ return StampFactory.empty(JavaKind.Long);
+ }
FloatStamp floatStamp = (FloatStamp) stamp;
assert floatStamp.getBits() == 32;
boolean mustHaveZero = !floatStamp.isNonNaN();
@@ -891,6 +967,9 @@ public class FloatStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp stamp) {
+ if (stamp.isEmpty()) {
+ return StampFactory.empty(JavaKind.Int);
+ }
FloatStamp floatStamp = (FloatStamp) stamp;
assert floatStamp.getBits() == 64;
boolean mustHaveZero = !floatStamp.isNonNaN();
@@ -917,6 +996,9 @@ public class FloatStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp stamp) {
+ if (stamp.isEmpty()) {
+ return StampFactory.empty(JavaKind.Long);
+ }
FloatStamp floatStamp = (FloatStamp) stamp;
assert floatStamp.getBits() == 64;
boolean mustHaveZero = !floatStamp.isNonNaN();
@@ -943,6 +1025,9 @@ public class FloatStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp stamp) {
+ if (stamp.isEmpty()) {
+ return StampFactory.empty(JavaKind.Double);
+ }
FloatStamp floatStamp = (FloatStamp) stamp;
assert floatStamp.getBits() == 32;
return StampFactory.forFloat(JavaKind.Double, floatStamp.lowerBound(), floatStamp.upperBound(), floatStamp.isNonNaN());
@@ -959,6 +1044,9 @@ public class FloatStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp stamp) {
+ if (stamp.isEmpty()) {
+ return StampFactory.empty(JavaKind.Float);
+ }
FloatStamp floatStamp = (FloatStamp) stamp;
assert floatStamp.getBits() == 64;
return StampFactory.forFloat(JavaKind.Float, (float) floatStamp.lowerBound(), (float) floatStamp.upperBound(), floatStamp.isNonNaN());
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/IntegerStamp.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/IntegerStamp.java
index 2ca05ce0a77..28054cb3e5a 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/IntegerStamp.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/IntegerStamp.java
@@ -122,11 +122,11 @@ public final class IntegerStamp extends PrimitiveStamp {
return new IntegerStamp(bits, lowerBoundTmp, upperBoundTmp, defaultMask & (downMask | boundedDownMask), defaultMask & upMask & boundedUpMask);
}
- static long significantBit(long bits, long value) {
+ private static long significantBit(long bits, long value) {
return (value >>> (bits - 1)) & 1;
}
- static long minValueForMasks(int bits, long downMask, long upMask) {
+ private static long minValueForMasks(int bits, long downMask, long upMask) {
if (significantBit(bits, upMask) == 0) {
// Value is always positive. Minimum value always positive.
assert significantBit(bits, downMask) == 0;
@@ -137,7 +137,7 @@ public final class IntegerStamp extends PrimitiveStamp {
}
}
- static long maxValueForMasks(int bits, long downMask, long upMask) {
+ private static long maxValueForMasks(int bits, long downMask, long upMask) {
if (significantBit(bits, downMask) == 1) {
// Value is always negative. Maximum value always negative.
assert significantBit(bits, upMask) == 1;
@@ -330,6 +330,12 @@ public final class IntegerStamp extends PrimitiveStamp {
if (otherStamp == this) {
return this;
}
+ if (isEmpty()) {
+ return otherStamp;
+ }
+ if (otherStamp.isEmpty()) {
+ return this;
+ }
IntegerStamp other = (IntegerStamp) otherStamp;
return createStamp(other, Math.max(upperBound, other.upperBound), Math.min(lowerBound, other.lowerBound), downMask & other.downMask, upMask | other.upMask);
}
@@ -413,7 +419,7 @@ public final class IntegerStamp extends PrimitiveStamp {
return super.equals(other);
}
- public static long upMaskFor(int bits, long lowerBound, long upperBound) {
+ private static long upMaskFor(int bits, long lowerBound, long upperBound) {
long mask = lowerBound | upperBound;
if (mask == 0) {
return 0;
@@ -595,6 +601,9 @@ public final class IntegerStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp s) {
+ if (s.isEmpty()) {
+ return s;
+ }
IntegerStamp stamp = (IntegerStamp) s;
int bits = stamp.getBits();
if (stamp.lowerBound == stamp.upperBound) {
@@ -622,6 +631,12 @@ public final class IntegerStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+ if (stamp1.isEmpty()) {
+ return stamp1;
+ }
+ if (stamp2.isEmpty()) {
+ return stamp2;
+ }
IntegerStamp a = (IntegerStamp) stamp1;
IntegerStamp b = (IntegerStamp) stamp2;
@@ -715,6 +730,12 @@ public final class IntegerStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+ if (stamp1.isEmpty()) {
+ return stamp1;
+ }
+ if (stamp2.isEmpty()) {
+ return stamp2;
+ }
IntegerStamp a = (IntegerStamp) stamp1;
IntegerStamp b = (IntegerStamp) stamp2;
@@ -885,6 +906,12 @@ public final class IntegerStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+ if (stamp1.isEmpty()) {
+ return stamp1;
+ }
+ if (stamp2.isEmpty()) {
+ return stamp2;
+ }
IntegerStamp a = (IntegerStamp) stamp1;
IntegerStamp b = (IntegerStamp) stamp2;
JavaKind javaKind = a.getStackKind();
@@ -952,6 +979,12 @@ public final class IntegerStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+ if (stamp1.isEmpty()) {
+ return stamp1;
+ }
+ if (stamp2.isEmpty()) {
+ return stamp2;
+ }
IntegerStamp a = (IntegerStamp) stamp1;
IntegerStamp b = (IntegerStamp) stamp2;
JavaKind javaKind = a.getStackKind();
@@ -1046,6 +1079,12 @@ public final class IntegerStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+ if (stamp1.isEmpty()) {
+ return stamp1;
+ }
+ if (stamp2.isEmpty()) {
+ return stamp2;
+ }
IntegerStamp a = (IntegerStamp) stamp1;
IntegerStamp b = (IntegerStamp) stamp2;
assert a.getBits() == b.getBits();
@@ -1083,6 +1122,12 @@ public final class IntegerStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+ if (stamp1.isEmpty()) {
+ return stamp1;
+ }
+ if (stamp2.isEmpty()) {
+ return stamp2;
+ }
IntegerStamp a = (IntegerStamp) stamp1;
IntegerStamp b = (IntegerStamp) stamp2;
assert a.getBits() == b.getBits();
@@ -1121,6 +1166,9 @@ public final class IntegerStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp stamp) {
+ if (stamp.isEmpty()) {
+ return stamp;
+ }
IntegerStamp integerStamp = (IntegerStamp) stamp;
int bits = integerStamp.getBits();
long defaultMask = CodeUtil.mask(bits);
@@ -1140,6 +1188,12 @@ public final class IntegerStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+ if (stamp1.isEmpty()) {
+ return stamp1;
+ }
+ if (stamp2.isEmpty()) {
+ return stamp2;
+ }
IntegerStamp a = (IntegerStamp) stamp1;
IntegerStamp b = (IntegerStamp) stamp2;
assert a.getBits() == b.getBits();
@@ -1167,6 +1221,12 @@ public final class IntegerStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+ if (stamp1.isEmpty()) {
+ return stamp1;
+ }
+ if (stamp2.isEmpty()) {
+ return stamp2;
+ }
IntegerStamp a = (IntegerStamp) stamp1;
IntegerStamp b = (IntegerStamp) stamp2;
assert a.getBits() == b.getBits();
@@ -1192,6 +1252,12 @@ public final class IntegerStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+ if (stamp1.isEmpty()) {
+ return stamp1;
+ }
+ if (stamp2.isEmpty()) {
+ return stamp2;
+ }
IntegerStamp a = (IntegerStamp) stamp1;
IntegerStamp b = (IntegerStamp) stamp2;
assert a.getBits() == b.getBits();
@@ -1269,8 +1335,7 @@ public final class IntegerStamp extends PrimitiveStamp {
upMask |= value.upMask() << (i & shiftMask);
}
}
- Stamp result = IntegerStamp.stampForMask(bits, downMask, upMask & defaultMask);
- return result;
+ return IntegerStamp.stampForMask(bits, downMask, upMask & defaultMask);
}
return value.unrestricted();
}
@@ -1392,6 +1457,9 @@ public final class IntegerStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp input) {
+ if (input.isEmpty()) {
+ return input;
+ }
IntegerStamp stamp = (IntegerStamp) input;
int bits = stamp.getBits();
if (stamp.lowerBound == stamp.upperBound) {
@@ -1419,6 +1487,9 @@ public final class IntegerStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(int inputBits, int resultBits, Stamp input) {
+ if (input.isEmpty()) {
+ return StampFactory.forInteger(resultBits).empty();
+ }
IntegerStamp stamp = (IntegerStamp) input;
assert inputBits == stamp.getBits();
assert inputBits <= resultBits;
@@ -1458,6 +1529,9 @@ public final class IntegerStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(int inputBits, int resultBits, Stamp input) {
+ if (input.isEmpty()) {
+ return StampFactory.forInteger(resultBits).empty();
+ }
IntegerStamp stamp = (IntegerStamp) input;
assert inputBits == stamp.getBits();
assert inputBits <= resultBits;
@@ -1487,6 +1561,9 @@ public final class IntegerStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(int inputBits, int resultBits, Stamp input) {
+ if (input.isEmpty()) {
+ return StampFactory.forInteger(resultBits).empty();
+ }
IntegerStamp stamp = (IntegerStamp) input;
assert inputBits == stamp.getBits();
assert resultBits <= inputBits;
@@ -1526,6 +1603,9 @@ public final class IntegerStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp input) {
+ if (input.isEmpty()) {
+ return StampFactory.empty(JavaKind.Float);
+ }
IntegerStamp stamp = (IntegerStamp) input;
assert stamp.getBits() == 32;
float lowerBound = stamp.lowerBound();
@@ -1544,6 +1624,9 @@ public final class IntegerStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp input) {
+ if (input.isEmpty()) {
+ return StampFactory.empty(JavaKind.Float);
+ }
IntegerStamp stamp = (IntegerStamp) input;
assert stamp.getBits() == 64;
float lowerBound = stamp.lowerBound();
@@ -1562,6 +1645,9 @@ public final class IntegerStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp input) {
+ if (input.isEmpty()) {
+ return StampFactory.empty(JavaKind.Double);
+ }
IntegerStamp stamp = (IntegerStamp) input;
assert stamp.getBits() == 32;
double lowerBound = stamp.lowerBound();
@@ -1580,6 +1666,9 @@ public final class IntegerStamp extends PrimitiveStamp {
@Override
public Stamp foldStamp(Stamp input) {
+ if (input.isEmpty()) {
+ return StampFactory.empty(JavaKind.Double);
+ }
IntegerStamp stamp = (IntegerStamp) input;
assert stamp.getBits() == 64;
double lowerBound = stamp.lowerBound();
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/StampFactory.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/StampFactory.java
index d726673a6cd..e73e1f259dc 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/StampFactory.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/StampFactory.java
@@ -161,6 +161,10 @@ public class StampFactory {
return IntegerStamp.create(bits, CodeUtil.minValue(bits), CodeUtil.maxValue(bits), 0, CodeUtil.mask(bits));
}
+ public static IntegerStamp forUnsignedInteger(int bits) {
+ return forUnsignedInteger(bits, 0, NumUtil.maxValueUnsigned(bits), 0, CodeUtil.mask(bits));
+ }
+
public static IntegerStamp forUnsignedInteger(int bits, long unsignedLowerBound, long unsignedUpperBound) {
return forUnsignedInteger(bits, unsignedLowerBound, unsignedUpperBound, 0, CodeUtil.mask(bits));
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/UnsignedLong.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/UnsignedLong.java
new file mode 100644
index 00000000000..c3531df832f
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/UnsignedLong.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2018, 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;
+
+public final class UnsignedLong {
+ private final long value;
+
+ public UnsignedLong(long value) {
+ this.value = value;
+ }
+
+ public long asLong() {
+ return value;
+ }
+
+ public boolean equals(long unsignedValue) {
+ return value == unsignedValue;
+ }
+
+ public boolean isLessThan(long unsignedValue) {
+ return Long.compareUnsigned(value, unsignedValue) < 0;
+ }
+
+ public boolean isLessOrEqualTo(long unsignedValue) {
+ return Long.compareUnsigned(value, unsignedValue) <= 0;
+ }
+
+ public UnsignedLong times(long unsignedValue) {
+ if (unsignedValue != 0 && Long.compareUnsigned(value, Long.divideUnsigned(0xffff_ffff_ffff_ffffL, unsignedValue)) > 0) {
+ throw new ArithmeticException();
+ }
+ return new UnsignedLong(value * unsignedValue);
+ }
+
+ public UnsignedLong minus(long unsignedValue) {
+ if (Long.compareUnsigned(value, unsignedValue) < 0) {
+ throw new ArithmeticException();
+ }
+ return new UnsignedLong(value - unsignedValue);
+ }
+
+ public UnsignedLong plus(long unsignedValue) {
+ if (Long.compareUnsigned(0xffff_ffff_ffff_ffffL - unsignedValue, value) < 0) {
+ throw new ArithmeticException();
+ }
+ return new UnsignedLong(value + unsignedValue);
+ }
+
+ public UnsignedLong wrappingPlus(long unsignedValue) {
+ return new UnsignedLong(value + unsignedValue);
+ }
+
+ public UnsignedLong wrappingTimes(long unsignedValue) {
+ return new UnsignedLong(value * unsignedValue);
+ }
+
+ @Override
+ public String toString() {
+ return "UnsignedLong(" + Long.toUnsignedString(value) + ")";
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ UnsignedLong that = (UnsignedLong) o;
+ return value == that.value;
+ }
+
+ @Override
+ public int hashCode() {
+ return Long.hashCode(value);
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/BasePhaseBinaryGraphTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/BasePhaseBinaryGraphTest.java
new file mode 100644
index 00000000000..0d4a3b1518a
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/BasePhaseBinaryGraphTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2011, 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.test;
+
+import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.phases.BasePhase;
+import org.graalvm.compiler.printer.BinaryGraphPrinter;
+import static org.junit.Assert.assertEquals;
+import org.junit.Before;
+import org.junit.Test;
+
+public class BasePhaseBinaryGraphTest {
+ private MyPhase phase;
+ private BinaryGraphPrinter printer;
+
+ @Before
+ public void createPhase() {
+ phase = new MyPhase();
+ }
+
+ @Before
+ public void createPrinter() throws Exception {
+ printer = new BinaryGraphPrinter(DebugContext.DISABLED, null);
+ }
+
+ @Test
+ public void phaseNameIsRecognizedAsType() {
+ String res = printer.typeName(phase.getName());
+ assertEquals(MyPhase.class.getName(), res);
+ }
+
+ private static final class MyPhase extends BasePhase {
+ @Override
+ protected void run(StructuredGraph graph, Void context) {
+ }
+
+ @Override
+ protected CharSequence getName() {
+ return super.getName();
+ }
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalNodeTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalNodeTest.java
new file mode 100644
index 00000000000..9d7259a9089
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalNodeTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 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.test;
+
+import org.junit.Test;
+
+public class ConditionalNodeTest extends GraalCompilerTest {
+
+ @SuppressWarnings("unused") private static int sink0;
+ @SuppressWarnings("unused") private static int sink1;
+
+ @Test
+ public void test0() {
+ test("conditionalTest0", 0);
+ test("conditionalTest0", 1);
+ }
+
+ public static int conditionalTest0(int a) {
+ int value;
+ if (a == 1) {
+ value = -1;
+ sink1 = 0;
+ } else {
+ value = 6;
+ sink1 = 1;
+ }
+ sink0 = 1;
+ return Math.max(value, 6);
+ }
+
+ @Test
+ public void test1() {
+ test("conditionalTest1", 0);
+ test("conditionalTest1", 1);
+ }
+
+ public static int conditionalTest1(int a) {
+ int value;
+ if (a == 1) {
+ value = -1;
+ sink1 = 0;
+ } else {
+ value = 6;
+ sink1 = 1;
+ }
+ sink0 = 1;
+ return Math.max(6, value);
+ }
+
+ @Test
+ public void test2() {
+ test("conditionalTest2", 0);
+ test("conditionalTest2", 1);
+ }
+
+ public static int conditionalTest2(int a) {
+ int value;
+ if (a == 1) {
+ value = -1;
+ sink1 = 0;
+ } else {
+ value = 6;
+ sink1 = 1;
+ }
+ sink0 = 1;
+ return Math.min(value, -1);
+ }
+
+ @Test
+ public void test3() {
+ test("conditionalTest3", 0);
+ test("conditionalTest3", 1);
+ }
+
+ public static int conditionalTest3(int a) {
+ int value;
+ if (a == 1) {
+ value = -1;
+ sink1 = 0;
+ } else {
+ value = 6;
+ sink1 = 1;
+ }
+ sink0 = 1;
+ return Math.min(-1, value);
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CountedLoopTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CountedLoopTest.java
index 1bd89c5f6d9..61cacfde4a8 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CountedLoopTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CountedLoopTest.java
@@ -30,6 +30,7 @@ import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.loop.InductionVariable;
import org.graalvm.compiler.loop.LoopsData;
import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
@@ -52,25 +53,47 @@ public class CountedLoopTest extends GraalCompilerTest {
ValueNode get(InductionVariable iv);
}
+ @FunctionalInterface
+ private interface StaticIVProperty {
+ long get(InductionVariable iv);
+ }
+
+ @FunctionalInterface
+ private interface IVPredicate {
+ boolean test(InductionVariable iv);
+ }
+
/**
* Get a property of an induction variable.
- *
- * @param property
*/
- private static int get(IVProperty property, int iv) {
+ private static int get(@SuppressWarnings("unused") IVProperty property, @SuppressWarnings("unused") StaticIVProperty staticProperty, @SuppressWarnings("unused") IVPredicate constantCheck,
+ int iv) {
+ return iv;
+ }
+
+ private static int get(@SuppressWarnings("unused") IVProperty property, int iv) {
+ return iv;
+ }
+
+ private static long get(@SuppressWarnings("unused") IVProperty property, @SuppressWarnings("unused") StaticIVProperty staticProperty, @SuppressWarnings("unused") IVPredicate constantCheck,
+ long iv) {
+ return iv;
+ }
+
+ private static long get(@SuppressWarnings("unused") IVProperty property, long iv) {
return iv;
}
private static class Result {
- public int extremum;
- public int exitValue;
+ public long extremum;
+ public long exitValue;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + exitValue;
- result = prime * result + extremum;
+ result = prime * result + Long.hashCode(exitValue);
+ result = prime * result + Long.hashCode(extremum);
return result;
}
@@ -95,7 +118,7 @@ public class CountedLoopTest extends GraalCompilerTest {
Result ret = new Result();
for (i = start; i < limit; i += inc) {
GraalDirectives.controlFlowAnchor();
- ret.extremum = get(InductionVariable::extremumNode, i);
+ ret.extremum = get(InductionVariable::extremumNode, InductionVariable::constantExtremum, InductionVariable::isConstantExtremum, i);
}
ret.exitValue = get(InductionVariable::exitValueNode, i);
return ret;
@@ -103,32 +126,42 @@ public class CountedLoopTest extends GraalCompilerTest {
@Test
public void increment1() {
- test("incrementSnippet", 0, 256, 1);
+ testCounted("incrementSnippet", 0, 256, 1);
}
@Test
public void increment2() {
- test("incrementSnippet", 0, 256, 2);
+ testCounted("incrementSnippet", 0, 256, 2);
}
@Test
public void increment3() {
- test("incrementSnippet", 0, 256, 3);
+ testCounted("incrementSnippet", 0, 256, 3);
}
@Test
public void increment4() {
- test("incrementSnippet", -10, Integer.MAX_VALUE, 1);
+ testCounted("incrementSnippet", -10, 1, Integer.MAX_VALUE);
}
@Test
public void increment5() {
- test("incrementSnippet", 256, 256, 1);
+ testCounted("incrementSnippet", 256, 256, 1);
}
@Test
public void increment6() {
- test("incrementSnippet", 257, 256, 1);
+ testCounted("incrementSnippet", 257, 256, 1);
+ }
+
+ @Test
+ public void increment7() {
+ testCounted("incrementSnippet", -10, Integer.MAX_VALUE, 1);
+ }
+
+ @Test
+ public void increment8() {
+ testCounted("incrementSnippet", -10, Integer.MAX_VALUE - 1, 2);
}
public static Result incrementEqSnippet(int start, int limit, int step) {
@@ -137,7 +170,7 @@ public class CountedLoopTest extends GraalCompilerTest {
Result ret = new Result();
for (i = start; i <= limit; i += inc) {
GraalDirectives.controlFlowAnchor();
- ret.extremum = get(InductionVariable::extremumNode, i);
+ ret.extremum = get(InductionVariable::extremumNode, InductionVariable::constantExtremum, InductionVariable::isConstantExtremum, i);
}
ret.exitValue = get(InductionVariable::exitValueNode, i);
return ret;
@@ -145,32 +178,42 @@ public class CountedLoopTest extends GraalCompilerTest {
@Test
public void incrementEq1() {
- test("incrementEqSnippet", 0, 256, 1);
+ testCounted("incrementEqSnippet", 0, 256, 1);
}
@Test
public void incrementEq2() {
- test("incrementEqSnippet", 0, 256, 2);
+ testCounted("incrementEqSnippet", 0, 256, 2);
}
@Test
public void incrementEq3() {
- test("incrementEqSnippet", 0, 256, 3);
+ testCounted("incrementEqSnippet", 0, 256, 3);
}
@Test
public void incrementEq4() {
- test("incrementEqSnippet", -10, 0, Integer.MAX_VALUE);
+ testCounted("incrementEqSnippet", -10, 0, Integer.MAX_VALUE);
}
@Test
public void incrementEq5() {
- test("incrementEqSnippet", 256, 256, 1);
+ testCounted("incrementEqSnippet", 256, 256, 1);
}
@Test
public void incrementEq6() {
- test("incrementEqSnippet", 257, 256, 1);
+ testCounted("incrementEqSnippet", 257, 256, 1);
+ }
+
+ @Test
+ public void incrementEq7() {
+ testCounted("incrementEqSnippet", -10, Integer.MAX_VALUE - 1, 1);
+ }
+
+ @Test
+ public void incrementEq8() {
+ testCounted("incrementEqSnippet", -10, Integer.MAX_VALUE - 2, 2);
}
public static Result decrementSnippet(int start, int limit, int step) {
@@ -179,7 +222,7 @@ public class CountedLoopTest extends GraalCompilerTest {
Result ret = new Result();
for (i = start; i > limit; i -= dec) {
GraalDirectives.controlFlowAnchor();
- ret.extremum = get(InductionVariable::extremumNode, i);
+ ret.extremum = get(InductionVariable::extremumNode, InductionVariable::constantExtremum, InductionVariable::isConstantExtremum, i);
}
ret.exitValue = get(InductionVariable::exitValueNode, i);
return ret;
@@ -187,17 +230,27 @@ public class CountedLoopTest extends GraalCompilerTest {
@Test
public void decrement1() {
- test("decrementSnippet", 256, 0, 1);
+ testCounted("decrementSnippet", 256, 0, 1);
}
@Test
public void decrement2() {
- test("decrementSnippet", 256, 0, 2);
+ testCounted("decrementSnippet", 256, 0, 2);
}
@Test
public void decrement3() {
- test("decrementSnippet", 256, 0, 3);
+ testCounted("decrementSnippet", 256, 0, 3);
+ }
+
+ @Test
+ public void decrement4() {
+ testCounted("decrementSnippet", Integer.MAX_VALUE, -10, 1);
+ }
+
+ @Test
+ public void decrement5() {
+ testCounted("decrementSnippet", Integer.MAX_VALUE, -10, 2);
}
public static Result decrementEqSnippet(int start, int limit, int step) {
@@ -206,7 +259,7 @@ public class CountedLoopTest extends GraalCompilerTest {
Result ret = new Result();
for (i = start; i >= limit; i -= dec) {
GraalDirectives.controlFlowAnchor();
- ret.extremum = get(InductionVariable::extremumNode, i);
+ ret.extremum = get(InductionVariable::extremumNode, InductionVariable::constantExtremum, InductionVariable::isConstantExtremum, i);
}
ret.exitValue = get(InductionVariable::exitValueNode, i);
return ret;
@@ -214,22 +267,32 @@ public class CountedLoopTest extends GraalCompilerTest {
@Test
public void decrementEq1() {
- test("decrementEqSnippet", 256, 0, 1);
+ testCounted("decrementEqSnippet", 256, 0, 1);
}
@Test
public void decrementEq2() {
- test("decrementEqSnippet", 256, 0, 2);
+ testCounted("decrementEqSnippet", 256, 0, 2);
}
@Test
public void decrementEq3() {
- test("decrementEqSnippet", 256, 0, 3);
+ testCounted("decrementEqSnippet", 256, 0, 3);
}
@Test
public void decrementEq4() {
- test("decrementEqSnippet", -10, 0, Integer.MAX_VALUE);
+ testCounted("decrementEqSnippet", -10, 0, Integer.MAX_VALUE);
+ }
+
+ @Test
+ public void decrementEq5() {
+ testCounted("decrementEqSnippet", Integer.MAX_VALUE, -10, 1);
+ }
+
+ @Test
+ public void decrementEq6() {
+ testCounted("decrementEqSnippet", Integer.MAX_VALUE, -10, 2);
}
public static Result twoVariablesSnippet() {
@@ -238,7 +301,7 @@ public class CountedLoopTest extends GraalCompilerTest {
for (int i = 0; i < 1024; i++) {
j += 5;
GraalDirectives.controlFlowAnchor();
- ret.extremum = get(InductionVariable::extremumNode, j);
+ ret.extremum = get(InductionVariable::extremumNode, InductionVariable::constantExtremum, InductionVariable::isConstantExtremum, j);
}
ret.exitValue = get(InductionVariable::exitValueNode, j);
return ret;
@@ -246,7 +309,83 @@ public class CountedLoopTest extends GraalCompilerTest {
@Test
public void testTwoVariables() {
- test("twoVariablesSnippet");
+ testCounted("twoVariablesSnippet");
+ }
+
+ public static Result incrementNeqSnippet(int limit) {
+ int i;
+ int posLimit = ((limit - 1) & 0xFFFF) + 1; // make sure limit is always strictly positive
+ Result ret = new Result();
+ for (i = 0; i != posLimit; i++) {
+ GraalDirectives.controlFlowAnchor();
+ ret.extremum = get(InductionVariable::extremumNode, InductionVariable::constantExtremum, InductionVariable::isConstantExtremum, i);
+ }
+ ret.exitValue = get(InductionVariable::exitValueNode, i);
+ return ret;
+ }
+
+ @Test
+ public void decrementNeq() {
+ testCounted("decrementNeqSnippet", 256);
+ }
+
+ public static Result decrementNeqSnippet(int limit) {
+ int i;
+ int posLimit = ((limit - 1) & 0xFFFF) + 1; // make sure limit is always strictly positive
+ Result ret = new Result();
+ for (i = posLimit; i != 0; i--) {
+ GraalDirectives.controlFlowAnchor();
+ ret.extremum = get(InductionVariable::extremumNode, InductionVariable::constantExtremum, InductionVariable::isConstantExtremum, i);
+ }
+ ret.exitValue = get(InductionVariable::exitValueNode, i);
+ return ret;
+ }
+
+ @Test
+ public void incrementNeq() {
+ testCounted("incrementNeqSnippet", 256);
+ }
+
+ public static Result incrementLongSnippet(long start, long limit, long step) {
+ long i;
+ long inc = ((step - 1) & 0xFFFF) + 1; // make sure this value is always strictly positive
+ Result ret = new Result();
+ for (i = start; i < limit; i += inc) {
+ GraalDirectives.controlFlowAnchor();
+ ret.extremum = get(InductionVariable::extremumNode, InductionVariable::constantExtremum, InductionVariable::isConstantExtremum, i);
+ }
+ ret.exitValue = get(InductionVariable::exitValueNode, i);
+ return ret;
+ }
+
+ @Test
+ public void incrementLong1() {
+ testCounted("incrementLongSnippet", 0L, 256L, 1L);
+ }
+
+ @Test
+ public void incrementLong2() {
+ testCounted("incrementLongSnippet", 0L, 256L, 2L);
+ }
+
+ @Test
+ public void incrementLong3() {
+ testCounted("incrementLongSnippet", 0L, 256L, 3L);
+ }
+
+ @Test
+ public void incrementLong4() {
+ testCounted("incrementLongSnippet", -10L, 1L, Long.MAX_VALUE);
+ }
+
+ @Test
+ public void incrementLong5() {
+ testCounted("incrementLongSnippet", 256L, 256L, 1L);
+ }
+
+ @Test
+ public void incrementLong6() {
+ testCounted("incrementLongSnippet", 257L, 256L, 1L);
}
@NodeInfo(cycles = CYCLES_IGNORED, size = SIZE_IGNORED)
@@ -255,18 +394,31 @@ public class CountedLoopTest extends GraalCompilerTest {
public static final NodeClass TYPE = NodeClass.create(IVPropertyNode.class);
private final IVProperty property;
+ private final StaticIVProperty staticProperty;
+ private final IVPredicate staticCheck;
@Input private ValueNode iv;
- protected IVPropertyNode(IVProperty property, ValueNode iv) {
+ protected IVPropertyNode(IVProperty property, StaticIVProperty staticProperty, IVPredicate staticCheck, ValueNode iv) {
super(TYPE, iv.stamp(NodeView.DEFAULT).unrestricted());
this.property = property;
+ this.staticProperty = staticProperty;
+ this.staticCheck = staticCheck;
this.iv = iv;
}
public void rewrite(LoopsData loops) {
InductionVariable inductionVariable = loops.getInductionVariable(iv);
assert inductionVariable != null;
- ValueNode node = property.get(inductionVariable);
+ ValueNode node = null;
+ if (staticCheck != null) {
+ assert staticProperty != null;
+ if (staticCheck.test(inductionVariable)) {
+ node = ConstantNode.forLong(staticProperty.get(inductionVariable), graph());
+ }
+ }
+ if (node == null) {
+ node = property.get(inductionVariable);
+ }
replaceAtUsagesAndDelete(node);
}
@@ -279,7 +431,13 @@ public class CountedLoopTest extends GraalCompilerTest {
@Override
protected void registerInvocationPlugins(InvocationPlugins invocationPlugins) {
Registration r = new Registration(invocationPlugins, CountedLoopTest.class);
- r.register2("get", IVProperty.class, int.class, new InvocationPlugin() {
+ registerPlugins(r, JavaKind.Int);
+ registerPlugins(r, JavaKind.Long);
+ super.registerInvocationPlugins(invocationPlugins);
+ }
+
+ private void registerPlugins(Registration r, JavaKind ivKind) {
+ r.register2("get", IVProperty.class, ivKind.toJavaClass(), new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg1, ValueNode arg2) {
IVProperty property = null;
@@ -287,14 +445,36 @@ public class CountedLoopTest extends GraalCompilerTest {
property = getSnippetReflection().asObject(IVProperty.class, arg1.asJavaConstant());
}
if (property != null) {
- b.addPush(JavaKind.Int, new IVPropertyNode(property, arg2));
+ b.addPush(ivKind, new IVPropertyNode(property, null, null, arg2));
+ return true;
+ } else {
+ return false;
+ }
+ }
+ });
+ r.register4("get", IVProperty.class, StaticIVProperty.class, IVPredicate.class, ivKind.toJavaClass(), new InvocationPlugin() {
+ @Override
+ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg1, ValueNode arg2, ValueNode arg3, ValueNode arg4) {
+ IVProperty property = null;
+ StaticIVProperty staticProperty = null;
+ IVPredicate staticCheck = null;
+ if (arg1.isConstant()) {
+ property = getSnippetReflection().asObject(IVProperty.class, arg1.asJavaConstant());
+ }
+ if (arg2.isConstant()) {
+ staticProperty = getSnippetReflection().asObject(StaticIVProperty.class, arg2.asJavaConstant());
+ }
+ if (arg3.isConstant()) {
+ staticCheck = getSnippetReflection().asObject(IVPredicate.class, arg3.asJavaConstant());
+ }
+ if (property != null && staticProperty != null && staticCheck != null) {
+ b.addPush(ivKind, new IVPropertyNode(property, staticProperty, staticCheck, arg4));
return true;
} else {
return false;
}
}
});
- super.registerInvocationPlugins(invocationPlugins);
}
@Override
@@ -308,37 +488,17 @@ public class CountedLoopTest extends GraalCompilerTest {
return true;
}
- public static Result incrementNeqSnippet(int limit) {
- int i;
- int posLimit = ((limit - 1) & 0xFFFF) + 1; // make sure limit is always strictly positive
- Result ret = new Result();
- for (i = 0; i != posLimit; i++) {
- GraalDirectives.controlFlowAnchor();
- ret.extremum = get(InductionVariable::extremumNode, i);
- }
- ret.exitValue = get(InductionVariable::exitValueNode, i);
- return ret;
+ private Object[] argsToBind;
+
+ @Override
+ protected Object[] getArgumentToBind() {
+ return argsToBind;
}
- @Test
- public void decrementNeq() {
- test("decrementNeqSnippet", 256);
- }
-
- public static Result decrementNeqSnippet(int limit) {
- int i;
- int posLimit = ((limit - 1) & 0xFFFF) + 1; // make sure limit is always strictly positive
- Result ret = new Result();
- for (i = posLimit; i != 0; i--) {
- GraalDirectives.controlFlowAnchor();
- ret.extremum = get(InductionVariable::extremumNode, i);
- }
- ret.exitValue = get(InductionVariable::exitValueNode, i);
- return ret;
- }
-
- @Test
- public void incrementNeq() {
- test("incrementNeqSnippet", 256);
+ public void testCounted(String snippetName, Object... args) {
+ test(snippetName, args);
+ argsToBind = args;
+ test(snippetName, args);
+ argsToBind = null;
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java
index 04972d5c321..991fab6af30 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java
@@ -22,6 +22,7 @@
*/
package org.graalvm.compiler.core.test;
+import static java.lang.reflect.Modifier.isStatic;
import static jdk.vm.ci.runtime.JVMCICompiler.INVOCATION_ENTRY_BCI;
import static org.graalvm.compiler.nodes.ConstantNode.getConstantNodes;
import static org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo.DO_NOT_INLINE_NO_EXCEPTION;
@@ -47,6 +48,7 @@ import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
+import jdk.vm.ci.meta.JavaConstant;
import org.graalvm.compiler.api.directives.GraalDirectives;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
import org.graalvm.compiler.api.test.Graal;
@@ -931,7 +933,8 @@ public abstract class GraalCompilerTest extends GraalTest {
*/
@SuppressWarnings("try")
protected InstalledCode getCode(final ResolvedJavaMethod installedCodeOwner, StructuredGraph graph, boolean forceCompile, boolean installAsDefault, OptionValues options) {
- if (!forceCompile && graph == null) {
+ boolean useCache = !forceCompile && getArgumentToBind() == null;
+ if (useCache && graph == null) {
InstalledCode cached = cache.get(installedCodeOwner);
if (cached != null) {
if (cached.isValid()) {
@@ -964,7 +967,7 @@ public abstract class GraalCompilerTest extends GraalTest {
throw new GraalError("Could not install code for " + installedCodeOwner.format("%H.%n(%p)"));
}
} catch (BailoutException e) {
- if (retry <= BAILOUT_RETRY_LIMIT && graph == null && !e.isPermanent()) {
+ if (retry < BAILOUT_RETRY_LIMIT && graph == null && !e.isPermanent()) {
// retry (if there is no predefined graph)
TTY.println(String.format("Restart compilation %s (%s) due to a non-permanent bailout!", installedCodeOwner, id));
continue;
@@ -978,7 +981,7 @@ public abstract class GraalCompilerTest extends GraalTest {
throw debug.handle(e);
}
- if (!forceCompile) {
+ if (useCache) {
cache.put(installedCodeOwner, installedCode);
}
return installedCode;
@@ -1243,12 +1246,33 @@ public abstract class GraalCompilerTest extends GraalTest {
DebugContext debug = graph.getDebug();
try (DebugContext.Scope ds = debug.scope("Parsing", javaMethod, graph)) {
graphBuilderSuite.apply(graph, getDefaultHighTierContext());
+ Object[] args = getArgumentToBind();
+ if (args != null) {
+ bindArguments(graph, args);
+ }
return graph;
} catch (Throwable e) {
throw debug.handle(e);
}
}
+ protected void bindArguments(StructuredGraph graph, Object[] argsToBind) {
+ ResolvedJavaMethod m = graph.method();
+ Object receiver = isStatic(m.getModifiers()) ? null : this;
+ Object[] args = argsWithReceiver(receiver, argsToBind);
+ JavaType[] parameterTypes = m.toParameterTypes();
+ assert parameterTypes.length == args.length;
+ for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
+ JavaConstant c = getSnippetReflection().forBoxed(parameterTypes[param.index()].getJavaKind(), args[param.index()]);
+ ConstantNode replacement = ConstantNode.forConstant(c, getMetaAccess(), graph);
+ param.replaceAtUsages(replacement);
+ }
+ }
+
+ protected Object[] getArgumentToBind() {
+ return null;
+ }
+
protected PhaseSuite getEagerGraphBuilderSuite() {
return getCustomGraphBuilderSuite(GraphBuilderConfiguration.getDefault(getDefaultGraphBuilderPlugins()).withEagerResolving(true).withUnresolvedIsError(true));
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraphEncoderTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraphEncoderTest.java
index 7f319c38a80..46a4502ea97 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraphEncoderTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraphEncoderTest.java
@@ -77,8 +77,7 @@ public class GraphEncoderTest extends GraalCompilerTest {
}
for (StructuredGraph originalGraph : originalGraphs) {
- EncodedGraph encodedGraph = new EncodedGraph(encoder.getEncoding(), startOffsets.get(originalGraph), encoder.getObjects(), encoder.getNodeClasses(), originalGraph.getAssumptions(),
- originalGraph.getMethods());
+ EncodedGraph encodedGraph = new EncodedGraph(encoder.getEncoding(), startOffsets.get(originalGraph), encoder.getObjects(), encoder.getNodeClasses(), originalGraph);
GraphEncoder.verifyEncoding(originalGraph, encodedGraph, getTarget().arch);
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SwitchDyingLoopTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SwitchDyingLoopTest.java
new file mode 100644
index 00000000000..dbb60193403
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SwitchDyingLoopTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2018, 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.test;
+
+import static org.graalvm.compiler.graph.test.matchers.NodeIterableCount.hasCount;
+import static org.graalvm.compiler.graph.test.matchers.NodeIterableIsEmpty.isEmpty;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+
+import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.nodes.LoopBeginNode;
+import org.graalvm.compiler.nodes.ParameterNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.extended.IntegerSwitchNode;
+import org.graalvm.compiler.phases.common.CanonicalizerPhase;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
+import org.junit.Test;
+
+import jdk.vm.ci.meta.JavaKind;
+
+public class SwitchDyingLoopTest extends GraalCompilerTest {
+
+ @SuppressWarnings("fallthrough")
+ public static int snippet(int a, int n) {
+ int r = 0;
+ loop: for (int i = 0; i < n; i++) {
+ int v = (i * 167 + 13) & 0xff;
+ switch (v & a) {
+ case 0x80:
+ r += 1; // fall through
+ case 0x40:
+ r += 2; // fall through
+ case 0x20:
+ r += 3;
+ continue;
+ case 0x08:
+ r += 5; // fall through
+ case 0x04:
+ r += 7; // fall through
+ case 0x02:
+ r += 9; // fall through
+ default:
+ break loop;
+ }
+ }
+ return r;
+ }
+
+ @Test
+ public void test() {
+ CanonicalizerPhase canonicalizerPhase = new CanonicalizerPhase();
+ HighTierContext highTierContext = getDefaultHighTierContext();
+ StructuredGraph graph = parseEager("snippet", StructuredGraph.AllowAssumptions.YES);
+ // there should be 1 loop and 1 switch
+ assertThat(graph.getNodes(LoopBeginNode.TYPE), hasCount(1));
+ assertThat(graph.getNodes(IntegerSwitchNode.TYPE), hasCount(1));
+ canonicalizerPhase.apply(graph, highTierContext);
+ // after canonicalization, the loop and switch should still be there
+ assertThat(graph.getNodes(LoopBeginNode.TYPE), hasCount(1));
+ assertThat(graph.getNodes(IntegerSwitchNode.TYPE), hasCount(1));
+ // add stamp to `a` so that paths leading to continue can be trimmed
+ ParameterNode parameter = graph.getParameter(0);
+ assertNotNull(parameter);
+ parameter.setStamp(StampFactory.forInteger(JavaKind.Int, 0, 255, 0, 0xf));
+ canonicalizerPhase.apply(graph, highTierContext);
+ // the loop should have disappeared and there should still be a switch
+ assertThat(graph.getNodes(LoopBeginNode.TYPE), isEmpty());
+ assertThat(graph.getNodes(IntegerSwitchNode.TYPE), hasCount(1));
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/TrivialInliningExplosionTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/TrivialInliningExplosionTest.java
index efe909d5db2..fc20da2d145 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/TrivialInliningExplosionTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/TrivialInliningExplosionTest.java
@@ -74,9 +74,9 @@ public class TrivialInliningExplosionTest extends GraalCompilerTest {
int afterCompileSize = lastCompiledGraph.getNodeCount();
// The values of afterParseSize and afterCompileSize when this
- // test was written were 849 and 848 respectively.
- Assert.assertTrue(afterParseSize < 2000);
- Assert.assertTrue(afterCompileSize < 2000);
+ // test was written were 3223 and 3505 respectively.
+ Assert.assertTrue(afterParseSize < 4000);
+ Assert.assertTrue(afterCompileSize < 4000);
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsignedLongTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsignedLongTest.java
new file mode 100644
index 00000000000..b8b00417bdb
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsignedLongTest.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 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.test;
+
+import org.graalvm.compiler.core.common.util.UnsignedLong;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class UnsignedLongTest {
+ @Test
+ public void testEquals() {
+ UnsignedLong fortyTwo = new UnsignedLong(42);
+ Assert.assertTrue(fortyTwo.equals(42));
+ Assert.assertFalse(fortyTwo.equals(99));
+ UnsignedLong longFortyTwo = new UnsignedLong(0x42_0000_8888L);
+ Assert.assertTrue(longFortyTwo.equals(0x42_0000_8888L));
+ Assert.assertFalse(longFortyTwo.equals(0x99_0000_8888L));
+ UnsignedLong longUnsigned = new UnsignedLong(0x8000_7777_0000_8888L);
+ Assert.assertTrue(longUnsigned.equals(0x8000_7777_0000_8888L));
+ Assert.assertFalse(longUnsigned.equals(0xf000_7777_0000_8888L));
+ }
+
+ @Test
+ public void testIsLessThan() {
+ UnsignedLong fortyTwo = new UnsignedLong(42);
+ Assert.assertTrue(fortyTwo.isLessThan(45));
+ Assert.assertFalse(fortyTwo.isLessThan(42));
+ Assert.assertFalse(fortyTwo.isLessThan(40));
+ Assert.assertTrue(fortyTwo.isLessThan(0xffff_ffff_ffff_ffffL));
+ UnsignedLong longUnsigned = new UnsignedLong(0x8000_7777_0000_8888L);
+ Assert.assertTrue(longUnsigned.isLessThan(0xffff_ffff_ffff_ffffL));
+ Assert.assertFalse(longUnsigned.isLessThan(42));
+ Assert.assertFalse(longUnsigned.isLessThan(0x8000_0777_0000_8888L));
+ Assert.assertFalse(longUnsigned.isLessThan(0x8000_7777_0000_8888L));
+ }
+
+ @Test
+ public void testIsLessOrEqualTo() {
+ UnsignedLong fortyTwo = new UnsignedLong(42);
+ Assert.assertTrue(fortyTwo.isLessOrEqualTo(45));
+ Assert.assertTrue(fortyTwo.isLessOrEqualTo(42));
+ Assert.assertFalse(fortyTwo.isLessOrEqualTo(40));
+ Assert.assertTrue(fortyTwo.isLessOrEqualTo(0xffff_ffff_ffff_ffffL));
+ UnsignedLong longUnsigned = new UnsignedLong(0x8000_7777_0000_8888L);
+ Assert.assertTrue(longUnsigned.isLessOrEqualTo(0xffff_ffff_ffff_ffffL));
+ Assert.assertFalse(longUnsigned.isLessOrEqualTo(42));
+ Assert.assertFalse(longUnsigned.isLessOrEqualTo(0x8000_0777_0000_8888L));
+ Assert.assertTrue(longUnsigned.isLessOrEqualTo(0x8000_7777_0000_8888L));
+ }
+
+ @Test
+ public void testTimes() {
+ UnsignedLong fortyTwo = new UnsignedLong(42);
+ Assert.assertEquals(42 * 42, fortyTwo.times(42).asLong());
+ Assert.assertEquals(0xffff_ffff_ffff_fff0L, fortyTwo.times(0x618618618618618L).asLong());
+ }
+
+ @Test(expected = ArithmeticException.class)
+ public void testTimesException() {
+ UnsignedLong fortyTwo = new UnsignedLong(42);
+ fortyTwo.times(0x618618618618619L);
+ }
+
+ @Test
+ public void testMinus() {
+ UnsignedLong fortyTwo = new UnsignedLong(42);
+ Assert.assertEquals(0, fortyTwo.minus(42).asLong());
+ Assert.assertEquals(40, fortyTwo.minus(2).asLong());
+ UnsignedLong longUnsigned = new UnsignedLong(0xffff_ffff_ffff_fff0L);
+ Assert.assertEquals(0, longUnsigned.minus(0xffff_ffff_ffff_fff0L).asLong());
+ }
+
+ @Test(expected = ArithmeticException.class)
+ public void testMinusException() {
+ UnsignedLong fortyTwo = new UnsignedLong(42);
+ fortyTwo.minus(43);
+ }
+
+ @Test(expected = ArithmeticException.class)
+ public void testMinusException2() {
+ UnsignedLong longUnsigned = new UnsignedLong(0xffff_ffff_ffff_fff0L);
+ longUnsigned.minus(0xffff_ffff_ffff_fff1L);
+ }
+
+ @Test
+ public void testPlus() {
+ UnsignedLong fortyTwo = new UnsignedLong(42);
+ Assert.assertEquals(84, fortyTwo.plus(42).asLong());
+ Assert.assertEquals(44, fortyTwo.plus(2).asLong());
+ UnsignedLong longUnsigned = new UnsignedLong(0xffff_ffff_ffff_fff0L);
+ Assert.assertEquals(0xffff_ffff_ffff_ffffL, longUnsigned.plus(0xf).asLong());
+ }
+
+ @Test(expected = ArithmeticException.class)
+ public void testPlusException() {
+ UnsignedLong fortyTwo = new UnsignedLong(42);
+ fortyTwo.plus(0xffff_ffff_ffff_fff0L);
+ }
+
+ @Test(expected = ArithmeticException.class)
+ public void testPlusException2() {
+ UnsignedLong longUnsigned = new UnsignedLong(0xffff_ffff_ffff_fff0L);
+ longUnsigned.plus(42);
+ }
+
+ @Test
+ public void testWrappingTimes() {
+ UnsignedLong fortyTwo = new UnsignedLong(42);
+ Assert.assertEquals(0x1a, fortyTwo.wrappingTimes(0x618618618618619L).asLong());
+ }
+
+ @Test
+ public void testWrappingPlus() {
+ UnsignedLong fortyTwo = new UnsignedLong(42);
+ Assert.assertEquals(0x1a, fortyTwo.wrappingPlus(0xffff_ffff_ffff_fff0L).asLong());
+ UnsignedLong longUnsigned = new UnsignedLong(0xffff_ffff_ffff_fff0L);
+ Assert.assertEquals(0x1a, longUnsigned.wrappingPlus(42).asLong());
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompiler.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompiler.java
index c005152cbc7..093e0ab38e2 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompiler.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompiler.java
@@ -240,6 +240,7 @@ public class GraalCompiler {
debug.dump(DebugContext.BASIC_LEVEL, graph, "After low tier");
debug.dump(DebugContext.BASIC_LEVEL, graph.getLastSchedule(), "Final HIR schedule");
+ graph.logInliningTree();
} catch (Throwable e) {
throw debug.handle(e);
} finally {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java
index a781a4251d3..7091847e552 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java
@@ -316,6 +316,10 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
return values.toArray(new Value[values.size()]);
}
+ public void doBlockPrologue(@SuppressWarnings("unused") Block block, @SuppressWarnings("unused") OptionValues options) {
+
+ }
+
@Override
@SuppressWarnings("try")
public void doBlock(Block block, StructuredGraph graph, BlockMap> blockMap) {
@@ -341,6 +345,7 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
}
}
}
+ doBlockPrologue(block, options);
List nodes = blockMap.get(block);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/HighTier.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/HighTier.java
index 358d6cb0b4f..ac4a0c6c9c7 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/HighTier.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/HighTier.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -45,6 +45,7 @@ import org.graalvm.compiler.options.OptionType;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.PhaseSuite;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
+import org.graalvm.compiler.phases.common.NodeCounterPhase;
import org.graalvm.compiler.phases.common.ConvertDeoptimizeToGuardPhase;
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
import org.graalvm.compiler.phases.common.IncrementalCanonicalizerPhase;
@@ -74,6 +75,10 @@ public class HighTier extends PhaseSuite {
appendPhase(canonicalizer);
+ if (NodeCounterPhase.Options.NodeCounters.getValue(options)) {
+ appendPhase(new NodeCounterPhase());
+ }
+
if (Options.Inline.getValue(options)) {
appendPhase(new InliningPhase(canonicalizer));
appendPhase(new DeadCodeEliminationPhase(Optional));
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java
index a27f5a2048a..9c4921683e6 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java
@@ -178,7 +178,7 @@ public abstract class Backend implements TargetProvider, ValueKindFactory
-
+
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java
index 9f0a763c312..1151396955b 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java
@@ -22,6 +22,9 @@
*/
package org.graalvm.compiler.graph;
+import static org.graalvm.compiler.graph.Graph.SourcePositionTracking.Default;
+import static org.graalvm.compiler.graph.Graph.SourcePositionTracking.Track;
+import static org.graalvm.compiler.graph.Graph.SourcePositionTracking.UpdateOnly;
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED;
@@ -33,6 +36,7 @@ import java.util.function.Consumer;
import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.Equivalence;
import org.graalvm.collections.UnmodifiableEconomicMap;
+import org.graalvm.compiler.core.common.GraalOptions;
import org.graalvm.compiler.debug.CounterKey;
import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.DebugContext;
@@ -65,6 +69,13 @@ public class Graph {
DeepFreeze
}
+ public enum SourcePositionTracking {
+ Default,
+ Ignore,
+ UpdateOnly,
+ Track
+ }
+
public final String name;
/**
@@ -80,7 +91,7 @@ public class Graph {
/**
* Records if updating of node source information is required when performing inlining.
*/
- boolean seenNodeSourcePosition;
+ protected SourcePositionTracking trackNodeSourcePosition;
/**
* The number of valid entries in {@link #nodes}.
@@ -195,7 +206,7 @@ public class Graph {
* was opened
*/
public DebugCloseable withNodeSourcePosition(NodeSourcePosition sourcePosition) {
- return sourcePosition != null ? new NodeSourcePositionScope(sourcePosition) : null;
+ return trackNodeSourcePosition() && sourcePosition != null ? new NodeSourcePositionScope(sourcePosition) : null;
}
/**
@@ -212,16 +223,26 @@ public class Graph {
* to short circuit logic for updating those positions after inlining since that requires
* visiting every node in the graph.
*/
- public boolean mayHaveNodeSourcePosition() {
- assert seenNodeSourcePosition || verifyHasNoSourcePosition();
- return seenNodeSourcePosition;
+ public boolean updateNodeSourcePosition() {
+ return trackNodeSourcePosition == Track || trackNodeSourcePosition == UpdateOnly;
}
- private boolean verifyHasNoSourcePosition() {
- for (Node node : getNodes()) {
- assert node.getNodeSourcePosition() == null;
+ public boolean trackNodeSourcePosition() {
+ return trackNodeSourcePosition == Track;
+ }
+
+ public void setTrackNodeSourcePosition() {
+ if (trackNodeSourcePosition != Track) {
+ assert trackNodeSourcePosition == Default : trackNodeSourcePosition;
+ trackNodeSourcePosition = Track;
}
- return true;
+ }
+
+ public static SourcePositionTracking trackNodeSourcePositionDefault(OptionValues options, DebugContext debug) {
+ if (GraalOptions.TrackNodeSourcePosition.getValue(options) || debug.isDumpEnabledForMethod()) {
+ return Track;
+ }
+ return Default;
}
/**
@@ -255,6 +276,7 @@ public class Graph {
iterableNodesLast = new ArrayList<>(NodeClass.allocatedNodeIterabledIds());
this.name = name;
this.options = options;
+ this.trackNodeSourcePosition = trackNodeSourcePositionDefault(options, debug);
assert debug != null;
this.debug = debug;
@@ -358,6 +380,9 @@ public class Graph {
*/
protected Graph copy(String newName, Consumer> duplicationMapCallback, DebugContext debugForCopy) {
Graph copy = new Graph(newName, options, debugForCopy);
+ if (trackNodeSourcePosition()) {
+ copy.setTrackNodeSourcePosition();
+ }
UnmodifiableEconomicMap duplicates = copy.addDuplicates(getNodes(), this, this.getNodeCount(), (EconomicMap) null);
if (duplicationMapCallback != null) {
duplicationMapCallback.accept(duplicates);
@@ -1069,10 +1094,9 @@ public class Graph {
int id = nodesSize++;
nodes[id] = node;
node.id = id;
- if (currentNodeSourcePosition != null) {
+ if (currentNodeSourcePosition != null && trackNodeSourcePosition()) {
node.setNodeSourcePosition(currentNodeSourcePosition);
}
- seenNodeSourcePosition = seenNodeSourcePosition || node.getNodeSourcePosition() != null;
updateNodeCaches(node);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/InlineCacheGuardPosition.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/InlineCacheGuardPosition.java
new file mode 100644
index 00000000000..f7ea84c3652
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/InlineCacheGuardPosition.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 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.util.Objects;
+
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+
+public class InlineCacheGuardPosition extends NodeSourcePosition {
+ private final ResolvedJavaType dispatchedType;
+ private final ResolvedJavaMethod concreteMethod;
+ private final int hashCode;
+
+ public InlineCacheGuardPosition(NodeSourcePosition callStack, ResolvedJavaType dispatchedType, ResolvedJavaMethod targetMethod) {
+ super(callStack.getCaller(), callStack.getMethod(), callStack.getBCI());
+ this.concreteMethod = targetMethod;
+ this.dispatchedType = dispatchedType;
+ this.hashCode = super.hashCode() + 7 * ((dispatchedType == null) ? 0 : dispatchedType.hashCode()) + 31 * targetMethod.hashCode();
+ }
+
+ public ResolvedJavaType getDispatchedType() {
+ return dispatchedType;
+ }
+
+ public ResolvedJavaMethod getTargetMethod() {
+ return concreteMethod;
+ }
+
+ @Override
+ public int hashCode() {
+ return hashCode;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj != null && getClass() == obj.getClass()) {
+ InlineCacheGuardPosition that = (InlineCacheGuardPosition) obj;
+ if (hashCode != that.hashCode) {
+ return false;
+ }
+ if (this.getBCI() == that.getBCI() && Objects.equals(this.getMethod(), that.getMethod()) && Objects.equals(this.getCaller(), that.getCaller()) &&
+ Objects.equals(this.concreteMethod, that.concreteMethod) && Objects.equals(this.dispatchedType, that.dispatchedType)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return "dispatchedType=" + (dispatchedType == null ? "null" : dispatchedType.getName()) + " target_method=" + concreteMethod.getName() + " target_method_class=" +
+ concreteMethod.getDeclaringClass().getName() + " position=" + super.toString();
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java
index 0f0c41299af..2dd4131de83 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java
@@ -593,10 +593,9 @@ public abstract class Node implements Cloneable, Formattable, NodeInterface {
* Set the source position to {@code sourcePosition}.
*/
public void setNodeSourcePosition(NodeSourcePosition sourcePosition) {
+ assert sourcePosition != null || this.sourcePosition == null || this.sourcePosition.isPlaceholder() : "Invalid source position at node with id " + id;
this.sourcePosition = sourcePosition;
- if (sourcePosition != null && graph != null && !graph.seenNodeSourcePosition) {
- graph.seenNodeSourcePosition = true;
- }
+ // assert sourcePosition == null || graph == null || graph.trackNodeSourcePosition;
}
/**
@@ -920,6 +919,9 @@ public abstract class Node implements Cloneable, Formattable, NodeInterface {
}
newNode.graph = into;
newNode.id = INITIAL_ID;
+ if (sourcePosition != null && (into == null || into.updateNodeSourcePosition())) {
+ newNode.setNodeSourcePosition(sourcePosition);
+ }
if (into != null) {
into.register(newNode);
}
@@ -928,9 +930,6 @@ public abstract class Node implements Cloneable, Formattable, NodeInterface {
if (into != null && useIntoLeafNodeCache) {
into.putNodeIntoCache(newNode);
}
- if (graph != null && into != null && sourcePosition != null) {
- newNode.setNodeSourcePosition(sourcePosition);
- }
newNode.afterClone(this);
return newNode;
}
@@ -1195,6 +1194,15 @@ public abstract class Node implements Cloneable, Formattable, NodeInterface {
return getNodeClass().dataEquals(this, other);
}
+ /**
+ * Determines if this node is equal to the other node while ignoring differences in
+ * {@linkplain Successor control-flow} edges.
+ *
+ */
+ public boolean dataFlowEquals(Node other) {
+ return this == other || nodeClass == other.getNodeClass() && this.valueEquals(other) && nodeClass.equalInputs(this, other);
+ }
+
public final void pushInputs(NodeStack stack) {
getNodeClass().pushInputs(this, stack);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java
index 7af23d60a85..516b3bf810a 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java
@@ -104,7 +104,7 @@ public final class NodeClass extends FieldIntrospection {
* Gets the {@link NodeClass} associated with a given {@link Class}.
*/
public static NodeClass create(Class c) {
- assert get(c) == null;
+ assert getUnchecked(c) == null;
Class super T> superclass = c.getSuperclass();
NodeClass super T> nodeSuperclass = null;
if (superclass != NODE_CLASS) {
@@ -114,9 +114,9 @@ public final class NodeClass extends FieldIntrospection {
}
@SuppressWarnings("unchecked")
- public static NodeClass get(Class superclass) {
+ private static NodeClass getUnchecked(Class clazz) {
try {
- Field field = superclass.getDeclaredField("TYPE");
+ Field field = clazz.getDeclaredField("TYPE");
field.setAccessible(true);
return (NodeClass) field.get(null);
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
@@ -124,6 +124,14 @@ public final class NodeClass extends FieldIntrospection {
}
}
+ public static NodeClass get(Class clazz) {
+ NodeClass result = getUnchecked(clazz);
+ if (result == null && clazz != NODE_CLASS) {
+ throw GraalError.shouldNotReachHere("TYPE field not initialized for class " + clazz.getTypeName());
+ }
+ return result;
+ }
+
private static final Class> NODE_CLASS = Node.class;
private static final Class> INPUT_LIST_CLASS = NodeInputList.class;
private static final Class> SUCCESSOR_LIST_CLASS = NodeSuccessorList.class;
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeSourcePosition.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeSourcePosition.java
index 688eb793968..660dc2c7464 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeSourcePosition.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeSourcePosition.java
@@ -22,31 +22,100 @@
*/
package org.graalvm.compiler.graph;
+import static org.graalvm.compiler.graph.NodeSourcePosition.Marker.None;
+import static org.graalvm.compiler.graph.NodeSourcePosition.Marker.Placeholder;
+import static org.graalvm.compiler.graph.NodeSourcePosition.Marker.Substitution;
+
import java.util.Objects;
+import org.graalvm.compiler.bytecode.BytecodeDisassembler;
+import org.graalvm.compiler.bytecode.Bytecodes;
+
+import jdk.vm.ci.code.BytecodeFrame;
import jdk.vm.ci.code.BytecodePosition;
import jdk.vm.ci.code.CodeUtil;
-import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaMethod;
import jdk.vm.ci.meta.MetaUtil;
import jdk.vm.ci.meta.ResolvedJavaMethod;
public class NodeSourcePosition extends BytecodePosition {
- /**
- * The receiver of the method this frame refers to.
- */
- private final JavaConstant receiver;
- private final int hashCode;
+ private static final boolean STRICT_SOURCE_POSITION = Boolean.getBoolean("debug.graal.SourcePositionStrictChecks");
+ private static final boolean SOURCE_POSITION_BYTECODES = Boolean.getBoolean("debug.graal.SourcePositionDisassemble");
- public NodeSourcePosition(JavaConstant receiver, NodeSourcePosition caller, ResolvedJavaMethod method, int bci) {
+ private final int hashCode;
+ private final Marker marker;
+ private final SourceLanguagePosition sourceLanguagePosition;
+
+ /**
+ * Remove marker frames.
+ */
+ public NodeSourcePosition trim() {
+ if (marker != None) {
+ return null;
+ }
+ NodeSourcePosition caller = getCaller();
+ if (caller != null) {
+ caller = caller.trim();
+ }
+ if (caller != getCaller()) {
+ return new NodeSourcePosition(caller, getMethod(), getBCI());
+ }
+ return this;
+ }
+
+ enum Marker {
+ None,
+ Placeholder,
+ Substitution
+ }
+
+ public NodeSourcePosition(NodeSourcePosition caller, ResolvedJavaMethod method, int bci) {
+ this(caller, method, bci, None);
+ }
+
+ public NodeSourcePosition(NodeSourcePosition caller, ResolvedJavaMethod method, int bci, Marker marker) {
+ this(null, caller, method, bci, marker);
+
+ }
+
+ public NodeSourcePosition(SourceLanguagePosition sourceLanguagePosition, NodeSourcePosition caller, ResolvedJavaMethod method, int bci) {
+ this(sourceLanguagePosition, caller, method, bci, None);
+ }
+
+ public NodeSourcePosition(SourceLanguagePosition sourceLanguagePosition, NodeSourcePosition caller, ResolvedJavaMethod method, int bci, Marker marker) {
super(caller, method, bci);
if (caller == null) {
this.hashCode = 31 * bci + method.hashCode();
} else {
this.hashCode = caller.hashCode * 7 + 31 * bci + method.hashCode();
}
- this.receiver = receiver;
- assert receiver == null || method.getDeclaringClass().isInstance(receiver);
+ this.marker = marker;
+ this.sourceLanguagePosition = sourceLanguagePosition;
+ }
+
+ public static NodeSourcePosition placeholder(ResolvedJavaMethod method) {
+ return new NodeSourcePosition(null, method, BytecodeFrame.INVALID_FRAMESTATE_BCI, Placeholder);
+ }
+
+ public static NodeSourcePosition placeholder(ResolvedJavaMethod method, int bci) {
+ return new NodeSourcePosition(null, method, bci, Placeholder);
+ }
+
+ public boolean isPlaceholder() {
+ return marker == Placeholder;
+ }
+
+ public static NodeSourcePosition substitution(ResolvedJavaMethod method) {
+ return new NodeSourcePosition(null, method, BytecodeFrame.INVALID_FRAMESTATE_BCI, Substitution);
+ }
+
+ public static NodeSourcePosition substitution(NodeSourcePosition caller, ResolvedJavaMethod method, int bci) {
+ return new NodeSourcePosition(caller, method, bci, Substitution);
+ }
+
+ public boolean isSubstitution() {
+ return marker == Substitution;
}
@Override
@@ -60,7 +129,7 @@ public class NodeSourcePosition extends BytecodePosition {
return false;
}
if (this.getBCI() == that.getBCI() && Objects.equals(this.getMethod(), that.getMethod()) && Objects.equals(this.getCaller(), that.getCaller()) &&
- Objects.equals(this.receiver, that.receiver)) {
+ Objects.equals(this.sourceLanguagePosition, that.sourceLanguagePosition)) {
return true;
}
}
@@ -72,8 +141,18 @@ public class NodeSourcePosition extends BytecodePosition {
return hashCode;
}
- public JavaConstant getReceiver() {
- return receiver;
+ public int depth() {
+ int d = 0;
+ NodeSourcePosition pos = this;
+ while (pos != null) {
+ d++;
+ pos = pos.getCaller();
+ }
+ return d;
+ }
+
+ public SourceLanguagePosition getSourceLanauage() {
+ return sourceLanguagePosition;
}
@Override
@@ -81,17 +160,29 @@ public class NodeSourcePosition extends BytecodePosition {
return (NodeSourcePosition) super.getCaller();
}
- public NodeSourcePosition addCaller(JavaConstant newCallerReceiver, NodeSourcePosition link) {
- if (getCaller() == null) {
- assert newCallerReceiver == null || receiver == null : "replacing receiver";
- return new NodeSourcePosition(newCallerReceiver, link, getMethod(), getBCI());
- } else {
- return new NodeSourcePosition(receiver, getCaller().addCaller(newCallerReceiver, link), getMethod(), getBCI());
- }
+ public NodeSourcePosition addCaller(SourceLanguagePosition newSourceLanguagePosition, NodeSourcePosition link) {
+ return addCaller(newSourceLanguagePosition, link, false);
}
public NodeSourcePosition addCaller(NodeSourcePosition link) {
- return addCaller(null, link);
+ return addCaller(null, link, false);
+ }
+
+ public NodeSourcePosition addCaller(NodeSourcePosition link, boolean isSubstitution) {
+ return addCaller(null, link, isSubstitution);
+ }
+
+ public NodeSourcePosition addCaller(SourceLanguagePosition newSourceLanguagePosition, NodeSourcePosition link, boolean isSubstitution) {
+ if (getCaller() == null) {
+ if (isPlaceholder()) {
+ return new NodeSourcePosition(newSourceLanguagePosition, link, getMethod(), 0);
+ }
+ assert link == null || isSubstitution || verifyCaller(this, link) : link;
+
+ return new NodeSourcePosition(newSourceLanguagePosition, link, getMethod(), getBCI());
+ } else {
+ return new NodeSourcePosition(getCaller().addCaller(newSourceLanguagePosition, link, isSubstitution), getMethod(), getBCI());
+ }
}
@Override
@@ -99,9 +190,9 @@ public class NodeSourcePosition extends BytecodePosition {
StringBuilder sb = new StringBuilder(100);
NodeSourcePosition pos = this;
while (pos != null) {
- MetaUtil.appendLocation(sb.append("at "), pos.getMethod(), pos.getBCI());
- if (pos.receiver != null) {
- sb.append("receiver=" + pos.receiver + " ");
+ format(sb, pos);
+ if (pos.sourceLanguagePosition != null) {
+ sb.append(" source=" + pos.sourceLanguagePosition.toShortString());
}
pos = pos.getCaller();
if (pos != null) {
@@ -110,4 +201,55 @@ public class NodeSourcePosition extends BytecodePosition {
}
return sb.toString();
}
+
+ private static void format(StringBuilder sb, NodeSourcePosition pos) {
+ MetaUtil.appendLocation(sb.append("at "), pos.getMethod(), pos.getBCI());
+ if (SOURCE_POSITION_BYTECODES) {
+ String disassembly = BytecodeDisassembler.disassembleOne(pos.getMethod(), pos.getBCI());
+ if (disassembly != null && disassembly.length() > 0) {
+ sb.append(" // ");
+ sb.append(disassembly);
+ }
+ }
+ }
+
+ String shallowToString() {
+ StringBuilder sb = new StringBuilder(100);
+ format(sb, this);
+ return sb.toString();
+ }
+
+ public boolean verify() {
+ NodeSourcePosition current = this;
+ NodeSourcePosition caller = getCaller();
+ while (caller != null) {
+ assert verifyCaller(current, caller) : current;
+ current = caller;
+ caller = caller.getCaller();
+ }
+ return true;
+ }
+
+ private static boolean verifyCaller(NodeSourcePosition current, NodeSourcePosition caller) {
+ if (!STRICT_SOURCE_POSITION) {
+ return true;
+ }
+ if (BytecodeFrame.isPlaceholderBci(caller.getBCI())) {
+ return true;
+ }
+ int opcode = BytecodeDisassembler.getBytecodeAt(caller.getMethod(), caller.getBCI());
+ JavaMethod method = BytecodeDisassembler.getInvokedMethodAt(caller.getMethod(), caller.getBCI());
+ /*
+ * It's not really possible to match the declaring classes since this might be an interface
+ * invoke. Matching name and signature probably provides enough accuracy.
+ */
+ assert method == null || (method.getName().equals(current.getMethod().getName()) &&
+ method.getSignature().equals(current.getMethod().getSignature())) ||
+ caller.getMethod().getName().equals("linkToTargetMethod") ||
+ opcode == Bytecodes.INVOKEDYNAMIC ||
+ caller.getMethod().getDeclaringClass().getName().startsWith("Ljava/lang/invoke/LambdaForm$") ||
+ current.getMethod().getName().equals("callInlined") : "expected " + method + " but found " +
+ current.getMethod();
+ return true;
+ }
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/SourceLanguagePosition.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/SourceLanguagePosition.java
new file mode 100644
index 00000000000..cf7f6bb94e8
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/SourceLanguagePosition.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 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.util.Map;
+
+/**
+ * Provides a path to report information about a high level language source position to the Graph
+ * Visualizer.
+ */
+public interface SourceLanguagePosition {
+
+ /**
+ * This is called during dumping of Nodes. The implementation should add any properties which
+ * describe this source position. The actual keys and values used are a private contract between
+ * the language implementation and the Graph Visualizer.
+ */
+ void addSourceInformation(Map props);
+
+ /**
+ * Produce a compact description of this position suitable for printing.
+ */
+ String toShortString();
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/TraceInliningMode.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/SourceLanguagePositionProvider.java
similarity index 77%
rename from src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/TraceInliningMode.java
rename to src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/SourceLanguagePositionProvider.java
index cbd0e24ee35..21bd9a2c276 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/TraceInliningMode.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/SourceLanguagePositionProvider.java
@@ -20,20 +20,13 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-package org.graalvm.compiler.core.common;
+package org.graalvm.compiler.graph;
-public enum TraceInliningMode {
- None(false),
- Linear(true),
- Tree(true);
+import jdk.vm.ci.meta.JavaConstant;
- private final boolean tracing;
-
- TraceInliningMode(boolean tracing) {
- this.tracing = tracing;
- }
-
- public boolean isTracing() {
- return tracing;
- }
+/**
+ * Provider of {@link SourceLanguagePosition} for a constant if it represents an AST node.
+ */
+public interface SourceLanguagePositionProvider {
+ SourceLanguagePosition getPosition(JavaConstant node);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackend.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackend.java
index a6bfcb92e49..28f3c6db2e8 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackend.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackend.java
@@ -288,33 +288,37 @@ public class AArch64HotSpotBackend extends HotSpotHostBackend {
}
private static void emitCodeBody(CompilationResultBuilder crb, LIR lir, AArch64MacroAssembler masm) {
- /*
- * Insert a nop at the start of the prolog so we can patch in a branch if we need to
- * invalidate the method later.
- */
+ emitInvalidatePlaceholder(crb, masm);
+ crb.emit(lir);
+ }
+
+ /**
+ * Insert a nop at the start of the prolog so we can patch in a branch if we need to invalidate
+ * the method later.
+ *
+ * @see "http://mail.openjdk.java.net/pipermail/aarch64-port-dev/2013-September/000273.html"
+ */
+ public static void emitInvalidatePlaceholder(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
crb.blockComment("[nop for method invalidation]");
masm.nop();
-
- crb.emit(lir);
}
private void emitCodeSuffix(CompilationResultBuilder crb, AArch64MacroAssembler masm, FrameMap frameMap) {
HotSpotProviders providers = getProviders();
HotSpotFrameContext frameContext = (HotSpotFrameContext) crb.frameContext;
if (!frameContext.isStub) {
+ HotSpotForeignCallsProvider foreignCalls = providers.getForeignCalls();
try (ScratchRegister sc = masm.getScratchRegister()) {
Register scratch = sc.getRegister();
- HotSpotForeignCallsProvider foreignCalls = providers.getForeignCalls();
crb.recordMark(config.MARKID_EXCEPTION_HANDLER_ENTRY);
ForeignCallLinkage linkage = foreignCalls.lookupForeignCall(EXCEPTION_HANDLER);
Register helper = AArch64Call.isNearCall(linkage) ? null : scratch;
AArch64Call.directCall(crb, masm, linkage, helper, null);
-
- crb.recordMark(config.MARKID_DEOPT_HANDLER_ENTRY);
- linkage = foreignCalls.lookupForeignCall(DEOPTIMIZATION_HANDLER);
- helper = AArch64Call.isNearCall(linkage) ? null : scratch;
- AArch64Call.directCall(crb, masm, linkage, helper, null);
}
+ crb.recordMark(config.MARKID_DEOPT_HANDLER_ENTRY);
+ ForeignCallLinkage linkage = foreignCalls.lookupForeignCall(DEOPTIMIZATION_HANDLER);
+ masm.adr(lr, 0); // Warning: the argument is an offset from the instruction!
+ AArch64Call.directJmp(crb, masm, linkage);
} else {
// No need to emit the stubs for entries back into the method since
// it has no calls that can cause such "return" entries
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotDeoptimizeOp.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotDeoptimizeOp.java
index f9d43ce56b2..586ced59150 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotDeoptimizeOp.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotDeoptimizeOp.java
@@ -46,7 +46,9 @@ public class AArch64HotSpotDeoptimizeOp extends AArch64BlockEndOp implements Blo
@Override
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
- AArch64Call.directCall(crb, masm, crb.foreignCalls.lookupForeignCall(UNCOMMON_TRAP_HANDLER), null, info);
+ try (AArch64MacroAssembler.ScratchRegister scratch = masm.getScratchRegister()) {
+ AArch64Call.directCall(crb, masm, crb.foreignCalls.lookupForeignCall(UNCOMMON_TRAP_HANDLER), scratch.getRegister(), info, null);
+ }
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotMove.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotMove.java
index b0de7d96da3..8766ddd1fd0 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotMove.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotMove.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -155,22 +155,24 @@ public class AArch64HotSpotMove {
@Override
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
- Register ptr = asRegister(input);
+ Register inputRegister = asRegister(input);
Register resultRegister = asRegister(result);
- Register base = (isRegister(baseRegister) ? asRegister(baseRegister) : zr);
+ Register base = encoding.hasBase() ? asRegister(baseRegister) : null;
+ emitUncompressCode(masm, inputRegister, resultRegister, base, encoding.getShift(), nonNull);
+ }
+
+ public static void emitUncompressCode(AArch64MacroAssembler masm, Register inputRegister, Register resReg, Register baseReg, int shift, boolean nonNull) {
// result = base + (ptr << shift)
- if (nonNull) {
- masm.add(64, resultRegister, base, ptr, AArch64Assembler.ShiftType.LSL, encoding.getShift());
- } else if (!encoding.hasBase()) {
- masm.add(64, resultRegister, zr, ptr, AArch64Assembler.ShiftType.LSL, encoding.getShift());
+ if (nonNull || baseReg == null) {
+ masm.add(64, resReg, baseReg == null ? zr : baseReg, inputRegister, AArch64Assembler.ShiftType.LSL, shift);
} else {
// if ptr is null it has to be null after decompression
Label done = new Label();
- if (!resultRegister.equals(ptr)) {
- masm.mov(32, resultRegister, ptr);
+ if (!resReg.equals(inputRegister)) {
+ masm.mov(32, resReg, inputRegister);
}
- masm.cbz(32, resultRegister, done);
- masm.add(64, resultRegister, base, resultRegister, AArch64Assembler.ShiftType.LSL, encoding.getShift());
+ masm.cbz(32, resReg, done);
+ masm.add(64, resReg, baseReg, resReg, AArch64Assembler.ShiftType.LSL, shift);
masm.bind(done);
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/StubAVXTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/StubAVXTest.java
index b72925f67eb..0ebadb778ef 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/StubAVXTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/StubAVXTest.java
@@ -65,6 +65,7 @@ import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.Value;
+import org.graalvm.compiler.hotspot.HotSpotBackend;
public class StubAVXTest extends LIRTest {
@@ -72,6 +73,10 @@ public class StubAVXTest extends LIRTest {
public void checkAMD64() {
Assume.assumeTrue("skipping AMD64 specific test", getTarget().arch instanceof AMD64);
Assume.assumeTrue("skipping AVX test", ((AMD64) getTarget().arch).getFeatures().contains(CPUFeature.AVX));
+ if (getBackend() instanceof HotSpotBackend) {
+ HotSpotBackend backend = (HotSpotBackend) getBackend();
+ Assume.assumeTrue("skipping because of MaxVectorSize", backend.getRuntime().getVMConfig().maxVectorSize >= 32);
+ }
}
private static final DataPointerConstant avxConstant = new ArrayDataPointerConstant(new float[]{1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f}, 32);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java
index d2d94c95da2..e14ed05b01c 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java
@@ -204,7 +204,7 @@ public class AMD64HotSpotAddressLowering extends AMD64CompressAddressLowering {
if (init >= 0 && extremum >= 0) {
long shortestTrip = (extremum - init) / stride + 1;
- if (shortestTrip == countedLoopInfo.constantMaxTripCount()) {
+ if (countedLoopInfo.constantMaxTripCount().equals(shortestTrip)) {
return graph.unique(new ZeroExtendNode(input, INT_BITS, ADDRESS_BITS, true));
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java
index a12c5c472b6..552a88e4c7b 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java
@@ -25,13 +25,13 @@ package org.graalvm.compiler.hotspot.amd64;
import static jdk.vm.ci.amd64.AMD64.rbp;
import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
import static org.graalvm.compiler.hotspot.HotSpotBackend.INITIALIZE_KLASS_BY_SYMBOL;
+import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_DYNAMIC_INVOKE;
import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_KLASS_BY_SYMBOL;
import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_METHOD_BY_SYMBOL_AND_LOAD_COUNTERS;
import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_STRING_BY_SYMBOL;
-import static org.graalvm.compiler.hotspot.HotSpotBackend.RESOLVE_DYNAMIC_INVOKE;
-import static org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction.RESOLVE;
import static org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction.INITIALIZE;
import static org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction.LOAD_COUNTERS;
+import static org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction.RESOLVE;
import java.util.ArrayList;
import java.util.List;
@@ -115,7 +115,7 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSp
}
private AMD64HotSpotLIRGenerator(HotSpotProviders providers, GraalHotSpotVMConfig config, LIRGenerationResult lirGenRes, BackupSlotProvider backupSlotProvider) {
- this(new AMD64HotSpotLIRKindTool(), new AMD64HotSpotArithmeticLIRGenerator(), new AMD64HotSpotMoveFactory(backupSlotProvider), providers, config, lirGenRes);
+ this(new AMD64HotSpotLIRKindTool(), new AMD64ArithmeticLIRGenerator(new AMD64HotSpotMaths()), new AMD64HotSpotMoveFactory(backupSlotProvider), providers, config, lirGenRes);
}
protected AMD64HotSpotLIRGenerator(LIRKindTool lirKindTool, AMD64ArithmeticLIRGenerator arithmeticLIRGen, MoveFactory moveFactory, HotSpotProviders providers, GraalHotSpotVMConfig config,
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotArithmeticLIRGenerator.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotMaths.java
similarity index 55%
rename from src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotArithmeticLIRGenerator.java
rename to src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotMaths.java
index 3e011324fd1..feff123da43 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotArithmeticLIRGenerator.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotMaths.java
@@ -31,49 +31,55 @@ import static org.graalvm.compiler.hotspot.amd64.AMD64HotSpotMathIntrinsicOp.Int
import org.graalvm.compiler.core.amd64.AMD64ArithmeticLIRGenerator;
import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.hotspot.HotSpotBackend.Options;
import org.graalvm.compiler.lir.Variable;
+import org.graalvm.compiler.lir.gen.LIRGenerator;
import jdk.vm.ci.meta.Value;
-public class AMD64HotSpotArithmeticLIRGenerator extends AMD64ArithmeticLIRGenerator {
+/**
+ * Lowering of selected {@link Math} routines that depends on the value of
+ * {@link Options#GraalArithmeticStubs}.
+ */
+public class AMD64HotSpotMaths implements AMD64ArithmeticLIRGenerator.Maths {
@Override
- public Value emitMathLog(Value input, boolean base10) {
- if (GraalArithmeticStubs.getValue(getOptions())) {
- return super.emitMathLog(input, base10);
+ public Variable emitLog(LIRGenerator gen, Value input, boolean base10) {
+ if (GraalArithmeticStubs.getValue(gen.getResult().getLIR().getOptions())) {
+ return null;
}
- Variable result = getLIRGen().newVariable(LIRKind.combine(input));
- getLIRGen().append(new AMD64HotSpotMathIntrinsicOp(base10 ? LOG10 : LOG, result, getLIRGen().asAllocatable(input)));
+ Variable result = gen.newVariable(LIRKind.combine(input));
+ gen.append(new AMD64HotSpotMathIntrinsicOp(base10 ? LOG10 : LOG, result, gen.asAllocatable(input)));
return result;
}
@Override
- public Value emitMathCos(Value input) {
- if (GraalArithmeticStubs.getValue(getOptions())) {
- return super.emitMathCos(input);
+ public Variable emitCos(LIRGenerator gen, Value input) {
+ if (GraalArithmeticStubs.getValue(gen.getResult().getLIR().getOptions())) {
+ return null;
}
- Variable result = getLIRGen().newVariable(LIRKind.combine(input));
- getLIRGen().append(new AMD64HotSpotMathIntrinsicOp(COS, result, getLIRGen().asAllocatable(input)));
+ Variable result = gen.newVariable(LIRKind.combine(input));
+ gen.append(new AMD64HotSpotMathIntrinsicOp(COS, result, gen.asAllocatable(input)));
return result;
}
@Override
- public Value emitMathSin(Value input) {
- if (GraalArithmeticStubs.getValue(getOptions())) {
- return super.emitMathSin(input);
+ public Variable emitSin(LIRGenerator gen, Value input) {
+ if (GraalArithmeticStubs.getValue(gen.getResult().getLIR().getOptions())) {
+ return null;
}
- Variable result = getLIRGen().newVariable(LIRKind.combine(input));
- getLIRGen().append(new AMD64HotSpotMathIntrinsicOp(SIN, result, getLIRGen().asAllocatable(input)));
+ Variable result = gen.newVariable(LIRKind.combine(input));
+ gen.append(new AMD64HotSpotMathIntrinsicOp(SIN, result, gen.asAllocatable(input)));
return result;
}
@Override
- public Value emitMathTan(Value input) {
- if (GraalArithmeticStubs.getValue(getOptions())) {
- return super.emitMathTan(input);
+ public Variable emitTan(LIRGenerator gen, Value input) {
+ if (GraalArithmeticStubs.getValue(gen.getResult().getLIR().getOptions())) {
+ return null;
}
- Variable result = getLIRGen().newVariable(LIRKind.combine(input));
- getLIRGen().append(new AMD64HotSpotMathIntrinsicOp(TAN, result, getLIRGen().asAllocatable(input)));
+ Variable result = gen.newVariable(LIRKind.combine(input));
+ gen.append(new AMD64HotSpotMathIntrinsicOp(TAN, result, gen.asAllocatable(input)));
return result;
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotMove.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotMove.java
index 2175bec863c..b57dd58b4f2 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotMove.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotMove.java
@@ -187,21 +187,26 @@ public class SPARCHotSpotMove {
public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
Register inputRegister = asRegister(input);
Register resReg = asRegister(result);
+ Register baseReg = encoding.hasBase() ? asRegister(baseRegister) : null;
+ emitUncompressCode(masm, inputRegister, resReg, baseReg, encoding.getShift(), nonNull);
+ }
+
+ public static void emitUncompressCode(SPARCMacroAssembler masm, Register inputRegister, Register resReg, Register baseReg, int shift, boolean nonNull) {
Register secondaryInput;
- if (encoding.getShift() != 0) {
- masm.sll(inputRegister, encoding.getShift(), resReg);
+ if (shift != 0) {
+ masm.sll(inputRegister, shift, resReg);
secondaryInput = resReg;
} else {
secondaryInput = inputRegister;
}
- if (encoding.hasBase()) {
+ if (baseReg != null) {
if (nonNull) {
- masm.add(secondaryInput, asRegister(baseRegister), resReg);
+ masm.add(secondaryInput, baseReg, resReg);
} else {
Label done = new Label();
BPR.emit(masm, Rc_z, ANNUL, PREDICT_TAKEN, secondaryInput, done);
- masm.add(asRegister(baseRegister), secondaryInput, resReg);
+ masm.add(baseReg, secondaryInput, resReg);
masm.bind(done);
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java
index 4572bd40d45..146296fe83d 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, 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
@@ -553,6 +553,7 @@ public final class CompileTheWorld {
classFileCounter++;
if (className.startsWith("jdk.management.") ||
+ className.startsWith("jdk.internal.cmm.*") ||
// GR-5881: The class initializer for
// sun.tools.jconsole.OutputViewer
// spawns non-daemon threads for redirecting sysout and syserr.
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotLazyInitializationTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotLazyInitializationTest.java
new file mode 100644
index 00000000000..d3beddc5a60
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotLazyInitializationTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 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.test;
+
+import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.hotspot.meta.HotSpotClassInitializationPlugin;
+import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+public class HotSpotLazyInitializationTest extends GraalCompilerTest {
+
+ HotSpotClassInitializationPlugin classInitPlugin = new HotSpotClassInitializationPlugin();
+
+ @Override
+ protected Plugins getDefaultGraphBuilderPlugins() {
+ Plugins plugins = super.getDefaultGraphBuilderPlugins();
+ plugins.setClassInitializationPlugin(classInitPlugin);
+ return plugins;
+ }
+
+ static boolean initializerRun = false;
+
+ static class X {
+ static {
+ initializerRun = true;
+ }
+
+ static void foo() {
+ }
+ }
+
+ public static void invokeStatic() {
+ X.foo();
+ }
+
+ // If constant pool can do eager resolve without eager initialization, then fail if the compiler
+ // causes the static initializer to run.
+ private void test(String name) {
+ ResolvedJavaMethod method = getResolvedJavaMethod(name);
+ Assume.assumeTrue("skipping for old JVMCI", classInitPlugin.supportsLazyInitialization(method.getConstantPool()));
+ parseEager(method, AllowAssumptions.NO);
+ Assert.assertFalse(initializerRun);
+ }
+
+ @Test
+ public void test1() {
+ test("invokeStatic");
+ }
+
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilerConfigurationFactory.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilerConfigurationFactory.java
index 0a3a667ff1c..18d6cb873f2 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilerConfigurationFactory.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilerConfigurationFactory.java
@@ -24,17 +24,25 @@ package org.graalvm.compiler.hotspot;
import static jdk.vm.ci.common.InitTimer.timer;
+import java.net.URL;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.graalvm.collections.EconomicMap;
import org.graalvm.compiler.debug.GraalError;
+import org.graalvm.compiler.debug.TTY;
+import org.graalvm.compiler.lir.phases.LIRPhase;
+import org.graalvm.compiler.lir.phases.LIRPhaseSuite;
+import org.graalvm.compiler.options.EnumOptionKey;
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.BasePhase;
+import org.graalvm.compiler.phases.PhaseSuite;
import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
import org.graalvm.compiler.serviceprovider.GraalServices;
@@ -48,12 +56,20 @@ import jdk.vm.ci.common.InitTimer;
*/
public abstract class CompilerConfigurationFactory implements Comparable {
+ enum ShowConfigurationLevel {
+ none,
+ info,
+ verbose
+ }
+
static class Options {
// @formatter:off
@Option(help = "Names the Graal compiler configuration to use. If ommitted, the compiler configuration " +
"with the highest auto-selection priority is used. To see the set of available configurations, " +
"supply the value 'help' to this option.", type = OptionType.Expert)
public static final OptionKey CompilerConfiguration = new OptionKey<>(null);
+ @Option(help = "Writes to the VM log information about the Graal compiler configuration selected.", type = OptionType.User)
+ public static final OptionKey ShowConfiguration = new EnumOptionKey<>(ShowConfigurationLevel.none);
// @formatter:on
}
@@ -192,6 +208,52 @@ public abstract class CompilerConfigurationFactory implements Comparable List phaseNames(PhaseSuite suite) {
+ Collection> phases = suite.getPhases();
+ List res = new ArrayList<>(phases.size());
+ for (BasePhase> phase : phases) {
+ res.add(phase.contractorName());
+ }
+ Collections.sort(res);
+ return res;
+ }
+
+ private static List phaseNames(LIRPhaseSuite suite) {
+ List> phases = suite.getPhases();
+ List res = new ArrayList<>(phases.size());
+ for (LIRPhase> phase : phases) {
+ res.add(phase.getClass().getName());
+ }
+ Collections.sort(res);
+ return res;
+ }
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java
index 565d92a0a1f..0622f1e7efd 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java
@@ -45,8 +45,9 @@ public class GraalHotSpotVMConfig extends HotSpotVMConfigAccess {
*/
public static final GraalHotSpotVMConfig INJECTED_VMCONFIG = null;
+ // this uses `1.9` which will give the correct result with `1.9`, `9`, `10` etc.
private final boolean isJDK8 = System.getProperty("java.specification.version").compareTo("1.9") < 0;
- private final int JDKVersion = isJDK8 ? 8 : Integer.parseInt(System.getProperty("java.specification.version"));
+ private final int jdkVersion = isJDK8 ? 8 : Integer.parseInt(System.getProperty("java.specification.version"));
public final String osName = getHostOSName();
public final String osArch = getHostArchitectureName();
public final boolean windowsOs = System.getProperty("os.name", "").startsWith("Windows");
@@ -160,6 +161,7 @@ public class GraalHotSpotVMConfig extends HotSpotVMConfigAccess {
public final boolean forceUnreachable = getFlag("ForceUnreachable", Boolean.class);
public final int codeSegmentSize = getFlag("CodeCacheSegmentSize", Integer.class);
public final boolean foldStableValues = getFlag("FoldStableValues", Boolean.class);
+ public final int maxVectorSize = getFlag("MaxVectorSize", Integer.class);
public final boolean useTLAB = getFlag("UseTLAB", Boolean.class);
public final boolean useBiasedLocking = getFlag("UseBiasedLocking", Boolean.class);
@@ -555,12 +557,10 @@ public class GraalHotSpotVMConfig extends HotSpotVMConfigAccess {
public final int logOfHRGrainBytes = getFieldValue("HeapRegion::LogOfHRGrainBytes", Integer.class, "int");
- public final byte dirtyCardValue = JDKVersion >= 11 ? getConstant("CardTable::dirty_card", Byte.class) :
- (JDKVersion > 8 ? getConstant("CardTableModRefBS::dirty_card", Byte.class) :
- getFieldValue("CompilerToVM::Data::dirty_card", Byte.class, "int"));
- public final byte g1YoungCardValue = JDKVersion >= 11 ? getConstant("G1CardTable::g1_young_gen", Byte.class) :
- (JDKVersion > 8 ? getConstant("G1SATBCardTableModRefBS::g1_young_gen", Byte.class) :
- getFieldValue("CompilerToVM::Data::g1_young_card", Byte.class, "int"));
+ public final byte dirtyCardValue = jdkVersion >= 11 ? getConstant("CardTable::dirty_card", Byte.class)
+ : (jdkVersion > 8 ? getConstant("CardTableModRefBS::dirty_card", Byte.class) : getFieldValue("CompilerToVM::Data::dirty_card", Byte.class, "int"));
+ public final byte g1YoungCardValue = jdkVersion >= 11 ? getConstant("G1CardTable::g1_young_gen", Byte.class)
+ : (jdkVersion > 8 ? getConstant("G1SATBCardTableModRefBS::g1_young_gen", Byte.class) : getFieldValue("CompilerToVM::Data::g1_young_card", Byte.class, "int"));
public final long cardtableStartAddress = getFieldValue("CompilerToVM::Data::cardtable_start_address", Long.class, "jbyte*");
public final int cardtableShift = getFieldValue("CompilerToVM::Data::cardtable_shift", Integer.class, "int");
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java
index 68904ddfa12..8b358c1f249 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java
@@ -91,7 +91,7 @@ public abstract class HotSpotBackend extends Backend implements FrameMap.Referen
public static class Options {
// @formatter:off
@Option(help = "Use Graal arithmetic stubs instead of HotSpot stubs where possible")
- public static final OptionKey GraalArithmeticStubs = new OptionKey<>(true);
+ public static final OptionKey GraalArithmeticStubs = new OptionKey<>(false); // GR-8276
@Option(help = "Enables instruction profiling on assembler level. Valid values are a comma separated list of supported instructions." +
" Compare with subclasses of Assembler.InstructionCounter.", type = OptionType.Debug)
public static final OptionKey ASMInstructionProfiling = new OptionKey<>(null);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCompiledCodeBuilder.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCompiledCodeBuilder.java
index 3bba3fbfbcf..825f2822a69 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCompiledCodeBuilder.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCompiledCodeBuilder.java
@@ -22,6 +22,8 @@
*/
package org.graalvm.compiler.hotspot;
+import static org.graalvm.util.CollectionsUtil.anyMatch;
+
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
@@ -37,9 +39,9 @@ import org.graalvm.compiler.code.CompilationResult;
import org.graalvm.compiler.code.CompilationResult.CodeAnnotation;
import org.graalvm.compiler.code.CompilationResult.CodeComment;
import org.graalvm.compiler.code.CompilationResult.JumpTable;
-import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.code.DataSection;
import org.graalvm.compiler.code.SourceMapping;
+import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.NodeSourcePosition;
import jdk.vm.ci.code.CodeCacheProvider;
@@ -55,7 +57,6 @@ import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
import jdk.vm.ci.hotspot.HotSpotCompiledCode;
import jdk.vm.ci.hotspot.HotSpotCompiledCode.Comment;
import jdk.vm.ci.hotspot.HotSpotCompiledNmethod;
-import jdk.vm.ci.hotspot.HotSpotObjectConstant;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.meta.Assumptions.Assumption;
import jdk.vm.ci.meta.ResolvedJavaMethod;
@@ -210,16 +211,31 @@ public class HotSpotCompiledCodeBuilder {
sites.addAll(target.getDataPatches());
sites.addAll(target.getMarks());
- /*
- * Translate the source mapping into appropriate info points. In HotSpot only one position
- * can really be represented and recording the end PC seems to give the best results and
- * corresponds with what C1 and C2 do.
- */
if (codeCache.shouldDebugNonSafepoints()) {
+ /*
+ * Translate the source mapping into appropriate info points. In HotSpot only one
+ * position can really be represented and recording the end PC seems to give the best
+ * results and corresponds with what C1 and C2 do. HotSpot doesn't like to see these
+ * unless -XX:+DebugNonSafepoints is enabled, so don't emit them in that case.
+ */
+ List sourcePositionSites = new ArrayList<>();
for (SourceMapping source : target.getSourceMappings()) {
- sites.add(new Infopoint(source.getEndOffset(), new DebugInfo(source.getSourcePosition()), InfopointReason.BYTECODE_POSITION));
- assert verifySourcePositionReceivers(source.getSourcePosition());
+ NodeSourcePosition sourcePosition = source.getSourcePosition();
+ assert sourcePosition.verify();
+ sourcePosition = sourcePosition.trim();
+ /*
+ * Don't add BYTECODE_POSITION info points that would potentially create conflicts.
+ * Under certain conditions the site's pc is not the pc that gets recorded by
+ * HotSpot (see @code {CodeInstaller::site_Call}). So, avoid adding any source
+ * positions that can potentially map to the same pc. To do that make sure that the
+ * source mapping doesn't contain a pc of any important Site.
+ */
+ if (sourcePosition != null && !anyMatch(sites, s -> source.contains(s.pcOffset))) {
+ sourcePositionSites.add(new Infopoint(source.getEndOffset(), new DebugInfo(sourcePosition), InfopointReason.BYTECODE_POSITION));
+
+ }
}
+ sites.addAll(sourcePositionSites);
}
SiteComparator c = new SiteComparator();
@@ -245,18 +261,4 @@ public class HotSpotCompiledCodeBuilder {
}
return sites.toArray(new Site[sites.size()]);
}
-
- /**
- * Verifies that the captured receiver type agrees with the declared type of the method.
- */
- private static boolean verifySourcePositionReceivers(NodeSourcePosition start) {
- NodeSourcePosition pos = start;
- while (pos != null) {
- if (pos.getReceiver() != null) {
- assert ((HotSpotObjectConstant) pos.getReceiver()).asObject(pos.getMethod().getDeclaringClass()) != null;
- }
- pos = pos.getCaller();
- }
- return true;
- }
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java
index 7146ad77271..b5c9ff861fc 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompilerFactory.java
@@ -26,8 +26,8 @@ import static jdk.vm.ci.common.InitTimer.timer;
import static org.graalvm.compiler.hotspot.HotSpotGraalOptionValues.GRAAL_OPTION_PROPERTY_PREFIX;
import java.io.PrintStream;
-import java.util.Map;
import java.util.Collections;
+import java.util.Map;
import org.graalvm.compiler.debug.MethodFilter;
import org.graalvm.compiler.options.Option;
@@ -36,6 +36,7 @@ import org.graalvm.compiler.options.OptionType;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.options.OptionsParser;
import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
+import org.graalvm.compiler.serviceprovider.JDK9Method;
import jdk.vm.ci.common.InitTimer;
import jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory;
@@ -48,6 +49,22 @@ public final class HotSpotGraalCompilerFactory extends HotSpotJVMCICompilerFacto
private static MethodFilter[] graalCompileOnlyFilter;
private static boolean compileGraalWithC1Only;
+ /**
+ * Module containing {@link HotSpotJVMCICompilerFactory}.
+ */
+ private Object jvmciModule;
+
+ /**
+ * Module containing {@link HotSpotGraalCompilerFactory}.
+ */
+ private Object graalModule;
+
+ /**
+ * Module containing the {@linkplain CompilerConfigurationFactory#selectFactory selected}
+ * configuration.
+ */
+ private Object compilerConfigurationModule;
+
private final HotSpotGraalJVMCIServiceLocator locator;
HotSpotGraalCompilerFactory(HotSpotGraalJVMCIServiceLocator locator) {
@@ -70,6 +87,10 @@ public final class HotSpotGraalCompilerFactory extends HotSpotJVMCICompilerFacto
assert options == null : "cannot select " + getClass() + " service more than once";
options = HotSpotGraalOptionValues.HOTSPOT_OPTIONS;
initializeGraalCompilePolicyFields(options);
+ if (!JDK9Method.Java8OrEarlier) {
+ jvmciModule = JDK9Method.getModule(HotSpotJVMCICompilerFactory.class);
+ graalModule = JDK9Method.getModule(HotSpotGraalCompilerFactory.class);
+ }
/*
* 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.
@@ -102,7 +123,9 @@ public final class HotSpotGraalCompilerFactory extends HotSpotJVMCICompilerFacto
@Option(help = "In tiered mode compile Graal and JVMCI using optimized first tier code.", type = OptionType.Expert)
public static final OptionKey CompileGraalWithC1Only = new OptionKey<>(true);
- @Option(help = "A method filter selecting what should be compiled by Graal. All other requests will be reduced to CompilationLevel.Simple.", type = OptionType.Expert)
+ @Option(help = "A filter applied to a method the VM has selected for compilation by Graal. " +
+ "A method not matching the filter is redirected to a lower tier compiler. " +
+ "The filter format is the same as for the MethodFilter option.", type = OptionType.Expert)
public static final OptionKey GraalCompileOnly = new OptionKey<>(null);
// @formatter:on
@@ -110,7 +133,11 @@ public final class HotSpotGraalCompilerFactory extends HotSpotJVMCICompilerFacto
@Override
public HotSpotGraalCompiler createCompiler(JVMCIRuntime runtime) {
- HotSpotGraalCompiler compiler = createCompiler(runtime, options, CompilerConfigurationFactory.selectFactory(null, options));
+ CompilerConfigurationFactory factory = CompilerConfigurationFactory.selectFactory(null, options);
+ if (!JDK9Method.Java8OrEarlier) {
+ compilerConfigurationModule = JDK9Method.getModule(factory.getClass());
+ }
+ HotSpotGraalCompiler compiler = createCompiler(runtime, options, factory);
// Only the HotSpotGraalRuntime associated with the compiler created via
// jdk.vm.ci.runtime.JVMCIRuntime.getCompiler() is registered for receiving
// VM events.
@@ -160,15 +187,54 @@ public final class HotSpotGraalCompilerFactory extends HotSpotJVMCICompilerFacto
assert HotSpotGraalCompilerFactory.class.getName().equals("org.graalvm.compiler.hotspot.HotSpotGraalCompilerFactory");
}
+ static final ClassLoader JVMCI_LOADER = HotSpotGraalCompilerFactory.class.getClassLoader();
+
/*
* This method is static so it can be exercised during initialization.
*/
- private static CompilationLevel adjustCompilationLevelInternal(Class> declaringClass, String name, String signature, CompilationLevel level) {
+ private CompilationLevel adjustCompilationLevelInternal(Class> declaringClass, String name, String signature, CompilationLevel level) {
if (compileGraalWithC1Only) {
if (level.ordinal() > CompilationLevel.Simple.ordinal()) {
- String declaringClassName = declaringClass.getName();
- if (declaringClassName.startsWith("jdk.vm.ci") || declaringClassName.startsWith("org.graalvm") || declaringClassName.startsWith("com.oracle.graal")) {
- return CompilationLevel.Simple;
+ if (JDK9Method.Java8OrEarlier) {
+ if (JVMCI_LOADER != null) {
+ // When running with +UseJVMCIClassLoader all classes in
+ // the JVMCI loader should be compiled with C1.
+ try {
+ if (declaringClass.getClassLoader() == JVMCI_LOADER) {
+ return CompilationLevel.Simple;
+ }
+ } catch (SecurityException e) {
+ // This is definitely not a JVMCI or Graal class
+ }
+ } else {
+ // JVMCI and Graal are on the bootclasspath so match based on the package.
+ String declaringClassName = declaringClass.getName();
+ if (declaringClassName.startsWith("jdk.vm.ci")) {
+ return CompilationLevel.Simple;
+ }
+ if (declaringClassName.startsWith("org.graalvm.") &&
+ (declaringClassName.startsWith("org.graalvm.compiler.") ||
+ declaringClassName.startsWith("org.graalvm.collections.") ||
+ declaringClassName.startsWith("org.graalvm.compiler.word.") ||
+ declaringClassName.startsWith("org.graalvm.graphio."))) {
+ return CompilationLevel.Simple;
+ }
+ if (declaringClassName.startsWith("com.oracle.graal") &&
+ (declaringClassName.startsWith("com.oracle.graal.enterprise") ||
+ declaringClassName.startsWith("com.oracle.graal.vector") ||
+ declaringClassName.startsWith("com.oracle.graal.asm"))) {
+ return CompilationLevel.Simple;
+ }
+ }
+ } else {
+ try {
+ Object module = JDK9Method.getModule(declaringClass);
+ if (jvmciModule == module || graalModule == module || compilerConfigurationModule == module) {
+ return CompilationLevel.Simple;
+ }
+ } catch (Throwable e) {
+ throw new InternalError(e);
+ }
}
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/NodeCostDumpUtil.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/NodeCostDumpUtil.java
index ad48b0e2956..7ae2198513f 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/NodeCostDumpUtil.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/NodeCostDumpUtil.java
@@ -24,7 +24,6 @@ package org.graalvm.compiler.hotspot;
import java.io.File;
import java.io.IOException;
-import java.lang.reflect.Field;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
@@ -114,14 +113,9 @@ public class NodeCostDumpUtil {
}
System.err.printf("Loaded %s node classes...\n", nodeClasses.size());
List> nc = new ArrayList<>();
- for (Class> nodeClass : nodeClasses) {
- Field f;
+ for (Class> c : nodeClasses) {
try {
- f = nodeClass.getField("TYPE");
- f.setAccessible(true);
- Object val = f.get(null);
- NodeClass> nodeType = (NodeClass>) val;
- nc.add(nodeType);
+ nc.add(NodeClass.get(c));
} catch (Throwable t) {
// Silently ignore problems here
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/lir/VerifyMaxRegisterSizePhase.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/lir/VerifyMaxRegisterSizePhase.java
new file mode 100644
index 00000000000..2b249964d1c
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/lir/VerifyMaxRegisterSizePhase.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 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.lir;
+
+import java.util.EnumSet;
+
+import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
+import org.graalvm.compiler.lir.LIR;
+import org.graalvm.compiler.lir.LIRInstruction;
+import org.graalvm.compiler.lir.gen.LIRGenerationResult;
+import org.graalvm.compiler.lir.phases.PostAllocationOptimizationPhase;
+
+import jdk.vm.ci.code.TargetDescription;
+import static jdk.vm.ci.code.ValueUtil.isRegister;
+import jdk.vm.ci.meta.Value;
+import org.graalvm.compiler.lir.LIRInstruction.OperandFlag;
+import org.graalvm.compiler.lir.LIRInstruction.OperandMode;
+
+/**
+ * Checks that no registers exceed the MaxVectorSize flag from the VM config.
+ */
+public final class VerifyMaxRegisterSizePhase extends PostAllocationOptimizationPhase {
+
+ private final int maxVectorSize;
+
+ public VerifyMaxRegisterSizePhase(int maxVectorSize) {
+ this.maxVectorSize = maxVectorSize;
+ }
+
+ @Override
+ protected void run(TargetDescription target, LIRGenerationResult lirGenRes, PostAllocationOptimizationContext context) {
+ LIR lir = lirGenRes.getLIR();
+ for (AbstractBlockBase> block : lir.getControlFlowGraph().getBlocks()) {
+ verifyBlock(lir, block);
+ }
+ }
+
+ protected void verifyBlock(LIR lir, AbstractBlockBase> block) {
+ for (LIRInstruction inst : lir.getLIRforBlock(block)) {
+ verifyInstruction(inst);
+ }
+ }
+
+ protected void verifyInstruction(LIRInstruction inst) {
+ inst.visitEachInput(this::verifyOperands);
+ inst.visitEachOutput(this::verifyOperands);
+ inst.visitEachAlive(this::verifyOperands);
+ inst.visitEachTemp(this::verifyOperands);
+ }
+
+ @SuppressWarnings("unused")
+ protected void verifyOperands(LIRInstruction instruction, Value value, OperandMode mode, EnumSet flags) {
+ if (isRegister(value)) {
+ assert value.getPlatformKind().getSizeInBytes() <= maxVectorSize : "value " + value + " exceeds MaxVectorSize " + maxVectorSize;
+ }
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotClassInitializationPlugin.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotClassInitializationPlugin.java
index f34dba44e97..05a21341e74 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotClassInitializationPlugin.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotClassInitializationPlugin.java
@@ -25,6 +25,7 @@ package org.graalvm.compiler.hotspot.meta;
import org.graalvm.compiler.core.common.type.ObjectStamp;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.hotspot.nodes.aot.InitializeKlassNode;
import org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantNode;
import org.graalvm.compiler.nodes.ConstantNode;
@@ -37,6 +38,11 @@ import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.ConstantPool;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
public final class HotSpotClassInitializationPlugin implements ClassInitializationPlugin {
@Override
@@ -73,4 +79,47 @@ public final class HotSpotClassInitializationPlugin implements ClassInitializati
result.setStateBefore(frameState);
return result;
}
+
+ private static final Class extends ConstantPool> hscp;
+ private static final MethodHandle loadReferencedTypeIIZMH;
+
+ static {
+ MethodHandle m = null;
+ Class extends ConstantPool> c = null;
+ try {
+ c = Class.forName("jdk.vm.ci.hotspot.HotSpotConstantPool").asSubclass(ConstantPool.class);
+ m = MethodHandles.lookup().findVirtual(c, "loadReferencedType", MethodType.methodType(void.class, int.class, int.class, boolean.class));
+ } catch (Exception e) {
+ }
+ loadReferencedTypeIIZMH = m;
+ hscp = c;
+ }
+
+ private static boolean isHotSpotConstantPool(ConstantPool cp) {
+ // jdk.vm.ci.hotspot.HotSpotConstantPool is final, so we can
+ // directly compare Classes.
+ return cp.getClass() == hscp;
+ }
+
+ @Override
+ public boolean supportsLazyInitialization(ConstantPool cp) {
+ if (loadReferencedTypeIIZMH != null && isHotSpotConstantPool(cp)) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void loadReferencedType(GraphBuilderContext builder, ConstantPool cp, int cpi, int opcode) {
+ if (loadReferencedTypeIIZMH != null && isHotSpotConstantPool(cp)) {
+ try {
+ loadReferencedTypeIIZMH.invoke(cp, cpi, opcode, false);
+ } catch (Throwable t) {
+ throw GraalError.shouldNotReachHere(t);
+ }
+ } else {
+ cp.loadReferencedType(cpi, opcode);
+ }
+ }
+
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java
index 94088d33e27..cdf8b8f8e5e 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java
@@ -234,7 +234,7 @@ public class HotSpotGraphBuilderPlugins {
b.addPush(JavaKind.Object, object);
} else {
FixedGuardNode fixedGuard = b.add(new FixedGuardNode(condition, DeoptimizationReason.ClassCastException, DeoptimizationAction.InvalidateReprofile, false));
- b.addPush(JavaKind.Object, new DynamicPiNode(object, fixedGuard, javaClass));
+ b.addPush(JavaKind.Object, DynamicPiNode.create(b.getAssumptions(), b.getConstantReflection(), object, fixedGuard, javaClass));
}
return true;
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotInvocationPlugins.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotInvocationPlugins.java
index ba8fcde9f16..5d7aaa2bfd3 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotInvocationPlugins.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotInvocationPlugins.java
@@ -24,6 +24,7 @@ package org.graalvm.compiler.hotspot.meta;
import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier;
+import java.lang.invoke.MethodHandle;
import java.lang.reflect.Type;
import java.util.Set;
@@ -129,7 +130,7 @@ final class HotSpotInvocationPlugins extends InvocationPlugins {
ClassLoader cl = javaClass.getClassLoader();
return cl == null || cl == getClass().getClassLoader() || cl == extLoader;
} else {
- Object module = JDK9Method.getModule.invoke(javaClass);
+ Object module = JDK9Method.getModule(javaClass);
return trustedModules.contains(module);
}
}
@@ -148,34 +149,43 @@ final class HotSpotInvocationPlugins extends InvocationPlugins {
}
}
+ /**
+ * Gets the set of modules whose methods can be intrinsified. This set is the module owning the
+ * class of {@code compilerConfiguration} and all its dependencies.
+ */
private static EconomicSet
*/
@SuppressWarnings("try")
- private static StructuredGraph parseBytecodes(ResolvedJavaMethod method, HighTierContext context, CanonicalizerPhase canonicalizer, StructuredGraph caller) {
+ private static StructuredGraph parseBytecodes(ResolvedJavaMethod method, HighTierContext context, CanonicalizerPhase canonicalizer, StructuredGraph caller, boolean trackNodeSourcePosition) {
DebugContext debug = caller.getDebug();
- StructuredGraph newGraph = new StructuredGraph.Builder(caller.getOptions(), debug, AllowAssumptions.ifNonNull(caller.getAssumptions())).method(method).build();
+ StructuredGraph newGraph = new StructuredGraph.Builder(caller.getOptions(), debug, AllowAssumptions.ifNonNull(caller.getAssumptions())).method(method).trackNodeSourcePosition(
+ trackNodeSourcePosition).build();
try (DebugContext.Scope s = debug.scope("InlineGraph", newGraph)) {
if (!caller.isUnsafeAccessTrackingEnabled()) {
newGraph.disableUnsafeAccessTracking();
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/GreedyInliningPolicy.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/GreedyInliningPolicy.java
index 0976740f586..d49985e394a 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/GreedyInliningPolicy.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/GreedyInliningPolicy.java
@@ -69,17 +69,17 @@ public class GreedyInliningPolicy extends AbstractInliningPolicy {
final double relevance = invocation.relevance();
if (InlineEverything.getValue(options)) {
- InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "inline everything");
+ InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "inline everything");
return true;
}
if (isIntrinsic(replacements, info)) {
- InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "intrinsic");
+ InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "intrinsic");
return true;
}
if (info.shouldInline()) {
- InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "forced inlining");
+ InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "forced inlining");
return true;
}
@@ -88,13 +88,13 @@ public class GreedyInliningPolicy extends AbstractInliningPolicy {
int lowLevelGraphSize = previousLowLevelGraphSize(info);
if (SmallCompiledLowLevelGraphSize.getValue(options) > 0 && lowLevelGraphSize > SmallCompiledLowLevelGraphSize.getValue(options) * inliningBonus) {
- InliningUtil.logNotInlinedMethod(info, inliningDepth, "too large previous low-level graph (low-level-nodes: %d, relevance=%f, probability=%f, bonus=%f, nodes=%d)", lowLevelGraphSize,
+ InliningUtil.traceNotInlinedMethod(info, inliningDepth, "too large previous low-level graph (low-level-nodes: %d, relevance=%f, probability=%f, bonus=%f, nodes=%d)", lowLevelGraphSize,
relevance, probability, inliningBonus, nodes);
return false;
}
if (nodes < TrivialInliningSize.getValue(options) * inliningBonus) {
- InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "trivial (relevance=%f, probability=%f, bonus=%f, nodes=%d)", relevance, probability, inliningBonus, nodes);
+ InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "trivial (relevance=%f, probability=%f, bonus=%f, nodes=%d)", relevance, probability, inliningBonus, nodes);
return true;
}
@@ -106,19 +106,19 @@ public class GreedyInliningPolicy extends AbstractInliningPolicy {
*/
double invokes = determineInvokeProbability(info);
if (LimitInlinedInvokes.getValue(options) > 0 && fullyProcessed && invokes > LimitInlinedInvokes.getValue(options) * inliningBonus) {
- InliningUtil.logNotInlinedMethod(info, inliningDepth, "callee invoke probability is too high (invokeP=%f, relevance=%f, probability=%f, bonus=%f, nodes=%d)", invokes, relevance,
+ InliningUtil.traceNotInlinedMethod(info, inliningDepth, "callee invoke probability is too high (invokeP=%f, relevance=%f, probability=%f, bonus=%f, nodes=%d)", invokes, relevance,
probability, inliningBonus, nodes);
return false;
}
double maximumNodes = computeMaximumSize(relevance, (int) (MaximumInliningSize.getValue(options) * inliningBonus));
if (nodes <= maximumNodes) {
- InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d <= %f)", relevance, probability, inliningBonus,
+ InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d <= %f)", relevance, probability, inliningBonus,
nodes, maximumNodes);
return true;
}
- InliningUtil.logNotInlinedMethod(info, inliningDepth, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d > %f)", relevance, probability, inliningBonus, nodes, maximumNodes);
+ InliningUtil.traceNotInlinedMethod(info, inliningDepth, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d > %f)", relevance, probability, inliningBonus, nodes, maximumNodes);
return false;
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InlineMethodSubstitutionsPolicy.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InlineMethodSubstitutionsPolicy.java
index 9b03288dcdc..0af953c9acb 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InlineMethodSubstitutionsPolicy.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/policy/InlineMethodSubstitutionsPolicy.java
@@ -39,7 +39,7 @@ public final class InlineMethodSubstitutionsPolicy extends InlineEverythingPolic
CallTargetNode callTarget = invocation.callee().invoke().callTarget();
if (callTarget instanceof MethodCallTargetNode) {
ResolvedJavaMethod calleeMethod = ((MethodCallTargetNode) callTarget).targetMethod();
- if (replacements.getSubstitution(calleeMethod, invocation.callee().invoke().bci()) != null) {
+ if (replacements.hasSubstitution(calleeMethod, invocation.callee().invoke().bci())) {
return true;
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/InliningData.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/InliningData.java
index f74fc8449ff..2411202e9ee 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/InliningData.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/InliningData.java
@@ -166,7 +166,7 @@ public class InliningData {
if (failureMessage == null) {
return true;
} else {
- InliningUtil.logNotInlined(invoke, inliningDepth(), method, failureMessage);
+ InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), method, failureMessage);
return false;
}
}
@@ -257,13 +257,13 @@ public class InliningData {
private InlineInfo getTypeCheckedInlineInfo(Invoke invoke, ResolvedJavaMethod targetMethod) {
JavaTypeProfile typeProfile = ((MethodCallTargetNode) invoke.callTarget()).getProfile();
if (typeProfile == null) {
- InliningUtil.logNotInlined(invoke, inliningDepth(), targetMethod, "no type profile exists");
+ InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "no type profile exists");
return null;
}
JavaTypeProfile.ProfiledType[] ptypes = typeProfile.getTypes();
if (ptypes == null || ptypes.length <= 0) {
- InliningUtil.logNotInlined(invoke, inliningDepth(), targetMethod, "no types in profile");
+ InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "no types in profile");
return null;
}
ResolvedJavaType contextType = invoke.getContextType();
@@ -272,7 +272,7 @@ public class InliningData {
OptionValues options = invoke.asNode().getOptions();
if (ptypes.length == 1 && notRecordedTypeProbability == 0) {
if (!optimisticOpts.inlineMonomorphicCalls(options)) {
- InliningUtil.logNotInlined(invoke, inliningDepth(), targetMethod, "inlining monomorphic calls is disabled");
+ InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "inlining monomorphic calls is disabled");
return null;
}
@@ -287,13 +287,13 @@ public class InliningData {
invoke.setPolymorphic(true);
if (!optimisticOpts.inlinePolymorphicCalls(options) && notRecordedTypeProbability == 0) {
- InliningUtil.logNotInlinedInvoke(invoke, inliningDepth(), targetMethod, "inlining polymorphic calls is disabled (%d types)", ptypes.length);
+ InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "inlining polymorphic calls is disabled (%d types)", ptypes.length);
return null;
}
if (!optimisticOpts.inlineMegamorphicCalls(options) && notRecordedTypeProbability > 0) {
// due to filtering impossible types, notRecordedTypeProbability can be > 0 although
// the number of types is lower than what can be recorded in a type profile
- InliningUtil.logNotInlinedInvoke(invoke, inliningDepth(), targetMethod, "inlining megamorphic calls is disabled (%d types, %f %% not recorded types)", ptypes.length,
+ InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "inlining megamorphic calls is disabled (%d types, %f %% not recorded types)", ptypes.length,
notRecordedTypeProbability * 100);
return null;
}
@@ -304,7 +304,7 @@ public class InliningData {
for (int i = 0; i < ptypes.length; i++) {
ResolvedJavaMethod concrete = ptypes[i].getType().resolveConcreteMethod(targetMethod, contextType);
if (concrete == null) {
- InliningUtil.logNotInlined(invoke, inliningDepth(), targetMethod, "could not resolve method");
+ InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "could not resolve method");
return null;
}
int index = concreteMethods.indexOf(concrete);
@@ -331,7 +331,7 @@ public class InliningData {
if (newConcreteMethods.isEmpty()) {
// No method left that is worth inlining.
- InliningUtil.logNotInlinedInvoke(invoke, inliningDepth(), targetMethod, "no methods remaining after filtering less frequent methods (%d methods previously)",
+ InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "no methods remaining after filtering less frequent methods (%d methods previously)",
concreteMethods.size());
return null;
}
@@ -341,7 +341,7 @@ public class InliningData {
}
if (concreteMethods.size() > maxMethodPerInlining) {
- InliningUtil.logNotInlinedInvoke(invoke, inliningDepth(), targetMethod, "polymorphic call with more than %d target methods", maxMethodPerInlining);
+ InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "polymorphic call with more than %d target methods", maxMethodPerInlining);
return null;
}
@@ -362,13 +362,13 @@ public class InliningData {
if (usedTypes.isEmpty()) {
// No type left that is worth checking for.
- InliningUtil.logNotInlinedInvoke(invoke, inliningDepth(), targetMethod, "no types remaining after filtering less frequent types (%d types previously)", ptypes.length);
+ InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "no types remaining after filtering less frequent types (%d types previously)", ptypes.length);
return null;
}
for (ResolvedJavaMethod concrete : concreteMethods) {
if (!checkTargetConditions(invoke, concrete)) {
- InliningUtil.logNotInlined(invoke, inliningDepth(), targetMethod, "it is a polymorphic method call and at least one invoked method cannot be inlined");
+ InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "it is a polymorphic method call and at least one invoked method cannot be inlined");
return null;
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/PhaseSuite.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/PhaseSuite.java
index 24c664d5b00..6a64d6924e4 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/PhaseSuite.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/PhaseSuite.java
@@ -95,6 +95,13 @@ public class PhaseSuite extends BasePhase {
return it;
}
+ /**
+ * Gets an unmodifiable view on the phases in this suite.
+ */
+ public List> getPhases() {
+ return Collections.unmodifiableList(phases);
+ }
+
/**
* Returns a {@link ListIterator} at the position of the first phase which is an instance of
* {@code phaseClass} or null if no such phase can be found.
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/contract/VerifyNodeCosts.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/contract/VerifyNodeCosts.java
index 0047dc97027..fec3f7e7807 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/contract/VerifyNodeCosts.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/contract/VerifyNodeCosts.java
@@ -22,7 +22,6 @@
*/
package org.graalvm.compiler.phases.contract;
-import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.function.Predicate;
@@ -64,13 +63,8 @@ public class VerifyNodeCosts {
}
private static NodeClass> getType(Class> c) {
- Field f;
try {
- f = c.getField("TYPE");
- f.setAccessible(true);
- Object val = f.get(null);
- NodeClass> nodeType = (NodeClass>) val;
- return nodeType;
+ return NodeClass.get(c);
} catch (Throwable t) {
throw new VerifyPhase.VerificationError("%s.java does not specify a TYPE field.", c.getName());
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java
index d5dc2508341..f51bb7f74c3 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java
@@ -46,6 +46,7 @@ import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.NodeMap;
import org.graalvm.compiler.graph.NodeSourcePosition;
+import org.graalvm.compiler.graph.SourceLanguagePosition;
import org.graalvm.compiler.nodes.AbstractBeginNode;
import org.graalvm.compiler.nodes.AbstractEndNode;
import org.graalvm.compiler.nodes.AbstractMergeNode;
@@ -67,9 +68,9 @@ import org.graalvm.graphio.GraphOutput;
import org.graalvm.graphio.GraphStructure;
import org.graalvm.graphio.GraphTypes;
+import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.Signature;
public class BinaryGraphPrinter implements
@@ -265,6 +266,17 @@ public class BinaryGraphPrinter implements
}
props.put("category", "floating");
}
+ if (node.getNodeSourcePosition() != null) {
+ NodeSourcePosition pos = node.getNodeSourcePosition();
+ while (pos != null) {
+ SourceLanguagePosition cur = pos.getSourceLanauage();
+ if (cur != null) {
+ cur.addSourceInformation(props);
+ break;
+ }
+ pos = pos.getCaller();
+ }
+ }
if (getSnippetReflectionProvider() != null) {
for (Map.Entry prop : props.entrySet()) {
if (prop.getValue() instanceof JavaConstantFormattable) {
@@ -380,8 +392,8 @@ public class BinaryGraphPrinter implements
if (obj instanceof Class>) {
return ((Class>) obj).getName();
}
- if (obj instanceof ResolvedJavaType) {
- return ((ResolvedJavaType) obj).toJavaName();
+ if (obj instanceof JavaType) {
+ return ((JavaType) obj).toJavaName();
}
return null;
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java
index 7cb7b9dc0ec..5540cb4784c 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java
@@ -79,7 +79,7 @@ interface GraphPrinter extends Closeable, JavaConstantFormatter {
/**
* {@code jdk.vm.ci} module.
*/
- Object JVMCI_MODULE = JDK9Method.JAVA_SPECIFICATION_VERSION < 9 ? null : JDK9Method.getModule.invoke(Services.class);
+ Object JVMCI_MODULE = JDK9Method.JAVA_SPECIFICATION_VERSION < 9 ? null : JDK9Method.getModule(Services.class);
/**
* Classes whose {@link #toString()} method does not run any untrusted code.
@@ -111,8 +111,8 @@ interface GraphPrinter extends Closeable, JavaConstantFormatter {
return true;
}
} else {
- Object module = JDK9Method.getModule.invoke(c);
- if (JVMCI_MODULE == module || (Boolean) JDK9Method.isOpenTo.invoke(JVMCI_MODULE, JVMCI_RUNTIME_PACKAGE, module)) {
+ Object module = JDK9Method.getModule(c);
+ if (JVMCI_MODULE == module || JDK9Method.isOpenTo(JVMCI_MODULE, JVMCI_RUNTIME_PACKAGE, module)) {
// Can access non-statically-exported package in JVMCI
return true;
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java
index a875ca30b01..9b6f38b9f28 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinterDumpHandler.java
@@ -244,7 +244,10 @@ public class GraphPrinterDumpHandler implements DebugDumpHandler {
lastMethodOrGraph = o;
}
}
-
+ if (result.size() == 2 && result.get(1).startsWith("TruffleGraal")) {
+ result.clear();
+ result.add("Graal Graphs");
+ }
if (result.isEmpty()) {
result.add(graph.toString());
graphSeen = true;
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64FloatArithmeticSnippets.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64FloatArithmeticSnippets.java
index ad5dbccd87f..fdf9ce335b0 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64FloatArithmeticSnippets.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64FloatArithmeticSnippets.java
@@ -75,7 +75,7 @@ public class AArch64FloatArithmeticSnippets extends SnippetTemplate.AbstractTemp
Arguments args = new Arguments(snippet, graph.getGuardsStage(), tool.getLoweringStage());
args.add("x", node.getX());
args.add("y", node.getY());
- template(graph.getDebug(), args).instantiate(providers.getMetaAccess(), node, SnippetTemplate.DEFAULT_REPLACER, tool, args);
+ template(node, args).instantiate(providers.getMetaAccess(), node, SnippetTemplate.DEFAULT_REPLACER, tool, args);
}
@Snippet
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64IntegerArithmeticSnippets.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64IntegerArithmeticSnippets.java
index cf6ba186a14..fab0c95b68c 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64IntegerArithmeticSnippets.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64IntegerArithmeticSnippets.java
@@ -106,7 +106,7 @@ public class AArch64IntegerArithmeticSnippets extends AbstractTemplates implemen
Arguments args = new Arguments(snippet, graph.getGuardsStage(), tool.getLoweringStage());
args.add("x", node.getX());
args.add("y", node.getY());
- template(graph.getDebug(), args).instantiate(providers.getMetaAccess(), node, SnippetTemplate.DEFAULT_REPLACER, args);
+ template(node, args).instantiate(providers.getMetaAccess(), node, SnippetTemplate.DEFAULT_REPLACER, args);
}
@Snippet
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64ConvertSnippets.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64ConvertSnippets.java
index d07bcfbc6d7..cee82b8d1e1 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64ConvertSnippets.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64ConvertSnippets.java
@@ -189,7 +189,7 @@ public class AMD64ConvertSnippets implements Snippets {
args.add("input", convert.getValue());
args.add("result", graph.unique(new AMD64FloatConvertNode(convert.getFloatConvert(), convert.getValue())));
- SnippetTemplate template = template(convert.getDebug(), args);
+ SnippetTemplate template = template(convert, args);
convert.getDebug().log("Lowering %s in %s: node=%s, template=%s, arguments=%s", convert.getFloatConvert(), graph, convert, template, args);
template.instantiate(providers.getMetaAccess(), convert, DEFAULT_REPLACER, tool, args);
convert.safeDelete();
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java
index 0cffd5ae3bf..c2cb77fbee9 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java
@@ -29,6 +29,7 @@ import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.Una
import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.LOG10;
import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.SIN;
import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.TAN;
+import static org.graalvm.compiler.serviceprovider.JDK9Method.JAVA_SPECIFICATION_VERSION;
import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier;
import java.util.Arrays;
@@ -75,6 +76,8 @@ public class AMD64GraphBuilderPlugins {
registerIntegerLongPlugins(invocationPlugins, LongSubstitutions.class, JavaKind.Long, arch, replacementsBytecodeProvider);
registerUnsafePlugins(invocationPlugins, replacementsBytecodeProvider);
registerStringPlugins(invocationPlugins, arch, replacementsBytecodeProvider);
+ registerStringLatin1Plugins(invocationPlugins, replacementsBytecodeProvider);
+ registerStringUTF16Plugins(invocationPlugins, replacementsBytecodeProvider);
registerMathPlugins(invocationPlugins, arch, arithmeticStubs, replacementsBytecodeProvider);
registerArraysEqualsPlugins(invocationPlugins, replacementsBytecodeProvider);
}
@@ -183,12 +186,34 @@ public class AMD64GraphBuilderPlugins {
}
private static void registerStringPlugins(InvocationPlugins plugins, AMD64 arch, BytecodeProvider replacementsBytecodeProvider) {
- if (Java8OrEarlier && arch.getFeatures().contains(CPUFeature.SSE4_2)) {
+ if (Java8OrEarlier) {
Registration r;
r = new Registration(plugins, String.class, replacementsBytecodeProvider);
r.setAllowOverwrite(true);
- r.registerMethodSubstitution(AMD64StringSubstitutions.class, "indexOf", char[].class, int.class,
- int.class, char[].class, int.class, int.class, int.class);
+ if (arch.getFeatures().contains(CPUFeature.SSE4_2)) {
+ r.registerMethodSubstitution(AMD64StringSubstitutions.class, "indexOf", char[].class, int.class,
+ int.class, char[].class, int.class, int.class, int.class);
+ }
+ // r.registerMethodSubstitution(AMD64StringSubstitutions.class, "compareTo",
+ // Receiver.class, String.class);
+ }
+ }
+
+ private static void registerStringLatin1Plugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) {
+ if (JAVA_SPECIFICATION_VERSION >= 9) {
+ Registration r = new Registration(plugins, "java.lang.StringLatin1", replacementsBytecodeProvider);
+ r.setAllowOverwrite(true);
+ r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "compareTo", byte[].class, byte[].class);
+ r.registerMethodSubstitution(AMD64StringLatin1Substitutions.class, "compareToUTF16", byte[].class, byte[].class);
+ }
+ }
+
+ private static void registerStringUTF16Plugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) {
+ if (JAVA_SPECIFICATION_VERSION >= 9) {
+ Registration r = new Registration(plugins, "java.lang.StringUTF16", replacementsBytecodeProvider);
+ r.setAllowOverwrite(true);
+ r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compareTo", byte[].class, byte[].class);
+ r.registerMethodSubstitution(AMD64StringUTF16Substitutions.class, "compareToLatin1", byte[].class, byte[].class);
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringLatin1Substitutions.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringLatin1Substitutions.java
new file mode 100644
index 00000000000..52c9d1db8ff
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringLatin1Substitutions.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2017, 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.amd64;
+
+import org.graalvm.compiler.api.replacements.ClassSubstitution;
+import org.graalvm.compiler.api.replacements.MethodSubstitution;
+import org.graalvm.compiler.replacements.nodes.ArrayCompareToNode;
+
+import jdk.vm.ci.meta.JavaKind;
+
+// JaCoCo Exclude
+
+/**
+ * Substitutions for {@code java.lang.StringLatin1} methods.
+ *
+ * Since JDK 9.
+ */
+@ClassSubstitution(className = "java.lang.StringLatin1", optional = true)
+public class AMD64StringLatin1Substitutions {
+
+ /**
+ * @param value is byte[]
+ * @param other is byte[]
+ */
+ @MethodSubstitution
+ public static int compareTo(byte[] value, byte[] other) {
+ return ArrayCompareToNode.compareTo(value, other, value.length, other.length, JavaKind.Byte, JavaKind.Byte);
+ }
+
+ /**
+ * @param value is byte[]
+ * @param other is char[]
+ */
+ @MethodSubstitution
+ public static int compareToUTF16(byte[] value, byte[] other) {
+ return ArrayCompareToNode.compareTo(value, other, value.length, other.length, JavaKind.Byte, JavaKind.Char);
+ }
+
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringSubstitutions.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringSubstitutions.java
index 0524356c185..9265db87a57 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringSubstitutions.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringSubstitutions.java
@@ -26,8 +26,11 @@ import org.graalvm.compiler.api.replacements.ClassSubstitution;
import org.graalvm.compiler.api.replacements.Fold;
import org.graalvm.compiler.api.replacements.Fold.InjectedParameter;
import org.graalvm.compiler.api.replacements.MethodSubstitution;
+import org.graalvm.compiler.core.common.SuppressFBWarnings;
import org.graalvm.compiler.core.common.spi.ArrayOffsetProvider;
import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
+import org.graalvm.compiler.replacements.StringSubstitutions;
+import org.graalvm.compiler.replacements.nodes.ArrayCompareToNode;
import org.graalvm.compiler.word.Word;
import org.graalvm.word.Pointer;
@@ -86,4 +89,16 @@ public class AMD64StringSubstitutions {
}
return result;
}
+
+ @MethodSubstitution(isStatic = false)
+ @SuppressFBWarnings(value = "ES_COMPARING_PARAMETER_STRING_WITH_EQ", justification = "reference equality on the receiver is what we want")
+ public static int compareTo(String receiver, String anotherString) {
+ if (receiver == anotherString) {
+ return 0;
+ }
+ char[] value = StringSubstitutions.getValue(receiver);
+ char[] other = StringSubstitutions.getValue(anotherString);
+ return ArrayCompareToNode.compareTo(value, other, value.length << 1, other.length << 1, JavaKind.Char, JavaKind.Char);
+ }
+
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringUTF16Substitutions.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringUTF16Substitutions.java
new file mode 100644
index 00000000000..e2e347918f9
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringUTF16Substitutions.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017, 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.amd64;
+
+import org.graalvm.compiler.api.replacements.ClassSubstitution;
+import org.graalvm.compiler.api.replacements.MethodSubstitution;
+import org.graalvm.compiler.replacements.nodes.ArrayCompareToNode;
+
+import jdk.vm.ci.meta.JavaKind;
+
+// JaCoCo Exclude
+
+/**
+ * Substitutions for {@code java.lang.StringUTF16} methods.
+ *
+ * Since JDK 9.
+ */
+@ClassSubstitution(className = "java.lang.StringUTF16", optional = true)
+public class AMD64StringUTF16Substitutions {
+
+ /**
+ * @param value is char[]
+ * @param other is char[]
+ */
+ @MethodSubstitution
+ public static int compareTo(byte[] value, byte[] other) {
+ return ArrayCompareToNode.compareTo(value, other, value.length, other.length, JavaKind.Char, JavaKind.Char);
+ }
+
+ /**
+ * @param value is char[]
+ * @param other is byte[]
+ */
+ @MethodSubstitution
+ public static int compareToLatin1(byte[] value, byte[] other) {
+ /*
+ * Swapping array arguments because intrinsic expects order to be byte[]/char[] but kind
+ * arguments stay in original order.
+ */
+ return ArrayCompareToNode.compareTo(other, value, other.length, value.length, JavaKind.Char, JavaKind.Byte);
+ }
+
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MethodSubstitutionTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MethodSubstitutionTest.java
index f99d7adb323..7d3eedce2f8 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MethodSubstitutionTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/MethodSubstitutionTest.java
@@ -109,7 +109,7 @@ public abstract class MethodSubstitutionTest extends GraalCompilerTest {
StructuredGraph graph = testGraph(testMethodName);
// Check to see if the resulting graph contains the expected node
- StructuredGraph replacement = getReplacements().getSubstitution(realMethod, -1);
+ StructuredGraph replacement = getReplacements().getSubstitution(realMethod, -1, false, null);
if (replacement == null && !optional) {
assertInGraph(graph, intrinsicClass);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PEGraphDecoderTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PEGraphDecoderTest.java
index 5fea8c8792a..519a7e23fcd 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PEGraphDecoderTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PEGraphDecoderTest.java
@@ -136,9 +136,9 @@ public class PEGraphDecoderTest extends GraalCompilerTest {
registerPlugins(graphBuilderConfig.getPlugins().getInvocationPlugins());
targetGraph = new StructuredGraph.Builder(getInitialOptions(), debug, AllowAssumptions.YES).method(testMethod).build();
CachingPEGraphDecoder decoder = new CachingPEGraphDecoder(getTarget().arch, targetGraph, getProviders(), graphBuilderConfig, OptimisticOptimizations.NONE, AllowAssumptions.YES,
- null, null, new InlineInvokePlugin[]{new InlineAll()}, null, null, null);
+ null, null, new InlineInvokePlugin[]{new InlineAll()}, null, null, null, null);
- decoder.decode(testMethod);
+ decoder.decode(testMethod, false);
debug.dump(DebugContext.BASIC_LEVEL, targetGraph, "Target Graph");
targetGraph.verify();
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SnippetsTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SnippetsTest.java
index 83f9949f3be..a2a7da369dd 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SnippetsTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SnippetsTest.java
@@ -43,6 +43,6 @@ public abstract class SnippetsTest extends ReplacementsTest {
@Override
protected StructuredGraph parse(Builder builder, PhaseSuite graphBuilderSuite) {
- return installer.makeGraph(getDebugContext(), bytecodeProvider, builder.getMethod(), null, null);
+ return installer.makeGraph(getDebugContext(), bytecodeProvider, builder.getMethod(), null, null, false, null);
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StandardMethodSubstitutionsTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StandardMethodSubstitutionsTest.java
index 3decde127de..bb556d564a4 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StandardMethodSubstitutionsTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StandardMethodSubstitutionsTest.java
@@ -24,8 +24,6 @@ package org.graalvm.compiler.replacements.test;
import java.util.HashMap;
-import org.junit.Test;
-
import org.graalvm.compiler.api.replacements.MethodSubstitution;
import org.graalvm.compiler.nodes.IfNode;
import org.graalvm.compiler.nodes.StructuredGraph;
@@ -35,6 +33,7 @@ import org.graalvm.compiler.replacements.nodes.BitCountNode;
import org.graalvm.compiler.replacements.nodes.BitScanForwardNode;
import org.graalvm.compiler.replacements.nodes.BitScanReverseNode;
import org.graalvm.compiler.replacements.nodes.ReverseBytesNode;
+import org.junit.Test;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.meta.ResolvedJavaMethod;
@@ -137,7 +136,7 @@ public class StandardMethodSubstitutionsTest extends MethodSubstitutionTest {
StructuredGraph graph = testGraph(testMethodName);
// Check to see if the resulting graph contains the expected node
- StructuredGraph replacement = getReplacements().getSubstitution(realJavaMethod, -1);
+ StructuredGraph replacement = getReplacements().getSubstitution(realJavaMethod, -1, false, null);
if (replacement == null && !optional) {
assertInGraph(graph, intrinsicClass);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompareToTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompareToTest.java
new file mode 100644
index 00000000000..53f0901c718
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompareToTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 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.test;
+
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.replacements.nodes.ArrayCompareToNode;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+/**
+ * Tests compareTo method intrinsic.
+ */
+public class StringCompareToTest extends MethodSubstitutionTest {
+
+ private ResolvedJavaMethod realMethod = null;
+ private ResolvedJavaMethod testMethod = null;
+ private InstalledCode testCode = null;
+
+ private final String[] testData = new String[]{
+ "A", "\uFF21", "AB", "A", "a", "Ab", "AA", "\uFF21",
+ "A\uFF21", "ABC", "AB", "ABcD", "ABCD\uFF21\uFF21", "ABCD\uFF21", "ABCDEFG\uFF21", "ABCD",
+ "ABCDEFGH\uFF21\uFF21", "\uFF22", "\uFF21\uFF22", "\uFF21A",
+ "\uFF21\uFF21",
+ "\u043c\u0430\u043c\u0430\u0020\u043c\u044b\u043b\u0430\u0020\u0440\u0430\u043c\u0443\u002c\u0020\u0440\u0430\u043c\u0430\u0020\u0441\u044a\u0435\u043b\u0430\u0020\u043c\u0430\u043c\u0443",
+ "crazy dog jumps over laszy fox",
+ "XMM-XMM-YMM-YMM-ZMM-ZMM-ZMM-ZMM-",
+ "XMM-XMM+YMM-YMM-ZMM-ZMM-ZMM-ZMM-",
+ "XMM-XMM-YMM-YMM+ZMM-ZMM-ZMM-ZMM-",
+ "XMM-XMM-YMM-YMM-ZMM-ZMM-ZMM-ZMM+",
+ "XMM-XMM-XMM-XMM-YMM-YMM-YMM-YMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-",
+ "XMM-XMM-XMM-XMM+YMM-YMM-YMM-YMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-",
+ "XMM-XMM-XMM-XMM-YMM-YMM-YMM-YMM+ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-",
+ "XMM-XMM-XMM-XMM-YMM-YMM-YMM-YMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM-ZMM+",
+ ""
+ };
+
+ public StringCompareToTest() {
+ Assume.assumeTrue(getTarget().arch instanceof AMD64);
+
+ realMethod = getResolvedJavaMethod(String.class, "compareTo", String.class);
+ testMethod = getResolvedJavaMethod("stringCompareTo");
+ StructuredGraph graph = testGraph("stringCompareTo");
+
+ // Check to see if the resulting graph contains the expected node
+ StructuredGraph replacement = getReplacements().getSubstitution(realMethod, -1, false, null);
+ if (replacement == null) {
+ assertInGraph(graph, ArrayCompareToNode.class);
+ }
+
+ // Force compilation
+ testCode = getCode(testMethod);
+ Assert.assertNotNull(testCode);
+ }
+
+ private void executeStringCompareTo(String s0, String s1) {
+ Object expected = invokeSafe(realMethod, s0, s1);
+ // Verify that the original method and the substitution produce the same value
+ assertDeepEquals(expected, invokeSafe(testMethod, null, s0, s1));
+ // Verify that the generated code and the original produce the same value
+ assertDeepEquals(expected, executeVarargsSafe(testCode, s0, s1));
+ }
+
+ public static int stringCompareTo(String a, String b) {
+ return a.compareTo(b);
+ }
+
+ @Test
+ @Ignore("GR-8748")
+ public void testEqualString() {
+ String s = "equal-string";
+ executeStringCompareTo(s, new String(s.toCharArray()));
+ }
+
+ @Test
+ @Ignore("GR-8748")
+ public void testDifferentString() {
+ executeStringCompareTo("some-string", "different-string");
+ }
+
+ @Test
+ @Ignore("GR-8748")
+ public void testAllStrings() {
+ for (String s0 : testData) {
+ for (String s1 : testData) {
+ executeStringCompareTo(s0, s1);
+ }
+ }
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringSubstitutionsTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringSubstitutionsTest.java
index 7c870fa0e32..a6ffa54a6ae 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringSubstitutionsTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringSubstitutionsTest.java
@@ -22,11 +22,10 @@
*/
package org.graalvm.compiler.replacements.test;
-import org.junit.Test;
-
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.replacements.StringSubstitutions;
import org.graalvm.compiler.replacements.nodes.ArrayEqualsNode;
+import org.junit.Test;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.meta.ResolvedJavaMethod;
@@ -42,7 +41,7 @@ public class StringSubstitutionsTest extends MethodSubstitutionTest {
StructuredGraph graph = testGraph(testMethodName);
// Check to see if the resulting graph contains the expected node
- StructuredGraph replacement = getReplacements().getSubstitution(realMethod, -1);
+ StructuredGraph replacement = getReplacements().getSubstitution(realMethod, -1, false, null);
if (replacement == null && !optional) {
assertInGraph(graph, intrinsicClass);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/WordTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/WordTest.java
index bc788a4dc98..6d463ca3e47 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/WordTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/WordTest.java
@@ -44,7 +44,7 @@ public class WordTest extends SnippetsTest {
protected StructuredGraph parse(Builder builder, PhaseSuite graphBuilderSuite) {
// create a copy to assign a valid compilation id
DebugContext debug = getDebugContext();
- StructuredGraph originalGraph = installer.makeGraph(debug, bytecodeProvider, builder.getMethod(), null, null);
+ StructuredGraph originalGraph = installer.makeGraph(debug, bytecodeProvider, builder.getMethod(), null, null, false, null);
return originalGraph.copyWithIdentifier(builder.getCompilationId(), debug);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/BoxingSnippets.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/BoxingSnippets.java
index 63e401302a0..23ac28e0672 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/BoxingSnippets.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/BoxingSnippets.java
@@ -29,8 +29,8 @@ import java.util.EnumMap;
import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter;
-import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
+import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.PiNode;
import org.graalvm.compiler.nodes.ValueNode;
@@ -207,7 +207,7 @@ public class BoxingSnippets implements Snippets {
args.add("value", box.getValue());
args.addConst("valueOfCounter", valueOfCounter);
- SnippetTemplate template = template(box.getDebug(), args);
+ SnippetTemplate template = template(box, args);
box.getDebug().log("Lowering integerValueOf in %s: node=%s, template=%s, arguments=%s", box.graph(), box, template, args);
template.instantiate(providers.getMetaAccess(), box, DEFAULT_REPLACER, args);
}
@@ -218,7 +218,7 @@ public class BoxingSnippets implements Snippets {
args.add("value", unbox.getValue());
args.addConst("valueCounter", valueCounter);
- SnippetTemplate template = template(unbox.getDebug(), args);
+ SnippetTemplate template = template(unbox, args);
unbox.getDebug().log("Lowering integerValueOf in %s: node=%s, template=%s, arguments=%s", unbox.graph(), unbox, template, args);
template.instantiate(providers.getMetaAccess(), unbox, DEFAULT_REPLACER, args);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java
index 57131df9922..1071d271c56 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java
@@ -27,6 +27,7 @@ import static org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.Compi
import org.graalvm.collections.EconomicMap;
import org.graalvm.compiler.bytecode.BytecodeProvider;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.graph.SourceLanguagePositionProvider;
import org.graalvm.compiler.java.GraphBuilderPhase;
import org.graalvm.compiler.nodes.EncodedGraph;
import org.graalvm.compiler.nodes.GraphEncoder;
@@ -63,9 +64,9 @@ public class CachingPEGraphDecoder extends PEGraphDecoder {
public CachingPEGraphDecoder(Architecture architecture, StructuredGraph graph, Providers providers, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts,
AllowAssumptions allowAssumptions, LoopExplosionPlugin loopExplosionPlugin, InvocationPlugins invocationPlugins, InlineInvokePlugin[] inlineInvokePlugins,
ParameterPlugin parameterPlugin,
- NodePlugin[] nodePlugins, ResolvedJavaMethod callInlinedMethod) {
+ NodePlugin[] nodePlugins, ResolvedJavaMethod callInlinedMethod, SourceLanguagePositionProvider sourceLanguagePositionProvider) {
super(architecture, graph, providers.getMetaAccess(), providers.getConstantReflection(), providers.getConstantFieldProvider(), providers.getStampProvider(), loopExplosionPlugin,
- invocationPlugins, inlineInvokePlugins, parameterPlugin, nodePlugins, callInlinedMethod);
+ invocationPlugins, inlineInvokePlugins, parameterPlugin, nodePlugins, callInlinedMethod, sourceLanguagePositionProvider);
this.providers = providers;
this.graphBuilderConfig = graphBuilderConfig;
@@ -80,10 +81,11 @@ public class CachingPEGraphDecoder extends PEGraphDecoder {
}
@SuppressWarnings("try")
- private EncodedGraph createGraph(ResolvedJavaMethod method, BytecodeProvider intrinsicBytecodeProvider) {
- StructuredGraph graphToEncode = new StructuredGraph.Builder(options, debug, allowAssumptions).useProfilingInfo(false).method(method).build();
+ private EncodedGraph createGraph(ResolvedJavaMethod method, ResolvedJavaMethod originalMethod, BytecodeProvider intrinsicBytecodeProvider) {
+ StructuredGraph graphToEncode = new StructuredGraph.Builder(options, debug, allowAssumptions).useProfilingInfo(false).trackNodeSourcePosition(
+ graphBuilderConfig.trackNodeSourcePosition()).method(method).build();
try (DebugContext.Scope scope = debug.scope("createGraph", graphToEncode)) {
- IntrinsicContext initialIntrinsicContext = intrinsicBytecodeProvider != null ? new IntrinsicContext(method, method, intrinsicBytecodeProvider, INLINE_AFTER_PARSING) : null;
+ IntrinsicContext initialIntrinsicContext = intrinsicBytecodeProvider != null ? new IntrinsicContext(originalMethod, method, intrinsicBytecodeProvider, INLINE_AFTER_PARSING) : null;
GraphBuilderPhase.Instance graphBuilderPhaseInstance = createGraphBuilderPhaseInstance(initialIntrinsicContext);
graphBuilderPhaseInstance.apply(graphToEncode);
@@ -106,10 +108,10 @@ public class CachingPEGraphDecoder extends PEGraphDecoder {
}
@Override
- protected EncodedGraph lookupEncodedGraph(ResolvedJavaMethod method, BytecodeProvider intrinsicBytecodeProvider) {
+ protected EncodedGraph lookupEncodedGraph(ResolvedJavaMethod method, ResolvedJavaMethod originalMethod, BytecodeProvider intrinsicBytecodeProvider, boolean trackNodeSourcePosition) {
EncodedGraph result = graphCache.get(method);
if (result == null && method.hasBytecodes()) {
- result = createGraph(method, intrinsicBytecodeProvider);
+ result = createGraph(method, originalMethod, intrinsicBytecodeProvider);
}
return result;
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantStringIndexOfSnippets.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantStringIndexOfSnippets.java
index eb2b260db00..1577e543c8a 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantStringIndexOfSnippets.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantStringIndexOfSnippets.java
@@ -65,7 +65,7 @@ public class ConstantStringIndexOfSnippets implements Snippets {
char[] targetCharArray = snippetReflection.asObject(char[].class, stringIndexOf.getArgument(3).asJavaConstant());
args.addConst("md2", md2(targetCharArray));
args.addConst("cache", computeCache(targetCharArray));
- template(graph.getDebug(), args).instantiate(providers.getMetaAccess(), stringIndexOf, DEFAULT_REPLACER, args);
+ template(stringIndexOf, args).instantiate(providers.getMetaAccess(), stringIndexOf, DEFAULT_REPLACER, args);
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java
index 6ccd8d4f91d..7617143bb1e 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/GraphKit.java
@@ -32,9 +32,11 @@ import java.util.List;
import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.core.common.type.StampPair;
+import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.Graph;
import org.graalvm.compiler.graph.Node.ValueNumberable;
+import org.graalvm.compiler.graph.NodeSourcePosition;
import org.graalvm.compiler.java.FrameStateBuilder;
import org.graalvm.compiler.java.GraphBuilderPhase;
import org.graalvm.compiler.nodes.AbstractBeginNode;
@@ -52,6 +54,7 @@ import org.graalvm.compiler.nodes.LogicNode;
import org.graalvm.compiler.nodes.MergeNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.UnwindNode;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.FloatingNode;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
@@ -224,28 +227,42 @@ public class GraphKit implements GraphBuilderTool {
* Creates and appends an {@link InvokeNode} for a call to a given method with a given set of
* arguments.
*/
+ @SuppressWarnings("try")
public InvokeNode createInvoke(ResolvedJavaMethod method, InvokeKind invokeKind, FrameStateBuilder frameStateBuilder, int bci, ValueNode... args) {
- assert method.isStatic() == (invokeKind == InvokeKind.Static);
- Signature signature = method.getSignature();
- JavaType returnType = signature.getReturnType(null);
- assert checkArgs(method, args);
- StampPair returnStamp = graphBuilderPlugins.getOverridingStamp(this, returnType, false);
- if (returnStamp == null) {
- returnStamp = StampFactory.forDeclaredType(graph.getAssumptions(), returnType, false);
- }
- MethodCallTargetNode callTarget = graph.add(createMethodCallTarget(invokeKind, method, args, returnStamp, bci));
- InvokeNode invoke = append(new InvokeNode(callTarget, bci));
+ try (DebugCloseable context = graph.withNodeSourcePosition(NodeSourcePosition.placeholder(method))) {
+ assert method.isStatic() == (invokeKind == InvokeKind.Static);
+ Signature signature = method.getSignature();
+ JavaType returnType = signature.getReturnType(null);
+ assert checkArgs(method, args);
+ StampPair returnStamp = graphBuilderPlugins.getOverridingStamp(this, returnType, false);
+ if (returnStamp == null) {
+ returnStamp = StampFactory.forDeclaredType(graph.getAssumptions(), returnType, false);
+ }
+ MethodCallTargetNode callTarget = graph.add(createMethodCallTarget(invokeKind, method, args, returnStamp, bci));
+ InvokeNode invoke = append(new InvokeNode(callTarget, bci));
- if (frameStateBuilder != null) {
- if (invoke.getStackKind() != JavaKind.Void) {
- frameStateBuilder.push(invoke.getStackKind(), invoke);
- }
- invoke.setStateAfter(frameStateBuilder.create(bci, invoke));
- if (invoke.getStackKind() != JavaKind.Void) {
- frameStateBuilder.pop(invoke.getStackKind());
+ if (frameStateBuilder != null) {
+ if (invoke.getStackKind() != JavaKind.Void) {
+ frameStateBuilder.push(invoke.getStackKind(), invoke);
+ }
+ invoke.setStateAfter(frameStateBuilder.create(bci, invoke));
+ if (invoke.getStackKind() != JavaKind.Void) {
+ frameStateBuilder.pop(invoke.getStackKind());
+ }
}
+ return invoke;
}
- return invoke;
+ }
+
+ public InvokeWithExceptionNode createInvokeWithExceptionAndUnwind(ResolvedJavaMethod method, InvokeKind invokeKind,
+ FrameStateBuilder frameStateBuilder, int invokeBci, int exceptionEdgeBci, ValueNode... args) {
+
+ InvokeWithExceptionNode result = startInvokeWithException(method, invokeKind, frameStateBuilder, invokeBci, exceptionEdgeBci, args);
+ exceptionPart();
+ ExceptionObjectNode exception = exceptionObject();
+ append(new UnwindNode(exception));
+ endInvokeWithException();
+ return result;
}
protected MethodCallTargetNode createMethodCallTarget(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args, StampPair returnStamp, @SuppressWarnings("unused") int bci) {
@@ -311,6 +328,9 @@ public class GraphKit implements GraphBuilderTool {
GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(plugins);
StructuredGraph calleeGraph = new StructuredGraph.Builder(invoke.getOptions(), invoke.getDebug()).method(method).build();
+ if (invoke.graph().trackNodeSourcePosition()) {
+ calleeGraph.setTrackNodeSourcePosition();
+ }
IntrinsicContext initialReplacementContext = new IntrinsicContext(method, method, providers.getReplacements().getDefaultReplacementBytecodeProvider(), INLINE_AFTER_PARSING);
GraphBuilderPhase.Instance instance = new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), providers.getConstantReflection(), providers.getConstantFieldProvider(), config,
OptimisticOptimizations.NONE,
@@ -357,11 +377,12 @@ public class GraphKit implements GraphBuilderTool {
*
* @param condition The condition for the if-block
* @param trueProbability The estimated probability the condition is true
+ * @return the created {@link IfNode}.
*/
- public void startIf(LogicNode condition, double trueProbability) {
+ public IfNode startIf(LogicNode condition, double trueProbability) {
AbstractBeginNode thenSuccessor = graph.add(new BeginNode());
AbstractBeginNode elseSuccessor = graph.add(new BeginNode());
- append(new IfNode(condition, thenSuccessor, elseSuccessor, trueProbability));
+ IfNode node = append(new IfNode(condition, thenSuccessor, elseSuccessor, trueProbability));
lastFixedNode = null;
IfStructure s = new IfStructure();
@@ -369,6 +390,7 @@ public class GraphKit implements GraphBuilderTool {
s.thenPart = thenSuccessor;
s.elsePart = elseSuccessor;
pushStructure(s);
+ return node;
}
private IfStructure saveLastIfNode() {
@@ -403,11 +425,18 @@ public class GraphKit implements GraphBuilderTool {
s.state = IfState.ELSE_PART;
}
- public void endIf() {
+ /**
+ * Ends an if block started with {@link #startIf(LogicNode, double)}.
+ *
+ * @return the created merge node, or {@code null} if no merge node was required (for example,
+ * when one part ended with a control sink).
+ */
+ public AbstractMergeNode endIf() {
IfStructure s = saveLastIfNode();
FixedWithNextNode thenPart = s.thenPart instanceof FixedWithNextNode ? (FixedWithNextNode) s.thenPart : null;
FixedWithNextNode elsePart = s.elsePart instanceof FixedWithNextNode ? (FixedWithNextNode) s.elsePart : null;
+ AbstractMergeNode merge = null;
if (thenPart != null && elsePart != null) {
/* Both parts are alive, we need a real merge. */
@@ -416,7 +445,7 @@ public class GraphKit implements GraphBuilderTool {
EndNode elseEnd = graph.add(new EndNode());
graph.addAfterFixed(elsePart, elseEnd);
- AbstractMergeNode merge = graph.add(new MergeNode());
+ merge = graph.add(new MergeNode());
merge.addForwardEnd(thenEnd);
merge.addForwardEnd(elseEnd);
@@ -436,6 +465,7 @@ public class GraphKit implements GraphBuilderTool {
}
s.state = IfState.FINISHED;
popStructure();
+ return merge;
}
static class InvokeWithExceptionStructure extends Structure {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/InlineDuringParsingPlugin.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/InlineDuringParsingPlugin.java
index 6e62b7addee..3e333301438 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/InlineDuringParsingPlugin.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/InlineDuringParsingPlugin.java
@@ -26,6 +26,7 @@ import static org.graalvm.compiler.core.common.GraalOptions.TrivialInliningSize;
import static org.graalvm.compiler.java.BytecodeParserOptions.InlineDuringParsingMaxDepth;
import static org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo.createStandardInlineInfo;
+import org.graalvm.compiler.java.BytecodeParserOptions;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
@@ -35,6 +36,15 @@ import jdk.vm.ci.meta.ResolvedJavaMethod;
public final class InlineDuringParsingPlugin implements InlineInvokePlugin {
+ /**
+ * 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 MaxDepthAfterBudgetExceeded = Integer.getInteger("InlineDuringParsingPlugin.MaxDepthAfterBudgetExceeded", 3);
+
@Override
public InlineInfo shouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
// @formatter:off
@@ -49,7 +59,7 @@ public final class InlineDuringParsingPlugin implements InlineInvokePlugin {
if (!method.isSynchronized() &&
checkSize(method, args, b.getGraph()) &&
- b.getDepth() < InlineDuringParsingMaxDepth.getValue(b.getOptions())) {
+ checkInliningDepth(b)) {
return createStandardInlineInfo(method);
}
}
@@ -57,6 +67,15 @@ public final class InlineDuringParsingPlugin implements InlineInvokePlugin {
return null;
}
+ private static boolean checkInliningDepth(GraphBuilderContext b) {
+ int nodeCount = b.getGraph().getNodeCount();
+ int maxDepth = InlineDuringParsingMaxDepth.getValue(b.getOptions());
+ if (nodeCount > NodeBudget && MaxDepthAfterBudgetExceeded < maxDepth) {
+ maxDepth = MaxDepthAfterBudgetExceeded;
+ }
+ return b.getDepth() < maxDepth;
+ }
+
private static boolean checkSize(ResolvedJavaMethod method, ValueNode[] args, StructuredGraph graph) {
int bonus = 1;
for (ValueNode v : args) {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/InstanceOfSnippetsTemplates.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/InstanceOfSnippetsTemplates.java
index abc6b32cdec..17ca86bec19 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/InstanceOfSnippetsTemplates.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/InstanceOfSnippetsTemplates.java
@@ -96,7 +96,7 @@ public abstract class InstanceOfSnippetsTemplates extends AbstractTemplates {
replacer.replaceUsingInstantiation();
} else {
Arguments args = makeArguments(replacer, tool);
- template(instanceOf.getDebug(), args).instantiate(providers.getMetaAccess(), instanceOf, replacer, tool, args);
+ template(instanceOf, args).instantiate(providers.getMetaAccess(), instanceOf, replacer, tool, args);
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/IntrinsicGraphBuilder.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/IntrinsicGraphBuilder.java
index 6e202e96bbb..17909ca0183 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/IntrinsicGraphBuilder.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/IntrinsicGraphBuilder.java
@@ -31,6 +31,8 @@ import org.graalvm.compiler.core.common.type.StampPair;
import org.graalvm.compiler.core.common.type.TypeReference;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.GraalError;
+import org.graalvm.compiler.debug.DebugCloseable;
+import org.graalvm.compiler.graph.NodeSourcePosition;
import org.graalvm.compiler.nodes.CallTargetNode;
import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
import org.graalvm.compiler.nodes.FixedNode;
@@ -91,6 +93,7 @@ public class IntrinsicGraphBuilder implements GraphBuilderContext, Receiver {
this.code = code;
this.method = code.getMethod();
this.graph = new StructuredGraph.Builder(options, debug, allowAssumptions).method(method).build();
+ this.graph.setTrackNodeSourcePosition();
this.invokeBci = invokeBci;
this.lastInstr = graph.start();
@@ -255,14 +258,18 @@ public class IntrinsicGraphBuilder implements GraphBuilderContext, Receiver {
return arguments[0];
}
+ @SuppressWarnings("try")
public StructuredGraph buildGraph(InvocationPlugin plugin) {
- Receiver receiver = method.isStatic() ? null : this;
- if (plugin.execute(this, method, receiver, arguments)) {
- assert (returnValue != null) == (method.getSignature().getReturnKind() != JavaKind.Void) : method;
- append(new ReturnNode(returnValue));
- return graph;
+ NodeSourcePosition position = graph.trackNodeSourcePosition() ? NodeSourcePosition.placeholder(method) : null;
+ try (DebugCloseable context = graph.withNodeSourcePosition(position)) {
+ Receiver receiver = method.isStatic() ? null : this;
+ if (plugin.execute(this, method, receiver, arguments)) {
+ assert (returnValue != null) == (method.getSignature().getReturnKind() != JavaKind.Void) : method;
+ append(new ReturnNode(returnValue));
+ return graph;
+ }
+ return null;
}
- return null;
}
@Override
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java
index 2c3be468112..2c284bf1b1f 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/PEGraphDecoder.java
@@ -48,6 +48,8 @@ import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.NodeSourcePosition;
+import org.graalvm.compiler.graph.SourceLanguagePosition;
+import org.graalvm.compiler.graph.SourceLanguagePositionProvider;
import org.graalvm.compiler.graph.spi.Canonicalizable;
import org.graalvm.compiler.java.GraphBuilderPhase;
import org.graalvm.compiler.nodeinfo.NodeInfo;
@@ -108,6 +110,7 @@ import org.graalvm.compiler.phases.common.inlining.InliningUtil;
import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.BailoutException;
import jdk.vm.ci.code.BytecodeFrame;
+import jdk.vm.ci.meta.Assumptions;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.DeoptimizationAction;
import jdk.vm.ci.meta.DeoptimizationReason;
@@ -142,7 +145,7 @@ public abstract class PEGraphDecoder extends SimplifyingGraphDecoder {
@Option(help = "Max number of loop explosions per method.", type = OptionType.Debug)//
public static final OptionKey MaximumLoopExplosionCount = new OptionKey<>(10000);
- @Option(help = "Do not bail out but throw an exception on failed loop explosion.", type = OptionType.Debug) //
+ @Option(help = "Do not bail out but throw an exception on failed loop explosion.", type = OptionType.Debug)//
public static final OptionKey FailedLoopExplosionIsFatal = new OptionKey<>(false);
}
@@ -154,6 +157,7 @@ public abstract class PEGraphDecoder extends SimplifyingGraphDecoder {
protected final int inliningDepth;
protected final ValueNode[] arguments;
+ private final SourceLanguagePosition sourceLanguagePosition;
protected FrameState outerState;
protected FrameState exceptionState;
@@ -169,6 +173,13 @@ public abstract class PEGraphDecoder extends SimplifyingGraphDecoder {
this.invokeData = invokeData;
this.inliningDepth = inliningDepth;
this.arguments = arguments;
+ SourceLanguagePosition position = null;
+ if (arguments != null && method.hasReceiver() && arguments.length > 0 && arguments[0].isJavaConstant()) {
+ JavaConstant constantArgument = arguments[0].asJavaConstant();
+ position = sourceLanguagePositionProvider.getPosition(constantArgument);
+ }
+ this.sourceLanguagePosition = position;
+
}
@Override
@@ -176,15 +187,24 @@ public abstract class PEGraphDecoder extends SimplifyingGraphDecoder {
return caller != null;
}
- public NodeSourcePosition getCallerBytecodePosition() {
+ @Override
+ public NodeSourcePosition getCallerBytecodePosition(NodeSourcePosition position) {
if (caller == null) {
- return null;
+ return position;
}
if (callerBytecodePosition == null) {
- JavaConstant constantReceiver = caller.invokeData == null ? null : caller.invokeData.constantReceiver;
- NodeSourcePosition callerPosition = caller.getCallerBytecodePosition();
NodeSourcePosition invokePosition = invokeData.invoke.asNode().getNodeSourcePosition();
- callerBytecodePosition = invokePosition != null ? invokePosition.addCaller(constantReceiver, callerPosition) : callerPosition;
+ if (invokePosition == null) {
+ assert position == null : "should only happen when tracking is disabled";
+ return null;
+ }
+ callerBytecodePosition = invokePosition;
+ }
+ if (position != null) {
+ return position.addCaller(caller.sourceLanguagePosition, callerBytecodePosition);
+ }
+ if (caller.sourceLanguagePosition != null && callerBytecodePosition != null) {
+ return new NodeSourcePosition(caller.sourceLanguagePosition, callerBytecodePosition.getCaller(), callerBytecodePosition.getMethod(), callerBytecodePosition.getBCI());
}
return callerBytecodePosition;
}
@@ -361,8 +381,11 @@ public abstract class PEGraphDecoder extends SimplifyingGraphDecoder {
}
private DebugCloseable withNodeSoucePosition() {
- if (getGraph().mayHaveNodeSourcePosition()) {
- return getGraph().withNodeSourcePosition(methodScope.getCallerBytecodePosition());
+ if (getGraph().trackNodeSourcePosition()) {
+ NodeSourcePosition callerBytecodePosition = methodScope.getCallerBytecodePosition();
+ if (callerBytecodePosition != null) {
+ return getGraph().withNodeSourcePosition(callerBytecodePosition);
+ }
}
return null;
}
@@ -440,11 +463,12 @@ public abstract class PEGraphDecoder extends SimplifyingGraphDecoder {
private final EconomicMap specialCallTargetCache;
private final EconomicMap invocationPluginCache;
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,
ParameterPlugin parameterPlugin,
- NodePlugin[] nodePlugins, ResolvedJavaMethod callInlinedMethod) {
+ NodePlugin[] nodePlugins, ResolvedJavaMethod callInlinedMethod, SourceLanguagePositionProvider sourceLanguagePositionProvider) {
super(architecture, graph, metaAccess, constantReflection, constantFieldProvider, stampProvider, true);
this.loopExplosionPlugin = loopExplosionPlugin;
this.invocationPlugins = invocationPlugins;
@@ -454,6 +478,7 @@ public abstract class PEGraphDecoder extends SimplifyingGraphDecoder {
this.specialCallTargetCache = EconomicMap.create(Equivalence.DEFAULT);
this.invocationPluginCache = EconomicMap.create(Equivalence.DEFAULT);
this.callInlinedMethod = callInlinedMethod;
+ this.sourceLanguagePositionProvider = sourceLanguagePositionProvider;
}
protected static LoopExplosionKind loopExplosionKind(ResolvedJavaMethod method, LoopExplosionPlugin loopExplosionPlugin) {
@@ -464,8 +489,8 @@ public abstract class PEGraphDecoder extends SimplifyingGraphDecoder {
}
}
- public void decode(ResolvedJavaMethod method) {
- PEMethodScope methodScope = new PEMethodScope(graph, null, null, lookupEncodedGraph(method, null), method, null, 0, loopExplosionPlugin, null);
+ public void decode(ResolvedJavaMethod method, boolean trackNodeSourcePosition) {
+ PEMethodScope methodScope = new PEMethodScope(graph, null, null, lookupEncodedGraph(method, null, null, trackNodeSourcePosition), method, null, 0, loopExplosionPlugin, null);
decode(createInitialLoopScope(methodScope, null));
cleanupGraph(methodScope);
@@ -533,6 +558,12 @@ public abstract class PEGraphDecoder extends SimplifyingGraphDecoder {
MethodCallTargetNode methodCall = (MethodCallTargetNode) callTarget;
if (methodCall.invokeKind().hasReceiver()) {
invokeData.constantReceiver = methodCall.arguments().get(0).asJavaConstant();
+ NodeSourcePosition invokePosition = invokeData.invoke.asNode().getNodeSourcePosition();
+ if (invokeData.constantReceiver != null && invokePosition != null) {
+ // new NodeSourcePosition(invokeData.constantReceiver,
+ // invokePosition.getCaller(), invokePosition.getMethod(),
+ // invokePosition.getBCI());
+ }
}
LoopScope inlineLoopScope = trySimplifyInvoke(methodScope, loopScope, invokeData, (MethodCallTargetNode) callTarget);
if (inlineLoopScope != null) {
@@ -687,11 +718,12 @@ public abstract class PEGraphDecoder extends SimplifyingGraphDecoder {
protected LoopScope doInline(PEMethodScope methodScope, LoopScope loopScope, InvokeData invokeData, InlineInfo inlineInfo, ValueNode[] arguments) {
ResolvedJavaMethod inlineMethod = inlineInfo.getMethodToInline();
- EncodedGraph graphToInline = lookupEncodedGraph(inlineMethod, inlineInfo.getIntrinsicBytecodeProvider());
+ EncodedGraph graphToInline = lookupEncodedGraph(inlineMethod, inlineInfo.getOriginalMethod(), inlineInfo.getIntrinsicBytecodeProvider(), graph.trackNodeSourcePosition());
if (graphToInline == null) {
return null;
}
+ assert !graph.trackNodeSourcePosition() || graphToInline.trackNodeSourcePosition() : graph + " " + graphToInline;
if (methodScope.inliningDepth > Options.InliningDepthError.getValue(options)) {
throw tooDeepInlining(methodScope);
}
@@ -740,6 +772,32 @@ public abstract class PEGraphDecoder extends SimplifyingGraphDecoder {
inlineLoopScope.createdNodes[firstArgumentNodeId + i] = arguments[i];
}
+ // Copy assumptions from inlinee to caller
+ Assumptions assumptions = graph.getAssumptions();
+ Assumptions inlinedAssumptions = graphToInline.getAssumptions();
+ if (assumptions != null) {
+ if (inlinedAssumptions != null) {
+ assumptions.record(inlinedAssumptions);
+ }
+ } else {
+ assert inlinedAssumptions == null : String.format("cannot inline graph (%s) which makes assumptions into a graph (%s) that doesn't", inlineMethod, graph);
+ }
+
+ // Copy inlined methods from inlinee to caller
+ List inlinedMethods = graphToInline.getInlinedMethods();
+ if (inlinedMethods != null) {
+ graph.getMethods().addAll(inlinedMethods);
+ }
+
+ if (graphToInline.getFields() != null) {
+ for (ResolvedJavaField field : graphToInline.getFields()) {
+ graph.recordField(field);
+ }
+ }
+ if (graphToInline.hasUnsafeAccess()) {
+ graph.markUnsafeAccess();
+ }
+
/*
* Do the actual inlining by returning the initial loop scope for the inlined method scope.
*/
@@ -927,7 +985,7 @@ public abstract class PEGraphDecoder extends SimplifyingGraphDecoder {
}
}
- protected abstract EncodedGraph lookupEncodedGraph(ResolvedJavaMethod method, BytecodeProvider intrinsicBytecodeProvider);
+ protected abstract EncodedGraph lookupEncodedGraph(ResolvedJavaMethod method, ResolvedJavaMethod originalMethod, BytecodeProvider intrinsicBytecodeProvider, boolean trackNodeSourcePosition);
@Override
protected void handleFixedNode(MethodScope s, LoopScope loopScope, int nodeOrderId, FixedNode node) {
@@ -1123,20 +1181,6 @@ public abstract class PEGraphDecoder extends SimplifyingGraphDecoder {
}
}
- @Override
- protected Node addFloatingNode(MethodScope s, Node node) {
- Node addedNode = super.addFloatingNode(s, node);
- PEMethodScope methodScope = (PEMethodScope) s;
- NodeSourcePosition pos = node.getNodeSourcePosition();
- if (methodScope.isInlinedMethod()) {
- if (pos != null) {
- NodeSourcePosition bytecodePosition = methodScope.getCallerBytecodePosition();
- node.setNodeSourcePosition(pos.addCaller(bytecodePosition));
- }
- }
- return addedNode;
- }
-
@Override
protected Node handleFloatingNodeAfterAdd(MethodScope s, LoopScope loopScope, Node node) {
PEMethodScope methodScope = (PEMethodScope) s;
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java
index f034fa3c2bc..45c3b8daed6 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java
@@ -55,6 +55,7 @@ import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.debug.TimerKey;
import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.graph.NodeSourcePosition;
import org.graalvm.compiler.graph.Node.NodeIntrinsic;
import org.graalvm.compiler.java.GraphBuilderPhase;
import org.graalvm.compiler.java.GraphBuilderPhase.Instance;
@@ -148,7 +149,7 @@ public class ReplacementsImpl implements Replacements, InlineInvokePlugin {
if (subst != null) {
if (b.parsingIntrinsic() || InlineDuringParsing.getValue(b.getOptions()) || InlineIntrinsicsDuringParsing.getValue(b.getOptions())) {
// Forced inlining of intrinsics
- return createIntrinsicInlineInfo(subst.getMethod(), subst.getOrigin());
+ return createIntrinsicInlineInfo(subst.getMethod(), method, subst.getOrigin());
}
return null;
}
@@ -156,7 +157,7 @@ public class ReplacementsImpl implements Replacements, InlineInvokePlugin {
assert b.getDepth() < MAX_GRAPH_INLINING_DEPTH : "inlining limit exceeded";
// Force inlining when parsing replacements
- return createIntrinsicInlineInfo(method, defaultBytecodeProvider);
+ return createIntrinsicInlineInfo(method, null, defaultBytecodeProvider);
} else {
assert method.getAnnotation(NodeIntrinsic.class) == null : String.format("@%s method %s must only be called from within a replacement%n%s", NodeIntrinsic.class.getSimpleName(),
method.format("%h.%n"), b);
@@ -202,8 +203,8 @@ public class ReplacementsImpl implements Replacements, InlineInvokePlugin {
private static final TimerKey SnippetPreparationTime = DebugContext.timer("SnippetPreparationTime");
@Override
- public StructuredGraph getSnippet(ResolvedJavaMethod method, Object[] args) {
- return getSnippet(method, null, args);
+ public StructuredGraph getSnippet(ResolvedJavaMethod method, Object[] args, boolean trackNodeSourcePosition, NodeSourcePosition replaceePosition) {
+ return getSnippet(method, null, args, trackNodeSourcePosition, replaceePosition);
}
private static final AtomicInteger nextDebugContextId = new AtomicInteger();
@@ -217,29 +218,34 @@ public class ReplacementsImpl implements Replacements, InlineInvokePlugin {
@Override
@SuppressWarnings("try")
- public StructuredGraph getSnippet(ResolvedJavaMethod method, ResolvedJavaMethod recursiveEntry, Object[] args) {
+ public StructuredGraph getSnippet(ResolvedJavaMethod method, ResolvedJavaMethod recursiveEntry, Object[] args, boolean trackNodeSourcePosition, NodeSourcePosition replaceePosition) {
assert method.getAnnotation(Snippet.class) != null : "Snippet must be annotated with @" + Snippet.class.getSimpleName();
assert method.hasBytecodes() : "Snippet must not be abstract or native";
StructuredGraph graph = UseSnippetGraphCache.getValue(options) ? graphs.get(method) : null;
- if (graph == null) {
+ if (graph == null || (trackNodeSourcePosition && !graph.trackNodeSourcePosition())) {
try (DebugContext debug = openDebugContext("Snippet_", method);
DebugCloseable a = SnippetPreparationTime.start(debug)) {
- StructuredGraph newGraph = makeGraph(debug, defaultBytecodeProvider, method, args, recursiveEntry);
+ StructuredGraph newGraph = makeGraph(debug, defaultBytecodeProvider, method, args, recursiveEntry, trackNodeSourcePosition, replaceePosition);
DebugContext.counter("SnippetNodeCount[%#s]", method).add(newGraph.getDebug(), newGraph.getNodeCount());
if (!UseSnippetGraphCache.getValue(options) || args != null) {
return newGraph;
}
newGraph.freeze();
- graphs.putIfAbsent(method, newGraph);
+ if (graph != null) {
+ graphs.replace(method, graph, newGraph);
+ } else {
+ graphs.putIfAbsent(method, newGraph);
+ }
graph = graphs.get(method);
}
}
+ assert !trackNodeSourcePosition || graph.trackNodeSourcePosition();
return graph;
}
@Override
- public void registerSnippet(ResolvedJavaMethod method) {
+ public void registerSnippet(ResolvedJavaMethod method, boolean trackNodeSourcePosition) {
// No initialization needed as snippet graphs are created on demand in getSnippet
}
@@ -266,7 +272,7 @@ public class ReplacementsImpl implements Replacements, InlineInvokePlugin {
}
@Override
- public StructuredGraph getSubstitution(ResolvedJavaMethod method, int invokeBci) {
+ public StructuredGraph getSubstitution(ResolvedJavaMethod method, int invokeBci, boolean trackNodeSourcePosition, NodeSourcePosition replaceePosition) {
StructuredGraph result;
InvocationPlugin plugin = graphBuilderPlugins.getInvocationPlugins().lookupInvocation(method);
if (plugin != null && (!plugin.inlineOnly() || invokeBci >= 0)) {
@@ -275,9 +281,9 @@ public class ReplacementsImpl implements Replacements, InlineInvokePlugin {
MethodSubstitutionPlugin msPlugin = (MethodSubstitutionPlugin) plugin;
ResolvedJavaMethod substitute = msPlugin.getSubstitute(metaAccess);
StructuredGraph graph = UseSnippetGraphCache.getValue(options) ? graphs.get(substitute) : null;
- if (graph == null) {
+ if (graph == null || graph.trackNodeSourcePosition() != trackNodeSourcePosition) {
try (DebugContext debug = openDebugContext("Substitution_", method)) {
- graph = makeGraph(debug, msPlugin.getBytecodeProvider(), substitute, null, method);
+ graph = makeGraph(debug, msPlugin.getBytecodeProvider(), substitute, null, method, trackNodeSourcePosition, replaceePosition);
if (!UseSnippetGraphCache.getValue(options)) {
return graph;
}
@@ -311,9 +317,11 @@ public class ReplacementsImpl implements Replacements, InlineInvokePlugin {
* @param args
* @param original the original method if {@code method} is a {@linkplain MethodSubstitution
* substitution} otherwise null
+ * @param trackNodeSourcePosition
*/
- public StructuredGraph makeGraph(DebugContext debug, BytecodeProvider bytecodeProvider, ResolvedJavaMethod method, Object[] args, ResolvedJavaMethod original) {
- return createGraphMaker(method, original).makeGraph(debug, bytecodeProvider, args);
+ public StructuredGraph makeGraph(DebugContext debug, BytecodeProvider bytecodeProvider, ResolvedJavaMethod method, Object[] args, ResolvedJavaMethod original, boolean trackNodeSourcePosition,
+ NodeSourcePosition replaceePosition) {
+ return createGraphMaker(method, original).makeGraph(debug, bytecodeProvider, args, trackNodeSourcePosition, replaceePosition);
}
/**
@@ -350,10 +358,10 @@ public class ReplacementsImpl implements Replacements, InlineInvokePlugin {
}
@SuppressWarnings("try")
- public StructuredGraph makeGraph(DebugContext debug, BytecodeProvider bytecodeProvider, Object[] args) {
+ public StructuredGraph makeGraph(DebugContext debug, BytecodeProvider bytecodeProvider, Object[] args, boolean trackNodeSourcePosition, NodeSourcePosition replaceePosition) {
try (DebugContext.Scope s = debug.scope("BuildSnippetGraph", method)) {
assert method.hasBytecodes() : method;
- StructuredGraph graph = buildInitialGraph(debug, bytecodeProvider, method, args);
+ StructuredGraph graph = buildInitialGraph(debug, bytecodeProvider, method, args, trackNodeSourcePosition, replaceePosition);
finalizeGraph(graph);
@@ -417,10 +425,12 @@ public class ReplacementsImpl implements Replacements, InlineInvokePlugin {
* Builds the initial graph for a replacement.
*/
@SuppressWarnings("try")
- protected StructuredGraph buildInitialGraph(DebugContext debug, BytecodeProvider bytecodeProvider, final ResolvedJavaMethod methodToParse, Object[] args) {
+ protected StructuredGraph buildInitialGraph(DebugContext debug, BytecodeProvider bytecodeProvider, final ResolvedJavaMethod methodToParse, Object[] args, boolean trackNodeSourcePosition,
+ NodeSourcePosition replaceePosition) {
// Replacements cannot have optimistic assumptions since they have
// to be valid for the entire run of the VM.
- final StructuredGraph graph = new StructuredGraph.Builder(replacements.options, debug).method(methodToParse).build();
+ final StructuredGraph graph = new StructuredGraph.Builder(replacements.options, debug).method(methodToParse).trackNodeSourcePosition(trackNodeSourcePosition).callerContext(
+ replaceePosition).build();
// Replacements are not user code so they do not participate in unsafe access
// tracking
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounterNode.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounterNode.java
index cdf3c60dbfb..b5fffd62580 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounterNode.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetCounterNode.java
@@ -156,7 +156,7 @@ public class SnippetCounterNode extends FixedWithNextNode implements Lowerable {
args.addConst("counter", counter.getCounter());
args.add("increment", counter.getIncrement());
- template(counter.getDebug(), args).instantiate(providers.getMetaAccess(), counter, DEFAULT_REPLACER, args);
+ template(counter, args).instantiate(providers.getMetaAccess(), counter, DEFAULT_REPLACER, args);
}
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java
index c53b361159d..fa80b3e1b1d 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java
@@ -47,27 +47,15 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Predicate;
-import jdk.vm.ci.code.TargetDescription;
-import jdk.vm.ci.meta.Constant;
-import jdk.vm.ci.meta.JavaConstant;
-import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.Local;
-import jdk.vm.ci.meta.LocalVariableTable;
-import jdk.vm.ci.meta.MetaAccessProvider;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.vm.ci.meta.ResolvedJavaType;
-import jdk.vm.ci.meta.Signature;
-import jdk.vm.ci.meta.ResolvedJavaMethod.Parameter;
-
import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.EconomicSet;
import org.graalvm.collections.Equivalence;
import org.graalvm.collections.UnmodifiableEconomicMap;
import org.graalvm.compiler.api.replacements.Snippet;
-import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter;
import org.graalvm.compiler.api.replacements.Snippet.NonNullParameter;
import org.graalvm.compiler.api.replacements.Snippet.VarargsParameter;
+import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
import org.graalvm.compiler.core.common.GraalOptions;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.core.common.type.StampFactory;
@@ -76,14 +64,15 @@ import org.graalvm.compiler.core.common.type.TypeReference;
import org.graalvm.compiler.debug.CounterKey;
import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugContext.Description;
import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.debug.TimerKey;
-import org.graalvm.compiler.debug.DebugContext.Description;
+import org.graalvm.compiler.graph.Graph.Mark;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.graph.NodeSourcePosition;
import org.graalvm.compiler.graph.Position;
-import org.graalvm.compiler.graph.Graph.Mark;
import org.graalvm.compiler.loop.LoopEx;
import org.graalvm.compiler.loop.LoopsData;
import org.graalvm.compiler.loop.phases.LoopTransformations;
@@ -97,20 +86,21 @@ import org.graalvm.compiler.nodes.DeoptimizingNode;
import org.graalvm.compiler.nodes.FixedNode;
import org.graalvm.compiler.nodes.FixedWithNextNode;
import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.InliningLog;
import org.graalvm.compiler.nodes.LoopBeginNode;
import org.graalvm.compiler.nodes.MergeNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.PhiNode;
+import org.graalvm.compiler.nodes.PiNode.Placeholder;
+import org.graalvm.compiler.nodes.PiNode.PlaceholderStamp;
import org.graalvm.compiler.nodes.ReturnNode;
import org.graalvm.compiler.nodes.StartNode;
import org.graalvm.compiler.nodes.StateSplit;
import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.StructuredGraph.GuardsStage;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.ValueNodeUtil;
-import org.graalvm.compiler.nodes.PiNode.Placeholder;
-import org.graalvm.compiler.nodes.PiNode.PlaceholderStamp;
-import org.graalvm.compiler.nodes.StructuredGraph.GuardsStage;
import org.graalvm.compiler.nodes.calc.FloatingNode;
import org.graalvm.compiler.nodes.java.LoadIndexedNode;
import org.graalvm.compiler.nodes.java.StoreIndexedNode;
@@ -131,10 +121,10 @@ import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
import org.graalvm.compiler.phases.common.FloatingReadPhase;
+import org.graalvm.compiler.phases.common.FloatingReadPhase.MemoryMapImpl;
import org.graalvm.compiler.phases.common.GuardLoweringPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
import org.graalvm.compiler.phases.common.RemoveValueProxyPhase;
-import org.graalvm.compiler.phases.common.FloatingReadPhase.MemoryMapImpl;
import org.graalvm.compiler.phases.common.inlining.InliningUtil;
import org.graalvm.compiler.phases.tiers.PhaseContext;
import org.graalvm.compiler.phases.util.Providers;
@@ -144,6 +134,18 @@ import org.graalvm.util.CollectionsUtil;
import org.graalvm.word.LocationIdentity;
import org.graalvm.word.WordBase;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.Local;
+import jdk.vm.ci.meta.LocalVariableTable;
+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;
+import jdk.vm.ci.meta.Signature;
+
/**
* A snippet template is a graph created by parsing a snippet method and then specialized by binding
* constants to the snippet's {@link ConstantParameter} parameters.
@@ -565,7 +567,7 @@ public class SnippetTemplate {
static class Options {
@Option(help = "Use a LRU cache for snippet templates.")//
- static final OptionKey UseSnippetTemplateCache = new OptionKey<>(true);
+ public static final OptionKey UseSnippetTemplateCache = new OptionKey<>(true);
@Option(help = "")//
static final OptionKey MaxTemplatesPerSnippet = new OptionKey<>(50);
@@ -618,7 +620,7 @@ public class SnippetTemplate {
assert method.getAnnotation(Snippet.class) != null : method + " must be annotated with @" + Snippet.class.getSimpleName();
assert findMethod(declaringClass, methodName, method) == null : "found more than one method named " + methodName + " in " + declaringClass;
ResolvedJavaMethod javaMethod = providers.getMetaAccess().lookupJavaMethod(method);
- providers.getReplacements().registerSnippet(javaMethod);
+ providers.getReplacements().registerSnippet(javaMethod, GraalOptions.TrackNodeSourcePosition.getValue(options));
LocationIdentity[] privateLocations = GraalOptions.SnippetCounters.getValue(options) ? SnippetCounterNode.addSnippetCounters(initialPrivateLocations) : initialPrivateLocations;
if (GraalOptions.EagerSnippets.getValue(options)) {
return new EagerSnippetInfo(javaMethod, privateLocations);
@@ -641,13 +643,15 @@ public class SnippetTemplate {
* Gets a template for a given key, creating it first if necessary.
*/
@SuppressWarnings("try")
- protected SnippetTemplate template(DebugContext outer, final Arguments args) {
+ protected SnippetTemplate template(ValueNode replacee, final Arguments args) {
+ StructuredGraph graph = replacee.graph();
+ DebugContext outer = graph.getDebug();
SnippetTemplate template = Options.UseSnippetTemplateCache.getValue(options) && args.cacheable ? templates.get(args.cacheKey) : null;
- if (template == null) {
+ if (template == null || (graph.trackNodeSourcePosition() && !template.snippet.trackNodeSourcePosition())) {
try (DebugContext debug = openDebugContext(outer, args)) {
try (DebugCloseable a = SnippetTemplateCreationTime.start(debug); DebugContext.Scope s = debug.scope("SnippetSpecialization", args.info.method)) {
SnippetTemplates.increment(debug);
- template = new SnippetTemplate(options, debug, providers, snippetReflection, args);
+ template = new SnippetTemplate(options, debug, providers, snippetReflection, args, graph.trackNodeSourcePosition(), replacee);
if (Options.UseSnippetTemplateCache.getValue(options) && args.cacheable) {
templates.put(args.cacheKey, template);
}
@@ -697,12 +701,13 @@ public class SnippetTemplate {
* Creates a snippet template.
*/
@SuppressWarnings("try")
- protected SnippetTemplate(OptionValues options, DebugContext debug, final Providers providers, SnippetReflectionProvider snippetReflection, Arguments args) {
+ protected SnippetTemplate(OptionValues options, DebugContext debug, final Providers providers, SnippetReflectionProvider snippetReflection, Arguments args, boolean trackNodeSourcePosition,
+ Node replacee) {
this.snippetReflection = snippetReflection;
this.info = args.info;
Object[] constantArgs = getConstantArgs(args);
- StructuredGraph snippetGraph = providers.getReplacements().getSnippet(args.info.method, args.info.original, constantArgs);
+ StructuredGraph snippetGraph = providers.getReplacements().getSnippet(args.info.method, args.info.original, constantArgs, trackNodeSourcePosition, replacee.getNodeSourcePosition());
ResolvedJavaMethod method = snippetGraph.method();
Signature signature = method.getSignature();
@@ -710,8 +715,12 @@ public class SnippetTemplate {
PhaseContext phaseContext = new PhaseContext(providers);
// Copy snippet graph, replacing constant parameters with given arguments
- final StructuredGraph snippetCopy = new StructuredGraph.Builder(options, debug).name(snippetGraph.name).method(snippetGraph.method()).build();
-
+ final StructuredGraph snippetCopy = new StructuredGraph.Builder(options, debug).name(snippetGraph.name).method(snippetGraph.method()).trackNodeSourcePosition(
+ snippetGraph.trackNodeSourcePosition()).build();
+ assert !GraalOptions.TrackNodeSourcePosition.getValue(options) || snippetCopy.trackNodeSourcePosition();
+ if (providers.getCodeCache() != null && providers.getCodeCache().shouldDebugNonSafepoints()) {
+ snippetCopy.setTrackNodeSourcePosition();
+ }
try (DebugContext.Scope scope = debug.scope("SpecializeSnippet", snippetCopy)) {
if (!snippetGraph.isUnsafeAccessTrackingEnabled()) {
snippetCopy.disableUnsafeAccessTracking();
@@ -755,7 +764,12 @@ public class SnippetTemplate {
}
}
}
- snippetCopy.addDuplicates(snippetGraph.getNodes(), snippetGraph, snippetGraph.getNodeCount(), nodeReplacements);
+ try (InliningLog.UpdateScope updateScope = snippetCopy.getInliningLog().openDefaultUpdateScope()) {
+ UnmodifiableEconomicMap duplicates = snippetCopy.addDuplicates(snippetGraph.getNodes(), snippetGraph, snippetGraph.getNodeCount(), nodeReplacements);
+ if (updateScope != null) {
+ snippetCopy.getInliningLog().replaceLog(duplicates, snippetGraph.getInliningLog());
+ }
+ }
debug.dump(DebugContext.INFO_LEVEL, snippetCopy, "Before specialization");
@@ -1396,8 +1410,7 @@ public class SnippetTemplate {
StructuredGraph replaceeGraph = replacee.graph();
EconomicMap replacements = bind(replaceeGraph, metaAccess, args);
replacements.put(entryPointNode, AbstractBeginNode.prevBegin(replacee));
- UnmodifiableEconomicMap duplicates = replaceeGraph.addDuplicates(nodes, snippet, snippet.getNodeCount(), replacements);
- debug.dump(DebugContext.DETAILED_LEVEL, replaceeGraph, "After inlining snippet %s", snippet.method());
+ UnmodifiableEconomicMap duplicates = inlineSnippet(replacee, debug, replaceeGraph, replacements);
// Re-wire the control flow graph around the replacee
FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode);
@@ -1490,6 +1503,27 @@ public class SnippetTemplate {
}
}
+ private UnmodifiableEconomicMap inlineSnippet(Node replacee, DebugContext debug, StructuredGraph replaceeGraph, EconomicMap replacements) {
+ Mark mark = replaceeGraph.getMark();
+ try (InliningLog.UpdateScope scope = replaceeGraph.getInliningLog().openUpdateScope((oldNode, newNode) -> {
+ InliningLog log = replaceeGraph.getInliningLog();
+ if (oldNode == null) {
+ log.trackNewCallsite(newNode);
+ }
+ })) {
+ UnmodifiableEconomicMap duplicates = replaceeGraph.addDuplicates(nodes, snippet, snippet.getNodeCount(), replacements);
+ if (scope != null) {
+ replaceeGraph.getInliningLog().addLog(duplicates, snippet.getInliningLog());
+ }
+ NodeSourcePosition position = replacee.getNodeSourcePosition();
+ if (position != null) {
+ InliningUtil.updateSourcePosition(replaceeGraph, duplicates, mark, position, true);
+ }
+ debug.dump(DebugContext.DETAILED_LEVEL, replaceeGraph, "After inlining snippet %s", snippet.method());
+ return duplicates;
+ }
+ }
+
private void propagateStamp(Node node) {
if (node instanceof PhiNode) {
PhiNode phi = (PhiNode) node;
@@ -1549,8 +1583,7 @@ public class SnippetTemplate {
StructuredGraph replaceeGraph = replacee.graph();
EconomicMap replacements = bind(replaceeGraph, metaAccess, args);
replacements.put(entryPointNode, tool.getCurrentGuardAnchor().asNode());
- UnmodifiableEconomicMap duplicates = replaceeGraph.addDuplicates(nodes, snippet, snippet.getNodeCount(), replacements);
- debug.dump(DebugContext.DETAILED_LEVEL, replaceeGraph, "After inlining snippet %s", snippet.method());
+ UnmodifiableEconomicMap duplicates = inlineSnippet(replacee, debug, replaceeGraph, replacements);
FixedWithNextNode lastFixedNode = tool.lastFixedNode();
assert lastFixedNode != null && lastFixedNode.isAlive() : replaceeGraph + " lastFixed=" + lastFixedNode;
@@ -1611,8 +1644,7 @@ public class SnippetTemplate {
floatingNodes.add(n);
}
}
- UnmodifiableEconomicMap duplicates = replaceeGraph.addDuplicates(floatingNodes, snippet, floatingNodes.size(), replacements);
- debug.dump(DebugContext.DETAILED_LEVEL, replaceeGraph, "After inlining snippet %s", snippet.method());
+ UnmodifiableEconomicMap duplicates = inlineSnippet(replacee, debug, replaceeGraph, replacements);
rewireFrameStates(replacee, duplicates);
updateStamps(replacee, duplicates);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java
index ddc64e3839d..8793b1eba4d 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java
@@ -385,6 +385,23 @@ public class StandardGraphBuilderPlugins {
if (allowDeoptimization) {
for (JavaKind kind : new JavaKind[]{JavaKind.Int, JavaKind.Long}) {
Class> type = kind.toJavaClass();
+
+ r.register1("decrementExact", type, new InvocationPlugin() {
+ @Override
+ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x) {
+ b.addPush(kind, new IntegerSubExactNode(x, ConstantNode.forIntegerKind(kind, 1)));
+ return true;
+ }
+ });
+
+ r.register1("incrementExact", type, new InvocationPlugin() {
+ @Override
+ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x) {
+ b.addPush(kind, new IntegerAddExactNode(x, ConstantNode.forIntegerKind(kind, 1)));
+ return true;
+ }
+ });
+
r.register2("addExact", type, type, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
@@ -392,6 +409,7 @@ public class StandardGraphBuilderPlugins {
return true;
}
});
+
r.register2("subtractExact", type, type, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
@@ -399,6 +417,7 @@ public class StandardGraphBuilderPlugins {
return true;
}
});
+
r.register2("multiplyExact", type, type, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StringSubstitutions.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StringSubstitutions.java
index b0d8b1aa89f..eee3b1a9643 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StringSubstitutions.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StringSubstitutions.java
@@ -63,5 +63,5 @@ public class StringSubstitutions {
/**
* Will be intrinsified with an {@link InvocationPlugin} to a {@link LoadFieldNode}.
*/
- private static native char[] getValue(String s);
+ public static native char[] getValue(String s);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java
index 88403c39fa4..f3d9ea9faed 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/ClassfileBytecodeProvider.java
@@ -101,8 +101,8 @@ public final class ClassfileBytecodeProvider implements BytecodeProvider {
private static InputStream getClassfileAsStream(Class> c) {
String classfilePath = c.getName().replace('.', '/') + ".class";
if (JDK9Method.JAVA_SPECIFICATION_VERSION >= 9) {
- Object module = getModule.invoke(c);
- return getResourceAsStream.invoke(module, classfilePath);
+ Object module = getModule(c);
+ return getResourceAsStream(module, classfilePath);
} else {
ClassLoader cl = c.getClassLoader();
if (cl == null) {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayCompareToNode.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayCompareToNode.java
new file mode 100644
index 00000000000..f290b2494fb
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ArrayCompareToNode.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2017, 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.nodes;
+
+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.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.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.ValueNodeUtil;
+import org.graalvm.compiler.nodes.memory.MemoryAccess;
+import org.graalvm.compiler.nodes.memory.MemoryNode;
+import org.graalvm.compiler.nodes.spi.LIRLowerable;
+import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
+import org.graalvm.compiler.nodes.spi.Virtualizable;
+import org.graalvm.compiler.nodes.spi.VirtualizerTool;
+import org.graalvm.compiler.nodes.util.GraphUtil;
+import org.graalvm.word.LocationIdentity;
+
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.Value;
+
+// JaCoCo Exclude
+
+/**
+ * Compares two arrays lexicographically.
+ */
+@NodeInfo(cycles = CYCLES_1024, size = SIZE_1024)
+public final class ArrayCompareToNode extends FixedWithNextNode implements LIRLowerable, Canonicalizable, Virtualizable, MemoryAccess {
+
+ public static final NodeClass TYPE = NodeClass.create(ArrayCompareToNode.class);
+
+ /** {@link JavaKind} of one array to compare. */
+ protected final JavaKind kind1;
+
+ /** {@link JavaKind} of the other array to compare. */
+ protected final JavaKind kind2;
+
+ /** One array to be tested for equality. */
+ @Input ValueNode array1;
+
+ /** The other array to be tested for equality. */
+ @Input ValueNode array2;
+
+ /** Length of one array. */
+ @Input ValueNode length1;
+
+ /** Length of the other array. */
+ @Input ValueNode length2;
+
+ @OptionalInput(Memory) MemoryNode lastLocationAccess;
+
+ public ArrayCompareToNode(ValueNode array1, ValueNode array2, ValueNode length1, ValueNode length2, @ConstantNodeParameter JavaKind kind1, @ConstantNodeParameter JavaKind kind2) {
+ super(TYPE, StampFactory.forKind(JavaKind.Int));
+ this.kind1 = kind1;
+ this.kind2 = kind2;
+ this.array1 = array1;
+ this.array2 = array2;
+ this.length1 = length1;
+ this.length2 = length2;
+ }
+
+ @Override
+ public Node canonical(CanonicalizerTool tool) {
+ if (tool.allUsagesAvailable() && hasNoUsages()) {
+ return null;
+ }
+ ValueNode a1 = GraphUtil.unproxify(array1);
+ ValueNode a2 = GraphUtil.unproxify(array2);
+ if (a1 == a2) {
+ return ConstantNode.forInt(0);
+ }
+ return this;
+ }
+
+ @Override
+ public void virtualize(VirtualizerTool tool) {
+ ValueNode alias1 = tool.getAlias(array1);
+ ValueNode alias2 = tool.getAlias(array2);
+ if (alias1 == alias2) {
+ // the same virtual objects will always have the same contents
+ tool.replaceWithValue(ConstantNode.forInt(0, graph()));
+ }
+ }
+
+ @NodeIntrinsic
+ public static native int compareTo(Object array1, Object array2, int length1, int length2, @ConstantNodeParameter JavaKind kind1, @ConstantNodeParameter JavaKind kind2);
+
+ @Override
+ public void generate(NodeLIRBuilderTool gen) {
+ Value result = gen.getLIRGeneratorTool().emitArrayCompareTo(kind1, kind2, gen.operand(array1), gen.operand(array2), gen.operand(length1), gen.operand(length2));
+ gen.setResult(this, result);
+ }
+
+ @Override
+ public LocationIdentity getLocationIdentity() {
+ return NamedLocationIdentity.getArrayLocation(kind1);
+ }
+
+ @Override
+ public MemoryNode getLastLocationAccess() {
+ return lastLocationAccess;
+ }
+
+ @Override
+ public void setLastLocationAccess(MemoryNode lla) {
+ updateUsages(ValueNodeUtil.asNode(lastLocationAccess), ValueNodeUtil.asNode(lla));
+ lastLocationAccess = lla;
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java
index 1c336b1517d..9372e31edfc 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java
@@ -29,12 +29,16 @@ import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_UNKNOWN;
import org.graalvm.compiler.api.replacements.MethodSubstitution;
import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.core.common.type.StampPair;
+import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.GraalError;
+import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.NodeInputList;
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.InvokeNode;
@@ -75,7 +79,7 @@ import jdk.vm.ci.meta.ResolvedJavaMethod;
size = SIZE_UNKNOWN,
sizeRationale = "If this node is not optimized away it will be lowered to a call, which we cannot estimate")
//@formatter:on
-public abstract class MacroNode extends FixedWithNextNode implements Lowerable {
+public abstract class MacroNode extends FixedWithNextNode implements Lowerable, Invokable {
public static final NodeClass TYPE = NodeClass.create(MacroNode.class);
@Input protected NodeInputList arguments;
@@ -108,10 +112,12 @@ public abstract class MacroNode extends FixedWithNextNode implements Lowerable {
return arguments.toArray(new ValueNode[0]);
}
- public int getBci() {
+ @Override
+ public int bci() {
return bci;
}
+ @Override
public ResolvedJavaMethod getTargetMethod() {
return targetMethod;
}
@@ -120,6 +126,16 @@ public abstract class MacroNode extends FixedWithNextNode implements Lowerable {
return null;
}
+ @Override
+ protected void afterClone(Node other) {
+ updateInliningLogAfterClone(other);
+ }
+
+ @Override
+ public FixedNode asFixedNode() {
+ return this;
+ }
+
/**
* Gets a snippet to be used for lowering this macro node. The returned graph (if non-null) must
* have been {@linkplain #lowerReplacement(StructuredGraph, LoweringTool) lowered}.
@@ -196,10 +212,13 @@ public abstract class MacroNode extends FixedWithNextNode implements Lowerable {
}
}
+ @SuppressWarnings("try")
public InvokeNode replaceWithInvoke() {
- InvokeNode invoke = createInvoke();
- graph().replaceFixedWithFixed(this, invoke);
- return invoke;
+ try (DebugCloseable context = withNodeSourcePosition()) {
+ InvokeNode invoke = createInvoke();
+ graph().replaceFixedWithFixed(this, invoke);
+ return invoke;
+ }
}
protected InvokeNode createInvoke() {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroStateSplitNode.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroStateSplitNode.java
index ee3df767dcf..08535f3f95c 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroStateSplitNode.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroStateSplitNode.java
@@ -85,7 +85,7 @@ public abstract class MacroStateSplitNode extends MacroNode implements StateSpli
}
assert invoke.stateAfter().bci == BytecodeFrame.AFTER_BCI;
// Here we need to fix the bci of the invoke
- InvokeNode newInvoke = snippetGraph.add(new InvokeNode(invoke.callTarget(), getBci()));
+ InvokeNode newInvoke = snippetGraph.add(new InvokeNode(invoke.callTarget(), bci()));
newInvoke.setStateAfter(invoke.stateAfter());
snippetGraph.replaceFixedWithFixed((InvokeNode) invoke.asNode(), newInvoke);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java
index 1f0a4483b4b..7821191c735 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java
@@ -54,14 +54,18 @@ public final class GraalServices {
* @param other all JVMCI packages will be opened to the module defining this class
*/
public static void openJVMCITo(Class> other) {
- Object jvmci = getModule.invoke(Services.class);
- Object otherModule = getModule.invoke(other);
+ Object jvmci = getModule(Services.class);
+ Object otherModule = getModule(other);
if (jvmci != otherModule) {
- Set packages = getPackages.invoke(jvmci);
+ Set packages = getPackages(jvmci);
for (String pkg : packages) {
- boolean opened = isOpenTo.invoke(jvmci, pkg, otherModule);
+ boolean opened = isOpenTo(jvmci, pkg, otherModule);
if (!opened) {
- addOpens.invoke(jvmci, pkg, otherModule);
+ try {
+ addOpens.invoke(jvmci, pkg, otherModule);
+ } catch (Throwable throwable) {
+ throw new InternalError(throwable);
+ }
}
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/JDK9Method.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/JDK9Method.java
index 17c8ae0dbbb..e8eb639db2b 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/JDK9Method.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/JDK9Method.java
@@ -22,9 +22,11 @@
*/
package org.graalvm.compiler.serviceprovider;
-import java.lang.reflect.InvocationTargetException;
+import java.io.InputStream;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
+import java.util.Set;
/**
* Reflection based access to API introduced by JDK 9. This allows the API to be used in code that
@@ -46,9 +48,17 @@ public final class JDK9Method {
*/
public static final int JAVA_SPECIFICATION_VERSION = getJavaSpecificationVersion();
- public JDK9Method(Class> declaringClass, String name, Class>... parameterTypes) {
+ public static MethodHandle lookupMethodHandle(Class> declaringClass, String name, Class>... parameterTypes) {
try {
- this.method = declaringClass.getMethod(name, parameterTypes);
+ return MethodHandles.lookup().unreflect(declaringClass.getMethod(name, parameterTypes));
+ } catch (Exception e) {
+ throw new InternalError(e);
+ }
+ }
+
+ private static Method lookupMethod(Class> declaringClass, String name, Class>... parameterTypes) {
+ try {
+ return declaringClass.getMethod(name, parameterTypes);
} catch (Exception e) {
throw new InternalError(e);
}
@@ -59,90 +69,85 @@ public final class JDK9Method {
*/
public static final boolean Java8OrEarlier = JAVA_SPECIFICATION_VERSION <= 8;
- public final Method method;
-
- public Class> getReturnType() {
- return method.getReturnType();
- }
-
/**
* {@code Class.getModule()}.
*/
- public static final JDK9Method getModule;
+ private static final MethodHandle getModuleHandle;
+
+ public static Object getModule(Class> clazz) {
+ try {
+ return getModuleHandle.invoke(clazz);
+ } catch (Throwable throwable) {
+ throw new InternalError(throwable);
+ }
+ }
/**
* {@code java.lang.Module.getPackages()}.
*/
- public static final JDK9Method getPackages;
+ private static final MethodHandle getPackages;
+
+ public static Set getPackages(Object module) {
+ try {
+ return (Set) getPackages.invoke(module);
+ } catch (Throwable throwable) {
+ throw new InternalError(throwable);
+ }
+ }
/**
* {@code java.lang.Module.getResourceAsStream(String)}.
*/
- public static final JDK9Method getResourceAsStream;
+ private static final MethodHandle getResourceAsStream;
+
+ public static InputStream getResourceAsStream(Object module, String resource) {
+ try {
+ return (InputStream) getResourceAsStream.invoke(module, resource);
+ } catch (Throwable throwable) {
+ throw new InternalError(throwable);
+ }
+ }
/**
- * {@code java.lang.Module.addOpens(String, Module)}.
+ * {@code java.lang.Module.addOpens(String, Module)}. This only seems to work correctly when
+ * invoked through reflection.
*/
- public static final JDK9Method addOpens;
+ public static final Method addOpens;
/**
* {@code java.lang.Module.isOpen(String, Module)}.
*/
- public static final JDK9Method isOpenTo;
+ private static final MethodHandle isOpenTo;
- /**
- * Invokes the static Module API method represented by this object.
- */
- @SuppressWarnings("unchecked")
- public T invokeStatic(Object... args) {
- checkAvailability();
- assert Modifier.isStatic(method.getModifiers());
+ public static boolean isOpenTo(Object module1, String pkg, Object module2) {
try {
- return (T) method.invoke(null, args);
- } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
- throw new InternalError(e);
+ return (boolean) isOpenTo.invoke(module1, pkg, module2);
+ } catch (Throwable throwable) {
+ throw new InternalError(throwable);
}
}
- /**
- * Invokes the non-static Module API method represented by this object.
- */
- @SuppressWarnings("unchecked")
- public T invoke(Object receiver, Object... args) {
- checkAvailability();
- assert !Modifier.isStatic(method.getModifiers());
- try {
- return (T) method.invoke(receiver, args);
- } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
- throw new InternalError(e);
- }
- }
-
- private void checkAvailability() throws InternalError {
- if (method == null) {
- throw new InternalError("Cannot use Module API on JDK " + JAVA_SPECIFICATION_VERSION);
- }
- }
+ public static final Class> MODULE_CLASS;
static {
if (JAVA_SPECIFICATION_VERSION >= 9) {
- getModule = new JDK9Method(Class.class, "getModule");
- Class> moduleClass = getModule.getReturnType();
- getPackages = new JDK9Method(moduleClass, "getPackages");
- addOpens = new JDK9Method(moduleClass, "addOpens", String.class, moduleClass);
- getResourceAsStream = new JDK9Method(moduleClass, "getResourceAsStream", String.class);
- isOpenTo = new JDK9Method(moduleClass, "isOpen", String.class, moduleClass);
+ try {
+ MODULE_CLASS = Class.class.getMethod("getModule").getReturnType();
+ getModuleHandle = lookupMethodHandle(Class.class, "getModule");
+ getPackages = lookupMethodHandle(MODULE_CLASS, "getPackages");
+ addOpens = lookupMethod(MODULE_CLASS, "addOpens", String.class, MODULE_CLASS);
+ getResourceAsStream = lookupMethodHandle(MODULE_CLASS, "getResourceAsStream", String.class);
+ isOpenTo = lookupMethodHandle(MODULE_CLASS, "isOpen", String.class, MODULE_CLASS);
+ } catch (NoSuchMethodException e) {
+ throw new InternalError(e);
+ }
} else {
- JDK9Method unavailable = new JDK9Method();
- getModule = unavailable;
- getPackages = unavailable;
- addOpens = unavailable;
- getResourceAsStream = unavailable;
- isOpenTo = unavailable;
+ MODULE_CLASS = null;
+ getModuleHandle = null;
+ getPackages = null;
+ addOpens = null;
+ getResourceAsStream = null;
+ isOpenTo = null;
}
}
-
- private JDK9Method() {
- method = null;
- }
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/ProtocolImpl.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/ProtocolImpl.java
index a6ef36838e1..2bb39b3c0cd 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/ProtocolImpl.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/ProtocolImpl.java
@@ -128,7 +128,11 @@ final class ProtocolImpl) && findJavaTypeName(type) == null) {
+ throw new IllegalStateException("nodeClassType method shall return a Java class (instance of Class)! Was: " + type);
+ }
+ return type;
}
@Override
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.micro.benchmarks/src/micro/benchmarks/StringBenchmark.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.micro.benchmarks/src/micro/benchmarks/StringBenchmark.java
index b6c8a127314..a5a7925e724 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.micro.benchmarks/src/micro/benchmarks/StringBenchmark.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.micro.benchmarks/src/micro/benchmarks/StringBenchmark.java
@@ -45,6 +45,7 @@ public class StringBenchmark extends BenchmarkBase {
// Checkstyle: stop
String lorem = "Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
+ String loremLastChar = "Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum?";
// Checkstyle: resume
}
@@ -71,4 +72,10 @@ public class StringBenchmark extends BenchmarkBase {
public int indexOfStringNotFound(BenchState state) {
return state.lorem.indexOf(state.s2);
}
+
+ @Benchmark
+ @Warmup(iterations = 5)
+ public int compareTo(BenchState state) {
+ return state.lorem.compareTo(state.loremLastChar);
+ }
}