8193439: Update Graal

Reviewed-by: kvn
This commit is contained in:
Igor Veresov 2017-12-13 12:28:22 -08:00
parent c11f132abe
commit f287b874f2
32 changed files with 452 additions and 214 deletions

View File

@ -107,7 +107,6 @@ suite = {
"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 @@ suite = {
"dependencies" : [
"JVMCI_API",
"org.graalvm.compiler.serviceprovider",
"org.graalvm.graphio",
"org.graalvm.compiler.options"
],
"annotationProcessors" : ["GRAAL_OPTIONS_PROCESSOR"],
@ -291,7 +291,6 @@ suite = {
"subDir" : "share/classes",
"sourceDirs" : ["src"],
"dependencies" : [
"org.graalvm.compiler.core.aarch64",
"org.graalvm.compiler.hotspot",
"org.graalvm.compiler.replacements.aarch64",
],
@ -435,6 +434,7 @@ suite = {
"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 @@ suite = {
"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 @@ suite = {
"subDir" : "share/classes",
"sourceDirs" : ["src"],
"dependencies" : [
"org.graalvm.graphio",
"org.graalvm.compiler.core",
"org.graalvm.compiler.java",
],

View File

@ -68,7 +68,7 @@ public class AArch64LIRKindTool implements LIRKindTool {
@Override
public LIRKind getNarrowOopKind() {
return LIRKind.reference(AArch64Kind.DWORD);
return LIRKind.compressedReference(AArch64Kind.DWORD);
}
@Override

View File

@ -33,8 +33,9 @@ import jdk.vm.ci.meta.ValueKind;
/**
* 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 @@ import jdk.vm.ci.meta.ValueKind;
* 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 @@ import jdk.vm.ci.meta.ValueKind;
*/
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 @@ public final class LIRKind extends ValueKind<LIRKind> {
* 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 @@ public final class LIRKind extends ValueKind<LIRKind> {
/**
* 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 @@ public final class LIRKind extends ValueKind<LIRKind> {
* 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 @@ public final class LIRKind extends ValueKind<LIRKind> {
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 @@ public final class LIRKind extends ValueKind<LIRKind> {
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 @@ public final class LIRKind extends ValueKind<LIRKind> {
} 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 @@ public final class LIRKind extends ValueKind<LIRKind> {
// 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 @@ public final class LIRKind extends ValueKind<LIRKind> {
* {@link LIRKind#unknownReference}.
*/
public LIRKind makeUnknownReference() {
return new LIRKind(getPlatformKind(), UNKNOWN_REFERENCE, null);
return new LIRKind(getPlatformKind(), UNKNOWN_REFERENCE, UNKNOWN_REFERENCE, null);
}
/**
@ -384,6 +408,17 @@ public final class LIRKind extends ValueKind<LIRKind> {
return !isUnknownReference() && (referenceMask & 1 << idx) != 0;
}
/**
* 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.
*/
@ -432,6 +467,7 @@ public final class LIRKind extends ValueKind<LIRKind> {
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 @@ public final class LIRKind extends ValueKind<LIRKind> {
}
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()) {

View File

@ -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 final class CompilationAlarm implements AutoCloseable {
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 @@ public final class CompilationAlarm implements AutoCloseable {
/**
* 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 @@ public final class CompilationAlarm implements AutoCloseable {
}
return null;
}
}

View File

@ -68,7 +68,7 @@ public class SPARCLIRKindTool implements LIRKindTool {
@Override
public LIRKind getNarrowOopKind() {
return LIRKind.reference(SPARCKind.WORD);
return LIRKind.compressedReference(SPARCKind.WORD);
}
@Override

View File

@ -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);
}
}

View File

@ -264,7 +264,7 @@ public class CountedLoopTest extends GraalCompilerTest {
}
@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)) {

View File

@ -54,8 +54,8 @@ public class Assertions {
// @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

View File

@ -472,6 +472,11 @@ public class Graph {
}
}
public <T extends Node> T addWithoutUniqueWithInputs(T node) {
addInputs(node);
return addHelper(node);
}
private final class AddInputsFilter extends Node.EdgeVisitor {
@Override

View File

@ -30,6 +30,7 @@ import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.JUMP_ADDRES
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 @@ public class AArch64HotSpotForeignCallsProvider extends HotSpotHostForeignCallsP
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);
}

View File

@ -30,8 +30,8 @@ import java.util.function.Function;
import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode;
import org.graalvm.compiler.asm.aarch64.AArch64Assembler.PrefetchMode;
import org.graalvm.compiler.asm.aarch64.AArch64Assembler.ConditionFlag;
import org.graalvm.compiler.asm.aarch64.AArch64Assembler.PrefetchMode;
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 @@ public class AArch64HotSpotLIRGenerator extends AArch64LIRGenerator implements H
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 {

View File

@ -33,6 +33,7 @@ import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEff
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 @@ public class AMD64HotSpotForeignCallsProvider extends HotSpotHostForeignCallsPro
// 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);
}

View File

@ -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

View File

@ -34,6 +34,7 @@ import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.JUMP_ADDRES
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 @@ public class SPARCHotSpotForeignCallsProvider extends HotSpotHostForeignCallsPro
// 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);
}

View File

@ -307,7 +307,7 @@ public class SPARCHotSpotLIRGenerator extends SPARCLIRGenerator implements HotSp
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 {

View File

@ -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);
}
}

View File

@ -466,6 +466,13 @@ public class CheckGraalIntrinsics extends GraalTest {
}
}
// 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()) {

View File

@ -33,9 +33,9 @@ import org.graalvm.compiler.code.CompilationResult;
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 @@ public class JVMCIInfopointErrorTest extends GraalCompilerTest {
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 @@ public class JVMCIInfopointErrorTest extends GraalCompilerTest {
});
}
@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));

View File

@ -165,6 +165,7 @@ public class GraalHotSpotVMConfig extends HotSpotVMConfigAccess {
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);

View File

@ -45,6 +45,7 @@ import jdk.vm.ci.code.CallingConvention;
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 @@ public abstract class HotSpotHostBackend extends HotSpotBackend {
@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);
}
}

View File

@ -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.PermanentBailoutException;
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.PermanentBailoutException;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.lir.LIRFrameState;
import org.graalvm.compiler.lir.Variable;
@ -52,8 +52,10 @@ public final class HotSpotReferenceMapBuilder extends ReferenceMapBuilder {
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 @@ public final class HotSpotReferenceMapBuilder extends ReferenceMapBuilder {
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;

View File

@ -46,6 +46,7 @@ import org.graalvm.compiler.hotspot.nodes.CurrentJavaThreadNode;
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 @@ public class HotSpotGraphBuilderPlugins {
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 @@ public class HotSpotGraphBuilderPlugins {
}
}
}
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);
}
}
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -30,8 +30,6 @@ import java.util.Arrays;
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 org.graalvm.util.Equivalence;
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 @@ public final class IfNode extends ControlSplitNode implements Simplifiable, LIRL
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 @@ public final class IfNode extends ControlSplitNode implements Simplifiable, LIRL
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 @@ public final class IfNode extends ControlSplitNode implements Simplifiable, LIRL
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();

View File

@ -60,7 +60,8 @@ public abstract class IntegerDivRemNode extends FixedBinaryNode implements Lower
// 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() {

View File

@ -121,7 +121,7 @@ public class ProfileCompiledMethodsPhase extends Phase {
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();

View File

@ -194,15 +194,26 @@ interface GraphPrinter extends Closeable, JavaConstantFormatter {
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) {

View File

@ -141,6 +141,7 @@ public class StandardGraphBuilderPlugins {
registerJMHBlackholePlugins(plugins, bytecodeProvider);
registerJFRThrowablePlugins(plugins, bytecodeProvider);
registerMethodHandleImplPlugins(plugins, snippetReflection, bytecodeProvider);
registerJcovCollectPlugins(plugins, bytecodeProvider);
}
private static final Field STRING_VALUE_FIELD;
@ -910,4 +911,21 @@ public class StandardGraphBuilderPlugins {
}
});
}
/**
* 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;
}
});
}
}

View File

@ -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 @@ public class Classfile {
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 @@ public class Classfile {
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);
}

View File

@ -34,7 +34,6 @@ import org.graalvm.compiler.nodes.IfNode;
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 final class GraphEffectList extends EffectList {
*/
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);
});
}