--- a/src/jdk.internal.vm.compiler/.mx.graal/suite.py Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/.mx.graal/suite.py Wed Dec 13 12:28:22 2017 -0800
@@ -107,7 +107,6 @@
"subDir" : "share/classes",
"dependencies" : ["JVMCI_SERVICES", "JVMCI_API", "org.graalvm.util"],
"sourceDirs" : ["src"],
- "dependencies" : ["org.graalvm.util"],
"checkstyle" : "org.graalvm.compiler.graph",
"uses" : ["org.graalvm.compiler.options.OptionDescriptors"],
"javaCompliance" : "1.8",
@@ -148,6 +147,7 @@
"dependencies" : [
"JVMCI_API",
"org.graalvm.compiler.serviceprovider",
+ "org.graalvm.graphio",
"org.graalvm.compiler.options"
],
"annotationProcessors" : ["GRAAL_OPTIONS_PROCESSOR"],
@@ -291,7 +291,6 @@
"subDir" : "share/classes",
"sourceDirs" : ["src"],
"dependencies" : [
- "org.graalvm.compiler.core.aarch64",
"org.graalvm.compiler.hotspot",
"org.graalvm.compiler.replacements.aarch64",
],
@@ -435,6 +434,7 @@
"mx:JUNIT",
"org.graalvm.compiler.api.test",
"org.graalvm.compiler.graph",
+ "org.graalvm.graphio",
],
"annotationProcessors" : ["GRAAL_NODEINFO_PROCESSOR"],
"javaCompliance" : "1.8",
@@ -945,6 +945,7 @@
"dependencies" : [
"org.graalvm.compiler.lir.jtt",
"org.graalvm.compiler.lir.amd64",
+ "org.graalvm.compiler.core.amd64",
"JVMCI_HOTSPOT"
],
"checkstyle" : "org.graalvm.compiler.graph",
@@ -1019,7 +1020,6 @@
"subDir" : "share/classes",
"sourceDirs" : ["src"],
"dependencies" : [
- "org.graalvm.graphio",
"org.graalvm.compiler.core",
"org.graalvm.compiler.java",
],
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LIRKindTool.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LIRKindTool.java Wed Dec 13 12:28:22 2017 -0800
@@ -68,7 +68,7 @@
@Override
public LIRKind getNarrowOopKind() {
- return LIRKind.reference(AArch64Kind.DWORD);
+ return LIRKind.compressedReference(AArch64Kind.DWORD);
}
@Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/LIRKind.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/LIRKind.java Wed Dec 13 12:28:22 2017 -0800
@@ -33,8 +33,9 @@
/**
* Represents the type of values in the LIR. It is composed of a {@link PlatformKind} that gives the
- * low level representation of the value, and a {@link #referenceMask} that describes the location
- * of object references in the value, and optionally a {@link #derivedReferenceBase}.
+ * low level representation of the value, a {@link #referenceMask} that describes the location of
+ * object references in the value, a {@link #referenceCompressionMask} that indicates which of these
+ * references are compressed references, and for derived references a {@link #derivedReferenceBase}.
*
* <h2>Constructing {@link LIRKind} instances</h2>
*
@@ -52,7 +53,7 @@
* compare-and-swap. For convert operations, {@link LIRKind#combine} should be used.
* <p>
* If it is known that the result will be a reference (e.g. pointer arithmetic where the end result
- * is a valid oop), {@link LIRKind#reference} should be used.
+ * is a valid oop), {@link #reference} or {@link LIRKind#compressedReference} should be used.
* <p>
* If it is known that the result will neither be a reference nor be derived from a reference,
* {@link LIRKind#value} can be used. If the operation producing this value has inputs, this is very
@@ -64,19 +65,28 @@
*/
public final class LIRKind extends ValueKind<LIRKind> {
+ /**
+ * The location of object references in the value. If the value is a vector type, each bit
+ * represents one component of the vector.
+ */
private final int referenceMask;
+ /** Mask with 1-bits indicating which references in {@link #referenceMask} are compressed. */
+ private final int referenceCompressionMask;
+
private AllocatableValue derivedReferenceBase;
private static final int UNKNOWN_REFERENCE = -1;
public static final LIRKind Illegal = unknownReference(ValueKind.Illegal.getPlatformKind());
- private LIRKind(PlatformKind platformKind, int referenceMask, AllocatableValue derivedReferenceBase) {
+ private LIRKind(PlatformKind platformKind, int referenceMask, int referenceCompressionMask, AllocatableValue derivedReferenceBase) {
super(platformKind);
this.referenceMask = referenceMask;
+ this.referenceCompressionMask = referenceCompressionMask;
this.derivedReferenceBase = derivedReferenceBase;
+ assert this.referenceCompressionMask == 0 || this.referenceMask == this.referenceCompressionMask : "mixing compressed and uncompressed references is untested";
assert derivedReferenceBase == null || !derivedReferenceBase.getValueKind(LIRKind.class).isDerivedReference() : "derived reference can't have another derived reference as base";
}
@@ -86,15 +96,23 @@
* reference. Otherwise, {@link #combine(Value...)} should be used instead.
*/
public static LIRKind value(PlatformKind platformKind) {
- return new LIRKind(platformKind, 0, null);
+ return new LIRKind(platformKind, 0, 0, null);
}
/**
- * Create a {@link LIRKind} of type {@code platformKind} that contains a single tracked oop
- * reference.
+ * Create a {@link LIRKind} of type {@code platformKind} that contains a single, tracked,
+ * uncompressed oop reference.
*/
public static LIRKind reference(PlatformKind platformKind) {
- return derivedReference(platformKind, null);
+ return derivedReference(platformKind, null, false);
+ }
+
+ /**
+ * Create a {@link LIRKind} of type {@code platformKind} that contains a single, tracked,
+ * compressed oop reference.
+ */
+ public static LIRKind compressedReference(PlatformKind platformKind) {
+ return derivedReference(platformKind, null, true);
}
/**
@@ -112,10 +130,12 @@
/**
* Create a {@link LIRKind} of type {@code platformKind} that contains a derived reference.
*/
- public static LIRKind derivedReference(PlatformKind platformKind, AllocatableValue base) {
+ public static LIRKind derivedReference(PlatformKind platformKind, AllocatableValue base, boolean compressed) {
int length = platformKind.getVectorLength();
assert 0 < length && length < 32 : "vector of " + length + " references not supported";
- return new LIRKind(platformKind, (1 << length) - 1, base);
+ int referenceMask = (1 << length) - 1;
+ int referenceCompressionMask = (compressed ? referenceMask : 0);
+ return new LIRKind(platformKind, referenceMask, referenceCompressionMask, base);
}
/**
@@ -125,7 +145,7 @@
* used instead to automatically propagate this information.
*/
public static LIRKind unknownReference(PlatformKind platformKind) {
- return new LIRKind(platformKind, UNKNOWN_REFERENCE, null);
+ return new LIRKind(platformKind, UNKNOWN_REFERENCE, UNKNOWN_REFERENCE, null);
}
/**
@@ -139,9 +159,9 @@
return makeUnknownReference();
} else {
if (isValue()) {
- return derivedReference(getPlatformKind(), base);
+ return derivedReference(getPlatformKind(), base, false);
} else {
- return new LIRKind(getPlatformKind(), referenceMask, base);
+ return new LIRKind(getPlatformKind(), referenceMask, referenceCompressionMask, base);
}
}
}
@@ -240,7 +260,7 @@
return mergeKind;
}
/* {@code mergeKind} is a reference. */
- if (mergeKind.referenceMask != inputKind.referenceMask) {
+ if (mergeKind.referenceMask != inputKind.referenceMask || mergeKind.referenceCompressionMask != inputKind.referenceCompressionMask) {
/*
* Reference masks do not match so the result can only be an unknown reference.
*/
@@ -284,9 +304,11 @@
} else {
// reference type
int newLength = Math.min(32, newPlatformKind.getVectorLength());
- int newReferenceMask = referenceMask & (0xFFFFFFFF >>> (32 - newLength));
+ int lengthMask = 0xFFFFFFFF >>> (32 - newLength);
+ int newReferenceMask = referenceMask & lengthMask;
+ int newReferenceCompressionMask = referenceCompressionMask & lengthMask;
assert newReferenceMask != UNKNOWN_REFERENCE;
- return new LIRKind(newPlatformKind, newReferenceMask, derivedReferenceBase);
+ return new LIRKind(newPlatformKind, newReferenceMask, newReferenceCompressionMask, derivedReferenceBase);
}
}
@@ -308,12 +330,14 @@
// repeat reference mask to fill new kind
int newReferenceMask = 0;
+ int newReferenceCompressionMask = 0;
for (int i = 0; i < newLength; i += getPlatformKind().getVectorLength()) {
newReferenceMask |= referenceMask << i;
+ newReferenceCompressionMask |= referenceCompressionMask << i;
}
assert newReferenceMask != UNKNOWN_REFERENCE;
- return new LIRKind(newPlatformKind, newReferenceMask, derivedReferenceBase);
+ return new LIRKind(newPlatformKind, newReferenceMask, newReferenceCompressionMask, derivedReferenceBase);
}
}
@@ -322,7 +346,7 @@
* {@link LIRKind#unknownReference}.
*/
public LIRKind makeUnknownReference() {
- return new LIRKind(getPlatformKind(), UNKNOWN_REFERENCE, null);
+ return new LIRKind(getPlatformKind(), UNKNOWN_REFERENCE, UNKNOWN_REFERENCE, null);
}
/**
@@ -385,6 +409,17 @@
}
/**
+ * Check whether the {@code idx}th part of this value is a <b>compressed</b> reference.
+ *
+ * @param idx The index into the vector if this is a vector kind. Must be 0 if this is a scalar
+ * kind.
+ */
+ public boolean isCompressedReference(int idx) {
+ assert 0 <= idx && idx < getPlatformKind().getVectorLength() : "invalid index " + idx + " in " + this;
+ return !isUnknownReference() && (referenceCompressionMask & (1 << idx)) != 0;
+ }
+
+ /**
* Check whether this kind is a value type that doesn't need to be tracked at safepoints.
*/
public boolean isValue() {
@@ -432,6 +467,7 @@
result = prime * result + ((getPlatformKind() == null) ? 0 : getPlatformKind().hashCode());
result = prime * result + ((getDerivedReferenceBase() == null) ? 0 : getDerivedReferenceBase().hashCode());
result = prime * result + referenceMask;
+ result = prime * result + referenceCompressionMask;
return result;
}
@@ -445,7 +481,7 @@
}
LIRKind other = (LIRKind) obj;
- if (getPlatformKind() != other.getPlatformKind() || referenceMask != other.referenceMask) {
+ if (getPlatformKind() != other.getPlatformKind() || referenceMask != other.referenceMask || referenceCompressionMask != other.referenceCompressionMask) {
return false;
}
if (isDerivedReference()) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/CompilationAlarm.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/CompilationAlarm.java Wed Dec 13 12:28:22 2017 -0800
@@ -22,6 +22,7 @@
*/
package org.graalvm.compiler.core.common.util;
+import org.graalvm.compiler.debug.Assertions;
import org.graalvm.compiler.options.Option;
import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionType;
@@ -34,7 +35,8 @@
public static class Options {
// @formatter:off
- @Option(help = "Time limit in seconds before a compilation expires (0 to disable the limit).", type = OptionType.Debug)
+ @Option(help = "Time limit in seconds before a compilation expires (0 to disable the limit). " +
+ "The compilation alarm will be implicitly disabled if assertions are enabled.", type = OptionType.Debug)
public static final OptionKey<Integer> CompilationExpirationPeriod = new OptionKey<>(300);
// @formatter:on
}
@@ -85,15 +87,16 @@
/**
* Starts an alarm for setting a time limit on a compilation if there isn't already an active
- * alarm and {@link CompilationAlarm.Options#CompilationExpirationPeriod}{@code > 0}. The
- * returned value can be used in a try-with-resource statement to disable the alarm once the
- * compilation is finished.
+ * alarm, if assertions are disabled and
+ * {@link CompilationAlarm.Options#CompilationExpirationPeriod}{@code > 0}. The returned value
+ * can be used in a try-with-resource statement to disable the alarm once the compilation is
+ * finished.
*
* @return a {@link CompilationAlarm} if there was no current alarm for the calling thread
* before this call otherwise {@code null}
*/
public static CompilationAlarm trackCompilationPeriod(OptionValues options) {
- int period = Options.CompilationExpirationPeriod.getValue(options);
+ int period = Assertions.assertionsEnabled() ? 0 : Options.CompilationExpirationPeriod.getValue(options);
if (period > 0) {
CompilationAlarm current = currentAlarm.get();
if (current == null) {
@@ -105,4 +108,5 @@
}
return null;
}
+
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCLIRKindTool.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCLIRKindTool.java Wed Dec 13 12:28:22 2017 -0800
@@ -68,7 +68,7 @@
@Override
public LIRKind getNarrowOopKind() {
- return LIRKind.reference(SPARCKind.WORD);
+ return LIRKind.compressedReference(SPARCKind.WORD);
}
@Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CooperativePhaseTest.java Wed Dec 13 11:59:55 2017 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-/*
- * Copyright (c) 2016, 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.core.common.util.CompilationAlarm.Options.CompilationExpirationPeriod;
-
-import org.graalvm.compiler.core.common.RetryableBailoutException;
-import org.graalvm.compiler.core.common.util.CompilationAlarm;
-import org.graalvm.compiler.debug.GraalError;
-import org.graalvm.compiler.nodes.StructuredGraph;
-import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
-import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.phases.Phase;
-import org.junit.Test;
-
-public class CooperativePhaseTest extends GraalCompilerTest {
-
- public static void snippet() {
- // dummy snippet
- }
-
- private static class CooperativePhase extends Phase {
-
- @Override
- protected void run(StructuredGraph graph) {
- CompilationAlarm compilationAlarm = CompilationAlarm.current();
- while (true) {
- sleep(200);
- if (compilationAlarm.hasExpired()) {
- return;
- }
- }
- }
-
- }
-
- private static class UnCooperativePhase extends Phase {
-
- @Override
- protected void run(StructuredGraph graph) {
- CompilationAlarm compilationAlarm = CompilationAlarm.current();
- while (true) {
- sleep(200);
- if (compilationAlarm.hasExpired()) {
- throw new RetryableBailoutException("Expiring...");
- }
- }
- }
-
- }
-
- private static class PartiallyCooperativePhase extends Phase {
-
- @Override
- protected void run(StructuredGraph graph) {
- CompilationAlarm compilationAlarm = CompilationAlarm.current();
- for (int i = 0; i < 10; i++) {
- sleep(200);
- if (compilationAlarm.hasExpired()) {
- throw new RuntimeException("Phase must not exit in the timeout path");
- }
- }
- }
- }
-
- private static class CooperativePhaseWithoutAlarm extends Phase {
-
- @Override
- protected void run(StructuredGraph graph) {
- CompilationAlarm compilationAlarm = CompilationAlarm.current();
- if (compilationAlarm.hasExpired()) {
- throw new RuntimeException("Phase must not exit in the timeout path");
- }
- }
- }
-
- private static void sleep(long millis) {
- try {
- Thread.sleep(millis);
- } catch (InterruptedException e) {
- GraalError.shouldNotReachHere(e.getCause());
- }
- }
-
- @Test(timeout = 60_000)
- @SuppressWarnings("try")
- public void test01() {
- initializeForTimeout();
- OptionValues initialOptions = getInitialOptions();
- OptionValues options = new OptionValues(initialOptions, CompilationExpirationPeriod, 1/* sec */);
- try (CompilationAlarm c1 = CompilationAlarm.trackCompilationPeriod(options)) {
- StructuredGraph g = parseEager("snippet", AllowAssumptions.NO, options);
- new CooperativePhase().apply(g);
- }
- }
-
- @Test(expected = RetryableBailoutException.class, timeout = 60_000)
- @SuppressWarnings("try")
- public void test02() {
- initializeForTimeout();
- OptionValues initialOptions = getInitialOptions();
- OptionValues options = new OptionValues(initialOptions, CompilationExpirationPeriod, 1/* sec */);
- try (CompilationAlarm c1 = CompilationAlarm.trackCompilationPeriod(options)) {
- StructuredGraph g = parseEager("snippet", AllowAssumptions.NO, options);
- new UnCooperativePhase().apply(g);
- }
- }
-
- @Test(timeout = 60_000)
- @SuppressWarnings("try")
- public void test03() {
- initializeForTimeout();
- // 0 disables alarm utility
- OptionValues initialOptions = getInitialOptions();
- OptionValues options = new OptionValues(initialOptions, CompilationExpirationPeriod, 0);
- try (CompilationAlarm c1 = CompilationAlarm.trackCompilationPeriod(options)) {
- StructuredGraph g = parseEager("snippet", AllowAssumptions.NO, options);
- new PartiallyCooperativePhase().apply(g);
- }
- }
-
- @Test(timeout = 60_000)
- @SuppressWarnings("try")
- public void test04() {
- initializeForTimeout();
- StructuredGraph g = parseEager("snippet", AllowAssumptions.NO);
- new CooperativePhaseWithoutAlarm().apply(g);
- }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CountedLoopTest.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CountedLoopTest.java Wed Dec 13 12:28:22 2017 -0800
@@ -264,7 +264,7 @@
}
@Override
- protected boolean checkMidTierGraph(StructuredGraph graph) {
+ protected boolean checkHighTierGraph(StructuredGraph graph) {
LoopsData loops = new LoopsData(graph);
loops.detectedCountedLoops();
for (IVPropertyNode node : graph.getNodes().filter(IVPropertyNode.class)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/Assertions.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/Assertions.java Wed Dec 13 12:28:22 2017 -0800
@@ -54,8 +54,8 @@
// @formatter:off
public static class Options {
- @Option(help = "Enable expensive assertions. (Require normal assertions enabled)", type = OptionType.Debug)
- public static final OptionKey<Boolean> DetailedAsserts = new OptionKey<>(true);
+ @Option(help = "Enable expensive assertions if normal assertions (i.e. -ea or -esa) are enabled.", type = OptionType.Debug)
+ public static final OptionKey<Boolean> DetailedAsserts = new OptionKey<>(false);
}
// @formatter:on
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java Wed Dec 13 12:28:22 2017 -0800
@@ -472,6 +472,11 @@
}
}
+ public <T extends Node> T addWithoutUniqueWithInputs(T node) {
+ addInputs(node);
+ return addHelper(node);
+ }
+
private final class AddInputsFilter extends Node.EdgeVisitor {
@Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotForeignCallsProvider.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotForeignCallsProvider.java Wed Dec 13 12:28:22 2017 -0800
@@ -30,6 +30,7 @@
import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.PRESERVES_REGISTERS;
import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.LEAF;
import static org.graalvm.compiler.hotspot.replacements.CRC32Substitutions.UPDATE_BYTES_CRC32;
+import static org.graalvm.compiler.hotspot.replacements.CRC32CSubstitutions.UPDATE_BYTES_CRC32C;
import static org.graalvm.word.LocationIdentity.any;
import org.graalvm.compiler.core.common.LIRKind;
@@ -79,6 +80,9 @@
if (config.useCRC32Intrinsics) {
registerForeignCall(UPDATE_BYTES_CRC32, config.updateBytesCRC32Stub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, any());
}
+ if (config.useCRC32CIntrinsics) {
+ registerForeignCall(UPDATE_BYTES_CRC32C, config.updateBytesCRC32C, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, any());
+ }
super.initialize(providers, options);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java Wed Dec 13 12:28:22 2017 -0800
@@ -30,8 +30,8 @@
import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode;
+import org.graalvm.compiler.asm.aarch64.AArch64Assembler.ConditionFlag;
import org.graalvm.compiler.asm.aarch64.AArch64Assembler.PrefetchMode;
-import org.graalvm.compiler.asm.aarch64.AArch64Assembler.ConditionFlag;
import org.graalvm.compiler.core.aarch64.AArch64ArithmeticLIRGenerator;
import org.graalvm.compiler.core.aarch64.AArch64LIRGenerator;
import org.graalvm.compiler.core.aarch64.AArch64LIRKindTool;
@@ -202,7 +202,7 @@
assert inputKind.getPlatformKind() == AArch64Kind.QWORD;
if (inputKind.isReference(0)) {
// oop
- Variable result = newVariable(LIRKind.reference(AArch64Kind.DWORD));
+ Variable result = newVariable(LIRKind.compressedReference(AArch64Kind.DWORD));
append(new AArch64HotSpotMove.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull));
return result;
} else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java Wed Dec 13 12:28:22 2017 -0800
@@ -33,6 +33,7 @@
import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.LEAF;
import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.LEAF_NOFP;
import static org.graalvm.compiler.hotspot.replacements.CRC32Substitutions.UPDATE_BYTES_CRC32;
+import static org.graalvm.compiler.hotspot.replacements.CRC32CSubstitutions.UPDATE_BYTES_CRC32C;
import static org.graalvm.word.LocationIdentity.any;
import org.graalvm.compiler.core.common.LIRKind;
@@ -99,6 +100,9 @@
// This stub does callee saving
registerForeignCall(UPDATE_BYTES_CRC32, config.updateBytesCRC32Stub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, any());
}
+ if (config.useCRC32CIntrinsics) {
+ registerForeignCall(UPDATE_BYTES_CRC32C, config.updateBytesCRC32C, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, any());
+ }
super.initialize(providers, options);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRKindTool.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRKindTool.java Wed Dec 13 12:28:22 2017 -0800
@@ -22,14 +22,15 @@
*/
package org.graalvm.compiler.hotspot.amd64;
-import jdk.vm.ci.amd64.AMD64Kind;
import org.graalvm.compiler.core.amd64.AMD64LIRKindTool;
import org.graalvm.compiler.core.common.LIRKind;
+import jdk.vm.ci.amd64.AMD64Kind;
+
public class AMD64HotSpotLIRKindTool extends AMD64LIRKindTool {
@Override
public LIRKind getNarrowOopKind() {
- return LIRKind.reference(AMD64Kind.DWORD);
+ return LIRKind.compressedReference(AMD64Kind.DWORD);
}
@Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotForeignCallsProvider.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotForeignCallsProvider.java Wed Dec 13 12:28:22 2017 -0800
@@ -34,6 +34,7 @@
import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.PRESERVES_REGISTERS;
import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.LEAF_NOFP;
import static org.graalvm.compiler.hotspot.replacements.CRC32Substitutions.UPDATE_BYTES_CRC32;
+import static org.graalvm.compiler.hotspot.replacements.CRC32CSubstitutions.UPDATE_BYTES_CRC32C;
import static org.graalvm.word.LocationIdentity.any;
import org.graalvm.compiler.core.common.LIRKind;
@@ -87,6 +88,9 @@
// This stub does callee saving
registerForeignCall(UPDATE_BYTES_CRC32, config.updateBytesCRC32Stub, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, any());
}
+ if (config.useCRC32CIntrinsics) {
+ registerForeignCall(UPDATE_BYTES_CRC32C, config.updateBytesCRC32C, NativeCall, PRESERVES_REGISTERS, LEAF_NOFP, NOT_REEXECUTABLE, any());
+ }
super.initialize(providers, options);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotLIRGenerator.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotLIRGenerator.java Wed Dec 13 12:28:22 2017 -0800
@@ -307,7 +307,7 @@
assert inputKind.getPlatformKind() == XWORD : inputKind;
if (inputKind.isReference(0)) {
// oop
- Variable result = newVariable(LIRKind.reference(WORD));
+ Variable result = newVariable(LIRKind.compressedReference(WORD));
append(new SPARCHotSpotMove.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull));
return result;
} else {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CRC32CSubstitutionsTest.java Wed Dec 13 12:28:22 2017 -0800
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2007, 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.hotspot.test;
+
+import java.io.DataInputStream;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.util.zip.Checksum;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+
+import org.graalvm.compiler.test.GraalTest;
+import org.graalvm.compiler.core.test.GraalCompilerTest;
+
+import org.junit.Test;
+
+import static org.junit.Assume.assumeFalse;
+
+/**
+ * Tests compiled calls to {@link java.util.zip.CRC32C}.
+ */
+@SuppressWarnings("javadoc")
+public class CRC32CSubstitutionsTest extends GraalCompilerTest {
+
+ public static long updateBytes(byte[] input, int offset, int end) throws Throwable {
+ Class<?> crcClass = Class.forName("java.util.zip.CRC32C");
+ MethodHandle newMH = MethodHandles.publicLookup().findConstructor(crcClass, MethodType.methodType(void.class));
+ Checksum crc = (Checksum) newMH.invoke();
+ crc.update(input, offset, end);
+ return crc.getValue();
+ }
+
+ @Test
+ public void test1() throws Throwable {
+ assumeFalse(GraalTest.Java8OrEarlier);
+ String classfileName = CRC32CSubstitutionsTest.class.getSimpleName().replace('.', '/') + ".class";
+ InputStream s = CRC32CSubstitutionsTest.class.getResourceAsStream(classfileName);
+ byte[] buf = new byte[s.available()];
+ new DataInputStream(s).readFully(buf);
+ int end = buf.length;
+ for (int offset = 0; offset < buf.length; offset++) {
+ test("updateBytes", buf, offset, end);
+ }
+ }
+
+ public static long updateByteBuffer(ByteBuffer buffer) throws Throwable {
+ Class<?> crcClass = Class.forName("java.util.zip.CRC32C");
+ MethodHandle newMH = MethodHandles.publicLookup().findConstructor(crcClass, MethodType.methodType(void.class));
+ MethodHandle updateMH = MethodHandles.publicLookup().findVirtual(crcClass, "update", MethodType.methodType(void.class, ByteBuffer.class));
+ Checksum crc = (Checksum) newMH.invoke();
+ buffer.rewind();
+ updateMH.invokeExact(crc, buffer); // Checksum.update(ByteBuffer) is also available since 9
+ return crc.getValue();
+ }
+
+ @Test
+ public void test2() throws Throwable {
+ assumeFalse(GraalTest.Java8OrEarlier);
+ String classfileName = CRC32CSubstitutionsTest.class.getSimpleName().replace('.', '/') + ".class";
+ InputStream s = CRC32CSubstitutionsTest.class.getResourceAsStream(classfileName);
+ byte[] buf = new byte[s.available()];
+ new DataInputStream(s).readFully(buf);
+
+ ByteBuffer directBuf = ByteBuffer.allocateDirect(buf.length);
+ directBuf.put(buf);
+ ByteBuffer heapBuf = ByteBuffer.wrap(buf);
+
+ test("updateByteBuffer", directBuf);
+ test("updateByteBuffer", heapBuf);
+ }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java Wed Dec 13 12:28:22 2017 -0800
@@ -466,6 +466,13 @@
}
}
+ // CRC32C intrinsics
+ if (!config.useCRC32CIntrinsics) {
+ add(IGNORE,
+ "java/util/zip/CRC32C.updateBytes(I[BII)I",
+ "java/util/zip/CRC32C.updateDirectByteBuffer(IJII)I");
+ }
+
// AES intrinsics
if (!config.useAESIntrinsics) {
if (isJDK9OrHigher()) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/JVMCIInfopointErrorTest.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/JVMCIInfopointErrorTest.java Wed Dec 13 12:28:22 2017 -0800
@@ -33,9 +33,9 @@
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.core.test.GraalCompilerTest;
-import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugContext.Scope;
+import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.hotspot.HotSpotCompiledCodeBuilder;
import org.graalvm.compiler.lir.FullInfopointOp;
@@ -150,7 +150,7 @@
codeCache.addCode(method, compiledCode, null, null);
}
- @Test(expected = JVMCIError.class)
+ @Test(expected = Error.class)
public void testInvalidShortOop() {
test((tool, state, safepoint) -> {
PlatformKind kind = tool.target().arch.getPlatformKind(JavaKind.Short);
@@ -163,14 +163,14 @@
});
}
- @Test(expected = JVMCIError.class)
+ @Test(expected = Error.class)
public void testInvalidShortDerivedOop() {
test((tool, state, safepoint) -> {
Variable baseOop = tool.newVariable(LIRKind.fromJavaKind(tool.target().arch, JavaKind.Object));
tool.append(new ValueDef(baseOop));
PlatformKind kind = tool.target().arch.getPlatformKind(JavaKind.Short);
- LIRKind lirKind = LIRKind.derivedReference(kind, baseOop);
+ LIRKind lirKind = LIRKind.derivedReference(kind, baseOop, false);
Variable var = tool.newVariable(lirKind);
tool.append(new ValueDef(var));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Wed Dec 13 12:28:22 2017 -0800
@@ -165,6 +165,7 @@
public final boolean usePopCountInstruction = getFlag("UsePopCountInstruction", Boolean.class);
public final boolean useAESIntrinsics = getFlag("UseAESIntrinsics", Boolean.class);
public final boolean useCRC32Intrinsics = getFlag("UseCRC32Intrinsics", Boolean.class);
+ public final boolean useCRC32CIntrinsics = isJDK8 ? false : getFlag("UseCRC32CIntrinsics", Boolean.class);
public final boolean threadLocalHandshakes = getFlag("ThreadLocalHandshakes", Boolean.class, false);
private final boolean useMultiplyToLenIntrinsic = getFlag("UseMultiplyToLenIntrinsic", Boolean.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotHostBackend.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotHostBackend.java Wed Dec 13 12:28:22 2017 -0800
@@ -45,6 +45,7 @@
import jdk.vm.ci.common.InitTimer;
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
+import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.runtime.JVMCICompiler;
@@ -142,7 +143,8 @@
@Override
public ReferenceMapBuilder newReferenceMapBuilder(int totalFrameSize) {
- return new HotSpotReferenceMapBuilder(totalFrameSize, config.maxOopMapStackOffset);
+ int uncompressedReferenceSize = getTarget().arch.getPlatformKind(JavaKind.Object).getSizeInBytes();
+ return new HotSpotReferenceMapBuilder(totalFrameSize, config.maxOopMapStackOffset, uncompressedReferenceSize);
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotReferenceMapBuilder.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotReferenceMapBuilder.java Wed Dec 13 12:28:22 2017 -0800
@@ -22,15 +22,15 @@
*/
package org.graalvm.compiler.hotspot;
-import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant;
import static jdk.vm.ci.code.ValueUtil.asRegister;
import static jdk.vm.ci.code.ValueUtil.asStackSlot;
import static jdk.vm.ci.code.ValueUtil.isRegister;
+import static org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant;
import java.util.ArrayList;
+import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.PermanentBailoutException;
-import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.lir.LIRFrameState;
import org.graalvm.compiler.lir.Variable;
@@ -52,8 +52,10 @@
private final int totalFrameSize;
private final int maxOopMapStackOffset;
+ private final int uncompressedReferenceSize;
- public HotSpotReferenceMapBuilder(int totalFrameSize, int maxOopMapStackOffset) {
+ public HotSpotReferenceMapBuilder(int totalFrameSize, int maxOopMapStackOffset, int uncompressedReferenceSize) {
+ this.uncompressedReferenceSize = uncompressedReferenceSize;
this.objectValues = new ArrayList<>();
this.objectCount = 0;
this.maxOopMapStackOffset = maxOopMapStackOffset;
@@ -116,6 +118,7 @@
for (int i = 0; i < kind.getPlatformKind().getVectorLength(); i++) {
if (kind.isReference(i)) {
+ assert kind.isCompressedReference(i) ? (bytes < uncompressedReferenceSize) : (bytes == uncompressedReferenceSize);
objects[idx] = toLocation(obj, i * bytes);
derivedBase[idx] = base;
sizeInBytes[idx] = bytes;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java Wed Dec 13 12:28:22 2017 -0800
@@ -46,6 +46,7 @@
import org.graalvm.compiler.hotspot.replacements.AESCryptSubstitutions;
import org.graalvm.compiler.hotspot.replacements.BigIntegerSubstitutions;
import org.graalvm.compiler.hotspot.replacements.CRC32Substitutions;
+import org.graalvm.compiler.hotspot.replacements.CRC32CSubstitutions;
import org.graalvm.compiler.hotspot.replacements.CallSiteTargetNode;
import org.graalvm.compiler.hotspot.replacements.CipherBlockChainingSubstitutions;
import org.graalvm.compiler.hotspot.replacements.ClassGetHubNode;
@@ -165,6 +166,7 @@
registerConstantPoolPlugins(invocationPlugins, wordTypes, config, replacementBytecodeProvider);
registerAESPlugins(invocationPlugins, config, replacementBytecodeProvider);
registerCRC32Plugins(invocationPlugins, config, replacementBytecodeProvider);
+ registerCRC32CPlugins(invocationPlugins, config, replacementBytecodeProvider);
registerBigIntegerPlugins(invocationPlugins, config, replacementBytecodeProvider);
registerSHAPlugins(invocationPlugins, config, replacementBytecodeProvider);
registerUnsafePlugins(invocationPlugins, replacementBytecodeProvider);
@@ -530,4 +532,12 @@
}
}
}
+
+ private static void registerCRC32CPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
+ if (config.useCRC32CIntrinsics) {
+ Registration r = new Registration(plugins, "java.util.zip.CRC32C", bytecodeProvider);
+ r.registerMethodSubstitution(CRC32CSubstitutions.class, "updateBytes", int.class, byte[].class, int.class, int.class);
+ r.registerMethodSubstitution(CRC32CSubstitutions.class, "updateDirectByteBuffer", int.class, long.class, int.class, int.class);
+ }
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/CRC32CSubstitutions.java Wed Dec 13 12:28:22 2017 -0800
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012, 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.hotspot.replacements;
+
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayBaseOffset;
+
+import org.graalvm.compiler.api.replacements.ClassSubstitution;
+import org.graalvm.compiler.api.replacements.MethodSubstitution;
+import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
+import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
+import org.graalvm.compiler.graph.Node.NodeIntrinsic;
+import org.graalvm.compiler.hotspot.nodes.ComputeObjectAddressNode;
+import org.graalvm.compiler.nodes.extended.ForeignCallNode;
+import org.graalvm.compiler.word.Word;
+import org.graalvm.word.WordBase;
+import org.graalvm.word.WordFactory;
+
+import jdk.vm.ci.meta.JavaKind;
+
+// JaCoCo Exclude
+
+/**
+ * Substitutions for java.util.zip.CRC32C.
+ */
+@ClassSubstitution(className = "java.util.zip.CRC32C", optional = true)
+public class CRC32CSubstitutions {
+
+ @MethodSubstitution
+ static int updateBytes(int crc, byte[] b, int off, int end) {
+ Word bufAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(b, arrayBaseOffset(JavaKind.Byte) + off));
+ return updateBytesCRC32(UPDATE_BYTES_CRC32C, crc, bufAddr, end - off);
+ }
+
+ @MethodSubstitution
+ static int updateDirectByteBuffer(int crc, long addr, int off, int end) {
+ WordBase bufAddr = WordFactory.unsigned(addr).add(off);
+ return updateBytesCRC32(UPDATE_BYTES_CRC32C, crc, bufAddr, end - off);
+ }
+
+ public static final ForeignCallDescriptor UPDATE_BYTES_CRC32C = new ForeignCallDescriptor("updateBytesCRC32C", int.class, int.class, WordBase.class, int.class);
+
+ @NodeIntrinsic(ForeignCallNode.class)
+ public static native int updateBytesCRC32(@ConstantNodeParameter ForeignCallDescriptor descriptor, int crc, WordBase buf, int length);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/bytecode/BC_idiv_overflow.java Wed Dec 13 12:28:22 2017 -0800
@@ -0,0 +1,47 @@
+/*
+ * 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.jtt.bytecode;
+
+import org.junit.Test;
+
+import org.graalvm.compiler.jtt.JTTTest;
+
+/*
+ */
+public class BC_idiv_overflow extends JTTTest {
+
+ public static int test(int a, int b) {
+ return a / (b | 1);
+ }
+
+ @Test
+ public void run0() throws Throwable {
+ runTest("test", Integer.MIN_VALUE, -1);
+ }
+
+ @Test
+ public void run1() throws Throwable {
+ runTest("test", Integer.MIN_VALUE, 1);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/bytecode/BC_ldiv_overflow.java Wed Dec 13 12:28:22 2017 -0800
@@ -0,0 +1,47 @@
+/*
+ * 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.jtt.bytecode;
+
+import org.junit.Test;
+
+import org.graalvm.compiler.jtt.JTTTest;
+
+/*
+ */
+public class BC_ldiv_overflow extends JTTTest {
+
+ public static long test(long a, long b) {
+ return a / (b | 1);
+ }
+
+ @Test
+ public void run0() throws Throwable {
+ runTest("test", Long.MIN_VALUE, -1L);
+ }
+
+ @Test
+ public void run1() throws Throwable {
+ runTest("test", Long.MIN_VALUE, 1L);
+ }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java Wed Dec 13 12:28:22 2017 -0800
@@ -30,8 +30,6 @@
import java.util.Iterator;
import java.util.List;
-import jdk.vm.ci.meta.MetaAccessProvider;
-import jdk.vm.ci.meta.ResolvedJavaType;
import org.graalvm.compiler.core.common.calc.Condition;
import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.core.common.type.Stamp;
@@ -67,7 +65,9 @@
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.PrimitiveConstant;
+import jdk.vm.ci.meta.ResolvedJavaType;
/**
* The {@code IfNode} represents a branch that can go one of two directions depending on the outcome
@@ -416,6 +416,7 @@
if (result.graph() == null) {
result = graph().addOrUniqueWithInputs(result);
}
+ result = proxyReplacement(result);
/*
* This optimization can be performed even if multiple values merge at this phi
* since the two inputs get simplified into one.
@@ -698,6 +699,7 @@
ValueNode falseValue = singlePhi.valueAt(falseEnd);
ValueNode conditional = canonicalizeConditionalCascade(tool, trueValue, falseValue);
if (conditional != null) {
+ conditional = proxyReplacement(conditional);
singlePhi.setValueAt(trueEnd, conditional);
removeThroughFalseBranch(tool, merge);
return true;
@@ -729,6 +731,36 @@
return false;
}
+ private ValueNode proxyReplacement(ValueNode replacement) {
+ /*
+ * Special case: Every empty diamond we collapse to a conditional node can potentially
+ * contain loop exit nodes on both branches. See the graph below: The two loop exits
+ * (instanceof begin node) exit the same loop. The resulting phi is defined outside the
+ * loop, but the resulting conditional node will be inside the loop, so we need to proxy the
+ * resulting conditional node. Callers of this method ensure that true and false successor
+ * have no usages, therefore a and b in the graph below can never be proxies themselves.
+ */
+ // @formatter:off
+ // +--+
+ // |If|
+ // +--+ +-----+ +-----+
+ // +----+ +----+ | a | | b |
+ // |Lex | |Lex | +----^+ +^----+
+ // +----+ +----+ | |
+ // +-------+ +---+
+ // | Merge +---------+Phi|
+ // +-------+ +---+
+ // @formatter:on
+ if (this.graph().hasValueProxies()) {
+ if (trueSuccessor instanceof LoopExitNode && falseSuccessor instanceof LoopExitNode) {
+ assert ((LoopExitNode) trueSuccessor).loopBegin() == ((LoopExitNode) falseSuccessor).loopBegin();
+ assert trueSuccessor.usages().isEmpty() && falseSuccessor.usages().isEmpty();
+ return this.graph().addOrUnique(new ValueProxyNode(replacement, (LoopExitNode) trueSuccessor));
+ }
+ }
+ return replacement;
+ }
+
protected void removeThroughFalseBranch(SimplifierTool tool, AbstractMergeNode merge) {
AbstractBeginNode trueBegin = trueSuccessor();
LogicNode conditionNode = condition();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerDivRemNode.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerDivRemNode.java Wed Dec 13 12:28:22 2017 -0800
@@ -60,7 +60,8 @@
// Assigning canDeopt during constructor, because it must never change during lifetime of
// the node.
- this.canDeopt = ((IntegerStamp) getY().stamp(NodeView.DEFAULT)).contains(0);
+ IntegerStamp yStamp = (IntegerStamp) getY().stamp(NodeView.DEFAULT);
+ this.canDeopt = yStamp.contains(0) || yStamp.contains(-1);
}
public final Op getOp() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ProfileCompiledMethodsPhase.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ProfileCompiledMethodsPhase.java Wed Dec 13 12:28:22 2017 -0800
@@ -121,7 +121,7 @@
private static void addSectionCounters(FixedWithNextNode start, Collection<Block> sectionBlocks, Collection<Loop<Block>> childLoops, ScheduleResult schedule, ControlFlowGraph cfg) {
HashSet<Block> blocks = new HashSet<>(sectionBlocks);
- for (Loop<?> loop : childLoops) {
+ for (Loop<Block> loop : childLoops) {
blocks.removeAll(loop.getBlocks());
}
double weight = getSectionWeight(schedule, blocks) / cfg.blockFor(start).probability();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/GraphPrinter.java Wed Dec 13 12:28:22 2017 -0800
@@ -194,15 +194,26 @@
static String constantToString(Object value) {
Class<?> c = value.getClass();
+ String suffix = "";
if (c.isArray()) {
return constantArrayToString(value);
} else if (value instanceof Enum) {
return ((Enum<?>) value).name();
} else if (isToStringTrusted(c)) {
- return value.toString();
+ try {
+ return value.toString();
+ } catch (Throwable t) {
+ suffix = "[toString error: " + t.getClass().getName() + "]";
+ if (isToStringTrusted(t.getClass())) {
+ try {
+ suffix = "[toString error: " + t + "]";
+ } catch (Throwable t2) {
+ // No point in going further
+ }
+ }
+ }
}
- return MetaUtil.getSimpleName(c, true) + "@" + Integer.toHexString(System.identityHashCode(value));
-
+ return MetaUtil.getSimpleName(c, true) + "@" + Integer.toHexString(System.identityHashCode(value)) + suffix;
}
static String constantArrayToString(Object array) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java Wed Dec 13 12:28:22 2017 -0800
@@ -141,6 +141,7 @@
registerJMHBlackholePlugins(plugins, bytecodeProvider);
registerJFRThrowablePlugins(plugins, bytecodeProvider);
registerMethodHandleImplPlugins(plugins, snippetReflection, bytecodeProvider);
+ registerJcovCollectPlugins(plugins, bytecodeProvider);
}
private static final Field STRING_VALUE_FIELD;
@@ -910,4 +911,21 @@
}
});
}
+
+ /**
+ * Registers a plugin to ignore {@code com.sun.tdk.jcov.runtime.Collect.hit} within an
+ * intrinsic.
+ */
+ private static void registerJcovCollectPlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
+ Registration r = new Registration(plugins, "com.sun.tdk.jcov.runtime.Collect", bytecodeProvider);
+ r.register1("hit", int.class, new InvocationPlugin() {
+ @Override
+ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
+ if (b.parsingIntrinsic()) {
+ return true;
+ }
+ return false;
+ }
+ });
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/Classfile.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/classfile/Classfile.java Wed Dec 13 12:28:22 2017 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -46,8 +46,8 @@
private final ResolvedJavaType type;
private final List<ClassfileBytecode> codeAttributes;
- private static final int MAJOR_VERSION_JAVA_MIN = 51;
- private static final int MAJOR_VERSION_JAVA_MAX = 54;
+ private static final int MAJOR_VERSION_JAVA7 = 51;
+ private static final int MAJOR_VERSION_JAVA10 = 54;
private static final int MAGIC = 0xCAFEBABE;
/**
@@ -65,7 +65,7 @@
int minor = stream.readUnsignedShort();
int major = stream.readUnsignedShort();
- if (major < MAJOR_VERSION_JAVA_MIN || major > MAJOR_VERSION_JAVA_MAX) {
+ if (major < MAJOR_VERSION_JAVA7 || major > MAJOR_VERSION_JAVA10) {
throw new UnsupportedClassVersionError("Unsupported class file version: " + major + "." + minor);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/GraphEffectList.java Wed Dec 13 11:59:55 2017 -0800
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/GraphEffectList.java Wed Dec 13 12:28:22 2017 -0800
@@ -34,7 +34,6 @@
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.PhiNode;
import org.graalvm.compiler.nodes.PiNode;
-import org.graalvm.compiler.nodes.ProxyNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.debug.DynamicCounterNode;
@@ -116,14 +115,7 @@
*/
public void addFloatingNode(ValueNode node, @SuppressWarnings("unused") String cause) {
add("add floating node", graph -> {
- if (node instanceof ProxyNode) {
- ProxyNode proxyNode = (ProxyNode) node;
- ValueNode value = proxyNode.value();
- if (!value.isAlive()) {
- graph.addWithoutUnique(value);
- }
- }
- graph.addWithoutUnique(node);
+ graph.addWithoutUniqueWithInputs(node);
});
}