8210777: Update Graal
Reviewed-by: kvn
This commit is contained in:
parent
c8ebf4da3b
commit
971575362a
@ -450,21 +450,17 @@ jdk.internal.vm.compiler_ADD_JAVAC_FLAGS += -parameters -XDstringConcat=inline \
|
|||||||
|
|
||||||
jdk.internal.vm.compiler_EXCLUDES += \
|
jdk.internal.vm.compiler_EXCLUDES += \
|
||||||
jdk.internal.vm.compiler.collections.test \
|
jdk.internal.vm.compiler.collections.test \
|
||||||
org.graalvm.compiler.processor \
|
jdk.tools.jaotc.test \
|
||||||
org.graalvm.compiler.core.match.processor \
|
|
||||||
org.graalvm.compiler.nodeinfo.processor \
|
|
||||||
org.graalvm.compiler.options.processor \
|
|
||||||
org.graalvm.compiler.serviceprovider.processor \
|
|
||||||
org.graalvm.compiler.replacements.processor \
|
|
||||||
org.graalvm.compiler.replacements.jdk9.test \
|
|
||||||
org.graalvm.compiler.api.directives.test \
|
org.graalvm.compiler.api.directives.test \
|
||||||
org.graalvm.compiler.api.test \
|
org.graalvm.compiler.api.test \
|
||||||
org.graalvm.compiler.asm.aarch64.test \
|
org.graalvm.compiler.asm.aarch64.test \
|
||||||
org.graalvm.compiler.asm.amd64.test \
|
org.graalvm.compiler.asm.amd64.test \
|
||||||
org.graalvm.compiler.asm.sparc.test \
|
org.graalvm.compiler.asm.sparc.test \
|
||||||
org.graalvm.compiler.asm.test \
|
org.graalvm.compiler.asm.test \
|
||||||
|
org.graalvm.compiler.core.aarch64.test \
|
||||||
org.graalvm.compiler.core.amd64.test \
|
org.graalvm.compiler.core.amd64.test \
|
||||||
org.graalvm.compiler.core.sparc.test \
|
org.graalvm.compiler.core.jdk9.test \
|
||||||
|
org.graalvm.compiler.core.match.processor \
|
||||||
org.graalvm.compiler.core.test \
|
org.graalvm.compiler.core.test \
|
||||||
org.graalvm.compiler.debug.test \
|
org.graalvm.compiler.debug.test \
|
||||||
org.graalvm.compiler.graph.test \
|
org.graalvm.compiler.graph.test \
|
||||||
@ -477,10 +473,18 @@ jdk.internal.vm.compiler_EXCLUDES += \
|
|||||||
org.graalvm.compiler.lir.test \
|
org.graalvm.compiler.lir.test \
|
||||||
org.graalvm.compiler.loop.test \
|
org.graalvm.compiler.loop.test \
|
||||||
org.graalvm.compiler.microbenchmarks \
|
org.graalvm.compiler.microbenchmarks \
|
||||||
|
org.graalvm.compiler.nodeinfo.processor \
|
||||||
org.graalvm.compiler.nodes.test \
|
org.graalvm.compiler.nodes.test \
|
||||||
|
org.graalvm.compiler.options.processor \
|
||||||
org.graalvm.compiler.options.test \
|
org.graalvm.compiler.options.test \
|
||||||
org.graalvm.compiler.phases.common.test \
|
org.graalvm.compiler.phases.common.test \
|
||||||
|
org.graalvm.compiler.processor \
|
||||||
|
org.graalvm.compiler.replacements.jdk12.test \
|
||||||
|
org.graalvm.compiler.replacements.jdk9.test \
|
||||||
|
org.graalvm.compiler.replacements.jdk9_11.test \
|
||||||
|
org.graalvm.compiler.replacements.processor \
|
||||||
org.graalvm.compiler.replacements.test \
|
org.graalvm.compiler.replacements.test \
|
||||||
|
org.graalvm.compiler.serviceprovider.processor \
|
||||||
org.graalvm.compiler.test \
|
org.graalvm.compiler.test \
|
||||||
org.graalvm.compiler.virtual.bench \
|
org.graalvm.compiler.virtual.bench \
|
||||||
org.graalvm.micro.benchmarks \
|
org.graalvm.micro.benchmarks \
|
||||||
|
@ -59,6 +59,7 @@ ifeq ($(INCLUDE_GRAAL), true)
|
|||||||
-Xlint:none \
|
-Xlint:none \
|
||||||
-processorpath $(BUILDTOOLS_OUTPUTDIR)/jdk.vm.compiler.replacements.verifier.jar \
|
-processorpath $(BUILDTOOLS_OUTPUTDIR)/jdk.vm.compiler.replacements.verifier.jar \
|
||||||
--add-exports jdk.unsupported/sun.misc=ALL-UNNAMED \
|
--add-exports jdk.unsupported/sun.misc=ALL-UNNAMED \
|
||||||
|
--add-exports java.base/jdk.internal.misc=ALL-UNNAMED \
|
||||||
|
|
||||||
### Copy 3rd party libs
|
### Copy 3rd party libs
|
||||||
$(eval $(call SetupCopyFiles, COPY_GRAALUNIT_LIBS, \
|
$(eval $(call SetupCopyFiles, COPY_GRAALUNIT_LIBS, \
|
||||||
@ -81,6 +82,7 @@ ifeq ($(INCLUDE_GRAAL), true)
|
|||||||
$(SRC_DIR)/org.graalvm.compiler.asm.test/src \
|
$(SRC_DIR)/org.graalvm.compiler.asm.test/src \
|
||||||
$(SRC_DIR)/org.graalvm.compiler.core.amd64.test/src \
|
$(SRC_DIR)/org.graalvm.compiler.core.amd64.test/src \
|
||||||
$(SRC_DIR)/org.graalvm.compiler.core.test/src \
|
$(SRC_DIR)/org.graalvm.compiler.core.test/src \
|
||||||
|
$(SRC_DIR)/org.graalvm.compiler.core.jdk9.test/src \
|
||||||
$(SRC_DIR)/org.graalvm.compiler.debug.test/src \
|
$(SRC_DIR)/org.graalvm.compiler.debug.test/src \
|
||||||
$(SRC_DIR)/org.graalvm.compiler.graph.test/src \
|
$(SRC_DIR)/org.graalvm.compiler.graph.test/src \
|
||||||
$(SRC_DIR)/org.graalvm.compiler.hotspot.amd64.test/src \
|
$(SRC_DIR)/org.graalvm.compiler.hotspot.amd64.test/src \
|
||||||
@ -92,6 +94,9 @@ ifeq ($(INCLUDE_GRAAL), true)
|
|||||||
$(SRC_DIR)/org.graalvm.compiler.nodes.test/src \
|
$(SRC_DIR)/org.graalvm.compiler.nodes.test/src \
|
||||||
$(SRC_DIR)/org.graalvm.compiler.options.test/src \
|
$(SRC_DIR)/org.graalvm.compiler.options.test/src \
|
||||||
$(SRC_DIR)/org.graalvm.compiler.phases.common.test/src \
|
$(SRC_DIR)/org.graalvm.compiler.phases.common.test/src \
|
||||||
|
$(SRC_DIR)/org.graalvm.compiler.replacements.jdk12.test/src \
|
||||||
|
$(SRC_DIR)/org.graalvm.compiler.replacements.jdk9.test/src \
|
||||||
|
$(SRC_DIR)/org.graalvm.compiler.replacements.jdk9_11.test/src \
|
||||||
$(SRC_DIR)/org.graalvm.compiler.replacements.test/src \
|
$(SRC_DIR)/org.graalvm.compiler.replacements.test/src \
|
||||||
$(SRC_DIR)/org.graalvm.compiler.test/src \
|
$(SRC_DIR)/org.graalvm.compiler.test/src \
|
||||||
$(SRC_DIR)/org.graalvm.util.test/src \
|
$(SRC_DIR)/org.graalvm.util.test/src \
|
||||||
|
@ -33,8 +33,8 @@ import org.graalvm.compiler.core.common.CompilationIdentifier;
|
|||||||
import org.graalvm.compiler.debug.DebugContext;
|
import org.graalvm.compiler.debug.DebugContext;
|
||||||
import org.graalvm.compiler.hotspot.HotSpotBackend;
|
import org.graalvm.compiler.hotspot.HotSpotBackend;
|
||||||
import org.graalvm.compiler.hotspot.HotSpotCompiledCodeBuilder;
|
import org.graalvm.compiler.hotspot.HotSpotCompiledCodeBuilder;
|
||||||
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
|
|
||||||
import org.graalvm.compiler.hotspot.meta.HotSpotInvokeDynamicPlugin;
|
import org.graalvm.compiler.hotspot.meta.HotSpotInvokeDynamicPlugin;
|
||||||
|
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
|
||||||
import org.graalvm.compiler.java.GraphBuilderPhase;
|
import org.graalvm.compiler.java.GraphBuilderPhase;
|
||||||
import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory;
|
import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory;
|
||||||
import org.graalvm.compiler.lir.phases.LIRSuites;
|
import org.graalvm.compiler.lir.phases.LIRSuites;
|
||||||
@ -167,7 +167,7 @@ final class AOTBackend {
|
|||||||
|
|
||||||
void printCompiledMethod(HotSpotResolvedJavaMethod resolvedMethod, CompilationResult compResult) {
|
void printCompiledMethod(HotSpotResolvedJavaMethod resolvedMethod, CompilationResult compResult) {
|
||||||
// This is really not installing the method.
|
// This is really not installing the method.
|
||||||
InstalledCode installedCode = codeCache.addCode(resolvedMethod, HotSpotCompiledCodeBuilder.createCompiledCode(codeCache, resolvedMethod, null, compResult), null, null);
|
InstalledCode installedCode = codeCache.addCode(resolvedMethod, HotSpotCompiledCodeBuilder.createCompiledCode(codeCache, resolvedMethod, null, compResult, graalOptions), null, null);
|
||||||
String disassembly = codeCache.disassemble(installedCode);
|
String disassembly = codeCache.disassemble(installedCode);
|
||||||
if (disassembly != null) {
|
if (disassembly != null) {
|
||||||
main.printer.printlnDebug(disassembly);
|
main.printer.printlnDebug(disassembly);
|
||||||
|
@ -32,8 +32,8 @@ import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
|
|||||||
import org.graalvm.compiler.code.CompilationResult;
|
import org.graalvm.compiler.code.CompilationResult;
|
||||||
import org.graalvm.compiler.core.GraalCompilerOptions;
|
import org.graalvm.compiler.core.GraalCompilerOptions;
|
||||||
import org.graalvm.compiler.debug.DebugContext;
|
import org.graalvm.compiler.debug.DebugContext;
|
||||||
import org.graalvm.compiler.debug.TTY;
|
|
||||||
import org.graalvm.compiler.debug.DebugContext.Activation;
|
import org.graalvm.compiler.debug.DebugContext.Activation;
|
||||||
|
import org.graalvm.compiler.debug.TTY;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.compiler.printer.GraalDebugHandlersFactory;
|
import org.graalvm.compiler.printer.GraalDebugHandlersFactory;
|
||||||
import org.graalvm.compiler.serviceprovider.GraalServices;
|
import org.graalvm.compiler.serviceprovider.GraalServices;
|
||||||
@ -143,7 +143,7 @@ final class AOTCompilationTask implements Runnable, Comparable<Object> {
|
|||||||
aotBackend.printCompiledMethod((HotSpotResolvedJavaMethod) method, compResult);
|
aotBackend.printCompiledMethod((HotSpotResolvedJavaMethod) method, compResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = new CompiledMethodInfo(compResult, new AOTHotSpotResolvedJavaMethod((HotSpotResolvedJavaMethod) method, aotBackend.getBackend()));
|
result = new CompiledMethodInfo(compResult, new AOTHotSpotResolvedJavaMethod((HotSpotResolvedJavaMethod) method, aotBackend.getBackend(), graalOptions));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getMethodDescription() {
|
private String getMethodDescription() {
|
||||||
|
@ -28,6 +28,8 @@ package jdk.tools.jaotc;
|
|||||||
import org.graalvm.compiler.code.CompilationResult;
|
import org.graalvm.compiler.code.CompilationResult;
|
||||||
import org.graalvm.compiler.core.target.Backend;
|
import org.graalvm.compiler.core.target.Backend;
|
||||||
import org.graalvm.compiler.hotspot.HotSpotCompiledCodeBuilder;
|
import org.graalvm.compiler.hotspot.HotSpotCompiledCodeBuilder;
|
||||||
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
|
|
||||||
import jdk.vm.ci.hotspot.HotSpotCompiledCode;
|
import jdk.vm.ci.hotspot.HotSpotCompiledCode;
|
||||||
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
|
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
|
||||||
|
|
||||||
@ -35,10 +37,12 @@ final class AOTHotSpotResolvedJavaMethod implements JavaMethodInfo {
|
|||||||
|
|
||||||
private final HotSpotResolvedJavaMethod method;
|
private final HotSpotResolvedJavaMethod method;
|
||||||
private final Backend backend;
|
private final Backend backend;
|
||||||
|
private final OptionValues options;
|
||||||
|
|
||||||
AOTHotSpotResolvedJavaMethod(HotSpotResolvedJavaMethod method, Backend backend) {
|
AOTHotSpotResolvedJavaMethod(HotSpotResolvedJavaMethod method, Backend backend, OptionValues options) {
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.backend = backend;
|
this.backend = backend;
|
||||||
|
this.options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -54,7 +58,7 @@ final class AOTHotSpotResolvedJavaMethod implements JavaMethodInfo {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HotSpotCompiledCode compiledCode(CompilationResult result) {
|
public HotSpotCompiledCode compiledCode(CompilationResult result) {
|
||||||
return HotSpotCompiledCodeBuilder.createCompiledCode(backend.getCodeCache(), method, null, result);
|
return HotSpotCompiledCodeBuilder.createCompiledCode(backend.getCodeCache(), method, null, result, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import org.graalvm.compiler.code.CompilationResult;
|
|||||||
import org.graalvm.compiler.core.target.Backend;
|
import org.graalvm.compiler.core.target.Backend;
|
||||||
import org.graalvm.compiler.hotspot.HotSpotCompiledCodeBuilder;
|
import org.graalvm.compiler.hotspot.HotSpotCompiledCodeBuilder;
|
||||||
import org.graalvm.compiler.hotspot.stubs.Stub;
|
import org.graalvm.compiler.hotspot.stubs.Stub;
|
||||||
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
|
|
||||||
import jdk.vm.ci.hotspot.HotSpotCompiledCode;
|
import jdk.vm.ci.hotspot.HotSpotCompiledCode;
|
||||||
|
|
||||||
@ -36,10 +37,12 @@ final class AOTStub implements JavaMethodInfo {
|
|||||||
|
|
||||||
private final Stub stub;
|
private final Stub stub;
|
||||||
private final Backend backend;
|
private final Backend backend;
|
||||||
|
private OptionValues options;
|
||||||
|
|
||||||
AOTStub(Stub stub, Backend backend) {
|
AOTStub(Stub stub, Backend backend, OptionValues options) {
|
||||||
this.stub = stub;
|
this.stub = stub;
|
||||||
this.backend = backend;
|
this.backend = backend;
|
||||||
|
this.options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -54,7 +57,7 @@ final class AOTStub implements JavaMethodInfo {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HotSpotCompiledCode compiledCode(CompilationResult result) {
|
public HotSpotCompiledCode compiledCode(CompilationResult result) {
|
||||||
return HotSpotCompiledCodeBuilder.createCompiledCode(backend.getCodeCache(), null, null, result);
|
return HotSpotCompiledCodeBuilder.createCompiledCode(backend.getCodeCache(), null, null, result, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -30,16 +30,15 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import jdk.tools.jaotc.binformat.BinaryContainer;
|
|
||||||
import jdk.tools.jaotc.binformat.ByteContainer;
|
|
||||||
import jdk.tools.jaotc.binformat.HeaderContainer;
|
|
||||||
|
|
||||||
import org.graalvm.compiler.code.CompilationResult;
|
import org.graalvm.compiler.code.CompilationResult;
|
||||||
import org.graalvm.compiler.debug.DebugContext;
|
import org.graalvm.compiler.debug.DebugContext;
|
||||||
import org.graalvm.compiler.hotspot.HotSpotHostBackend;
|
import org.graalvm.compiler.hotspot.HotSpotHostBackend;
|
||||||
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
|
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
|
||||||
import org.graalvm.compiler.hotspot.stubs.Stub;
|
import org.graalvm.compiler.hotspot.stubs.Stub;
|
||||||
|
|
||||||
|
import jdk.tools.jaotc.binformat.BinaryContainer;
|
||||||
|
import jdk.tools.jaotc.binformat.ByteContainer;
|
||||||
|
import jdk.tools.jaotc.binformat.HeaderContainer;
|
||||||
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
|
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
|
||||||
import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
|
import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
|
||||||
import jdk.vm.ci.hotspot.VMField;
|
import jdk.vm.ci.hotspot.VMField;
|
||||||
@ -190,7 +189,7 @@ final class DataBuilder {
|
|||||||
for (Stub stub : foreignCallsProvider.getStubs()) {
|
for (Stub stub : foreignCallsProvider.getStubs()) {
|
||||||
try (DebugContext.Scope scope = debug.scope("CompileStubs")) {
|
try (DebugContext.Scope scope = debug.scope("CompileStubs")) {
|
||||||
CompilationResult result = stub.getCompilationResult(debug, backend);
|
CompilationResult result = stub.getCompilationResult(debug, backend);
|
||||||
CompiledMethodInfo cm = new CompiledMethodInfo(result, new AOTStub(stub, backend));
|
CompiledMethodInfo cm = new CompiledMethodInfo(result, new AOTStub(stub, backend, debug.getOptions()));
|
||||||
stubs.add(cm);
|
stubs.add(cm);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
throw debug.handle(e);
|
throw debug.handle(e);
|
||||||
|
@ -150,10 +150,16 @@ public final class HotSpotGraalManagement implements HotSpotGraalManagementRegis
|
|||||||
*/
|
*/
|
||||||
synchronized void poll() {
|
synchronized void poll() {
|
||||||
if (platformMBeanServer == null) {
|
if (platformMBeanServer == null) {
|
||||||
ArrayList<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null);
|
try {
|
||||||
if (!servers.isEmpty()) {
|
ArrayList<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null);
|
||||||
platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
|
if (!servers.isEmpty()) {
|
||||||
process();
|
platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||||
|
process();
|
||||||
|
}
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
// Without permission to find or create the MBeanServer,
|
||||||
|
// we cannot process any Graal mbeans.
|
||||||
|
deferred = null;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
process();
|
process();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.collections.test;
|
package jdk.internal.vm.compiler.collections.test;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -117,7 +133,7 @@ public class EconomicMapImplTest {
|
|||||||
Assert.assertTrue(set.add(newInteger(0)));
|
Assert.assertTrue(set.add(newInteger(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings({"deprecation", "unused"})
|
||||||
private static Integer newInteger(int value) {
|
private static Integer newInteger(int value) {
|
||||||
return new Integer(value);
|
return new Integer(value);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.collections.test;
|
package jdk.internal.vm.compiler.collections.test;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.collections.test;
|
package jdk.internal.vm.compiler.collections.test;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.collections.test;
|
package jdk.internal.vm.compiler.collections.test;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -145,7 +161,7 @@ public class EconomicSetTest {
|
|||||||
Assert.assertEquals(newInteger(9), finalList.get(0));
|
Assert.assertEquals(newInteger(9), finalList.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings({"deprecation", "unused"})
|
||||||
private static Integer newInteger(int value) {
|
private static Integer newInteger(int value) {
|
||||||
return new Integer(value);
|
return new Integer(value);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.collections.test;
|
package jdk.internal.vm.compiler.collections.test;
|
||||||
|
|
||||||
import jdk.internal.vm.compiler.collections.Equivalence;
|
import jdk.internal.vm.compiler.collections.Equivalence;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.collections.test;
|
package jdk.internal.vm.compiler.collections.test;
|
||||||
|
|
||||||
import jdk.internal.vm.compiler.collections.Pair;
|
import jdk.internal.vm.compiler.collections.Pair;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.collections;
|
package jdk.internal.vm.compiler.collections;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.collections;
|
package jdk.internal.vm.compiler.collections;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.collections;
|
package jdk.internal.vm.compiler.collections;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.collections;
|
package jdk.internal.vm.compiler.collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.collections;
|
package jdk.internal.vm.compiler.collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.collections;
|
package jdk.internal.vm.compiler.collections;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.collections;
|
package jdk.internal.vm.compiler.collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.collections;
|
package jdk.internal.vm.compiler.collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.collections;
|
package jdk.internal.vm.compiler.collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -35,4 +35,20 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.collections;
|
package jdk.internal.vm.compiler.collections;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.word;
|
package jdk.internal.vm.compiler.word;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.word;
|
package jdk.internal.vm.compiler.word;
|
||||||
|
|
||||||
// JaCoCo Exclude
|
// JaCoCo Exclude
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.word;
|
package jdk.internal.vm.compiler.word;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -959,7 +975,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
|||||||
void writeObject(WordBase offset, Object val);
|
void writeObject(WordBase offset, Object val);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
* In a single atomic step, compares the memory at address {@code (this + offset)} to the
|
||||||
|
* expected value, and if equal, exchanges it for the new value. Both the base address and
|
||||||
* offset are in bytes.
|
* offset are in bytes.
|
||||||
* <p>
|
* <p>
|
||||||
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
||||||
@ -967,17 +984,19 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
|||||||
* knows that the highest-order bit of the unsigned value is never used).
|
* knows that the highest-order bit of the unsigned value is never used).
|
||||||
*
|
*
|
||||||
* @param offset the signed offset for the memory access
|
* @param offset the signed offset for the memory access
|
||||||
* @param expectedValue the expected value of the atomic exchange
|
* @param expectedValue the expected current value at the memory address
|
||||||
* @param newValue the new value of the atomic exchange
|
* @param newValue the new value for the atomic exchange
|
||||||
* @param locationIdentity the identity of the memory location
|
* @param locationIdentity the identity of the memory location
|
||||||
* @return The value after the atomic exchange
|
* @return The value that was read for comparison, which is {@code expectedValue} if the
|
||||||
|
* exchange was performed.
|
||||||
*
|
*
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
int compareAndSwapInt(WordBase offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
|
int compareAndSwapInt(WordBase offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
* In a single atomic step, compares the memory at address {@code (this + offset)} to the
|
||||||
|
* expected value, and if equal, exchanges it for the new value. Both the base address and
|
||||||
* offset are in bytes.
|
* offset are in bytes.
|
||||||
* <p>
|
* <p>
|
||||||
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
||||||
@ -985,17 +1004,19 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
|||||||
* knows that the highest-order bit of the unsigned value is never used).
|
* knows that the highest-order bit of the unsigned value is never used).
|
||||||
*
|
*
|
||||||
* @param offset the signed offset for the memory access
|
* @param offset the signed offset for the memory access
|
||||||
* @param expectedValue the expected value of the atomic exchange
|
* @param expectedValue the expected current value at the memory address
|
||||||
* @param newValue the new value of the atomic exchange
|
* @param newValue the new value for the atomic exchange
|
||||||
* @param locationIdentity the identity of the memory location
|
* @param locationIdentity the identity of the memory location
|
||||||
* @return The value after the atomic exchange
|
* @return The value that was read for comparison, which is {@code expectedValue} if the
|
||||||
|
* exchange was performed.
|
||||||
*
|
*
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
long compareAndSwapLong(WordBase offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
|
long compareAndSwapLong(WordBase offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
* In a single atomic step, compares the memory at address {@code (this + offset)} to the
|
||||||
|
* expected value, and if equal, exchanges it for the new value. Both the base address and
|
||||||
* offset are in bytes.
|
* offset are in bytes.
|
||||||
* <p>
|
* <p>
|
||||||
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
||||||
@ -1003,17 +1024,19 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
|||||||
* knows that the highest-order bit of the unsigned value is never used).
|
* knows that the highest-order bit of the unsigned value is never used).
|
||||||
*
|
*
|
||||||
* @param offset the signed offset for the memory access
|
* @param offset the signed offset for the memory access
|
||||||
* @param expectedValue the expected value of the atomic exchange
|
* @param expectedValue the expected current value at the memory address
|
||||||
* @param newValue the new value of the atomic exchange
|
* @param newValue the new value for the atomic exchange
|
||||||
* @param locationIdentity the identity of the memory location
|
* @param locationIdentity the identity of the memory location
|
||||||
* @return The value after the atomic exchange
|
* @return The value that was read for comparison, which is {@code expectedValue} if the
|
||||||
|
* exchange was performed.
|
||||||
*
|
*
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
<T extends WordBase> T compareAndSwapWord(WordBase offset, T expectedValue, T newValue, LocationIdentity locationIdentity);
|
<T extends WordBase> T compareAndSwapWord(WordBase offset, T expectedValue, T newValue, LocationIdentity locationIdentity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
* In a single atomic step, compares the memory at address {@code (this + offset)} to the
|
||||||
|
* expected value, and if equal, exchanges it for the new value. Both the base address and
|
||||||
* offset are in bytes.
|
* offset are in bytes.
|
||||||
* <p>
|
* <p>
|
||||||
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
||||||
@ -1021,17 +1044,19 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
|||||||
* knows that the highest-order bit of the unsigned value is never used).
|
* knows that the highest-order bit of the unsigned value is never used).
|
||||||
*
|
*
|
||||||
* @param offset the signed offset for the memory access
|
* @param offset the signed offset for the memory access
|
||||||
* @param expectedValue the expected value of the atomic exchange
|
* @param expectedValue the expected current value at the memory address
|
||||||
* @param newValue the new value of the atomic exchange
|
* @param newValue the new value for the atomic exchange
|
||||||
* @param locationIdentity the identity of the memory location
|
* @param locationIdentity the identity of the memory location
|
||||||
* @return The value after the atomic exchange
|
* @return The value that was read for comparison, which is {@code expectedValue} if the
|
||||||
|
* exchange was performed.
|
||||||
*
|
*
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
Object compareAndSwapObject(WordBase offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
|
Object compareAndSwapObject(WordBase offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
* In a single atomic step, compares the memory at address {@code (this + offset)} to the
|
||||||
|
* expected value, and if equal, exchanges it for the new value. Both the base address and
|
||||||
* offset are in bytes.
|
* offset are in bytes.
|
||||||
* <p>
|
* <p>
|
||||||
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
||||||
@ -1039,8 +1064,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
|||||||
* knows that the highest-order bit of the unsigned value is never used).
|
* knows that the highest-order bit of the unsigned value is never used).
|
||||||
*
|
*
|
||||||
* @param offset the signed offset for the memory access
|
* @param offset the signed offset for the memory access
|
||||||
* @param expectedValue the expected value of the atomic exchange
|
* @param expectedValue the expected current value at the memory address
|
||||||
* @param newValue the new value of the atomic exchange
|
* @param newValue the new value for the atomic exchange
|
||||||
* @param locationIdentity the identity of the memory location
|
* @param locationIdentity the identity of the memory location
|
||||||
* @return {@code true} if successful. False return indicates that the actual value was not
|
* @return {@code true} if successful. False return indicates that the actual value was not
|
||||||
* equal to the expected value.
|
* equal to the expected value.
|
||||||
@ -1050,7 +1075,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
|||||||
boolean logicCompareAndSwapInt(WordBase offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
|
boolean logicCompareAndSwapInt(WordBase offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
* In a single atomic step, compares the memory at address {@code (this + offset)} to the
|
||||||
|
* expected value, and if equal, exchanges it for the new value. Both the base address and
|
||||||
* offset are in bytes.
|
* offset are in bytes.
|
||||||
* <p>
|
* <p>
|
||||||
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
||||||
@ -1058,8 +1084,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
|||||||
* knows that the highest-order bit of the unsigned value is never used).
|
* knows that the highest-order bit of the unsigned value is never used).
|
||||||
*
|
*
|
||||||
* @param offset the signed offset for the memory access
|
* @param offset the signed offset for the memory access
|
||||||
* @param expectedValue the expected value of the atomic exchange
|
* @param expectedValue the expected current value at the memory address
|
||||||
* @param newValue the new value of the atomic exchange
|
* @param newValue the new value for the atomic exchange
|
||||||
* @param locationIdentity the identity of the memory location
|
* @param locationIdentity the identity of the memory location
|
||||||
* @return {@code true} if successful. False return indicates that the actual value was not
|
* @return {@code true} if successful. False return indicates that the actual value was not
|
||||||
* equal to the expected value.
|
* equal to the expected value.
|
||||||
@ -1069,7 +1095,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
|||||||
boolean logicCompareAndSwapLong(WordBase offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
|
boolean logicCompareAndSwapLong(WordBase offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
* In a single atomic step, compares the memory at address {@code (this + offset)} to the
|
||||||
|
* expected value, and if equal, exchanges it for the new value. Both the base address and
|
||||||
* offset are in bytes.
|
* offset are in bytes.
|
||||||
* <p>
|
* <p>
|
||||||
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
||||||
@ -1077,8 +1104,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
|||||||
* knows that the highest-order bit of the unsigned value is never used).
|
* knows that the highest-order bit of the unsigned value is never used).
|
||||||
*
|
*
|
||||||
* @param offset the signed offset for the memory access
|
* @param offset the signed offset for the memory access
|
||||||
* @param expectedValue the expected value of the atomic exchange
|
* @param expectedValue the expected current value at the memory address
|
||||||
* @param newValue the new value of the atomic exchange
|
* @param newValue the new value for the atomic exchange
|
||||||
* @param locationIdentity the identity of the memory location
|
* @param locationIdentity the identity of the memory location
|
||||||
* @return {@code true} if successful. False return indicates that the actual value was not
|
* @return {@code true} if successful. False return indicates that the actual value was not
|
||||||
* equal to the expected value.
|
* equal to the expected value.
|
||||||
@ -1088,7 +1115,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
|||||||
boolean logicCompareAndSwapWord(WordBase offset, WordBase expectedValue, WordBase newValue, LocationIdentity locationIdentity);
|
boolean logicCompareAndSwapWord(WordBase offset, WordBase expectedValue, WordBase newValue, LocationIdentity locationIdentity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
* In a single atomic step, compares the memory at address {@code (this + offset)} to the
|
||||||
|
* expected value, and if equal, exchanges it for the new value. Both the base address and
|
||||||
* offset are in bytes.
|
* offset are in bytes.
|
||||||
* <p>
|
* <p>
|
||||||
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
* The offset is always treated as a {@link SignedWord} value. However, the static type is
|
||||||
@ -1096,8 +1124,8 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
|||||||
* knows that the highest-order bit of the unsigned value is never used).
|
* knows that the highest-order bit of the unsigned value is never used).
|
||||||
*
|
*
|
||||||
* @param offset the signed offset for the memory access
|
* @param offset the signed offset for the memory access
|
||||||
* @param expectedValue the expected value of the atomic exchange
|
* @param expectedValue the expected current value at the memory address
|
||||||
* @param newValue the new value of the atomic exchange
|
* @param newValue the new value for the atomic exchange
|
||||||
* @param locationIdentity the identity of the memory location
|
* @param locationIdentity the identity of the memory location
|
||||||
* @return {@code true} if successful. False return indicates that the actual value was not
|
* @return {@code true} if successful. False return indicates that the actual value was not
|
||||||
* equal to the expected value.
|
* equal to the expected value.
|
||||||
@ -1206,68 +1234,77 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
|||||||
void writeObject(int offset, Object val);
|
void writeObject(int offset, Object val);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
* In a single atomic step, compares the memory at address {@code (this + offset)} to the
|
||||||
|
* expected value, and if equal, exchanges it for the new value. Both the base address and
|
||||||
* offset are in bytes.
|
* offset are in bytes.
|
||||||
*
|
*
|
||||||
* @param offset the signed offset for the memory access
|
* @param offset the signed offset for the memory access
|
||||||
* @param expectedValue the expected value of the atomic exchange
|
* @param expectedValue the expected current value at the memory address
|
||||||
* @param newValue the new value of the atomic exchange
|
* @param newValue the new value for the atomic exchange
|
||||||
* @param locationIdentity the identity of the memory location
|
* @param locationIdentity the identity of the memory location
|
||||||
* @return The value after the atomic exchange
|
* @return The value that was read for comparison, which is {@code expectedValue} if the
|
||||||
|
* exchange was performed.
|
||||||
*
|
*
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
int compareAndSwapInt(int offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
|
int compareAndSwapInt(int offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
* In a single atomic step, compares the memory at address {@code (this + offset)} to the
|
||||||
|
* expected value, and if equal, exchanges it for the new value. Both the base address and
|
||||||
* offset are in bytes.
|
* offset are in bytes.
|
||||||
*
|
*
|
||||||
* @param offset the signed offset for the memory access
|
* @param offset the signed offset for the memory access
|
||||||
* @param expectedValue the expected value of the atomic exchange
|
* @param expectedValue the expected current value at the memory address
|
||||||
* @param newValue the new value of the atomic exchange
|
* @param newValue the new value for the atomic exchange
|
||||||
* @param locationIdentity the identity of the memory location
|
* @param locationIdentity the identity of the memory location
|
||||||
* @return The value after the atomic exchange
|
* @return The value that was read for comparison, which is {@code expectedValue} if the
|
||||||
|
* exchange was performed.
|
||||||
*
|
*
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
long compareAndSwapLong(int offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
|
long compareAndSwapLong(int offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
* In a single atomic step, compares the memory at address {@code (this + offset)} to the
|
||||||
|
* expected value, and if equal, exchanges it for the new value. Both the base address and
|
||||||
* offset are in bytes.
|
* offset are in bytes.
|
||||||
*
|
*
|
||||||
* @param offset the signed offset for the memory access
|
* @param offset the signed offset for the memory access
|
||||||
* @param expectedValue the expected value of the atomic exchange
|
* @param expectedValue the expected current value at the memory address
|
||||||
* @param newValue the new value of the atomic exchange
|
* @param newValue the new value for the atomic exchange
|
||||||
* @param locationIdentity the identity of the memory location
|
* @param locationIdentity the identity of the memory location
|
||||||
* @return The value after the atomic exchange
|
* @return The value that was read for comparison, which is {@code expectedValue} if the
|
||||||
|
* exchange was performed.
|
||||||
*
|
*
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
<T extends WordBase> T compareAndSwapWord(int offset, T expectedValue, T newValue, LocationIdentity locationIdentity);
|
<T extends WordBase> T compareAndSwapWord(int offset, T expectedValue, T newValue, LocationIdentity locationIdentity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
* In a single atomic step, compares the memory at address {@code (this + offset)} to the
|
||||||
|
* expected value, and if equal, exchanges it for the new value. Both the base address and
|
||||||
* offset are in bytes.
|
* offset are in bytes.
|
||||||
*
|
*
|
||||||
* @param offset the signed offset for the memory access
|
* @param offset the signed offset for the memory access
|
||||||
* @param expectedValue the expected value of the atomic exchange
|
* @param expectedValue the expected current value at the memory address
|
||||||
* @param newValue the new value of the atomic exchange
|
* @param newValue the new value for the atomic exchange
|
||||||
* @param locationIdentity the identity of the memory location
|
* @param locationIdentity the identity of the memory location
|
||||||
* @return The value after the atomic exchange
|
* @return The value that was read for comparison, which is {@code expectedValue} if the
|
||||||
|
* exchange was performed.
|
||||||
*
|
*
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
Object compareAndSwapObject(int offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
|
Object compareAndSwapObject(int offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
* In a single atomic step, compares the memory at address {@code (this + offset)} to the
|
||||||
|
* expected value, and if equal, exchanges it for the new value. Both the base address and
|
||||||
* offset are in bytes.
|
* offset are in bytes.
|
||||||
*
|
*
|
||||||
* @param offset the signed offset for the memory access
|
* @param offset the signed offset for the memory access
|
||||||
* @param expectedValue the expected value of the atomic exchange
|
* @param expectedValue the expected current value at the memory address
|
||||||
* @param newValue the new value of the atomic exchange
|
* @param newValue the new value for the atomic exchange
|
||||||
* @param locationIdentity the identity of the memory location
|
* @param locationIdentity the identity of the memory location
|
||||||
* @return {@code true} if successful. False return indicates that the actual value was not
|
* @return {@code true} if successful. False return indicates that the actual value was not
|
||||||
* equal to the expected value.
|
* equal to the expected value.
|
||||||
@ -1277,12 +1314,13 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
|||||||
boolean logicCompareAndSwapInt(int offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
|
boolean logicCompareAndSwapInt(int offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
* In a single atomic step, compares the memory at address {@code (this + offset)} to the
|
||||||
|
* expected value, and if equal, exchanges it for the new value. Both the base address and
|
||||||
* offset are in bytes.
|
* offset are in bytes.
|
||||||
*
|
*
|
||||||
* @param offset the signed offset for the memory access
|
* @param offset the signed offset for the memory access
|
||||||
* @param expectedValue the expected value of the atomic exchange
|
* @param expectedValue the expected current value at the memory address
|
||||||
* @param newValue the new value of the atomic exchange
|
* @param newValue the new value for the atomic exchange
|
||||||
* @param locationIdentity the identity of the memory location
|
* @param locationIdentity the identity of the memory location
|
||||||
* @return {@code true} if successful. False return indicates that the actual value was not
|
* @return {@code true} if successful. False return indicates that the actual value was not
|
||||||
* equal to the expected value.
|
* equal to the expected value.
|
||||||
@ -1292,12 +1330,13 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
|||||||
boolean logicCompareAndSwapLong(int offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
|
boolean logicCompareAndSwapLong(int offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
* In a single atomic step, compares the memory at address {@code (this + offset)} to the
|
||||||
|
* expected value, and if equal, exchanges it for the new value. Both the base address and
|
||||||
* offset are in bytes.
|
* offset are in bytes.
|
||||||
*
|
*
|
||||||
* @param offset the signed offset for the memory access
|
* @param offset the signed offset for the memory access
|
||||||
* @param expectedValue the expected value of the atomic exchange
|
* @param expectedValue the expected current value at the memory address
|
||||||
* @param newValue the new value of the atomic exchange
|
* @param newValue the new value for the atomic exchange
|
||||||
* @param locationIdentity the identity of the memory location
|
* @param locationIdentity the identity of the memory location
|
||||||
* @return {@code true} if successful. False return indicates that the actual value was not
|
* @return {@code true} if successful. False return indicates that the actual value was not
|
||||||
* equal to the expected value.
|
* equal to the expected value.
|
||||||
@ -1307,12 +1346,13 @@ public interface Pointer extends UnsignedWord, PointerBase {
|
|||||||
boolean logicCompareAndSwapWord(int offset, WordBase expectedValue, WordBase newValue, LocationIdentity locationIdentity);
|
boolean logicCompareAndSwapWord(int offset, WordBase expectedValue, WordBase newValue, LocationIdentity locationIdentity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Atomically exchanges memory at address {@code (this + offset)}. Both the base address and
|
* In a single atomic step, compares the memory at address {@code (this + offset)} to the
|
||||||
|
* expected value, and if equal, exchanges it for the new value. Both the base address and
|
||||||
* offset are in bytes.
|
* offset are in bytes.
|
||||||
*
|
*
|
||||||
* @param offset the signed offset for the memory access
|
* @param offset the signed offset for the memory access
|
||||||
* @param expectedValue the expected value of the atomic exchange
|
* @param expectedValue the expected current value at the memory address
|
||||||
* @param newValue the new value of the atomic exchange
|
* @param newValue the new value for the atomic exchange
|
||||||
* @param locationIdentity the identity of the memory location
|
* @param locationIdentity the identity of the memory location
|
||||||
* @return {@code true} if successful. False return indicates that the actual value was not
|
* @return {@code true} if successful. False return indicates that the actual value was not
|
||||||
* equal to the expected value.
|
* equal to the expected value.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.word;
|
package jdk.internal.vm.compiler.word;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.word;
|
package jdk.internal.vm.compiler.word;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.word;
|
package jdk.internal.vm.compiler.word;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.word;
|
package jdk.internal.vm.compiler.word;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.word;
|
package jdk.internal.vm.compiler.word;
|
||||||
|
|
||||||
import jdk.internal.vm.compiler.word.impl.WordBoxFactory;
|
import jdk.internal.vm.compiler.word.impl.WordBoxFactory;
|
||||||
|
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.word.impl;
|
package jdk.internal.vm.compiler.word.impl;
|
||||||
|
|
||||||
import jdk.internal.vm.compiler.word.WordBase;
|
import jdk.internal.vm.compiler.word.WordBase;
|
||||||
|
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.word.impl;
|
package jdk.internal.vm.compiler.word.impl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,6 +22,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.word.impl;
|
package jdk.internal.vm.compiler.word.impl;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -33,4 +33,20 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package jdk.internal.vm.compiler.word;
|
package jdk.internal.vm.compiler.word;
|
@ -2775,7 +2775,8 @@ public abstract class AArch64Assembler extends Assembler {
|
|||||||
WFE(0x2),
|
WFE(0x2),
|
||||||
WFI(0x3),
|
WFI(0x3),
|
||||||
SEV(0x4),
|
SEV(0x4),
|
||||||
SEVL(0x5);
|
SEVL(0x5),
|
||||||
|
CSDB(0x14);
|
||||||
|
|
||||||
private final int encoding;
|
private final int encoding;
|
||||||
|
|
||||||
|
@ -1475,6 +1475,14 @@ public class AArch64MacroAssembler extends AArch64Assembler {
|
|||||||
super.hint(SystemHint.NOP);
|
super.hint(SystemHint.NOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Consumption of Speculative Data Barrier. This is a memory barrier that controls speculative
|
||||||
|
* execution and data value prediction.
|
||||||
|
*/
|
||||||
|
public void csdb() {
|
||||||
|
super.hint(SystemHint.CSDB);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as {@link #nop()}.
|
* Same as {@link #nop()}.
|
||||||
*/
|
*/
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -59,6 +59,7 @@ import jdk.vm.ci.amd64.AMD64;
|
|||||||
import jdk.vm.ci.amd64.AMD64.CPUFeature;
|
import jdk.vm.ci.amd64.AMD64.CPUFeature;
|
||||||
import jdk.vm.ci.amd64.AMD64Kind;
|
import jdk.vm.ci.amd64.AMD64Kind;
|
||||||
import jdk.vm.ci.code.Register;
|
import jdk.vm.ci.code.Register;
|
||||||
|
import jdk.vm.ci.code.Register.RegisterCategory;
|
||||||
import jdk.vm.ci.code.TargetDescription;
|
import jdk.vm.ci.code.TargetDescription;
|
||||||
import jdk.vm.ci.meta.PlatformKind;
|
import jdk.vm.ci.meta.PlatformKind;
|
||||||
|
|
||||||
@ -269,8 +270,12 @@ public abstract class AMD64BaseAssembler extends Assembler {
|
|||||||
return ((AMD64) target.arch).getFeatures().contains(feature);
|
return ((AMD64) target.arch).getFeatures().contains(feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static boolean inRC(RegisterCategory rc, Register r) {
|
||||||
|
return r.getRegisterCategory().equals(rc);
|
||||||
|
}
|
||||||
|
|
||||||
protected static int encode(Register r) {
|
protected static int encode(Register r) {
|
||||||
assert r.encoding >= 0 && (r.getRegisterCategory().equals(XMM) ? r.encoding < 32 : r.encoding < 16) : "encoding out of range: " + r.encoding;
|
assert r.encoding >= 0 && (inRC(XMM, r) ? r.encoding < 32 : r.encoding < 16) : "encoding out of range: " + r.encoding;
|
||||||
return r.encoding & 0x7;
|
return r.encoding & 0x7;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,6 +301,10 @@ public abstract class AMD64BaseAssembler extends Assembler {
|
|||||||
private static final int REXWRB = 0x4D;
|
private static final int REXWRB = 0x4D;
|
||||||
private static final int REXWRX = 0x4E;
|
private static final int REXWRX = 0x4E;
|
||||||
private static final int REXWRXB = 0x4F;
|
private static final int REXWRXB = 0x4F;
|
||||||
|
|
||||||
|
private static final int VEX2 = 0xC5;
|
||||||
|
private static final int VEX3 = 0xC4;
|
||||||
|
private static final int EVEX = 0x62;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final void rexw() {
|
protected final void rexw() {
|
||||||
@ -797,12 +806,17 @@ public abstract class AMD64BaseAssembler extends Assembler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void simdPrefix(Register reg, Register nds, AMD64Address rm, int sizePrefix, int opcodeEscapePrefix, boolean isRexW) {
|
public void simdPrefix(Register reg, Register nds, AMD64Address rm, int sizePrefix, int opcodeEscapePrefix, boolean isRexW) {
|
||||||
emitVEX(L128, sizePrefixToPP(sizePrefix), opcodeEscapePrefixToMMMMM(opcodeEscapePrefix), isRexW ? W1 : W0, getRXB(reg, rm), nds.isValid() ? nds.encoding : 0);
|
assert reg.encoding < 16 : "encoding out of range: " + reg.encoding;
|
||||||
|
assert nds.encoding < 16 : "encoding out of range: " + nds.encoding;
|
||||||
|
emitVEX(L128, sizePrefixToPP(sizePrefix), opcodeEscapePrefixToMMMMM(opcodeEscapePrefix), isRexW ? W1 : W0, getRXB(reg, rm), nds.isValid() ? nds.encoding : 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void simdPrefix(Register dst, Register nds, Register src, int sizePrefix, int opcodeEscapePrefix, boolean isRexW) {
|
public void simdPrefix(Register dst, Register nds, Register src, int sizePrefix, int opcodeEscapePrefix, boolean isRexW) {
|
||||||
emitVEX(L128, sizePrefixToPP(sizePrefix), opcodeEscapePrefixToMMMMM(opcodeEscapePrefix), isRexW ? W1 : W0, getRXB(dst, src), nds.isValid() ? nds.encoding : 0);
|
assert dst.encoding < 16 : "encoding out of range: " + dst.encoding;
|
||||||
|
assert src.encoding < 16 : "encoding out of range: " + src.encoding;
|
||||||
|
assert nds.encoding < 16 : "encoding out of range: " + nds.encoding;
|
||||||
|
emitVEX(L128, sizePrefixToPP(sizePrefix), opcodeEscapePrefixToMMMMM(opcodeEscapePrefix), isRexW ? W1 : W0, getRXB(dst, src), nds.isValid() ? nds.encoding : 0, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -822,6 +836,46 @@ public abstract class AMD64BaseAssembler extends Assembler {
|
|||||||
simdEncoder.simdPrefix(dst, nds, src, size.sizePrefix, opcodeEscapePrefix, isRexW);
|
simdEncoder.simdPrefix(dst, nds, src, size.sizePrefix, opcodeEscapePrefix, isRexW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @formatter:off
|
||||||
|
//
|
||||||
|
// Instruction Format and VEX illustrated below (optional []):
|
||||||
|
//
|
||||||
|
// #of bytes: 2,3 1 1 1 1,2,4 1
|
||||||
|
// [Prefixes] VEX OpCode ModR/M [SIB] [Disp8*N] [Immediate]
|
||||||
|
// [Disp16,32]
|
||||||
|
//
|
||||||
|
// VEX: 0xC4 | P1 | P2
|
||||||
|
//
|
||||||
|
// 7 6 5 4 3 2 1 0
|
||||||
|
// P1 R X B m m m m m P[ 7:0]
|
||||||
|
// P2 W v v v v L p p P[15:8]
|
||||||
|
//
|
||||||
|
// VEX: 0xC5 | B1
|
||||||
|
//
|
||||||
|
// 7 6 5 4 3 2 1 0
|
||||||
|
// P1 R v v v v L p p P[7:0]
|
||||||
|
//
|
||||||
|
// Figure. Bit Field Layout of the VEX Prefix
|
||||||
|
//
|
||||||
|
// Table. VEX Prefix Bit Field Functional Grouping
|
||||||
|
//
|
||||||
|
// Notation Bit field Group Position Comment
|
||||||
|
// ---------- ------------------------- -------- -------------------
|
||||||
|
// VEX.RXB Next-8 register specifier P[7:5] Combine with ModR/M.reg, ModR/M.rm (base, index/vidx).
|
||||||
|
// VEX.R REX.R inverse P[7] Combine with EVEX.R and ModR/M.reg.
|
||||||
|
// VEX.X REX.X inverse P[6] Combine with EVEX.B and ModR/M.rm, when SIB/VSIB absent.
|
||||||
|
// VEX.B REX.B inverse P[5]
|
||||||
|
// VEX.mmmmmm 0F, 0F_38, 0F_3A encoding P[4:0] b01/0x0F, b10/0F_38, b11/0F_3A (all other reserved)
|
||||||
|
//
|
||||||
|
// VEX.W Opcode specific P[15]
|
||||||
|
// VEX.vvvv A register specifier P[14:11] In inverse form, b1111 if not used.
|
||||||
|
// P[6:3]
|
||||||
|
// VEX.L Vector length/RC P[10] b0/scalar or 128b vec, b1/256b vec.
|
||||||
|
// P[2]
|
||||||
|
// VEX.pp Compressed legacy prefix P[9:8] b00/None, b01/0x66, b10/0xF3, b11/0xF2
|
||||||
|
// P[1:0]
|
||||||
|
// @formatter:on
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Low-level function to encode and emit the VEX prefix.
|
* Low-level function to encode and emit the VEX prefix.
|
||||||
* <p>
|
* <p>
|
||||||
@ -846,8 +900,8 @@ public abstract class AMD64BaseAssembler extends Assembler {
|
|||||||
* This function automatically chooses the 2 or 3 byte encoding, based on the XBW flags and the
|
* This function automatically chooses the 2 or 3 byte encoding, based on the XBW flags and the
|
||||||
* m-mmmm field.
|
* m-mmmm field.
|
||||||
*/
|
*/
|
||||||
protected final void emitVEX(int l, int pp, int mmmmm, int w, int rxb, int vvvv) {
|
protected final void emitVEX(int l, int pp, int mmmmm, int w, int rxb, int vvvv, boolean checkAVX) {
|
||||||
assert ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX) : "emitting VEX prefix on a CPU without AVX support";
|
assert !checkAVX || ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX) : "emitting VEX prefix on a CPU without AVX support";
|
||||||
|
|
||||||
assert l == L128 || l == L256 : "invalid value for VEX.L";
|
assert l == L128 || l == L256 : "invalid value for VEX.L";
|
||||||
assert pp == P_ || pp == P_66 || pp == P_F3 || pp == P_F2 : "invalid value for VEX.pp";
|
assert pp == P_ || pp == P_66 || pp == P_F3 || pp == P_F2 : "invalid value for VEX.pp";
|
||||||
@ -867,7 +921,7 @@ public abstract class AMD64BaseAssembler extends Assembler {
|
|||||||
byte2 |= l << 2;
|
byte2 |= l << 2;
|
||||||
byte2 |= pp;
|
byte2 |= pp;
|
||||||
|
|
||||||
emitByte(0xC5);
|
emitByte(Prefix.VEX2);
|
||||||
emitByte(byte2);
|
emitByte(byte2);
|
||||||
} else {
|
} else {
|
||||||
// 3 byte encoding
|
// 3 byte encoding
|
||||||
@ -881,7 +935,7 @@ public abstract class AMD64BaseAssembler extends Assembler {
|
|||||||
byte3 |= l << 2;
|
byte3 |= l << 2;
|
||||||
byte3 |= pp;
|
byte3 |= pp;
|
||||||
|
|
||||||
emitByte(0xC4);
|
emitByte(Prefix.VEX3);
|
||||||
emitByte(byte2);
|
emitByte(byte2);
|
||||||
emitByte(byte3);
|
emitByte(byte3);
|
||||||
}
|
}
|
||||||
@ -900,12 +954,12 @@ public abstract class AMD64BaseAssembler extends Assembler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void vexPrefix(Register dst, Register nds, Register src, AVXSize size, int pp, int mmmmm, int w) {
|
public final void vexPrefix(Register dst, Register nds, Register src, AVXSize size, int pp, int mmmmm, int w, boolean checkAVX) {
|
||||||
emitVEX(getLFlag(size), pp, mmmmm, w, getRXB(dst, src), nds.isValid() ? nds.encoding() : 0);
|
emitVEX(getLFlag(size), pp, mmmmm, w, getRXB(dst, src), nds.isValid() ? nds.encoding() : 0, checkAVX);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void vexPrefix(Register dst, Register nds, AMD64Address src, AVXSize size, int pp, int mmmmm, int w) {
|
public final void vexPrefix(Register dst, Register nds, AMD64Address src, AVXSize size, int pp, int mmmmm, int w, boolean checkAVX) {
|
||||||
emitVEX(getLFlag(size), pp, mmmmm, w, getRXB(dst, src), nds.isValid() ? nds.encoding() : 0);
|
emitVEX(getLFlag(size), pp, mmmmm, w, getRXB(dst, src), nds.isValid() ? nds.encoding() : 0, checkAVX);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static final class EVEXPrefixConfig {
|
protected static final class EVEXPrefixConfig {
|
||||||
@ -986,6 +1040,51 @@ public abstract class AMD64BaseAssembler extends Assembler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @formatter:off
|
||||||
|
//
|
||||||
|
// Instruction Format and EVEX illustrated below (optional []):
|
||||||
|
//
|
||||||
|
// #of bytes: 4 1 1 1 1,2,4 1
|
||||||
|
// [Prefixes] EVEX OpCode ModR/M [SIB] [Disp8*N] [Immediate]
|
||||||
|
// [Disp16,32]
|
||||||
|
//
|
||||||
|
// The EVEX prefix is a 4-byte prefix, with the first two bytes derived from unused encoding
|
||||||
|
// form of the 32-bit-mode-only BOUND instruction. The layout of the EVEX prefix is shown in
|
||||||
|
// the figure below. The first byte must be 0x62, followed by three pay-load bytes, denoted
|
||||||
|
// as P1, P2, and P3 individually or collectively as P[23:0] (see below).
|
||||||
|
//
|
||||||
|
// EVEX: 0x62 | P1 | P2 | P3
|
||||||
|
//
|
||||||
|
// 7 6 5 4 3 2 1 0
|
||||||
|
// P1 R X B R' 0 0 m m P[ 7: 0]
|
||||||
|
// P2 W v v v v 1 p p P[15: 8]
|
||||||
|
// P3 z L' L b V' a a a P[23:16]
|
||||||
|
//
|
||||||
|
// Figure. Bit Field Layout of the EVEX Prefix
|
||||||
|
//
|
||||||
|
// Table. EVEX Prefix Bit Field Functional Grouping
|
||||||
|
//
|
||||||
|
// Notation Bit field Group Position Comment
|
||||||
|
// --------- -------------------------- -------- -----------------------
|
||||||
|
// EVEX.RXB Next-8 register specifier P[7:5] Combine with ModR/M.reg, ModR/M.rm (base, index/vidx).
|
||||||
|
// EVEX.X High-16 register specifier P[6] Combine with EVEX.B and ModR/M.rm, when SIB/VSIB absent.
|
||||||
|
// EVEX.R' High-16 register specifier P[4] Combine with EVEX.R and ModR/M.reg.
|
||||||
|
// -- Reserved P[3:2] Must be 0.
|
||||||
|
// EVEX.mm Compressed legacy escape P[1:0] Identical to low two bits of VEX.mmmmm.
|
||||||
|
//
|
||||||
|
// EVEX.W Osize promotion/Opcode ext P[15]
|
||||||
|
// EVEX.vvvv NDS register specifier P[14:11] Same as VEX.vvvv.
|
||||||
|
// -- Fixed Value P[10] Must be 1.
|
||||||
|
// EVEX.pp Compressed legacy prefix P[9:8] Identical to VEX.pp.
|
||||||
|
//
|
||||||
|
// EVEX.z Zeroing/Merging P[23]
|
||||||
|
// EVEX.L'L Vector length/RC P[22:21]
|
||||||
|
// EVEX.b Broadcast/RC/SAE Context P[20]
|
||||||
|
// EVEX.V' High-16 NDS/VIDX register P[19] Combine with EVEX.vvvv or VSIB when present.
|
||||||
|
// EVEX.aaa Embedded opmask register P[18:16]
|
||||||
|
//
|
||||||
|
// @formatter:on
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Low-level function to encode and emit the EVEX prefix.
|
* Low-level function to encode and emit the EVEX prefix.
|
||||||
* <p>
|
* <p>
|
||||||
@ -1021,13 +1120,13 @@ public abstract class AMD64BaseAssembler extends Assembler {
|
|||||||
|
|
||||||
assert (rxb & 0x07) == rxb : "invalid value for EVEX.RXB";
|
assert (rxb & 0x07) == rxb : "invalid value for EVEX.RXB";
|
||||||
assert (reg & 0x1F) == reg : "invalid value for EVEX.R'";
|
assert (reg & 0x1F) == reg : "invalid value for EVEX.R'";
|
||||||
assert (vvvvv & 0x1F) == vvvvv : "invalid value for EVEX.vvvvv";
|
assert (vvvvv & 0x1F) == vvvvv : "invalid value for EVEX.V'vvvv";
|
||||||
|
|
||||||
assert z == Z0 || z == Z1 : "invalid value for EVEX.z";
|
assert z == Z0 || z == Z1 : "invalid value for EVEX.z";
|
||||||
assert b == B0 || b == B1 : "invalid value for EVEX.b";
|
assert b == B0 || b == B1 : "invalid value for EVEX.b";
|
||||||
assert (aaa & 0x07) == aaa : "invalid value for EVEX.aaa";
|
assert (aaa & 0x07) == aaa : "invalid value for EVEX.aaa";
|
||||||
|
|
||||||
emitByte(0x62);
|
emitByte(Prefix.EVEX);
|
||||||
int p1 = 0;
|
int p1 = 0;
|
||||||
p1 |= ((rxb ^ 0x07) & 0x07) << 5;
|
p1 |= ((rxb ^ 0x07) & 0x07) << 5;
|
||||||
p1 |= reg < 16 ? 0x10 : 0;
|
p1 |= reg < 16 ? 0x10 : 0;
|
||||||
@ -1037,7 +1136,7 @@ public abstract class AMD64BaseAssembler extends Assembler {
|
|||||||
int p2 = 0;
|
int p2 = 0;
|
||||||
p2 |= w << 7;
|
p2 |= w << 7;
|
||||||
p2 |= ((vvvvv ^ 0x0F) & 0x0F) << 3;
|
p2 |= ((vvvvv ^ 0x0F) & 0x0F) << 3;
|
||||||
p2 |= 0x4;
|
p2 |= 0x04;
|
||||||
p2 |= pp;
|
p2 |= pp;
|
||||||
emitByte(p2);
|
emitByte(p2);
|
||||||
|
|
||||||
@ -1050,6 +1149,11 @@ public abstract class AMD64BaseAssembler extends Assembler {
|
|||||||
emitByte(p3);
|
emitByte(p3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get RXB bits for register-register instructions in EVEX-encoding, where ModRM.rm contains a
|
||||||
|
* register index. The R bit extends the ModRM.reg field and the X and B bits extends the
|
||||||
|
* ModRM.rm field.
|
||||||
|
*/
|
||||||
private static int getRXBForEVEX(Register reg, Register rm) {
|
private static int getRXBForEVEX(Register reg, Register rm) {
|
||||||
int rxb = (reg == null ? 0 : reg.encoding & 0x08) >> 1;
|
int rxb = (reg == null ? 0 : reg.encoding & 0x08) >> 1;
|
||||||
rxb |= (rm == null ? 0 : rm.encoding & 0x018) >> 3;
|
rxb |= (rm == null ? 0 : rm.encoding & 0x018) >> 3;
|
||||||
@ -1060,7 +1164,7 @@ public abstract class AMD64BaseAssembler extends Assembler {
|
|||||||
* Helper method for emitting EVEX prefix in the form of RRRR.
|
* Helper method for emitting EVEX prefix in the form of RRRR.
|
||||||
*/
|
*/
|
||||||
protected final void evexPrefix(Register dst, Register mask, Register nds, Register src, AVXSize size, int pp, int mm, int w, int z, int b) {
|
protected final void evexPrefix(Register dst, Register mask, Register nds, Register src, AVXSize size, int pp, int mm, int w, int z, int b) {
|
||||||
assert !mask.isValid() || mask.getRegisterCategory().equals(MASK);
|
assert !mask.isValid() || inRC(MASK, mask);
|
||||||
emitEVEX(getLFlag(size), pp, mm, w, getRXBForEVEX(dst, src), dst.encoding, nds.isValid() ? nds.encoding() : 0, z, b, mask.isValid() ? mask.encoding : 0);
|
emitEVEX(getLFlag(size), pp, mm, w, getRXBForEVEX(dst, src), dst.encoding, nds.isValid() ? nds.encoding() : 0, z, b, mask.isValid() ? mask.encoding : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1071,7 +1175,7 @@ public abstract class AMD64BaseAssembler extends Assembler {
|
|||||||
* {@link #emitEVEXOperandHelper(Register, AMD64Address, int, int)}.
|
* {@link #emitEVEXOperandHelper(Register, AMD64Address, int, int)}.
|
||||||
*/
|
*/
|
||||||
protected final void evexPrefix(Register dst, Register mask, Register nds, AMD64Address src, AVXSize size, int pp, int mm, int w, int z, int b) {
|
protected final void evexPrefix(Register dst, Register mask, Register nds, AMD64Address src, AVXSize size, int pp, int mm, int w, int z, int b) {
|
||||||
assert !mask.isValid() || mask.getRegisterCategory().equals(MASK);
|
assert !mask.isValid() || inRC(MASK, mask);
|
||||||
emitEVEX(getLFlag(size), pp, mm, w, getRXB(dst, src), dst.encoding, nds.isValid() ? nds.encoding() : 0, z, b, mask.isValid() ? mask.encoding : 0);
|
emitEVEX(getLFlag(size), pp, mm, w, getRXB(dst, src), dst.encoding, nds.isValid() ? nds.encoding() : 0, z, b, mask.isValid() ? mask.encoding : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,6 +24,8 @@
|
|||||||
|
|
||||||
package org.graalvm.compiler.asm.amd64;
|
package org.graalvm.compiler.asm.amd64;
|
||||||
|
|
||||||
|
import static jdk.vm.ci.amd64.AMD64.rbp;
|
||||||
|
import static jdk.vm.ci.amd64.AMD64.rsp;
|
||||||
import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseIncDec;
|
import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseIncDec;
|
||||||
import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseXmmLoadAndClearUpper;
|
import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseXmmLoadAndClearUpper;
|
||||||
import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseXmmRegToRegMoveAll;
|
import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseXmmRegToRegMoveAll;
|
||||||
@ -82,6 +84,20 @@ public class AMD64MacroAssembler extends AMD64Assembler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final void enter(int frameSize) {
|
||||||
|
if (NumUtil.isUShort(frameSize)) {
|
||||||
|
// Can use enter instruction only for frame size that fits in 16 bits.
|
||||||
|
emitByte(0xC8);
|
||||||
|
emitShort(frameSize);
|
||||||
|
emitByte(0x00);
|
||||||
|
} else {
|
||||||
|
// Fall back to manual sequence.
|
||||||
|
push(rbp);
|
||||||
|
movq(rbp, rsp);
|
||||||
|
decrementq(rsp, frameSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void incrementq(Register reg, int value) {
|
public void incrementq(Register reg, int value) {
|
||||||
if (value == Integer.MIN_VALUE) {
|
if (value == Integer.MIN_VALUE) {
|
||||||
addq(reg, value);
|
addq(reg, value);
|
||||||
|
@ -191,6 +191,10 @@ public class CompilationResult {
|
|||||||
|
|
||||||
private StackSlot customStackArea = null;
|
private StackSlot customStackArea = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A customized name that is unrelated to {@link #compilationId}. Can be null if
|
||||||
|
* {@link #compilationId} fully describes the compilation.
|
||||||
|
*/
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
private final CompilationIdentifier compilationId;
|
private final CompilationIdentifier compilationId;
|
||||||
@ -228,7 +232,7 @@ public class CompilationResult {
|
|||||||
private boolean isImmutablePIC;
|
private boolean isImmutablePIC;
|
||||||
|
|
||||||
public CompilationResult(CompilationIdentifier compilationId) {
|
public CompilationResult(CompilationIdentifier compilationId) {
|
||||||
this(compilationId, compilationId.toString(CompilationIdentifier.Verbosity.NAME), false);
|
this(compilationId, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompilationResult(CompilationIdentifier compilationId, String name) {
|
public CompilationResult(CompilationIdentifier compilationId, String name) {
|
||||||
@ -677,6 +681,10 @@ public class CompilationResult {
|
|||||||
return unmodifiableList(sourceMapping);
|
return unmodifiableList(sourceMapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the name for this compilation result. This will only be non-null when it provides a
|
||||||
|
* value unrelated to {@link #getCompilationId()}.
|
||||||
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,187 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2018, Arm Limited and 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.aarch64.test;
|
||||||
|
|
||||||
|
import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticOp;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class AArch64AddSubShiftTest extends AArch64MatchRuleTest {
|
||||||
|
/**
|
||||||
|
* addSubShift match rule test for add operation with int type.
|
||||||
|
*/
|
||||||
|
private static int addLeftShiftInt(int input) {
|
||||||
|
int output = (input << 5) + input;
|
||||||
|
output += output << -5;
|
||||||
|
output += output << 32;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int addRightShiftInt(int input) {
|
||||||
|
int output = (input >> 5) + input;
|
||||||
|
output += output >> -5;
|
||||||
|
output += output >> 32;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int addUnsignedRightShiftInt(int input) {
|
||||||
|
int output = (input >>> 5) + input;
|
||||||
|
output += output >>> -5;
|
||||||
|
output += output >>> 32;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int addShiftInt(int input) {
|
||||||
|
return addLeftShiftInt(input) + addRightShiftInt(input) + addUnsignedRightShiftInt(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the addSubShift match rule in AArch64NodeMatchRules does work for add operation
|
||||||
|
* with int type and check if the expected LIR instructions show up.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testAddShiftInt() {
|
||||||
|
int expected = addShiftInt(123);
|
||||||
|
|
||||||
|
Result result = executeActual(getResolvedJavaMethod("addShiftInt"), null, 123);
|
||||||
|
int actual = (int) result.returnValue;
|
||||||
|
Assert.assertEquals(expected, actual);
|
||||||
|
|
||||||
|
checkLIR(AArch64ArithmeticOp.AddSubShiftOp.class, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* addSubShift match rule test for add operation with long type.
|
||||||
|
*/
|
||||||
|
private static long addLeftShiftLong(long input) {
|
||||||
|
long output = (input << 5) + input;
|
||||||
|
output += output << -5;
|
||||||
|
output += output << 64;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long addRightShiftLong(long input) {
|
||||||
|
long output = (input >> 5) + input;
|
||||||
|
output += output >> -5;
|
||||||
|
output += output >> 64;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long addUnsignedRightShiftLong(long input) {
|
||||||
|
long output = (input >>> 5) + input;
|
||||||
|
output += output >>> -5;
|
||||||
|
output += output >>> 64;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long addShiftLong(long input) {
|
||||||
|
return addLeftShiftLong(input) + addRightShiftLong(input) + addUnsignedRightShiftLong(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the addSubShift match rule in AArch64NodeMatchRules does work for add operation
|
||||||
|
* with long type and check if the expected LIR instructions show up.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testAddShiftLong() {
|
||||||
|
long expected = addShiftLong(1234567);
|
||||||
|
|
||||||
|
Result result = executeActual(getResolvedJavaMethod("addShiftLong"), null, (long) 1234567);
|
||||||
|
long actual = (long) result.returnValue;
|
||||||
|
Assert.assertEquals(expected, actual);
|
||||||
|
|
||||||
|
checkLIR(AArch64ArithmeticOp.AddSubShiftOp.class, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* addSubShift match rule test for sub operation with int type.
|
||||||
|
*/
|
||||||
|
private static int subLeftShiftInt(int input0, int input1) {
|
||||||
|
return input0 - (input1 << 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int subRightShiftInt(int input0, int input1) {
|
||||||
|
return input0 - (input1 >> 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int subUnsignedRightShiftInt(int input0, int input1) {
|
||||||
|
return input0 - (input1 >>> 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int subShiftInt(int input0, int input1) {
|
||||||
|
return subLeftShiftInt(input0, input1) + subRightShiftInt(input0, input1) + subUnsignedRightShiftInt(input0, input1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the addSubShift match rule in AArch64NodeMatchRules does work for sub operation
|
||||||
|
* with int type and check if the expected LIR instructions show up.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testSubShiftInt() {
|
||||||
|
int expected = subShiftInt(123, 456);
|
||||||
|
|
||||||
|
Result result = executeActual(getResolvedJavaMethod("subShiftInt"), null, 123, 456);
|
||||||
|
int actual = (int) result.returnValue;
|
||||||
|
Assert.assertEquals(expected, actual);
|
||||||
|
|
||||||
|
checkLIR(AArch64ArithmeticOp.AddSubShiftOp.class, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* addSubShift match rule test for sub operation with long type.
|
||||||
|
*/
|
||||||
|
private static long subLeftShiftLong(long input0, long input1) {
|
||||||
|
return input0 - (input1 << 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long subRightShiftLong(long input0, long input1) {
|
||||||
|
return input0 - (input1 >> 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long subUnsignedRightShiftLong(long input0, long input1) {
|
||||||
|
return input0 - (input1 >>> 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long subShiftLong(long input0, long input1) {
|
||||||
|
return subLeftShiftLong(input0, input1) + subRightShiftLong(input0, input1) + subUnsignedRightShiftLong(input0, input1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the addSubShift match rule in AArch64NodeMatchRules does work for sub operation
|
||||||
|
* with long type and check if the expected LIR instructions show up.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testSubShiftLong() {
|
||||||
|
long expected = subShiftLong(1234567, 123);
|
||||||
|
|
||||||
|
Result result = executeActual(getResolvedJavaMethod("subShiftLong"), null, (long) 1234567, (long) 123);
|
||||||
|
long actual = (long) result.returnValue;
|
||||||
|
Assert.assertEquals(expected, actual);
|
||||||
|
|
||||||
|
checkLIR(AArch64ArithmeticOp.AddSubShiftOp.class, 3);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2018, Arm Limited and 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.aarch64.test;
|
||||||
|
|
||||||
|
import jdk.vm.ci.aarch64.AArch64;
|
||||||
|
import jdk.vm.ci.code.TargetDescription;
|
||||||
|
import org.graalvm.compiler.core.test.GraalCompilerTest;
|
||||||
|
import org.graalvm.compiler.lir.LIR;
|
||||||
|
import org.graalvm.compiler.lir.LIRInstruction;
|
||||||
|
import org.graalvm.compiler.lir.aarch64.AArch64LIRInstruction;
|
||||||
|
import org.graalvm.compiler.lir.gen.LIRGenerationResult;
|
||||||
|
import org.graalvm.compiler.lir.phases.LIRPhase;
|
||||||
|
import org.graalvm.compiler.lir.phases.LIRSuites;
|
||||||
|
import org.graalvm.compiler.lir.phases.PreAllocationOptimizationPhase;
|
||||||
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
|
||||||
|
import static org.junit.Assume.assumeTrue;
|
||||||
|
|
||||||
|
public abstract class AArch64MatchRuleTest extends GraalCompilerTest {
|
||||||
|
private LIR lir;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void checkAArch64() {
|
||||||
|
assumeTrue("skipping AArch64 specific test", getTarget().arch instanceof AArch64);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected LIRSuites createLIRSuites(OptionValues options) {
|
||||||
|
LIRSuites suites = super.createLIRSuites(options);
|
||||||
|
suites.getPreAllocationOptimizationStage().appendPhase(new CheckPhase());
|
||||||
|
return suites;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class CheckPhase extends LIRPhase<PreAllocationOptimizationPhase.PreAllocationOptimizationContext> {
|
||||||
|
@Override
|
||||||
|
protected void run(TargetDescription target, LIRGenerationResult lirGenRes,
|
||||||
|
PreAllocationOptimizationPhase.PreAllocationOptimizationContext context) {
|
||||||
|
lir = lirGenRes.getLIR();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkLIR(Class<? extends AArch64LIRInstruction> op, int expected) {
|
||||||
|
int actualOpNum = 0;
|
||||||
|
for (LIRInstruction ins : lir.getLIRforBlock(lir.codeEmittingOrder()[0])) {
|
||||||
|
if (ins.getClass() == op) {
|
||||||
|
actualOpNum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Assert.assertEquals(expected, actualOpNum);
|
||||||
|
}
|
||||||
|
}
|
@ -201,6 +201,16 @@ public class AArch64ArithmeticLIRGenerator extends ArithmeticLIRGenerator implem
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Value emitAddSubShift(AArch64ArithmeticOp op, Value a, Value b, AArch64MacroAssembler.ShiftType shiftType, int shiftAmount) {
|
||||||
|
assert isNumericInteger(a.getPlatformKind());
|
||||||
|
assert isNumericInteger(b.getPlatformKind());
|
||||||
|
Variable result = getLIRGen().newVariable(LIRKind.combine(a, b));
|
||||||
|
AllocatableValue x = moveSp(asAllocatable(a));
|
||||||
|
AllocatableValue y = moveSp(asAllocatable(b));
|
||||||
|
getLIRGen().append(new AArch64ArithmeticOp.AddSubShiftOp(op, result, x, y, shiftType, shiftAmount));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private static PlatformKind getFloatConvertResultKind(FloatConvert op) {
|
private static PlatformKind getFloatConvertResultKind(FloatConvert op) {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case F2I:
|
case F2I:
|
||||||
|
@ -61,6 +61,7 @@ import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.CompareAndSwapOp;
|
|||||||
import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndWriteOp;
|
import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndWriteOp;
|
||||||
import org.graalvm.compiler.lir.aarch64.AArch64Move.MembarOp;
|
import org.graalvm.compiler.lir.aarch64.AArch64Move.MembarOp;
|
||||||
import org.graalvm.compiler.lir.aarch64.AArch64PauseOp;
|
import org.graalvm.compiler.lir.aarch64.AArch64PauseOp;
|
||||||
|
import org.graalvm.compiler.lir.aarch64.AArch64SpeculativeBarrier;
|
||||||
import org.graalvm.compiler.lir.gen.LIRGenerationResult;
|
import org.graalvm.compiler.lir.gen.LIRGenerationResult;
|
||||||
import org.graalvm.compiler.lir.gen.LIRGenerator;
|
import org.graalvm.compiler.lir.gen.LIRGenerator;
|
||||||
import org.graalvm.compiler.phases.util.Providers;
|
import org.graalvm.compiler.phases.util.Providers;
|
||||||
@ -465,9 +466,9 @@ public abstract class AArch64LIRGenerator extends LIRGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length) {
|
public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length, int constantLength, boolean directPointers) {
|
||||||
Variable result = newVariable(LIRKind.value(AArch64Kind.DWORD));
|
Variable result = newVariable(LIRKind.value(AArch64Kind.DWORD));
|
||||||
append(new AArch64ArrayEqualsOp(this, kind, result, array1, array2, asAllocatable(length)));
|
append(new AArch64ArrayEqualsOp(this, kind, result, array1, array2, asAllocatable(length), directPointers));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -513,4 +514,9 @@ public abstract class AArch64LIRGenerator extends LIRGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public abstract void emitCCall(long address, CallingConvention nativeCallingConvention, Value[] args);
|
public abstract void emitCCall(long address, CallingConvention nativeCallingConvention, Value[] args);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void emitSpeculationFence() {
|
||||||
|
append(new AArch64SpeculativeBarrier());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ import org.graalvm.compiler.core.common.type.DataPointerConstant;
|
|||||||
import org.graalvm.compiler.debug.GraalError;
|
import org.graalvm.compiler.debug.GraalError;
|
||||||
import org.graalvm.compiler.lir.LIRInstruction;
|
import org.graalvm.compiler.lir.LIRInstruction;
|
||||||
import org.graalvm.compiler.lir.aarch64.AArch64AddressValue;
|
import org.graalvm.compiler.lir.aarch64.AArch64AddressValue;
|
||||||
|
import org.graalvm.compiler.lir.aarch64.AArch64LIRInstruction;
|
||||||
import org.graalvm.compiler.lir.aarch64.AArch64Move;
|
import org.graalvm.compiler.lir.aarch64.AArch64Move;
|
||||||
import org.graalvm.compiler.lir.aarch64.AArch64Move.LoadAddressOp;
|
import org.graalvm.compiler.lir.aarch64.AArch64Move.LoadAddressOp;
|
||||||
import org.graalvm.compiler.lir.gen.LIRGeneratorTool.MoveFactory;
|
import org.graalvm.compiler.lir.gen.LIRGeneratorTool.MoveFactory;
|
||||||
@ -69,7 +70,7 @@ public class AArch64MoveFactory implements MoveFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LIRInstruction createLoad(AllocatableValue dst, Constant src) {
|
public AArch64LIRInstruction createLoad(AllocatableValue dst, Constant src) {
|
||||||
if (src instanceof JavaConstant) {
|
if (src instanceof JavaConstant) {
|
||||||
JavaConstant javaConstant = (JavaConstant) src;
|
JavaConstant javaConstant = (JavaConstant) src;
|
||||||
if (canInlineConstant(javaConstant)) {
|
if (canInlineConstant(javaConstant)) {
|
||||||
|
@ -25,11 +25,22 @@
|
|||||||
|
|
||||||
package org.graalvm.compiler.core.aarch64;
|
package org.graalvm.compiler.core.aarch64;
|
||||||
|
|
||||||
|
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
|
||||||
import org.graalvm.compiler.core.gen.NodeMatchRules;
|
import org.graalvm.compiler.core.gen.NodeMatchRules;
|
||||||
|
import org.graalvm.compiler.core.match.ComplexMatchResult;
|
||||||
|
import org.graalvm.compiler.core.match.MatchRule;
|
||||||
import org.graalvm.compiler.lir.LIRFrameState;
|
import org.graalvm.compiler.lir.LIRFrameState;
|
||||||
|
import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticOp;
|
||||||
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
|
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
|
||||||
|
import org.graalvm.compiler.nodes.ConstantNode;
|
||||||
import org.graalvm.compiler.nodes.DeoptimizingNode;
|
import org.graalvm.compiler.nodes.DeoptimizingNode;
|
||||||
import org.graalvm.compiler.nodes.NodeView;
|
import org.graalvm.compiler.nodes.NodeView;
|
||||||
|
import org.graalvm.compiler.nodes.ValueNode;
|
||||||
|
import org.graalvm.compiler.nodes.calc.AddNode;
|
||||||
|
import org.graalvm.compiler.nodes.calc.BinaryNode;
|
||||||
|
import org.graalvm.compiler.nodes.calc.LeftShiftNode;
|
||||||
|
import org.graalvm.compiler.nodes.calc.RightShiftNode;
|
||||||
|
import org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode;
|
||||||
import org.graalvm.compiler.nodes.memory.Access;
|
import org.graalvm.compiler.nodes.memory.Access;
|
||||||
|
|
||||||
import jdk.vm.ci.aarch64.AArch64Kind;
|
import jdk.vm.ci.aarch64.AArch64Kind;
|
||||||
@ -51,6 +62,36 @@ public class AArch64NodeMatchRules extends NodeMatchRules {
|
|||||||
return (AArch64Kind) gen.getLIRKind(access.asNode().stamp(NodeView.DEFAULT)).getPlatformKind();
|
return (AArch64Kind) gen.getLIRKind(access.asNode().stamp(NodeView.DEFAULT)).getPlatformKind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ComplexMatchResult emitAddSubShift(AArch64ArithmeticOp op, ValueNode value, BinaryNode shift) {
|
||||||
|
assert shift.getY() instanceof ConstantNode;
|
||||||
|
int shiftAmount = shift.getY().asJavaConstant().asInt();
|
||||||
|
|
||||||
|
if (shift instanceof LeftShiftNode) {
|
||||||
|
return builder -> getArithmeticLIRGenerator().emitAddSubShift(op, operand(value), operand(shift.getX()),
|
||||||
|
AArch64MacroAssembler.ShiftType.LSL, shiftAmount);
|
||||||
|
} else if (shift instanceof RightShiftNode) {
|
||||||
|
return builder -> getArithmeticLIRGenerator().emitAddSubShift(op, operand(value), operand(shift.getX()),
|
||||||
|
AArch64MacroAssembler.ShiftType.ASR, shiftAmount);
|
||||||
|
} else {
|
||||||
|
assert shift instanceof UnsignedRightShiftNode;
|
||||||
|
return builder -> getArithmeticLIRGenerator().emitAddSubShift(op, operand(value), operand(shift.getX()),
|
||||||
|
AArch64MacroAssembler.ShiftType.LSR, shiftAmount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@MatchRule("(Add=binary a (LeftShift=shift b Constant))")
|
||||||
|
@MatchRule("(Add=binary a (RightShift=shift b Constant))")
|
||||||
|
@MatchRule("(Add=binary a (UnsignedRightShift=shift b Constant))")
|
||||||
|
@MatchRule("(Sub=binary a (LeftShift=shift b Constant))")
|
||||||
|
@MatchRule("(Sub=binary a (RightShift=shift b Constant))")
|
||||||
|
@MatchRule("(Sub=binary a (UnsignedRightShift=shift b Constant))")
|
||||||
|
public ComplexMatchResult addSubShift(BinaryNode binary, ValueNode a, BinaryNode shift) {
|
||||||
|
if (binary instanceof AddNode) {
|
||||||
|
return emitAddSubShift(AArch64ArithmeticOp.ADD, a, shift);
|
||||||
|
}
|
||||||
|
return emitAddSubShift(AArch64ArithmeticOp.SUB, a, shift);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AArch64LIRGenerator getLIRGeneratorTool() {
|
public AArch64LIRGenerator getLIRGeneratorTool() {
|
||||||
return (AArch64LIRGenerator) gen;
|
return (AArch64LIRGenerator) gen;
|
||||||
|
@ -84,7 +84,10 @@ import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMIOp;
|
|||||||
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp;
|
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp;
|
||||||
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64Shift;
|
import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64Shift;
|
||||||
import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
|
import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
|
||||||
|
import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexGeneralPurposeRVMOp;
|
||||||
|
import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexGeneralPurposeRMOp;
|
||||||
import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize;
|
import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize;
|
||||||
|
import org.graalvm.compiler.asm.amd64.AVXKind.AVXSize;
|
||||||
import org.graalvm.compiler.core.common.LIRKind;
|
import org.graalvm.compiler.core.common.LIRKind;
|
||||||
import org.graalvm.compiler.core.common.NumUtil;
|
import org.graalvm.compiler.core.common.NumUtil;
|
||||||
import org.graalvm.compiler.core.common.calc.FloatConvert;
|
import org.graalvm.compiler.core.common.calc.FloatConvert;
|
||||||
@ -106,6 +109,8 @@ import org.graalvm.compiler.lir.amd64.AMD64MulDivOp;
|
|||||||
import org.graalvm.compiler.lir.amd64.AMD64ShiftOp;
|
import org.graalvm.compiler.lir.amd64.AMD64ShiftOp;
|
||||||
import org.graalvm.compiler.lir.amd64.AMD64SignExtendOp;
|
import org.graalvm.compiler.lir.amd64.AMD64SignExtendOp;
|
||||||
import org.graalvm.compiler.lir.amd64.AMD64Unary;
|
import org.graalvm.compiler.lir.amd64.AMD64Unary;
|
||||||
|
import org.graalvm.compiler.lir.amd64.vector.AMD64VectorBinary;
|
||||||
|
import org.graalvm.compiler.lir.amd64.vector.AMD64VectorUnary;
|
||||||
import org.graalvm.compiler.lir.gen.ArithmeticLIRGenerator;
|
import org.graalvm.compiler.lir.gen.ArithmeticLIRGenerator;
|
||||||
import org.graalvm.compiler.lir.gen.LIRGenerator;
|
import org.graalvm.compiler.lir.gen.LIRGenerator;
|
||||||
|
|
||||||
@ -931,6 +936,57 @@ public class AMD64ArithmeticLIRGenerator extends ArithmeticLIRGenerator implemen
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Value emitLogicalAndNot(Value value1, Value value2) {
|
||||||
|
Variable result = getLIRGen().newVariable(LIRKind.combine(value1, value2));
|
||||||
|
|
||||||
|
if (value1.getPlatformKind() == AMD64Kind.QWORD) {
|
||||||
|
getLIRGen().append(new AMD64VectorBinary.AVXBinaryOp(VexGeneralPurposeRVMOp.ANDN, AVXSize.QWORD, result, asAllocatable(value1), asAllocatable(value2)));
|
||||||
|
} else {
|
||||||
|
getLIRGen().append(new AMD64VectorBinary.AVXBinaryOp(VexGeneralPurposeRVMOp.ANDN, AVXSize.DWORD, result, asAllocatable(value1), asAllocatable(value2)));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Value emitLowestSetIsolatedBit(Value value) {
|
||||||
|
Variable result = getLIRGen().newVariable(LIRKind.combine(value));
|
||||||
|
|
||||||
|
if (value.getPlatformKind() == AMD64Kind.QWORD) {
|
||||||
|
getLIRGen().append(new AMD64VectorUnary.AVXUnaryOp(VexGeneralPurposeRMOp.BLSI, AVXSize.QWORD, result, asAllocatable(value)));
|
||||||
|
} else {
|
||||||
|
getLIRGen().append(new AMD64VectorUnary.AVXUnaryOp(VexGeneralPurposeRMOp.BLSI, AVXSize.DWORD, result, asAllocatable(value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Value emitGetMaskUpToLowestSetBit(Value value) {
|
||||||
|
Variable result = getLIRGen().newVariable(LIRKind.combine(value));
|
||||||
|
|
||||||
|
if (value.getPlatformKind() == AMD64Kind.QWORD) {
|
||||||
|
getLIRGen().append(new AMD64VectorUnary.AVXUnaryOp(VexGeneralPurposeRMOp.BLSMSK, AVXSize.QWORD, result, asAllocatable(value)));
|
||||||
|
} else {
|
||||||
|
getLIRGen().append(new AMD64VectorUnary.AVXUnaryOp(VexGeneralPurposeRMOp.BLSMSK, AVXSize.DWORD, result, asAllocatable(value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Value emitResetLowestSetBit(Value value) {
|
||||||
|
Variable result = getLIRGen().newVariable(LIRKind.combine(value));
|
||||||
|
|
||||||
|
if (value.getPlatformKind() == AMD64Kind.QWORD) {
|
||||||
|
getLIRGen().append(new AMD64VectorUnary.AVXUnaryOp(VexGeneralPurposeRMOp.BLSR, AVXSize.QWORD, result, asAllocatable(value)));
|
||||||
|
} else {
|
||||||
|
getLIRGen().append(new AMD64VectorUnary.AVXUnaryOp(VexGeneralPurposeRMOp.BLSR, AVXSize.DWORD, result, asAllocatable(value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value emitMathAbs(Value input) {
|
public Value emitMathAbs(Value input) {
|
||||||
Variable result = getLIRGen().newVariable(LIRKind.combine(input));
|
Variable result = getLIRGen().newVariable(LIRKind.combine(input));
|
||||||
|
@ -87,7 +87,8 @@ import org.graalvm.compiler.lir.amd64.AMD64Move.CompareAndSwapOp;
|
|||||||
import org.graalvm.compiler.lir.amd64.AMD64Move.MembarOp;
|
import org.graalvm.compiler.lir.amd64.AMD64Move.MembarOp;
|
||||||
import org.graalvm.compiler.lir.amd64.AMD64Move.StackLeaOp;
|
import org.graalvm.compiler.lir.amd64.AMD64Move.StackLeaOp;
|
||||||
import org.graalvm.compiler.lir.amd64.AMD64PauseOp;
|
import org.graalvm.compiler.lir.amd64.AMD64PauseOp;
|
||||||
import org.graalvm.compiler.lir.amd64.AMD64StringIndexOfOp;
|
import org.graalvm.compiler.lir.amd64.AMD64StringLatin1InflateOp;
|
||||||
|
import org.graalvm.compiler.lir.amd64.AMD64StringUTF16CompressOp;
|
||||||
import org.graalvm.compiler.lir.amd64.AMD64ZapRegistersOp;
|
import org.graalvm.compiler.lir.amd64.AMD64ZapRegistersOp;
|
||||||
import org.graalvm.compiler.lir.amd64.AMD64ZapStackOp;
|
import org.graalvm.compiler.lir.amd64.AMD64ZapStackOp;
|
||||||
import org.graalvm.compiler.lir.gen.LIRGenerationResult;
|
import org.graalvm.compiler.lir.gen.LIRGenerationResult;
|
||||||
@ -262,8 +263,8 @@ public abstract class AMD64LIRGenerator extends LIRGenerator {
|
|||||||
|
|
||||||
public void emitCompareAndSwapBranch(ValueKind<?> kind, AMD64AddressValue address, Value expectedValue, Value newValue, Condition condition, LabelRef trueLabel, LabelRef falseLabel,
|
public void emitCompareAndSwapBranch(ValueKind<?> kind, AMD64AddressValue address, Value expectedValue, Value newValue, Condition condition, LabelRef trueLabel, LabelRef falseLabel,
|
||||||
double trueLabelProbability) {
|
double trueLabelProbability) {
|
||||||
assert kind.equals(expectedValue.getValueKind());
|
assert kind.getPlatformKind().getSizeInBytes() <= expectedValue.getValueKind().getPlatformKind().getSizeInBytes();
|
||||||
assert kind.equals(newValue.getValueKind());
|
assert kind.getPlatformKind().getSizeInBytes() <= newValue.getValueKind().getPlatformKind().getSizeInBytes();
|
||||||
assert condition == Condition.EQ || condition == Condition.NE;
|
assert condition == Condition.EQ || condition == Condition.NE;
|
||||||
AMD64Kind memKind = (AMD64Kind) kind.getPlatformKind();
|
AMD64Kind memKind = (AMD64Kind) kind.getPlatformKind();
|
||||||
RegisterValue raxValue = AMD64.rax.asValue(kind);
|
RegisterValue raxValue = AMD64.rax.asValue(kind);
|
||||||
@ -542,9 +543,9 @@ public abstract class AMD64LIRGenerator extends LIRGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length) {
|
public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length, int constantLength, boolean directPointers) {
|
||||||
Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD));
|
Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD));
|
||||||
append(new AMD64ArrayEqualsOp(this, kind, result, array1, array2, asAllocatable(length)));
|
append(new AMD64ArrayEqualsOp(this, kind, result, array1, array2, asAllocatable(length), constantLength, directPointers, getMaxVectorSize()));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,22 +556,56 @@ public abstract class AMD64LIRGenerator extends LIRGenerator {
|
|||||||
return 4096;
|
return 4096;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the maximum size of vector registers used in SSE/AVX instructions.
|
||||||
|
*/
|
||||||
|
protected int getMaxVectorSize() {
|
||||||
|
// default for "unlimited"
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Variable emitStringIndexOf(Value source, Value sourceCount, Value target, Value targetCount, int constantTargetCount) {
|
public Variable emitArrayIndexOf(JavaKind kind, boolean findTwoConsecutive, Value arrayPointer, Value arrayLength, Value... searchValues) {
|
||||||
Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD));
|
Variable result = newVariable(LIRKind.value(AMD64Kind.QWORD));
|
||||||
RegisterValue cnt1 = AMD64.rdx.asValue(sourceCount.getValueKind());
|
Value[] allocatableSearchValues = new Value[searchValues.length];
|
||||||
emitMove(cnt1, sourceCount);
|
for (int i = 0; i < searchValues.length; i++) {
|
||||||
RegisterValue cnt2 = AMD64.rax.asValue(targetCount.getValueKind());
|
allocatableSearchValues[i] = asAllocatable(searchValues[i]);
|
||||||
emitMove(cnt2, targetCount);
|
}
|
||||||
append(new AMD64StringIndexOfOp(this, result, source, target, cnt1, cnt2, AMD64.rcx.asValue(), AMD64.xmm0.asValue(), constantTargetCount, getVMPageSize()));
|
append(new AMD64ArrayIndexOfOp(kind, findTwoConsecutive, getVMPageSize(), getMaxVectorSize(), this, result, asAllocatable(arrayPointer), asAllocatable(arrayLength), allocatableSearchValues));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Variable emitArrayIndexOf(JavaKind kind, Value arrayPointer, Value arrayLength, Value charValue) {
|
public void emitStringLatin1Inflate(Value src, Value dst, Value len) {
|
||||||
Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD));
|
RegisterValue rsrc = AMD64.rsi.asValue(src.getValueKind());
|
||||||
append(new AMD64ArrayIndexOfOp(kind, getVMPageSize(), this, result, asAllocatable(arrayPointer), asAllocatable(arrayLength), asAllocatable(charValue)));
|
RegisterValue rdst = AMD64.rdi.asValue(dst.getValueKind());
|
||||||
return result;
|
RegisterValue rlen = AMD64.rdx.asValue(len.getValueKind());
|
||||||
|
|
||||||
|
emitMove(rsrc, src);
|
||||||
|
emitMove(rdst, dst);
|
||||||
|
emitMove(rlen, len);
|
||||||
|
|
||||||
|
append(new AMD64StringLatin1InflateOp(this, rsrc, rdst, rlen));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Variable emitStringUTF16Compress(Value src, Value dst, Value len) {
|
||||||
|
RegisterValue rsrc = AMD64.rsi.asValue(src.getValueKind());
|
||||||
|
RegisterValue rdst = AMD64.rdi.asValue(dst.getValueKind());
|
||||||
|
RegisterValue rlen = AMD64.rdx.asValue(len.getValueKind());
|
||||||
|
|
||||||
|
emitMove(rsrc, src);
|
||||||
|
emitMove(rdst, dst);
|
||||||
|
emitMove(rlen, len);
|
||||||
|
|
||||||
|
LIRKind reskind = LIRKind.value(AMD64Kind.DWORD);
|
||||||
|
RegisterValue rres = AMD64.rax.asValue(reskind);
|
||||||
|
|
||||||
|
append(new AMD64StringUTF16CompressOp(this, rres, rsrc, rdst, rlen));
|
||||||
|
|
||||||
|
Variable res = newVariable(reskind);
|
||||||
|
emitMove(res, rres);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -614,7 +649,8 @@ public abstract class AMD64LIRGenerator extends LIRGenerator {
|
|||||||
return new AMD64ZapStackOp(zappedStack, zapValues);
|
return new AMD64ZapStackOp(zappedStack, zapValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void emitLFence() {
|
@Override
|
||||||
|
public void emitSpeculationFence() {
|
||||||
append(new AMD64LFenceOp());
|
append(new AMD64LFenceOp());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,6 @@
|
|||||||
|
|
||||||
package org.graalvm.compiler.core.amd64;
|
package org.graalvm.compiler.core.amd64;
|
||||||
|
|
||||||
import static org.graalvm.compiler.core.amd64.AMD64NodeLIRBuilder.Options.MitigateSpeculativeExecutionAttacks;
|
|
||||||
|
|
||||||
import org.graalvm.compiler.core.gen.NodeLIRBuilder;
|
import org.graalvm.compiler.core.gen.NodeLIRBuilder;
|
||||||
import org.graalvm.compiler.debug.GraalError;
|
import org.graalvm.compiler.debug.GraalError;
|
||||||
import org.graalvm.compiler.lir.LIRFrameState;
|
import org.graalvm.compiler.lir.LIRFrameState;
|
||||||
@ -41,11 +39,6 @@ import org.graalvm.compiler.nodes.StructuredGraph;
|
|||||||
import org.graalvm.compiler.nodes.ValueNode;
|
import org.graalvm.compiler.nodes.ValueNode;
|
||||||
import org.graalvm.compiler.nodes.calc.IntegerDivRemNode;
|
import org.graalvm.compiler.nodes.calc.IntegerDivRemNode;
|
||||||
import org.graalvm.compiler.nodes.calc.IntegerDivRemNode.Op;
|
import org.graalvm.compiler.nodes.calc.IntegerDivRemNode.Op;
|
||||||
import org.graalvm.compiler.nodes.cfg.Block;
|
|
||||||
import org.graalvm.compiler.options.Option;
|
|
||||||
import org.graalvm.compiler.options.OptionKey;
|
|
||||||
import org.graalvm.compiler.options.OptionType;
|
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
|
||||||
|
|
||||||
import jdk.vm.ci.amd64.AMD64;
|
import jdk.vm.ci.amd64.AMD64;
|
||||||
import jdk.vm.ci.meta.AllocatableValue;
|
import jdk.vm.ci.meta.AllocatableValue;
|
||||||
@ -53,13 +46,6 @@ import jdk.vm.ci.meta.Value;
|
|||||||
|
|
||||||
public abstract class AMD64NodeLIRBuilder extends NodeLIRBuilder {
|
public abstract class AMD64NodeLIRBuilder extends NodeLIRBuilder {
|
||||||
|
|
||||||
public static class Options {
|
|
||||||
// @formatter:off
|
|
||||||
@Option(help = "AMD64: Emit lfence instructions at the beginning of basic blocks", type = OptionType.Expert)
|
|
||||||
public static final OptionKey<Boolean> MitigateSpeculativeExecutionAttacks = new OptionKey<>(false);
|
|
||||||
// @formatter:on
|
|
||||||
}
|
|
||||||
|
|
||||||
public AMD64NodeLIRBuilder(StructuredGraph graph, LIRGeneratorTool gen, AMD64NodeMatchRules nodeMatchRules) {
|
public AMD64NodeLIRBuilder(StructuredGraph graph, LIRGeneratorTool gen, AMD64NodeMatchRules nodeMatchRules) {
|
||||||
super(graph, gen, nodeMatchRules);
|
super(graph, gen, nodeMatchRules);
|
||||||
}
|
}
|
||||||
@ -137,21 +123,4 @@ public abstract class AMD64NodeLIRBuilder extends NodeLIRBuilder {
|
|||||||
public AMD64LIRGenerator getLIRGeneratorTool() {
|
public AMD64LIRGenerator getLIRGeneratorTool() {
|
||||||
return (AMD64LIRGenerator) gen;
|
return (AMD64LIRGenerator) gen;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doBlockPrologue(Block block, OptionValues options) {
|
|
||||||
if (MitigateSpeculativeExecutionAttacks.getValue(options)) {
|
|
||||||
boolean hasControlSplitPredecessor = false;
|
|
||||||
for (Block b : block.getPredecessors()) {
|
|
||||||
if (b.getSuccessorCount() > 1) {
|
|
||||||
hasControlSplitPredecessor = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
boolean isStartBlock = block.getPredecessorCount() == 0;
|
|
||||||
if (hasControlSplitPredecessor || isStartBlock) {
|
|
||||||
getLIRGeneratorTool().emitLFence();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -78,9 +78,12 @@ import org.graalvm.compiler.nodes.memory.LIRLowerableAccess;
|
|||||||
import org.graalvm.compiler.nodes.memory.WriteNode;
|
import org.graalvm.compiler.nodes.memory.WriteNode;
|
||||||
import org.graalvm.compiler.nodes.util.GraphUtil;
|
import org.graalvm.compiler.nodes.util.GraphUtil;
|
||||||
|
|
||||||
|
import jdk.vm.ci.amd64.AMD64;
|
||||||
|
import jdk.vm.ci.amd64.AMD64.CPUFeature;
|
||||||
import jdk.vm.ci.amd64.AMD64Kind;
|
import jdk.vm.ci.amd64.AMD64Kind;
|
||||||
import jdk.vm.ci.meta.AllocatableValue;
|
import jdk.vm.ci.meta.AllocatableValue;
|
||||||
import jdk.vm.ci.meta.JavaConstant;
|
import jdk.vm.ci.meta.JavaConstant;
|
||||||
|
import jdk.vm.ci.meta.JavaKind;
|
||||||
import jdk.vm.ci.meta.PlatformKind;
|
import jdk.vm.ci.meta.PlatformKind;
|
||||||
import jdk.vm.ci.meta.Value;
|
import jdk.vm.ci.meta.Value;
|
||||||
import jdk.vm.ci.meta.ValueKind;
|
import jdk.vm.ci.meta.ValueKind;
|
||||||
@ -272,6 +275,81 @@ public class AMD64NodeMatchRules extends NodeMatchRules {
|
|||||||
return getArithmeticLIRGenerator().emitLoad(to, address, state);
|
return getArithmeticLIRGenerator().emitLoad(to, address, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean supports(CPUFeature feature) {
|
||||||
|
return ((AMD64) getLIRGeneratorTool().target().arch).getFeatures().contains(feature);
|
||||||
|
}
|
||||||
|
|
||||||
|
@MatchRule("(And (Not a) b)")
|
||||||
|
public ComplexMatchResult logicalAndNot(ValueNode a, ValueNode b) {
|
||||||
|
if (!supports(CPUFeature.BMI1)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return builder -> getArithmeticLIRGenerator().emitLogicalAndNot(operand(a), operand(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
@MatchRule("(And a (Negate a))")
|
||||||
|
public ComplexMatchResult lowestSetIsolatedBit(ValueNode a) {
|
||||||
|
if (!supports(CPUFeature.BMI1)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return builder -> getArithmeticLIRGenerator().emitLowestSetIsolatedBit(operand(a));
|
||||||
|
}
|
||||||
|
|
||||||
|
@MatchRule("(Xor a (Add a b))")
|
||||||
|
public ComplexMatchResult getMaskUpToLowestSetBit(ValueNode a, ValueNode b) {
|
||||||
|
if (!supports(CPUFeature.BMI1)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure that the pattern matches a subtraction by one.
|
||||||
|
if (!b.isJavaConstant()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
JavaConstant bCst = b.asJavaConstant();
|
||||||
|
long bValue;
|
||||||
|
if (bCst.getJavaKind() == JavaKind.Int) {
|
||||||
|
bValue = bCst.asInt();
|
||||||
|
} else if (bCst.getJavaKind() == JavaKind.Long) {
|
||||||
|
bValue = bCst.asLong();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bValue == -1) {
|
||||||
|
return builder -> getArithmeticLIRGenerator().emitGetMaskUpToLowestSetBit(operand(a));
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@MatchRule("(And a (Add a b))")
|
||||||
|
public ComplexMatchResult resetLowestSetBit(ValueNode a, ValueNode b) {
|
||||||
|
if (!supports(CPUFeature.BMI1)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Make sure that the pattern matches a subtraction by one.
|
||||||
|
if (!b.isJavaConstant()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
JavaConstant bCst = b.asJavaConstant();
|
||||||
|
long bValue;
|
||||||
|
if (bCst.getJavaKind() == JavaKind.Int) {
|
||||||
|
bValue = bCst.asInt();
|
||||||
|
} else if (bCst.getJavaKind() == JavaKind.Long) {
|
||||||
|
bValue = bCst.asLong();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bValue == -1) {
|
||||||
|
return builder -> getArithmeticLIRGenerator().emitResetLowestSetBit(operand(a));
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@MatchRule("(If (IntegerTest Read=access value))")
|
@MatchRule("(If (IntegerTest Read=access value))")
|
||||||
@MatchRule("(If (IntegerTest FloatingRead=access value))")
|
@MatchRule("(If (IntegerTest FloatingRead=access value))")
|
||||||
public ComplexMatchResult integerTestBranchMemory(IfNode root, LIRLowerableAccess access, ValueNode value) {
|
public ComplexMatchResult integerTestBranchMemory(IfNode root, LIRLowerableAccess access, ValueNode value) {
|
||||||
|
@ -215,14 +215,14 @@ public class NumUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static long maxUnsigned(long a, long b) {
|
public static long maxUnsigned(long a, long b) {
|
||||||
if (Long.compareUnsigned(a, b) > 0) {
|
if (Long.compareUnsigned(a, b) < 0) {
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long minUnsigned(long a, long b) {
|
public static long minUnsigned(long a, long b) {
|
||||||
if (Long.compareUnsigned(a, b) > 0) {
|
if (Long.compareUnsigned(a, b) < 0) {
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
return b;
|
return b;
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package org.graalvm.compiler.core.common;
|
||||||
|
|
||||||
|
import org.graalvm.compiler.options.EnumOptionKey;
|
||||||
|
import org.graalvm.compiler.options.Option;
|
||||||
|
import org.graalvm.compiler.options.OptionKey;
|
||||||
|
import org.graalvm.compiler.options.OptionType;
|
||||||
|
|
||||||
|
public enum SpeculativeExecutionAttacksMitigations {
|
||||||
|
None,
|
||||||
|
AllTargets,
|
||||||
|
GuardTargets,
|
||||||
|
NonDeoptGuardTargets;
|
||||||
|
|
||||||
|
public static class Options {
|
||||||
|
// @formatter:off
|
||||||
|
@Option(help = "Select a strategy to mitigate speculative execution attacks (e.g., SPECTRE)", type = OptionType.User)
|
||||||
|
public static final EnumOptionKey<SpeculativeExecutionAttacksMitigations> MitigateSpeculativeExecutionAttacks = new EnumOptionKey<>(None);
|
||||||
|
@Option(help = "Use index masking after bounds check to mitigate speculative execution attacks", type = OptionType.User)
|
||||||
|
public static final OptionKey<Boolean> UseIndexMasking = new OptionKey<>(false);
|
||||||
|
// @formatter:on
|
||||||
|
}
|
||||||
|
}
|
@ -63,7 +63,7 @@ public final class BiDirectionalTraceBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static int compare(AbstractBlockBase<?> a, AbstractBlockBase<?> b) {
|
private static int compare(AbstractBlockBase<?> a, AbstractBlockBase<?> b) {
|
||||||
return Double.compare(b.probability(), a.probability());
|
return Double.compare(b.getRelativeFrequency(), a.getRelativeFrequency());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean processed(AbstractBlockBase<?> b) {
|
private boolean processed(AbstractBlockBase<?> b) {
|
||||||
@ -132,7 +132,7 @@ public final class BiDirectionalTraceBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addBlockToTrace(DebugContext debug, AbstractBlockBase<?> block) {
|
private void addBlockToTrace(DebugContext debug, AbstractBlockBase<?> block) {
|
||||||
debug.log("add %s (prob: %f)", block, block.probability());
|
debug.log("add %s (freq: %f)", block, block.getRelativeFrequency());
|
||||||
processed.set(block.getId());
|
processed.set(block.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +142,7 @@ public final class BiDirectionalTraceBuilder {
|
|||||||
private AbstractBlockBase<?> selectPredecessor(AbstractBlockBase<?> block) {
|
private AbstractBlockBase<?> selectPredecessor(AbstractBlockBase<?> block) {
|
||||||
AbstractBlockBase<?> next = null;
|
AbstractBlockBase<?> next = null;
|
||||||
for (AbstractBlockBase<?> pred : block.getPredecessors()) {
|
for (AbstractBlockBase<?> pred : block.getPredecessors()) {
|
||||||
if (!processed(pred) && !isBackEdge(pred, block) && (next == null || pred.probability() > next.probability())) {
|
if (!processed(pred) && !isBackEdge(pred, block) && (next == null || pred.getRelativeFrequency() > next.getRelativeFrequency())) {
|
||||||
next = pred;
|
next = pred;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,7 +160,7 @@ public final class BiDirectionalTraceBuilder {
|
|||||||
private AbstractBlockBase<?> selectSuccessor(AbstractBlockBase<?> block) {
|
private AbstractBlockBase<?> selectSuccessor(AbstractBlockBase<?> block) {
|
||||||
AbstractBlockBase<?> next = null;
|
AbstractBlockBase<?> next = null;
|
||||||
for (AbstractBlockBase<?> succ : block.getSuccessors()) {
|
for (AbstractBlockBase<?> succ : block.getSuccessors()) {
|
||||||
if (!processed(succ) && (next == null || succ.probability() > next.probability())) {
|
if (!processed(succ) && (next == null || succ.getRelativeFrequency() > next.getRelativeFrequency())) {
|
||||||
next = succ;
|
next = succ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,11 +143,11 @@ public final class ComputeBlockOrder {
|
|||||||
double unscheduledSum = 0.0;
|
double unscheduledSum = 0.0;
|
||||||
for (T pred : mostLikelySuccessor.getPredecessors()) {
|
for (T pred : mostLikelySuccessor.getPredecessors()) {
|
||||||
if (pred.getLinearScanNumber() == -1) {
|
if (pred.getLinearScanNumber() == -1) {
|
||||||
unscheduledSum += pred.probability();
|
unscheduledSum += pred.getRelativeFrequency();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unscheduledSum > block.probability() / PENALTY_VERSUS_UNSCHEDULED) {
|
if (unscheduledSum > block.getRelativeFrequency() / PENALTY_VERSUS_UNSCHEDULED) {
|
||||||
// Add this merge only after at least one additional predecessor gets scheduled.
|
// Add this merge only after at least one additional predecessor gets scheduled.
|
||||||
visitedBlocks.clear(mostLikelySuccessor.getId());
|
visitedBlocks.clear(mostLikelySuccessor.getId());
|
||||||
return null;
|
return null;
|
||||||
@ -212,8 +212,8 @@ public final class ComputeBlockOrder {
|
|||||||
private static <T extends AbstractBlockBase<T>> T findAndMarkMostLikelySuccessor(T block, BitSet visitedBlocks) {
|
private static <T extends AbstractBlockBase<T>> T findAndMarkMostLikelySuccessor(T block, BitSet visitedBlocks) {
|
||||||
T result = null;
|
T result = null;
|
||||||
for (T successor : block.getSuccessors()) {
|
for (T successor : block.getSuccessors()) {
|
||||||
assert successor.probability() >= 0.0 : "Probabilities must be positive";
|
assert successor.getRelativeFrequency() >= 0.0 : "Relative frequencies must be positive";
|
||||||
if (!visitedBlocks.get(successor.getId()) && successor.getLoopDepth() >= block.getLoopDepth() && (result == null || successor.probability() >= result.probability())) {
|
if (!visitedBlocks.get(successor.getId()) && successor.getLoopDepth() >= block.getLoopDepth() && (result == null || successor.getRelativeFrequency() >= result.getRelativeFrequency())) {
|
||||||
result = successor;
|
result = successor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -261,7 +261,7 @@ public final class ComputeBlockOrder {
|
|||||||
public int compare(T a, T b) {
|
public int compare(T a, T b) {
|
||||||
// Loop blocks before any loop exit block. The only exception are blocks that are
|
// Loop blocks before any loop exit block. The only exception are blocks that are
|
||||||
// (almost) impossible to reach.
|
// (almost) impossible to reach.
|
||||||
if (a.probability() > EPSILON && b.probability() > EPSILON) {
|
if (a.getRelativeFrequency() > EPSILON && b.getRelativeFrequency() > EPSILON) {
|
||||||
int diff = b.getLoopDepth() - a.getLoopDepth();
|
int diff = b.getLoopDepth() - a.getLoopDepth();
|
||||||
if (diff != 0) {
|
if (diff != 0) {
|
||||||
return diff;
|
return diff;
|
||||||
@ -269,7 +269,7 @@ public final class ComputeBlockOrder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Blocks with high probability before blocks with low probability.
|
// Blocks with high probability before blocks with low probability.
|
||||||
if (a.probability() > b.probability()) {
|
if (a.getRelativeFrequency() > b.getRelativeFrequency()) {
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -59,13 +59,13 @@ public final class TraceStatisticsPrinter {
|
|||||||
double max = Double.NEGATIVE_INFINITY;
|
double max = Double.NEGATIVE_INFINITY;
|
||||||
double min = Double.POSITIVE_INFINITY;
|
double min = Double.POSITIVE_INFINITY;
|
||||||
for (AbstractBlockBase<?> block : t) {
|
for (AbstractBlockBase<?> block : t) {
|
||||||
double probability = block.probability();
|
double frequency = block.getRelativeFrequency();
|
||||||
total += probability;
|
total += frequency;
|
||||||
if (probability < min) {
|
if (frequency < min) {
|
||||||
min = probability;
|
min = frequency;
|
||||||
}
|
}
|
||||||
if (probability > max) {
|
if (frequency > max) {
|
||||||
max = probability;
|
max = frequency;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printLine(debug, i, total, min, max, t.length);
|
printLine(debug, i, total, min, max, t.length);
|
||||||
|
@ -65,7 +65,7 @@ public final class UniDirectionalTraceBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static int compare(AbstractBlockBase<?> a, AbstractBlockBase<?> b) {
|
private static int compare(AbstractBlockBase<?> a, AbstractBlockBase<?> b) {
|
||||||
return Double.compare(b.probability(), a.probability());
|
return Double.compare(b.getRelativeFrequency(), a.getRelativeFrequency());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean processed(AbstractBlockBase<?> b) {
|
private boolean processed(AbstractBlockBase<?> b) {
|
||||||
@ -110,7 +110,7 @@ public final class UniDirectionalTraceBuilder {
|
|||||||
int blockNumber = 0;
|
int blockNumber = 0;
|
||||||
try (Indent i = debug.logAndIndent("StartTrace: %s", traceStart)) {
|
try (Indent i = debug.logAndIndent("StartTrace: %s", traceStart)) {
|
||||||
for (AbstractBlockBase<?> block = traceStart; block != null; block = selectNext(block)) {
|
for (AbstractBlockBase<?> block = traceStart; block != null; block = selectNext(block)) {
|
||||||
debug.log("add %s (prob: %f)", block, block.probability());
|
debug.log("add %s (freq: %f)", block, block.getRelativeFrequency());
|
||||||
processed.set(block.getId());
|
processed.set(block.getId());
|
||||||
trace.add(block);
|
trace.add(block);
|
||||||
unblock(block);
|
unblock(block);
|
||||||
@ -149,7 +149,7 @@ public final class UniDirectionalTraceBuilder {
|
|||||||
private AbstractBlockBase<?> selectNext(AbstractBlockBase<?> block) {
|
private AbstractBlockBase<?> selectNext(AbstractBlockBase<?> block) {
|
||||||
AbstractBlockBase<?> next = null;
|
AbstractBlockBase<?> next = null;
|
||||||
for (AbstractBlockBase<?> successor : block.getSuccessors()) {
|
for (AbstractBlockBase<?> successor : block.getSuccessors()) {
|
||||||
if (!processed(successor) && (next == null || successor.probability() > next.probability())) {
|
if (!processed(successor) && (next == null || successor.getRelativeFrequency() > next.getRelativeFrequency())) {
|
||||||
next = successor;
|
next = successor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ public abstract class AbstractBlockBase<T extends AbstractBlockBase<T>> {
|
|||||||
|
|
||||||
public abstract T getPostdominator();
|
public abstract T getPostdominator();
|
||||||
|
|
||||||
public abstract double probability();
|
public abstract double getRelativeFrequency();
|
||||||
|
|
||||||
public abstract T getDominator(int distance);
|
public abstract T getDominator(int distance);
|
||||||
|
|
||||||
|
@ -41,6 +41,4 @@ public interface CodeGenProviders {
|
|||||||
ForeignCallsProvider getForeignCalls();
|
ForeignCallsProvider getForeignCalls();
|
||||||
|
|
||||||
ConstantReflectionProvider getConstantReflection();
|
ConstantReflectionProvider getConstantReflection();
|
||||||
|
|
||||||
ArrayOffsetProvider getArrayOffsetProvider();
|
|
||||||
}
|
}
|
||||||
|
@ -142,10 +142,13 @@ public abstract class AbstractPointerStamp extends Stamp {
|
|||||||
@Override
|
@Override
|
||||||
public Constant asConstant() {
|
public Constant asConstant() {
|
||||||
if (alwaysNull) {
|
if (alwaysNull) {
|
||||||
return JavaConstant.NULL_POINTER;
|
return nullConstant();
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
return super.asConstant();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JavaConstant nullConstant() {
|
||||||
|
return JavaConstant.NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -0,0 +1,342 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package org.graalvm.compiler.core.jdk9.test.ea;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import org.graalvm.compiler.core.test.ea.EATestBase;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import jdk.vm.ci.meta.JavaConstant;
|
||||||
|
|
||||||
|
public class AtomicVirtualizationTests extends EATestBase {
|
||||||
|
private static final TestObject OBJ1 = new TestObject(1);
|
||||||
|
private static final TestObject OBJ2 = new TestObject(2);
|
||||||
|
private static TestObject obj6 = new TestObject(6);
|
||||||
|
private static TestObject obj7 = new TestObject(7);
|
||||||
|
private static TestObject obj8 = new TestObject(8);
|
||||||
|
|
||||||
|
private static final class TestObject {
|
||||||
|
final int id;
|
||||||
|
|
||||||
|
private TestObject(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
TestObject that = (TestObject) o;
|
||||||
|
return id == that.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "TestObject{id=" + id + '}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// c = constant (heap-allocated); v = virtual; u = unknown (heap-allocated)
|
||||||
|
|
||||||
|
public static boolean cvvNoMatchCAS() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(null);
|
||||||
|
return a.compareAndSet(new TestObject(3), new TestObject(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testcvvNoMatchCAS() {
|
||||||
|
testAtomicVirtualization("cvvNoMatchCAS", JavaConstant.INT_0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object cvvNoMatchCAE() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(null);
|
||||||
|
return a.compareAndExchange(new TestObject(3), new TestObject(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testcvvNoMatchCAE() {
|
||||||
|
testAtomicVirtualization("cvvNoMatchCAE", JavaConstant.NULL_POINTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean ccvNoMatchCAS() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(null);
|
||||||
|
return a.compareAndSet(OBJ1, new TestObject(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testccvNoMatchCAS() {
|
||||||
|
testAtomicVirtualization("ccvNoMatchCAS", JavaConstant.INT_0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object ccvNoMatchCAE() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(null);
|
||||||
|
return a.compareAndExchange(OBJ1, new TestObject(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testccvNoMatchCAE() {
|
||||||
|
testAtomicVirtualization("ccvNoMatchCAE", JavaConstant.NULL_POINTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean cccNoMatchCAS() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(null);
|
||||||
|
return a.compareAndSet(OBJ1, OBJ2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testcccNoMatchCAS() {
|
||||||
|
testAtomicVirtualization("cccNoMatchCAS", JavaConstant.INT_0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object cccNoMatchCAE() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(null);
|
||||||
|
return a.compareAndExchange(OBJ1, OBJ2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testcccNoMatchCAE() {
|
||||||
|
testAtomicVirtualization("cccNoMatchCAE", JavaConstant.NULL_POINTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean ccvCAS() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(null);
|
||||||
|
return a.compareAndSet(null, new TestObject(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testccvCAS() {
|
||||||
|
testAtomicVirtualization("ccvCAS", JavaConstant.INT_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object ccvCAE() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(null);
|
||||||
|
return a.compareAndExchange(null, new TestObject(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testccvCAE() {
|
||||||
|
testAtomicVirtualization("ccvCAE", null, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean cccCAS() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(null);
|
||||||
|
return a.compareAndSet(null, OBJ2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testcccCAS() {
|
||||||
|
testAtomicVirtualization("cccCAS", JavaConstant.INT_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object cccCAE() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(null);
|
||||||
|
return a.compareAndExchange(null, OBJ2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testcccCAE() {
|
||||||
|
testAtomicVirtualization("cccCAE", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean vvvNoMatchCAS() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
|
||||||
|
return a.compareAndSet(new TestObject(4), new TestObject(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testvvvNoMatchCAS() {
|
||||||
|
testAtomicVirtualization("vvvNoMatchCAS", JavaConstant.INT_0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object vvvNoMatchCAE() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
|
||||||
|
return a.compareAndExchange(new TestObject(4), new TestObject(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testvvvNoMatchCAE() {
|
||||||
|
testAtomicVirtualization("vvvNoMatchCAE", null, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean vcvNoMatchCAS() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
|
||||||
|
return a.compareAndSet(OBJ1, new TestObject(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testvcvNoMatchCAS() {
|
||||||
|
testAtomicVirtualization("vcvNoMatchCAS", JavaConstant.INT_0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object vcvNoMatchCAE() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
|
||||||
|
return a.compareAndExchange(OBJ1, new TestObject(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testvcvNoMatchCAE() {
|
||||||
|
testAtomicVirtualization("vcvNoMatchCAE", null, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean vccNoMatchCAS() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
|
||||||
|
return a.compareAndSet(OBJ1, OBJ2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testvccNoMatchCAS() {
|
||||||
|
testAtomicVirtualization("vccNoMatchCAS", JavaConstant.INT_0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object vccNoMatchCAE() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
|
||||||
|
return a.compareAndExchange(OBJ1, OBJ2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testvccNoMatchCAE() {
|
||||||
|
testAtomicVirtualization("vccNoMatchCAE", null, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean uvvCAS() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(obj6);
|
||||||
|
return a.compareAndSet(new TestObject(3), new TestObject(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testuvvCAS() {
|
||||||
|
testAtomicVirtualization("uvvCAS", JavaConstant.INT_0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object uvvCAE() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(obj6);
|
||||||
|
return a.compareAndExchange(new TestObject(3), new TestObject(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testuvvCAE() {
|
||||||
|
testAtomicVirtualization("uvvCAE", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean uuvCAS() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(obj6);
|
||||||
|
return a.compareAndSet(obj7, new TestObject(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testuuvCAS() {
|
||||||
|
testAtomicVirtualization("uuvCAS", null, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object uuvCAE() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(obj6);
|
||||||
|
return a.compareAndExchange(obj7, new TestObject(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testuuvCAE() {
|
||||||
|
testAtomicVirtualization("uuvCAE", null, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean uuuCAS() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(obj6);
|
||||||
|
return a.compareAndSet(obj7, obj8);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testuuuCAS() {
|
||||||
|
testAtomicVirtualization("uuuCAS", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object uuuCAE() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(obj6);
|
||||||
|
return a.compareAndExchange(obj7, obj8);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testuuuCAE() {
|
||||||
|
testAtomicVirtualization("uuuCAE", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean vuvCAS() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
|
||||||
|
return a.compareAndSet(obj6, new TestObject(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testvuvCAS() {
|
||||||
|
testAtomicVirtualization("vuvCAS", JavaConstant.INT_0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object vuvCAE() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
|
||||||
|
return a.compareAndExchange(obj6, new TestObject(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testvuvCAE() {
|
||||||
|
testAtomicVirtualization("vuvCAE", null, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean vuuCAS() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
|
||||||
|
return a.compareAndSet(obj6, obj7);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testvuuCAS() {
|
||||||
|
testAtomicVirtualization("vuuCAS", JavaConstant.INT_0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object vuuCAE() {
|
||||||
|
AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
|
||||||
|
return a.compareAndExchange(obj6, obj7);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testvuuCAE() {
|
||||||
|
testAtomicVirtualization("vuuCAE", null, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testAtomicVirtualization(String snippet, JavaConstant expectedValue) {
|
||||||
|
testAtomicVirtualization(snippet, expectedValue, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void testAtomicVirtualization(String snippet, JavaConstant expectedValue, int expectedAllocations) {
|
||||||
|
testEscapeAnalysis(snippet, expectedValue, false, expectedAllocations);
|
||||||
|
test(snippet);
|
||||||
|
}
|
||||||
|
}
|
@ -692,7 +692,7 @@ public class MatchProcessor extends AbstractProcessor {
|
|||||||
private RoundEnvironment currentRound;
|
private RoundEnvironment currentRound;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
public boolean doProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||||
if (roundEnv.processingOver()) {
|
if (roundEnv.processingOver()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -420,9 +420,9 @@ public abstract class SPARCLIRGenerator extends LIRGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length) {
|
public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length, int constantLength, boolean directPointers) {
|
||||||
Variable result = newVariable(LIRKind.value(SPARCKind.WORD));
|
Variable result = newVariable(LIRKind.value(SPARCKind.WORD));
|
||||||
append(new SPARCArrayEqualsOp(this, kind, result, load(array1), load(array2), asAllocatable(length)));
|
append(new SPARCArrayEqualsOp(this, kind, result, load(array1), load(array2), asAllocatable(length), directPointers));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,4 +477,9 @@ public abstract class SPARCLIRGenerator extends LIRGenerator {
|
|||||||
public void emitPause() {
|
public void emitPause() {
|
||||||
append(new SPARCPauseOp());
|
append(new SPARCPauseOp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void emitSpeculationFence() {
|
||||||
|
throw GraalError.unimplemented();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,6 +181,7 @@ public class CheckGraalInvariants extends GraalCompilerTest {
|
|||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("try")
|
@SuppressWarnings("try")
|
||||||
public void test() {
|
public void test() {
|
||||||
|
assumeManagementLibraryIsLoadable();
|
||||||
runTest(new InvariantsTool());
|
runTest(new InvariantsTool());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,56 +24,74 @@
|
|||||||
|
|
||||||
package org.graalvm.compiler.core.test;
|
package org.graalvm.compiler.core.test;
|
||||||
|
|
||||||
import static org.graalvm.compiler.graph.test.matchers.NodeIterableIsEmpty.isNotEmpty;
|
|
||||||
|
|
||||||
import org.graalvm.compiler.nodes.StructuredGraph;
|
import org.graalvm.compiler.nodes.StructuredGraph;
|
||||||
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
|
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
|
||||||
import org.graalvm.compiler.nodes.calc.IntegerLessThanNode;
|
|
||||||
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
|
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
|
||||||
import org.graalvm.compiler.phases.tiers.PhaseContext;
|
import org.graalvm.compiler.phases.tiers.PhaseContext;
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class CompareCanonicalizerTest2 extends GraalCompilerTest {
|
public class CompareCanonicalizerTest2 extends GraalCompilerTest {
|
||||||
|
|
||||||
@SuppressWarnings("unused") private static int sink0;
|
@SuppressWarnings("unused") private static boolean sink;
|
||||||
@SuppressWarnings("unused") private static int sink1;
|
|
||||||
|
|
||||||
private StructuredGraph getCanonicalizedGraph(String name) {
|
private StructuredGraph getCanonicalizedGraph(String name) {
|
||||||
StructuredGraph graph = parseEager(name, AllowAssumptions.YES);
|
StructuredGraph graph = getRegularGraph(name);
|
||||||
new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
|
new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
|
||||||
return graph;
|
return graph;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIntegerTestCanonicalization(String name) {
|
private StructuredGraph getRegularGraph(String name) {
|
||||||
StructuredGraph graph = getCanonicalizedGraph(name);
|
StructuredGraph graph = parseEager(name, AllowAssumptions.YES);
|
||||||
Assert.assertThat(graph.getNodes().filter(IntegerLessThanNode.class), isNotEmpty());
|
return graph;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test0() {
|
public void test0() {
|
||||||
testIntegerTestCanonicalization("integerTestCanonicalization0");
|
assertEquals(getCanonicalizedGraph("integerTestCanonicalization0"), getRegularGraph("integerTestCanonicalization0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void integerTestCanonicalization0(int a) {
|
||||||
|
sink = 1 < a + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test1() {
|
public void test1() {
|
||||||
testIntegerTestCanonicalization("integerTestCanonicalization1");
|
assertEquals(getCanonicalizedGraph("integerTestCanonicalization1"), getRegularGraph("integerTestCanonicalization1"));
|
||||||
}
|
|
||||||
|
|
||||||
public static void integerTestCanonicalization0(int a) {
|
|
||||||
if (1 < a + 1) {
|
|
||||||
sink1 = 0;
|
|
||||||
} else {
|
|
||||||
sink0 = -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void integerTestCanonicalization1(int a) {
|
public static void integerTestCanonicalization1(int a) {
|
||||||
if (a - 1 < -1) {
|
sink = a - 1 < -1;
|
||||||
sink1 = 0;
|
}
|
||||||
} else {
|
|
||||||
sink0 = -1;
|
@Test
|
||||||
}
|
public void test2() {
|
||||||
|
assertEquals(getCanonicalizedGraph("integerTestCanonicalization2a"), getCanonicalizedGraph("integerTestCanonicalization2Reference"));
|
||||||
|
assertEquals(getCanonicalizedGraph("integerTestCanonicalization2b"), getCanonicalizedGraph("integerTestCanonicalization2Reference"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean integerTestCanonicalization2a(Object[] arr) {
|
||||||
|
return arr.length - 1 < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean integerTestCanonicalization2b(Object[] arr) {
|
||||||
|
return arr.length < 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean integerTestCanonicalization2Reference(Object[] arr) {
|
||||||
|
return arr.length == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test3() {
|
||||||
|
assertEquals(getCanonicalizedGraph("integerTestCanonicalization3"), getCanonicalizedGraph("integerTestCanonicalization3Reference"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean integerTestCanonicalization3(Object[] arr) {
|
||||||
|
return ((long) (arr.length - 1)) - 1 < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean integerTestCanonicalization3Reference(Object[] arr) {
|
||||||
|
return arr.length < 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -92,16 +92,18 @@ public class CompareCanonicalizerTest3 extends GraalCompilerTest {
|
|||||||
assertCanonicallyEqual("integerTestCanonicalization1", "referenceSnippet1");
|
assertCanonicallyEqual("integerTestCanonicalization1", "referenceSnippet1");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void integerTestCanonicalization1(char a) {
|
public static void integerTestCanonicalization1(char[] a) {
|
||||||
if (Integer.compareUnsigned(a - 2, a) < 0) {
|
int len = a.length;
|
||||||
|
if (Integer.compareUnsigned(len - 2, len) < 0) {
|
||||||
sink1 = 0;
|
sink1 = 0;
|
||||||
} else {
|
} else {
|
||||||
sink0 = -1;
|
sink0 = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void referenceSnippet1(char a) {
|
public static void referenceSnippet1(char[] a) {
|
||||||
if (Integer.compareUnsigned(a, 2) >= 0) {
|
int len = a.length;
|
||||||
|
if (Integer.compareUnsigned(len, 2) >= 0) {
|
||||||
sink1 = 0;
|
sink1 = 0;
|
||||||
} else {
|
} else {
|
||||||
sink0 = -1;
|
sink0 = -1;
|
||||||
@ -238,12 +240,18 @@ public class CompareCanonicalizerTest3 extends GraalCompilerTest {
|
|||||||
StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
|
StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
|
||||||
PhaseContext context = new PhaseContext(getProviders());
|
PhaseContext context = new PhaseContext(getProviders());
|
||||||
CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
|
CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
|
||||||
|
|
||||||
canonicalizer.apply(graph, context);
|
canonicalizer.apply(graph, context);
|
||||||
new GuardLoweringPhase().apply(graph, new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo()));
|
new GuardLoweringPhase().apply(graph, new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo()));
|
||||||
new FrameStateAssignmentPhase().apply(graph);
|
new FrameStateAssignmentPhase().apply(graph);
|
||||||
canonicalizer.apply(graph, context);
|
canonicalizer.apply(graph, context);
|
||||||
|
|
||||||
StructuredGraph referenceGraph = parseEager(reference, AllowAssumptions.YES);
|
StructuredGraph referenceGraph = parseEager(reference, AllowAssumptions.YES);
|
||||||
canonicalizer.apply(referenceGraph, context);
|
canonicalizer.apply(referenceGraph, context);
|
||||||
|
new GuardLoweringPhase().apply(referenceGraph, new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo()));
|
||||||
|
new FrameStateAssignmentPhase().apply(referenceGraph);
|
||||||
|
canonicalizer.apply(referenceGraph, context);
|
||||||
|
|
||||||
canonicalizer.apply(referenceGraph, context);
|
canonicalizer.apply(referenceGraph, context);
|
||||||
assertEquals(referenceGraph, graph, true, true);
|
assertEquals(referenceGraph, graph, true, true);
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
|
|||||||
import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin;
|
import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin;
|
||||||
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
|
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
|
||||||
import org.graalvm.compiler.phases.tiers.PhaseContext;
|
import org.graalvm.compiler.phases.tiers.PhaseContext;
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||||
@ -282,6 +283,7 @@ public class ConditionalEliminationTest13 extends ConditionalEliminationTestBase
|
|||||||
testConditionalElimination("testSnippet9", "referenceSnippet9");
|
testConditionalElimination("testSnippet9", "referenceSnippet9");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Ignore("Need better unsigned stamps for this conditional elimination to work.")
|
||||||
@Test
|
@Test
|
||||||
public void test10() {
|
public void test10() {
|
||||||
testConditionalElimination("testSnippet10", "referenceSnippet4");
|
testConditionalElimination("testSnippet10", "referenceSnippet4");
|
||||||
|
@ -47,6 +47,7 @@ public class DumpPathTest extends GraalCompilerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDump() throws IOException {
|
public void testDump() throws IOException {
|
||||||
|
assumeManagementLibraryIsLoadable();
|
||||||
Path dumpDirectoryPath = Files.createTempDirectory("DumpPathTest");
|
Path dumpDirectoryPath = Files.createTempDirectory("DumpPathTest");
|
||||||
String[] extensions = new String[]{".cfg", ".bgv", ".graph-strings"};
|
String[] extensions = new String[]{".cfg", ".bgv", ".graph-strings"};
|
||||||
EconomicMap<OptionKey<?>, Object> overrides = OptionValues.newOptionMap();
|
EconomicMap<OptionKey<?>, Object> overrides = OptionValues.newOptionMap();
|
||||||
|
@ -43,6 +43,7 @@ public class GraphResetDebugTest extends GraalCompilerTest {
|
|||||||
@SuppressWarnings("try")
|
@SuppressWarnings("try")
|
||||||
@Test
|
@Test
|
||||||
public void test1() {
|
public void test1() {
|
||||||
|
assumeManagementLibraryIsLoadable();
|
||||||
EconomicMap<OptionKey<?>, Object> map = EconomicMap.create();
|
EconomicMap<OptionKey<?>, Object> map = EconomicMap.create();
|
||||||
// Configure with an option that enables scopes
|
// Configure with an option that enables scopes
|
||||||
map.put(DebugOptions.DumpOnError, true);
|
map.put(DebugOptions.DumpOnError, true);
|
||||||
|
@ -34,7 +34,7 @@ import org.graalvm.compiler.nodes.InvokeNode;
|
|||||||
import org.graalvm.compiler.nodes.StructuredGraph;
|
import org.graalvm.compiler.nodes.StructuredGraph;
|
||||||
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
|
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
|
||||||
import org.graalvm.compiler.nodes.ValueNode;
|
import org.graalvm.compiler.nodes.ValueNode;
|
||||||
import org.graalvm.compiler.nodes.debug.OpaqueNode;
|
import org.graalvm.compiler.nodes.extended.OpaqueNode;
|
||||||
import org.graalvm.compiler.nodes.extended.LoadHubNode;
|
import org.graalvm.compiler.nodes.extended.LoadHubNode;
|
||||||
import org.graalvm.compiler.nodes.extended.LoadMethodNode;
|
import org.graalvm.compiler.nodes.extended.LoadMethodNode;
|
||||||
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
|
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
|
||||||
|
@ -35,7 +35,7 @@ import org.graalvm.compiler.nodes.ReturnNode;
|
|||||||
import org.graalvm.compiler.nodes.StructuredGraph;
|
import org.graalvm.compiler.nodes.StructuredGraph;
|
||||||
import org.graalvm.compiler.nodes.ValueNode;
|
import org.graalvm.compiler.nodes.ValueNode;
|
||||||
import org.graalvm.compiler.nodes.calc.AddNode;
|
import org.graalvm.compiler.nodes.calc.AddNode;
|
||||||
import org.graalvm.compiler.nodes.debug.OpaqueNode;
|
import org.graalvm.compiler.nodes.extended.OpaqueNode;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
|
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
|
||||||
import org.graalvm.compiler.phases.schedule.SchedulePhase;
|
import org.graalvm.compiler.phases.schedule.SchedulePhase;
|
||||||
@ -71,7 +71,7 @@ public class LongNodeChainTest extends GraalCompilerTest {
|
|||||||
addNode.setY(newAddNode);
|
addNode.setY(newAddNode);
|
||||||
addNode = newAddNode;
|
addNode = newAddNode;
|
||||||
}
|
}
|
||||||
opaque.replaceAndDelete(opaque.getValue());
|
opaque.remove();
|
||||||
} else {
|
} else {
|
||||||
value = constant;
|
value = constant;
|
||||||
for (int i = 0; i < N; ++i) {
|
for (int i = 0; i < N; ++i) {
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
|
|
||||||
package org.graalvm.compiler.core.test.ea;
|
package org.graalvm.compiler.core.test.ea;
|
||||||
|
|
||||||
|
import static org.graalvm.compiler.graph.iterators.NodePredicates.isA;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.graalvm.compiler.core.test.GraalCompilerTest;
|
import org.graalvm.compiler.core.test.GraalCompilerTest;
|
||||||
@ -33,6 +35,7 @@ import org.graalvm.compiler.nodes.StructuredGraph;
|
|||||||
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
|
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
|
||||||
import org.graalvm.compiler.nodes.java.NewArrayNode;
|
import org.graalvm.compiler.nodes.java.NewArrayNode;
|
||||||
import org.graalvm.compiler.nodes.java.NewInstanceNode;
|
import org.graalvm.compiler.nodes.java.NewInstanceNode;
|
||||||
|
import org.graalvm.compiler.nodes.virtual.AllocatedObjectNode;
|
||||||
import org.graalvm.compiler.nodes.virtual.CommitAllocationNode;
|
import org.graalvm.compiler.nodes.virtual.CommitAllocationNode;
|
||||||
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
|
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
|
||||||
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
|
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
|
||||||
@ -139,6 +142,10 @@ public class EATestBase extends GraalCompilerTest {
|
|||||||
* iteration
|
* iteration
|
||||||
*/
|
*/
|
||||||
protected void testEscapeAnalysis(String snippet, JavaConstant expectedConstantResult, boolean iterativeEscapeAnalysis) {
|
protected void testEscapeAnalysis(String snippet, JavaConstant expectedConstantResult, boolean iterativeEscapeAnalysis) {
|
||||||
|
testEscapeAnalysis(snippet, expectedConstantResult, iterativeEscapeAnalysis, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void testEscapeAnalysis(String snippet, JavaConstant expectedConstantResult, boolean iterativeEscapeAnalysis, int expectedAllocationCount) {
|
||||||
prepareGraph(snippet, iterativeEscapeAnalysis);
|
prepareGraph(snippet, iterativeEscapeAnalysis);
|
||||||
if (expectedConstantResult != null) {
|
if (expectedConstantResult != null) {
|
||||||
for (ReturnNode returnNode : returnNodes) {
|
for (ReturnNode returnNode : returnNodes) {
|
||||||
@ -146,9 +153,11 @@ public class EATestBase extends GraalCompilerTest {
|
|||||||
Assert.assertEquals(expectedConstantResult, returnNode.result().asConstant());
|
Assert.assertEquals(expectedConstantResult, returnNode.result().asConstant());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int newInstanceCount = graph.getNodes().filter(NewInstanceNode.class).count() + graph.getNodes().filter(NewArrayNode.class).count() +
|
int newInstanceCount = graph.getNodes().filter(isA(NewInstanceNode.class).or(NewArrayNode.class).or(AllocatedObjectNode.class)).count();
|
||||||
graph.getNodes().filter(CommitAllocationNode.class).count();
|
Assert.assertEquals("Expected allocation count does not match", expectedAllocationCount, newInstanceCount);
|
||||||
Assert.assertEquals(0, newInstanceCount);
|
if (expectedAllocationCount == 0) {
|
||||||
|
Assert.assertTrue("Unexpected CommitAllocationNode", graph.getNodes().filter(CommitAllocationNode.class).isEmpty());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("try")
|
@SuppressWarnings("try")
|
||||||
|
@ -45,7 +45,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
|||||||
|
|
||||||
public static Object field;
|
public static Object field;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings({"deprecation", "unused"})
|
||||||
public static void snippet1(int i) {
|
public static void snippet1(int i) {
|
||||||
Integer object = new Integer(i);
|
Integer object = new Integer(i);
|
||||||
GraalDirectives.ensureVirtualized(object);
|
GraalDirectives.ensureVirtualized(object);
|
||||||
@ -56,7 +56,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
|||||||
test("snippet1", 1);
|
test("snippet1", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings({"deprecation", "unused"})
|
||||||
public static void snippet2(int i) {
|
public static void snippet2(int i) {
|
||||||
Integer object = new Integer(i);
|
Integer object = new Integer(i);
|
||||||
GraalDirectives.ensureVirtualized(object);
|
GraalDirectives.ensureVirtualized(object);
|
||||||
@ -68,7 +68,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
|||||||
test("snippet2", 1);
|
test("snippet2", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings({"deprecation", "unused"})
|
||||||
public static void snippet3(int i) {
|
public static void snippet3(int i) {
|
||||||
Integer object = new Integer(i);
|
Integer object = new Integer(i);
|
||||||
field = object;
|
field = object;
|
||||||
@ -80,7 +80,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
|||||||
test("snippet3", 1);
|
test("snippet3", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings({"deprecation", "unused"})
|
||||||
public static void snippetHere1(int i) {
|
public static void snippetHere1(int i) {
|
||||||
Integer object = new Integer(i);
|
Integer object = new Integer(i);
|
||||||
GraalDirectives.ensureVirtualizedHere(object);
|
GraalDirectives.ensureVirtualizedHere(object);
|
||||||
@ -91,7 +91,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
|||||||
test("snippetHere1", 1);
|
test("snippetHere1", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings({"deprecation", "unused"})
|
||||||
public static void snippetHere2(int i) {
|
public static void snippetHere2(int i) {
|
||||||
Integer object = new Integer(i);
|
Integer object = new Integer(i);
|
||||||
GraalDirectives.ensureVirtualizedHere(object);
|
GraalDirectives.ensureVirtualizedHere(object);
|
||||||
@ -103,7 +103,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
|||||||
test("snippetHere2", 1);
|
test("snippetHere2", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings({"deprecation", "unused"})
|
||||||
public static void snippetHere3(int i) {
|
public static void snippetHere3(int i) {
|
||||||
Integer object = new Integer(i);
|
Integer object = new Integer(i);
|
||||||
field = object;
|
field = object;
|
||||||
@ -136,7 +136,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
|||||||
test("snippetBoxing2", 1);
|
test("snippetBoxing2", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings({"deprecation", "unused"})
|
||||||
public static void snippetControlFlow1(boolean b, int i) {
|
public static void snippetControlFlow1(boolean b, int i) {
|
||||||
Integer object = new Integer(i);
|
Integer object = new Integer(i);
|
||||||
if (b) {
|
if (b) {
|
||||||
@ -151,7 +151,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
|||||||
test("snippetControlFlow1", true, 1);
|
test("snippetControlFlow1", true, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings({"deprecation", "unused"})
|
||||||
public static void snippetControlFlow2(boolean b, int i) {
|
public static void snippetControlFlow2(boolean b, int i) {
|
||||||
Integer object = new Integer(i);
|
Integer object = new Integer(i);
|
||||||
if (b) {
|
if (b) {
|
||||||
@ -168,7 +168,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
|||||||
test("snippetControlFlow2", true, 1);
|
test("snippetControlFlow2", true, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings({"deprecation", "unused"})
|
||||||
public static void snippetControlFlow3(boolean b, int i) {
|
public static void snippetControlFlow3(boolean b, int i) {
|
||||||
Integer object = new Integer(i);
|
Integer object = new Integer(i);
|
||||||
GraalDirectives.ensureVirtualized(object);
|
GraalDirectives.ensureVirtualized(object);
|
||||||
@ -186,7 +186,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
|||||||
test("snippetControlFlow3", true, 1);
|
test("snippetControlFlow3", true, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings({"deprecation", "unused"})
|
||||||
public static void snippetControlFlow4(boolean b, int i) {
|
public static void snippetControlFlow4(boolean b, int i) {
|
||||||
Integer object = new Integer(i);
|
Integer object = new Integer(i);
|
||||||
if (b) {
|
if (b) {
|
||||||
@ -202,7 +202,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
|||||||
test("snippetControlFlow4", true, 1);
|
test("snippetControlFlow4", true, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings({"deprecation", "unused"})
|
||||||
public static void snippetControlFlow5(boolean b, int i) {
|
public static void snippetControlFlow5(boolean b, int i) {
|
||||||
Integer object = new Integer(i);
|
Integer object = new Integer(i);
|
||||||
if (b) {
|
if (b) {
|
||||||
@ -223,7 +223,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
|||||||
Object b;
|
Object b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings({"deprecation", "unused"})
|
||||||
public static void snippetIndirect1(boolean b, int i) {
|
public static void snippetIndirect1(boolean b, int i) {
|
||||||
Integer object = new Integer(i);
|
Integer object = new Integer(i);
|
||||||
TestClass t = new TestClass();
|
TestClass t = new TestClass();
|
||||||
@ -242,7 +242,7 @@ public class PEAAssertionsTest extends GraalCompilerTest {
|
|||||||
test("snippetIndirect1", true, 1);
|
test("snippetIndirect1", true, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings({"deprecation", "unused"})
|
||||||
public static void snippetIndirect2(boolean b, int i) {
|
public static void snippetIndirect2(boolean b, int i) {
|
||||||
Integer object = new Integer(i);
|
Integer object = new Integer(i);
|
||||||
TestClass t = new TestClass();
|
TestClass t = new TestClass();
|
||||||
|
@ -293,14 +293,14 @@ public class PartialEscapeAnalysisTest extends EATestBase {
|
|||||||
Assert.assertTrue("partial escape analysis should have removed all NewArrayNode allocations", graph.getNodes().filter(NewArrayNode.class).isEmpty());
|
Assert.assertTrue("partial escape analysis should have removed all NewArrayNode allocations", graph.getNodes().filter(NewArrayNode.class).isEmpty());
|
||||||
|
|
||||||
ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, false, false);
|
ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, false, false);
|
||||||
double probabilitySum = 0;
|
double frequencySum = 0;
|
||||||
int materializeCount = 0;
|
int materializeCount = 0;
|
||||||
for (CommitAllocationNode materialize : graph.getNodes().filter(CommitAllocationNode.class)) {
|
for (CommitAllocationNode materialize : graph.getNodes().filter(CommitAllocationNode.class)) {
|
||||||
probabilitySum += cfg.blockFor(materialize).probability() * materialize.getVirtualObjects().size();
|
frequencySum += cfg.blockFor(materialize).getRelativeFrequency() * materialize.getVirtualObjects().size();
|
||||||
materializeCount += materialize.getVirtualObjects().size();
|
materializeCount += materialize.getVirtualObjects().size();
|
||||||
}
|
}
|
||||||
Assert.assertEquals("unexpected number of MaterializeObjectNodes", expectedCount, materializeCount);
|
Assert.assertEquals("unexpected number of MaterializeObjectNodes", expectedCount, materializeCount);
|
||||||
Assert.assertEquals("unexpected probability of MaterializeObjectNodes", expectedProbability, probabilitySum, 0.01);
|
Assert.assertEquals("unexpected frequency of MaterializeObjectNodes", expectedProbability, frequencySum, 0.01);
|
||||||
for (Node node : graph.getNodes()) {
|
for (Node node : graph.getNodes()) {
|
||||||
for (Class<? extends Node> clazz : invalidNodeClasses) {
|
for (Class<? extends Node> clazz : invalidNodeClasses) {
|
||||||
Assert.assertFalse("instance of invalid class: " + clazz.getSimpleName(), clazz.isInstance(node) && node.usages().isNotEmpty());
|
Assert.assertFalse("instance of invalid class: " + clazz.getSimpleName(), clazz.isInstance(node) && node.usages().isNotEmpty());
|
||||||
|
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package org.graalvm.compiler.core.test.ea;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||||
|
|
||||||
|
import org.graalvm.compiler.nodes.java.LogicCompareAndSwapNode;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import jdk.vm.ci.meta.JavaConstant;
|
||||||
|
|
||||||
|
public class UnsafeCompareAndSwapVirtualizationTest extends EATestBase {
|
||||||
|
|
||||||
|
private static Object obj1 = new Object();
|
||||||
|
private static Object obj2 = new Object();
|
||||||
|
private static final Object OBJ1 = new Object();
|
||||||
|
|
||||||
|
public static boolean bothVirtualNoMatch() {
|
||||||
|
AtomicReference<Object> a = new AtomicReference<>();
|
||||||
|
return a.compareAndSet(new Object(), new Object());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bothVirtualNoMatchTest() {
|
||||||
|
testEscapeAnalysis("bothVirtualNoMatch", JavaConstant.INT_0, true);
|
||||||
|
assertTrue(graph.getNodes(LogicCompareAndSwapNode.TYPE).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean bothVirtualMatch() {
|
||||||
|
Object expect = new Object();
|
||||||
|
AtomicReference<Object> a = new AtomicReference<>(expect);
|
||||||
|
return a.compareAndSet(expect, new Object());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bothVirtualMatchTest() {
|
||||||
|
testEscapeAnalysis("bothVirtualMatch", JavaConstant.INT_1, true);
|
||||||
|
assertTrue(graph.getNodes(LogicCompareAndSwapNode.TYPE).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean expectedVirtualMatch() {
|
||||||
|
Object o = new Object();
|
||||||
|
AtomicReference<Object> a = new AtomicReference<>(o);
|
||||||
|
return a.compareAndSet(o, obj1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void expectedVirtualMatchTest() {
|
||||||
|
testEscapeAnalysis("expectedVirtualMatch", JavaConstant.INT_1, true);
|
||||||
|
assertTrue(graph.getNodes(LogicCompareAndSwapNode.TYPE).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean expectedVirtualNoMatch() {
|
||||||
|
Object o = new Object();
|
||||||
|
AtomicReference<Object> a = new AtomicReference<>();
|
||||||
|
return a.compareAndSet(o, obj1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void expectedVirtualNoMatchTest() {
|
||||||
|
testEscapeAnalysis("expectedVirtualNoMatch", JavaConstant.INT_0, true);
|
||||||
|
assertTrue(graph.getNodes(LogicCompareAndSwapNode.TYPE).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean bothNonVirtualNoMatch() {
|
||||||
|
AtomicReference<Object> a = new AtomicReference<>();
|
||||||
|
return a.compareAndSet(OBJ1, obj2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bothNonVirtualNoMatchTest() {
|
||||||
|
testEscapeAnalysis("bothNonVirtualNoMatch", JavaConstant.INT_0, true);
|
||||||
|
assertTrue(graph.getNodes(LogicCompareAndSwapNode.TYPE).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean bothNonVirtualMatch() {
|
||||||
|
AtomicReference<Object> a = new AtomicReference<>(OBJ1);
|
||||||
|
return a.compareAndSet(OBJ1, obj2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bothNonVirtualMatchTest() {
|
||||||
|
testEscapeAnalysis("bothNonVirtualMatch", JavaConstant.INT_1, true);
|
||||||
|
assertTrue(graph.getNodes(LogicCompareAndSwapNode.TYPE).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean onlyInitialValueVirtualNoMatch() {
|
||||||
|
AtomicReference<Object> a = new AtomicReference<>(new Object());
|
||||||
|
return a.compareAndSet(obj1, obj2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onlyInitialValueVirtualNoMatchTest() {
|
||||||
|
testEscapeAnalysis("onlyInitialValueVirtualNoMatch", JavaConstant.INT_0, true);
|
||||||
|
assertTrue(graph.getNodes(LogicCompareAndSwapNode.TYPE).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean onlyInitialValueVirtualMatch() {
|
||||||
|
Object o = new Object();
|
||||||
|
AtomicReference<Object> a = new AtomicReference<>(o);
|
||||||
|
return a.compareAndSet(o, obj2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onlyInitialValueVirtualMatchTest() {
|
||||||
|
testEscapeAnalysis("onlyInitialValueVirtualMatch", JavaConstant.INT_1, true);
|
||||||
|
assertTrue(graph.getNodes(LogicCompareAndSwapNode.TYPE).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean bothVirtualNoMatchArray() {
|
||||||
|
AtomicReferenceArray<Object> array = new AtomicReferenceArray<>(1);
|
||||||
|
return array.compareAndSet(0, new Object(), new Object());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bothVirtualNoMatchArrayTest() {
|
||||||
|
testEscapeAnalysis("bothVirtualNoMatchArray", JavaConstant.INT_0, true);
|
||||||
|
assertTrue(graph.getNodes(LogicCompareAndSwapNode.TYPE).isEmpty());
|
||||||
|
}
|
||||||
|
}
|
@ -48,6 +48,8 @@ import org.graalvm.compiler.phases.common.inlining.InliningPhase;
|
|||||||
import org.graalvm.compiler.phases.tiers.HighTierContext;
|
import org.graalvm.compiler.phases.tiers.HighTierContext;
|
||||||
import org.graalvm.compiler.test.SubprocessUtil;
|
import org.graalvm.compiler.test.SubprocessUtil;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
import org.junit.Assume;
|
||||||
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -55,6 +57,11 @@ import java.util.List;
|
|||||||
|
|
||||||
public class PolymorphicInliningTest extends GraalCompilerTest {
|
public class PolymorphicInliningTest extends GraalCompilerTest {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void checkJavaAgent() {
|
||||||
|
Assume.assumeFalse("Java Agent found -> skipping", SubprocessUtil.isJavaAgentAttached());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInSubprocess() throws InterruptedException, IOException {
|
public void testInSubprocess() throws InterruptedException, IOException {
|
||||||
String recursionPropName = getClass().getName() + ".recursion";
|
String recursionPropName = getClass().getName() + ".recursion";
|
||||||
|
@ -120,7 +120,7 @@ public class StaticAnalysisTests {
|
|||||||
assertEquals(m(sa, B.class, "foo").getFormalReturn(), t(Data.class));
|
assertEquals(m(sa, B.class, "foo").getFormalReturn(), t(Data.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings({"deprecation", "unused"})
|
||||||
static void test03Entry() {
|
static void test03Entry() {
|
||||||
Data data = new Data();
|
Data data = new Data();
|
||||||
data.f = new Integer(42);
|
data.f = new Integer(42);
|
||||||
@ -148,7 +148,7 @@ public class StaticAnalysisTests {
|
|||||||
assertEquals(m(sa, B.class, "foo").getFormalReturn(), t(Data.class), t(Integer.class));
|
assertEquals(m(sa, B.class, "foo").getFormalReturn(), t(Data.class), t(Integer.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings({"deprecation", "unused"})
|
||||||
static void test04Entry() {
|
static void test04Entry() {
|
||||||
Data data = null;
|
Data data = null;
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
|
@ -41,7 +41,6 @@ import java.io.IOException;
|
|||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.graalvm.compiler.debug.DebugCloseable;
|
|
||||||
import org.graalvm.compiler.debug.DebugContext;
|
import org.graalvm.compiler.debug.DebugContext;
|
||||||
import org.graalvm.compiler.debug.DiagnosticsOutputDirectory;
|
import org.graalvm.compiler.debug.DiagnosticsOutputDirectory;
|
||||||
import org.graalvm.compiler.debug.PathUtilities;
|
import org.graalvm.compiler.debug.PathUtilities;
|
||||||
@ -163,8 +162,9 @@ public abstract class CompilationWrapper<T> {
|
|||||||
* Creates the {@link DebugContext} to use when retrying a compilation.
|
* Creates the {@link DebugContext} to use when retrying a compilation.
|
||||||
*
|
*
|
||||||
* @param options the options for configuring the debug context
|
* @param options the options for configuring the debug context
|
||||||
|
* @param logStream the log stream to use in the debug context
|
||||||
*/
|
*/
|
||||||
protected abstract DebugContext createRetryDebugContext(OptionValues options);
|
protected abstract DebugContext createRetryDebugContext(OptionValues options, PrintStream logStream);
|
||||||
|
|
||||||
@SuppressWarnings("try")
|
@SuppressWarnings("try")
|
||||||
public final T run(DebugContext initialDebug) {
|
public final T run(DebugContext initialDebug) {
|
||||||
@ -227,22 +227,27 @@ public abstract class CompilationWrapper<T> {
|
|||||||
return handleException(cause);
|
return handleException(cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
String dir = this.outputDirectory.getPath();
|
File dumpPath = null;
|
||||||
if (dir == null) {
|
try {
|
||||||
return handleException(cause);
|
String dir = this.outputDirectory.getPath();
|
||||||
}
|
if (dir != null) {
|
||||||
String dumpName = PathUtilities.sanitizeFileName(toString());
|
String dumpName = PathUtilities.sanitizeFileName(toString());
|
||||||
File dumpPath = new File(dir, dumpName);
|
dumpPath = new File(dir, dumpName);
|
||||||
dumpPath.mkdirs();
|
dumpPath.mkdirs();
|
||||||
if (!dumpPath.exists()) {
|
if (!dumpPath.exists()) {
|
||||||
TTY.println("Warning: could not create diagnostics directory " + dumpPath);
|
TTY.println("Warning: could not create diagnostics directory " + dumpPath);
|
||||||
return handleException(cause);
|
dumpPath = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
TTY.println("Warning: could not create Graal diagnostic directory");
|
||||||
|
t.printStackTrace(TTY.out);
|
||||||
}
|
}
|
||||||
|
|
||||||
String message;
|
String message;
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
try (PrintStream ps = new PrintStream(baos)) {
|
try (PrintStream ps = new PrintStream(baos)) {
|
||||||
ps.printf("%s: Compilation of %s failed: ", Thread.currentThread(), this);
|
ps.printf("%s: Compilation of %s failed:%n", Thread.currentThread(), this);
|
||||||
cause.printStackTrace(ps);
|
cause.printStackTrace(ps);
|
||||||
ps.printf("To disable compilation %s notifications, set %s to %s (e.g., -Dgraal.%s=%s).%n",
|
ps.printf("To disable compilation %s notifications, set %s to %s (e.g., -Dgraal.%s=%s).%n",
|
||||||
causeType,
|
causeType,
|
||||||
@ -253,11 +258,19 @@ public abstract class CompilationWrapper<T> {
|
|||||||
causeType,
|
causeType,
|
||||||
actionKey.getName(), ExceptionAction.Print,
|
actionKey.getName(), ExceptionAction.Print,
|
||||||
actionKey.getName(), ExceptionAction.Print);
|
actionKey.getName(), ExceptionAction.Print);
|
||||||
ps.println("Retrying compilation of " + this);
|
if (dumpPath != null) {
|
||||||
|
ps.println("Retrying compilation of " + this);
|
||||||
|
} else {
|
||||||
|
ps.println("Not retrying compilation of " + this + " as the dump path could not be created.");
|
||||||
|
}
|
||||||
message = baos.toString();
|
message = baos.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
TTY.print(message);
|
TTY.print(message);
|
||||||
|
if (dumpPath == null) {
|
||||||
|
return handleException(cause);
|
||||||
|
}
|
||||||
|
|
||||||
File retryLogFile = new File(dumpPath, "retry.log");
|
File retryLogFile = new File(dumpPath, "retry.log");
|
||||||
try (PrintStream ps = new PrintStream(new FileOutputStream(retryLogFile))) {
|
try (PrintStream ps = new PrintStream(new FileOutputStream(retryLogFile))) {
|
||||||
ps.print(message);
|
ps.print(message);
|
||||||
@ -270,15 +283,27 @@ public abstract class CompilationWrapper<T> {
|
|||||||
MethodFilter, null,
|
MethodFilter, null,
|
||||||
DumpPath, dumpPath.getPath());
|
DumpPath, dumpPath.getPath());
|
||||||
|
|
||||||
try (DebugContext retryDebug = createRetryDebugContext(retryOptions); DebugCloseable s = retryDebug.disableIntercept()) {
|
ByteArrayOutputStream logBaos = new ByteArrayOutputStream();
|
||||||
|
PrintStream ps = new PrintStream(logBaos);
|
||||||
|
try (DebugContext retryDebug = createRetryDebugContext(retryOptions, ps)) {
|
||||||
T res = performCompilation(retryDebug);
|
T res = performCompilation(retryDebug);
|
||||||
|
ps.println("There was no exception during retry.");
|
||||||
maybeExitVM(action);
|
maybeExitVM(action);
|
||||||
return res;
|
return res;
|
||||||
} catch (Throwable ignore) {
|
} catch (Throwable e) {
|
||||||
|
ps.println("Exception during retry:");
|
||||||
|
e.printStackTrace(ps);
|
||||||
// Failures during retry are silent
|
// Failures during retry are silent
|
||||||
T res = handleException(cause);
|
T res = handleException(cause);
|
||||||
maybeExitVM(action);
|
maybeExitVM(action);
|
||||||
return res;
|
return res;
|
||||||
|
} finally {
|
||||||
|
ps.close();
|
||||||
|
try (FileOutputStream fos = new FileOutputStream(retryLogFile, true)) {
|
||||||
|
fos.write(logBaos.toByteArray());
|
||||||
|
} catch (Throwable e) {
|
||||||
|
TTY.printf("Error writing to %s: %s%n", retryLogFile, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,8 @@ package org.graalvm.compiler.core.gen;
|
|||||||
import static jdk.vm.ci.code.ValueUtil.asRegister;
|
import static jdk.vm.ci.code.ValueUtil.asRegister;
|
||||||
import static jdk.vm.ci.code.ValueUtil.isLegal;
|
import static jdk.vm.ci.code.ValueUtil.isLegal;
|
||||||
import static jdk.vm.ci.code.ValueUtil.isRegister;
|
import static jdk.vm.ci.code.ValueUtil.isRegister;
|
||||||
|
import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.AllTargets;
|
||||||
|
import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.Options.MitigateSpeculativeExecutionAttacks;
|
||||||
import static org.graalvm.compiler.core.common.GraalOptions.MatchExpressions;
|
import static org.graalvm.compiler.core.common.GraalOptions.MatchExpressions;
|
||||||
import static org.graalvm.compiler.debug.DebugOptions.LogVerbose;
|
import static org.graalvm.compiler.debug.DebugOptions.LogVerbose;
|
||||||
import static org.graalvm.compiler.lir.LIR.verifyBlock;
|
import static org.graalvm.compiler.lir.LIR.verifyBlock;
|
||||||
@ -312,6 +314,19 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
|
|||||||
|
|
||||||
public void doBlockPrologue(@SuppressWarnings("unused") Block block, @SuppressWarnings("unused") OptionValues options) {
|
public void doBlockPrologue(@SuppressWarnings("unused") Block block, @SuppressWarnings("unused") OptionValues options) {
|
||||||
|
|
||||||
|
if (MitigateSpeculativeExecutionAttacks.getValue(options) == AllTargets) {
|
||||||
|
boolean hasControlSplitPredecessor = false;
|
||||||
|
for (Block b : block.getPredecessors()) {
|
||||||
|
if (b.getSuccessorCount() > 1) {
|
||||||
|
hasControlSplitPredecessor = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
boolean isStartBlock = block.getPredecessorCount() == 0;
|
||||||
|
if (hasControlSplitPredecessor || isStartBlock) {
|
||||||
|
getLIRGeneratorTool().emitSpeculationFence();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -372,6 +387,8 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
|
|||||||
debug.log("interior match for %s", valueNode);
|
debug.log("interior match for %s", valueNode);
|
||||||
} else if (operand instanceof ComplexMatchValue) {
|
} else if (operand instanceof ComplexMatchValue) {
|
||||||
debug.log("complex match for %s", valueNode);
|
debug.log("complex match for %s", valueNode);
|
||||||
|
// Set current position to the position of the root matched node.
|
||||||
|
setSourcePosition(node.getNodeSourcePosition());
|
||||||
ComplexMatchValue match = (ComplexMatchValue) operand;
|
ComplexMatchValue match = (ComplexMatchValue) operand;
|
||||||
operand = match.evaluate(this);
|
operand = match.evaluate(this);
|
||||||
if (operand != null) {
|
if (operand != null) {
|
||||||
|
@ -47,10 +47,13 @@ import org.graalvm.compiler.nodes.calc.IntegerTestNode;
|
|||||||
import org.graalvm.compiler.nodes.calc.LeftShiftNode;
|
import org.graalvm.compiler.nodes.calc.LeftShiftNode;
|
||||||
import org.graalvm.compiler.nodes.calc.MulNode;
|
import org.graalvm.compiler.nodes.calc.MulNode;
|
||||||
import org.graalvm.compiler.nodes.calc.NarrowNode;
|
import org.graalvm.compiler.nodes.calc.NarrowNode;
|
||||||
|
import org.graalvm.compiler.nodes.calc.NegateNode;
|
||||||
|
import org.graalvm.compiler.nodes.calc.NotNode;
|
||||||
import org.graalvm.compiler.nodes.calc.ObjectEqualsNode;
|
import org.graalvm.compiler.nodes.calc.ObjectEqualsNode;
|
||||||
import org.graalvm.compiler.nodes.calc.OrNode;
|
import org.graalvm.compiler.nodes.calc.OrNode;
|
||||||
import org.graalvm.compiler.nodes.calc.PointerEqualsNode;
|
import org.graalvm.compiler.nodes.calc.PointerEqualsNode;
|
||||||
import org.graalvm.compiler.nodes.calc.ReinterpretNode;
|
import org.graalvm.compiler.nodes.calc.ReinterpretNode;
|
||||||
|
import org.graalvm.compiler.nodes.calc.RightShiftNode;
|
||||||
import org.graalvm.compiler.nodes.calc.SignExtendNode;
|
import org.graalvm.compiler.nodes.calc.SignExtendNode;
|
||||||
import org.graalvm.compiler.nodes.calc.SubNode;
|
import org.graalvm.compiler.nodes.calc.SubNode;
|
||||||
import org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode;
|
import org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode;
|
||||||
@ -78,6 +81,8 @@ import jdk.vm.ci.meta.Value;
|
|||||||
@MatchableNode(nodeClass = WriteNode.class, inputs = {"address", "value"})
|
@MatchableNode(nodeClass = WriteNode.class, inputs = {"address", "value"})
|
||||||
@MatchableNode(nodeClass = ZeroExtendNode.class, inputs = {"value"})
|
@MatchableNode(nodeClass = ZeroExtendNode.class, inputs = {"value"})
|
||||||
@MatchableNode(nodeClass = AndNode.class, inputs = {"x", "y"}, commutative = true)
|
@MatchableNode(nodeClass = AndNode.class, inputs = {"x", "y"}, commutative = true)
|
||||||
|
@MatchableNode(nodeClass = NegateNode.class, inputs = {"value"})
|
||||||
|
@MatchableNode(nodeClass = NotNode.class, inputs = {"value"})
|
||||||
@MatchableNode(nodeClass = FloatEqualsNode.class, inputs = {"x", "y"}, commutative = true)
|
@MatchableNode(nodeClass = FloatEqualsNode.class, inputs = {"x", "y"}, commutative = true)
|
||||||
@MatchableNode(nodeClass = FloatLessThanNode.class, inputs = {"x", "y"}, commutative = true)
|
@MatchableNode(nodeClass = FloatLessThanNode.class, inputs = {"x", "y"}, commutative = true)
|
||||||
@MatchableNode(nodeClass = PointerEqualsNode.class, inputs = {"x", "y"}, commutative = true)
|
@MatchableNode(nodeClass = PointerEqualsNode.class, inputs = {"x", "y"}, commutative = true)
|
||||||
@ -93,6 +98,7 @@ import jdk.vm.ci.meta.Value;
|
|||||||
@MatchableNode(nodeClass = PiNode.class, inputs = {"object"})
|
@MatchableNode(nodeClass = PiNode.class, inputs = {"object"})
|
||||||
@MatchableNode(nodeClass = LogicCompareAndSwapNode.class, inputs = {"address", "expectedValue", "newValue"})
|
@MatchableNode(nodeClass = LogicCompareAndSwapNode.class, inputs = {"address", "expectedValue", "newValue"})
|
||||||
@MatchableNode(nodeClass = ValueCompareAndSwapNode.class, inputs = {"address", "expectedValue", "newValue"})
|
@MatchableNode(nodeClass = ValueCompareAndSwapNode.class, inputs = {"address", "expectedValue", "newValue"})
|
||||||
|
@MatchableNode(nodeClass = RightShiftNode.class, inputs = {"x", "y"})
|
||||||
public abstract class NodeMatchRules {
|
public abstract class NodeMatchRules {
|
||||||
|
|
||||||
NodeLIRBuilder lirBuilder;
|
NodeLIRBuilder lirBuilder;
|
||||||
|
@ -34,7 +34,7 @@ import org.graalvm.compiler.nodes.LogicConstantNode;
|
|||||||
import org.graalvm.compiler.nodes.StructuredGraph;
|
import org.graalvm.compiler.nodes.StructuredGraph;
|
||||||
import org.graalvm.compiler.phases.BasePhase;
|
import org.graalvm.compiler.phases.BasePhase;
|
||||||
import org.graalvm.compiler.phases.PhaseSuite;
|
import org.graalvm.compiler.phases.PhaseSuite;
|
||||||
import org.graalvm.compiler.phases.common.util.HashSetNodeEventListener;
|
import org.graalvm.compiler.phases.common.util.EconomicSetNodeEventListener;
|
||||||
import org.graalvm.compiler.phases.tiers.PhaseContext;
|
import org.graalvm.compiler.phases.tiers.PhaseContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,7 +68,7 @@ public class GraphChangeMonitoringPhase<C extends PhaseContext> extends PhaseSui
|
|||||||
* Phase may add nodes but not end up using them so ignore additions. Nodes going dead and
|
* Phase may add nodes but not end up using them so ignore additions. Nodes going dead and
|
||||||
* having their inputs change are the main interesting differences.
|
* having their inputs change are the main interesting differences.
|
||||||
*/
|
*/
|
||||||
HashSetNodeEventListener listener = new HashSetNodeEventListener().exclude(NodeEvent.NODE_ADDED);
|
EconomicSetNodeEventListener listener = new EconomicSetNodeEventListener().exclude(NodeEvent.NODE_ADDED);
|
||||||
StructuredGraph graphCopy = (StructuredGraph) graph.copy(graph.getDebug());
|
StructuredGraph graphCopy = (StructuredGraph) graph.copy(graph.getDebug());
|
||||||
DebugContext debug = graph.getDebug();
|
DebugContext debug = graph.getDebug();
|
||||||
try (NodeEventScope s = graphCopy.trackNodeEvents(listener)) {
|
try (NodeEventScope s = graphCopy.trackNodeEvents(listener)) {
|
||||||
@ -90,7 +90,7 @@ public class GraphChangeMonitoringPhase<C extends PhaseContext> extends PhaseSui
|
|||||||
}
|
}
|
||||||
if (!filteredNodes.isEmpty()) {
|
if (!filteredNodes.isEmpty()) {
|
||||||
/* rerun it on the real graph in a new Debug scope so Dump and Log can find it. */
|
/* rerun it on the real graph in a new Debug scope so Dump and Log can find it. */
|
||||||
listener = new HashSetNodeEventListener();
|
listener = new EconomicSetNodeEventListener();
|
||||||
try (NodeEventScope s = graph.trackNodeEvents(listener)) {
|
try (NodeEventScope s = graph.trackNodeEvents(listener)) {
|
||||||
try (DebugContext.Scope s2 = debug.scope("WithGraphChangeMonitoring")) {
|
try (DebugContext.Scope s2 = debug.scope("WithGraphChangeMonitoring")) {
|
||||||
if (debug.isDumpEnabled(DebugContext.DETAILED_LEVEL)) {
|
if (debug.isDumpEnabled(DebugContext.DETAILED_LEVEL)) {
|
||||||
|
@ -24,6 +24,9 @@
|
|||||||
|
|
||||||
package org.graalvm.compiler.core.phases;
|
package org.graalvm.compiler.core.phases;
|
||||||
|
|
||||||
|
import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.GuardTargets;
|
||||||
|
import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.NonDeoptGuardTargets;
|
||||||
|
import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.Options.MitigateSpeculativeExecutionAttacks;
|
||||||
import static org.graalvm.compiler.core.common.GraalOptions.ConditionalElimination;
|
import static org.graalvm.compiler.core.common.GraalOptions.ConditionalElimination;
|
||||||
import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
|
import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
|
||||||
import static org.graalvm.compiler.core.common.GraalOptions.OptDeoptimizationGrouping;
|
import static org.graalvm.compiler.core.common.GraalOptions.OptDeoptimizationGrouping;
|
||||||
@ -47,6 +50,7 @@ import org.graalvm.compiler.phases.common.FloatingReadPhase;
|
|||||||
import org.graalvm.compiler.phases.common.FrameStateAssignmentPhase;
|
import org.graalvm.compiler.phases.common.FrameStateAssignmentPhase;
|
||||||
import org.graalvm.compiler.phases.common.GuardLoweringPhase;
|
import org.graalvm.compiler.phases.common.GuardLoweringPhase;
|
||||||
import org.graalvm.compiler.phases.common.IncrementalCanonicalizerPhase;
|
import org.graalvm.compiler.phases.common.IncrementalCanonicalizerPhase;
|
||||||
|
import org.graalvm.compiler.phases.common.InsertGuardFencesPhase;
|
||||||
import org.graalvm.compiler.phases.common.IterativeConditionalEliminationPhase;
|
import org.graalvm.compiler.phases.common.IterativeConditionalEliminationPhase;
|
||||||
import org.graalvm.compiler.phases.common.LockEliminationPhase;
|
import org.graalvm.compiler.phases.common.LockEliminationPhase;
|
||||||
import org.graalvm.compiler.phases.common.LoopSafepointInsertionPhase;
|
import org.graalvm.compiler.phases.common.LoopSafepointInsertionPhase;
|
||||||
@ -78,6 +82,10 @@ public class MidTier extends PhaseSuite<MidTierContext> {
|
|||||||
|
|
||||||
appendPhase(new GuardLoweringPhase());
|
appendPhase(new GuardLoweringPhase());
|
||||||
|
|
||||||
|
if (MitigateSpeculativeExecutionAttacks.getValue(options) == GuardTargets || MitigateSpeculativeExecutionAttacks.getValue(options) == NonDeoptGuardTargets) {
|
||||||
|
appendPhase(new InsertGuardFencesPhase());
|
||||||
|
}
|
||||||
|
|
||||||
if (VerifyHeapAtReturn.getValue(options)) {
|
if (VerifyHeapAtReturn.getValue(options)) {
|
||||||
appendPhase(new VerifyHeapAtReturnPhase());
|
appendPhase(new VerifyHeapAtReturnPhase());
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ import org.graalvm.compiler.lir.gen.LIRGenerationResult;
|
|||||||
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
|
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
|
||||||
import org.graalvm.compiler.nodes.StructuredGraph;
|
import org.graalvm.compiler.nodes.StructuredGraph;
|
||||||
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
|
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
|
||||||
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.compiler.phases.tiers.SuitesProvider;
|
import org.graalvm.compiler.phases.tiers.SuitesProvider;
|
||||||
import org.graalvm.compiler.phases.tiers.TargetProvider;
|
import org.graalvm.compiler.phases.tiers.TargetProvider;
|
||||||
import org.graalvm.compiler.phases.util.Providers;
|
import org.graalvm.compiler.phases.util.Providers;
|
||||||
@ -153,7 +154,7 @@ public abstract class Backend implements TargetProvider, ValueKindFactory<LIRKin
|
|||||||
* Turns a Graal {@link CompilationResult} into a {@link CompiledCode} object that can be passed
|
* Turns a Graal {@link CompilationResult} into a {@link CompiledCode} object that can be passed
|
||||||
* to the VM for code installation.
|
* to the VM for code installation.
|
||||||
*/
|
*/
|
||||||
protected abstract CompiledCode createCompiledCode(ResolvedJavaMethod method, CompilationRequest compilationRequest, CompilationResult compilationResult);
|
protected abstract CompiledCode createCompiledCode(ResolvedJavaMethod method, CompilationRequest compilationRequest, CompilationResult compilationResult, boolean isDefault, OptionValues options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see #createInstalledCode(DebugContext, ResolvedJavaMethod, CompilationRequest,
|
* @see #createInstalledCode(DebugContext, ResolvedJavaMethod, CompilationRequest,
|
||||||
@ -192,6 +193,9 @@ public abstract class Backend implements TargetProvider, ValueKindFactory<LIRKin
|
|||||||
* @param context a custom debug context to use for the code installation
|
* @param context a custom debug context to use for the code installation
|
||||||
* @return a reference to the compiled and ready-to-run installed code
|
* @return a reference to the compiled and ready-to-run installed code
|
||||||
* @throws BailoutException if the code installation failed
|
* @throws BailoutException if the code installation failed
|
||||||
|
* @throws IllegalArgumentException if {@code installedCode != null} and this platform does not
|
||||||
|
* {@linkplain CodeCacheProvider#installCode support} a predefined
|
||||||
|
* {@link InstalledCode} object
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("try")
|
@SuppressWarnings("try")
|
||||||
public InstalledCode createInstalledCode(DebugContext debug, ResolvedJavaMethod method, CompilationRequest compilationRequest, CompilationResult compilationResult,
|
public InstalledCode createInstalledCode(DebugContext debug, ResolvedJavaMethod method, CompilationRequest compilationRequest, CompilationResult compilationResult,
|
||||||
@ -209,8 +213,8 @@ public abstract class Backend implements TargetProvider, ValueKindFactory<LIRKin
|
|||||||
|
|
||||||
InstalledCode installedCode;
|
InstalledCode installedCode;
|
||||||
try {
|
try {
|
||||||
preCodeInstallationTasks(tasks, compilationResult, predefinedInstalledCode);
|
preCodeInstallationTasks(tasks, compilationResult);
|
||||||
CompiledCode compiledCode = createCompiledCode(method, compilationRequest, compilationResult);
|
CompiledCode compiledCode = createCompiledCode(method, compilationRequest, compilationResult, isDefault, debug.getOptions());
|
||||||
installedCode = getProviders().getCodeCache().installCode(method, compiledCode, predefinedInstalledCode, speculationLog, isDefault);
|
installedCode = getProviders().getCodeCache().installCode(method, compiledCode, predefinedInstalledCode, speculationLog, isDefault);
|
||||||
assert predefinedInstalledCode == null || installedCode == predefinedInstalledCode;
|
assert predefinedInstalledCode == null || installedCode == predefinedInstalledCode;
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
@ -218,7 +222,7 @@ public abstract class Backend implements TargetProvider, ValueKindFactory<LIRKin
|
|||||||
throw t;
|
throw t;
|
||||||
}
|
}
|
||||||
|
|
||||||
postCodeInstallationTasks(tasks, installedCode);
|
postCodeInstallationTasks(tasks, compilationResult, installedCode);
|
||||||
|
|
||||||
return installedCode;
|
return installedCode;
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
@ -232,16 +236,16 @@ public abstract class Backend implements TargetProvider, ValueKindFactory<LIRKin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void preCodeInstallationTasks(CodeInstallationTask[] tasks, CompilationResult compilationResult, InstalledCode predefinedInstalledCode) {
|
private static void preCodeInstallationTasks(CodeInstallationTask[] tasks, CompilationResult compilationResult) {
|
||||||
for (CodeInstallationTask task : tasks) {
|
for (CodeInstallationTask task : tasks) {
|
||||||
task.preProcess(compilationResult, predefinedInstalledCode);
|
task.preProcess(compilationResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void postCodeInstallationTasks(CodeInstallationTask[] tasks, InstalledCode installedCode) {
|
private static void postCodeInstallationTasks(CodeInstallationTask[] tasks, CompilationResult compilationResult, InstalledCode installedCode) {
|
||||||
try {
|
try {
|
||||||
for (CodeInstallationTask task : tasks) {
|
for (CodeInstallationTask task : tasks) {
|
||||||
task.postProcess(installedCode);
|
task.postProcess(compilationResult, installedCode);
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
installedCode.invalidate();
|
installedCode.invalidate();
|
||||||
@ -310,19 +314,18 @@ public abstract class Backend implements TargetProvider, ValueKindFactory<LIRKin
|
|||||||
* Task to run before code installation.
|
* Task to run before code installation.
|
||||||
*
|
*
|
||||||
* @param compilationResult the code about to be installed
|
* @param compilationResult the code about to be installed
|
||||||
* @param predefinedInstalledCode a pre-allocated {@link InstalledCode} object that will be
|
|
||||||
* used as a reference to the installed code. May be {@code null}.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void preProcess(CompilationResult compilationResult, InstalledCode predefinedInstalledCode) {
|
public void preProcess(CompilationResult compilationResult) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Task to run after the code is installed.
|
* Task to run after the code is installed.
|
||||||
*
|
*
|
||||||
|
* @param compilationResult the code about to be installed
|
||||||
* @param installedCode a reference to the installed code
|
* @param installedCode a reference to the installed code
|
||||||
*/
|
*/
|
||||||
public void postProcess(InstalledCode installedCode) {
|
public void postProcess(CompilationResult compilationResult, InstalledCode installedCode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -197,6 +197,7 @@ public class DebugContextTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEnabledSandbox() {
|
public void testEnabledSandbox() {
|
||||||
|
TimerKeyTest.assumeManagementLibraryIsLoadable();
|
||||||
EconomicMap<OptionKey<?>, Object> map = EconomicMap.create();
|
EconomicMap<OptionKey<?>, Object> map = EconomicMap.create();
|
||||||
// Configure with an option that enables scopes
|
// Configure with an option that enables scopes
|
||||||
map.put(DebugOptions.DumpOnError, true);
|
map.put(DebugOptions.DumpOnError, true);
|
||||||
@ -226,6 +227,7 @@ public class DebugContextTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDisabledSandbox() {
|
public void testDisabledSandbox() {
|
||||||
|
TimerKeyTest.assumeManagementLibraryIsLoadable();
|
||||||
EconomicMap<OptionKey<?>, Object> map = EconomicMap.create();
|
EconomicMap<OptionKey<?>, Object> map = EconomicMap.create();
|
||||||
// Configure with an option that enables scopes
|
// Configure with an option that enables scopes
|
||||||
map.put(DebugOptions.DumpOnError, true);
|
map.put(DebugOptions.DumpOnError, true);
|
||||||
@ -283,6 +285,7 @@ public class DebugContextTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDisableIntercept() {
|
public void testDisableIntercept() {
|
||||||
|
TimerKeyTest.assumeManagementLibraryIsLoadable();
|
||||||
EconomicMap<OptionKey<?>, Object> map = EconomicMap.create();
|
EconomicMap<OptionKey<?>, Object> map = EconomicMap.create();
|
||||||
// Configure with an option that enables scopes
|
// Configure with an option that enables scopes
|
||||||
map.put(DebugOptions.DumpOnError, true);
|
map.put(DebugOptions.DumpOnError, true);
|
||||||
|
@ -39,6 +39,7 @@ import org.graalvm.compiler.options.OptionKey;
|
|||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.compiler.serviceprovider.GraalServices;
|
import org.graalvm.compiler.serviceprovider.GraalServices;
|
||||||
import org.junit.Assume;
|
import org.junit.Assume;
|
||||||
|
import org.junit.AssumptionViolatedException;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ -47,9 +48,20 @@ public class TimerKeyTest {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void checkCapabilities() {
|
public void checkCapabilities() {
|
||||||
|
assumeManagementLibraryIsLoadable();
|
||||||
Assume.assumeTrue("skipping management interface test", GraalServices.isCurrentThreadCpuTimeSupported());
|
Assume.assumeTrue("skipping management interface test", GraalServices.isCurrentThreadCpuTimeSupported());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @see <a href="https://bugs.openjdk.java.net/browse/JDK-8076557">JDK-8076557</a> */
|
||||||
|
static void assumeManagementLibraryIsLoadable() {
|
||||||
|
try {
|
||||||
|
/* Trigger loading of the management library using the bootstrap class loader. */
|
||||||
|
GraalServices.getCurrentThreadAllocatedBytes();
|
||||||
|
} catch (UnsatisfiedLinkError | NoClassDefFoundError | UnsupportedOperationException e) {
|
||||||
|
throw new AssumptionViolatedException("Management interface is unavailable: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Actively spins the current thread for at least a given number of milliseconds in such a way
|
* Actively spins the current thread for at least a given number of milliseconds in such a way
|
||||||
* that timers for the current thread keep ticking over.
|
* that timers for the current thread keep ticking over.
|
||||||
|
@ -80,7 +80,7 @@ import jdk.vm.ci.meta.JavaMethod;
|
|||||||
*/
|
*/
|
||||||
public final class DebugContext implements AutoCloseable {
|
public final class DebugContext implements AutoCloseable {
|
||||||
|
|
||||||
public static final Description NO_DESCRIPTION = null;
|
public static final Description NO_DESCRIPTION = new Description(null, "NO_DESCRIPTION");
|
||||||
public static final GlobalMetrics NO_GLOBAL_METRIC_VALUES = null;
|
public static final GlobalMetrics NO_GLOBAL_METRIC_VALUES = null;
|
||||||
public static final Iterable<DebugHandlersFactory> NO_CONFIG_CUSTOMIZERS = Collections.emptyList();
|
public static final Iterable<DebugHandlersFactory> NO_CONFIG_CUSTOMIZERS = Collections.emptyList();
|
||||||
|
|
||||||
@ -404,6 +404,18 @@ public final class DebugContext implements AutoCloseable {
|
|||||||
return new DebugContext(NO_DESCRIPTION, NO_GLOBAL_METRIC_VALUES, DEFAULT_LOG_STREAM, Immutable.create(options), factories);
|
return new DebugContext(NO_DESCRIPTION, NO_GLOBAL_METRIC_VALUES, DEFAULT_LOG_STREAM, Immutable.create(options), factories);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static DebugContext create(OptionValues options, PrintStream logStream, DebugHandlersFactory factory) {
|
||||||
|
return new DebugContext(NO_DESCRIPTION, NO_GLOBAL_METRIC_VALUES, logStream, Immutable.create(options), Collections.singletonList(factory));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link DebugContext} based on a given set of option values and {@code factories}.
|
||||||
|
* The {@link DebugHandlersFactory#LOADER} can be used for the latter.
|
||||||
|
*/
|
||||||
|
public static DebugContext create(OptionValues options, Description description, Iterable<DebugHandlersFactory> factories) {
|
||||||
|
return new DebugContext(description, NO_GLOBAL_METRIC_VALUES, DEFAULT_LOG_STREAM, Immutable.create(options), factories);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@link DebugContext}.
|
* Creates a {@link DebugContext}.
|
||||||
*/
|
*/
|
||||||
|
@ -127,8 +127,6 @@ public class DebugOptions {
|
|||||||
@Option(help = "Enable dumping LIR, register allocation and code generation info to the C1Visualizer.", type = OptionType.Debug)
|
@Option(help = "Enable dumping LIR, register allocation and code generation info to the C1Visualizer.", type = OptionType.Debug)
|
||||||
public static final OptionKey<Boolean> PrintBackendCFG = new OptionKey<>(true);
|
public static final OptionKey<Boolean> PrintBackendCFG = new OptionKey<>(true);
|
||||||
|
|
||||||
@Option(help = "Output probabilities for fixed nodes during binary graph dumping.", type = OptionType.Debug)
|
|
||||||
public static final OptionKey<Boolean> PrintGraphProbabilities = new OptionKey<>(false);
|
|
||||||
@Option(help = "Enable dumping to the IdealGraphVisualizer.", type = OptionType.Debug)
|
@Option(help = "Enable dumping to the IdealGraphVisualizer.", type = OptionType.Debug)
|
||||||
public static final OptionKey<Boolean> PrintGraph = new OptionKey<>(true);
|
public static final OptionKey<Boolean> PrintGraph = new OptionKey<>(true);
|
||||||
@Option(help = "Print graphs to files instead of sending them over the network.", type = OptionType.Debug)
|
@Option(help = "Print graphs to files instead of sending them over the network.", type = OptionType.Debug)
|
||||||
|
@ -86,6 +86,7 @@ public class DiagnosticsOutputDirectory {
|
|||||||
}
|
}
|
||||||
if (CLOSED.equals(path)) {
|
if (CLOSED.equals(path)) {
|
||||||
TTY.println("Warning: Graal diagnostic directory already closed");
|
TTY.println("Warning: Graal diagnostic directory already closed");
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
@ -129,6 +130,7 @@ public class DiagnosticsOutputDirectory {
|
|||||||
|
|
||||||
Path dir = Paths.get(outDir);
|
Path dir = Paths.get(outDir);
|
||||||
if (dir.toFile().exists()) {
|
if (dir.toFile().exists()) {
|
||||||
|
String prefix = new File(outDir).getName() + "/";
|
||||||
File zip = new File(outDir + ".zip").getAbsoluteFile();
|
File zip = new File(outDir + ".zip").getAbsoluteFile();
|
||||||
List<Path> toDelete = new ArrayList<>();
|
List<Path> toDelete = new ArrayList<>();
|
||||||
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zip))) {
|
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zip))) {
|
||||||
@ -137,7 +139,7 @@ public class DiagnosticsOutputDirectory {
|
|||||||
@Override
|
@Override
|
||||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||||
if (attrs.isRegularFile()) {
|
if (attrs.isRegularFile()) {
|
||||||
String name = dir.relativize(file).toString();
|
String name = prefix + dir.relativize(file).toString();
|
||||||
ZipEntry ze = new ZipEntry(name);
|
ZipEntry ze = new ZipEntry(name);
|
||||||
zos.putNextEntry(ze);
|
zos.putNextEntry(ze);
|
||||||
Files.copy(file, zos);
|
Files.copy(file, zos);
|
||||||
|
@ -31,7 +31,7 @@ import org.junit.Assume;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class GraphSnippetTest {
|
public class GraphSnippetTest {
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings({"deprecation", "unused"})
|
||||||
@Test
|
@Test
|
||||||
public void dumpTheFile() throws Exception {
|
public void dumpTheFile() throws Exception {
|
||||||
Class<?> snippets = null;
|
Class<?> snippets = null;
|
||||||
|
@ -28,6 +28,7 @@ import static org.graalvm.compiler.graph.NodeSourcePosition.Marker.None;
|
|||||||
import static org.graalvm.compiler.graph.NodeSourcePosition.Marker.Placeholder;
|
import static org.graalvm.compiler.graph.NodeSourcePosition.Marker.Placeholder;
|
||||||
import static org.graalvm.compiler.graph.NodeSourcePosition.Marker.Substitution;
|
import static org.graalvm.compiler.graph.NodeSourcePosition.Marker.Substitution;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import org.graalvm.compiler.bytecode.BytecodeDisassembler;
|
import org.graalvm.compiler.bytecode.BytecodeDisassembler;
|
||||||
@ -40,7 +41,7 @@ import jdk.vm.ci.meta.JavaMethod;
|
|||||||
import jdk.vm.ci.meta.MetaUtil;
|
import jdk.vm.ci.meta.MetaUtil;
|
||||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||||
|
|
||||||
public class NodeSourcePosition extends BytecodePosition {
|
public class NodeSourcePosition extends BytecodePosition implements Iterable<NodeSourcePosition> {
|
||||||
|
|
||||||
private static final boolean STRICT_SOURCE_POSITION = Boolean.getBoolean("debug.graal.SourcePositionStrictChecks");
|
private static final boolean STRICT_SOURCE_POSITION = Boolean.getBoolean("debug.graal.SourcePositionStrictChecks");
|
||||||
private static final boolean SOURCE_POSITION_BYTECODES = Boolean.getBoolean("debug.graal.SourcePositionDisassemble");
|
private static final boolean SOURCE_POSITION_BYTECODES = Boolean.getBoolean("debug.graal.SourcePositionDisassemble");
|
||||||
@ -53,17 +54,16 @@ public class NodeSourcePosition extends BytecodePosition {
|
|||||||
* Remove marker frames.
|
* Remove marker frames.
|
||||||
*/
|
*/
|
||||||
public NodeSourcePosition trim() {
|
public NodeSourcePosition trim() {
|
||||||
if (marker != None) {
|
NodeSourcePosition lastMarker = null;
|
||||||
return null;
|
for (NodeSourcePosition current = this; current != null; current = current.getCaller()) {
|
||||||
|
if (current.marker != None) {
|
||||||
|
lastMarker = current;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
NodeSourcePosition caller = getCaller();
|
if (lastMarker == null) {
|
||||||
if (caller != null) {
|
return this;
|
||||||
caller = caller.trim();
|
|
||||||
}
|
}
|
||||||
if (caller != getCaller()) {
|
return lastMarker.getCaller();
|
||||||
return new NodeSourcePosition(caller, getMethod(), getBCI());
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResolvedJavaMethod getRootMethod() {
|
public ResolvedJavaMethod getRootMethod() {
|
||||||
@ -81,6 +81,25 @@ public class NodeSourcePosition extends BytecodePosition {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<NodeSourcePosition> iterator() {
|
||||||
|
return new Iterator<NodeSourcePosition>() {
|
||||||
|
private NodeSourcePosition currentPosition = NodeSourcePosition.this;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return currentPosition != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NodeSourcePosition next() {
|
||||||
|
NodeSourcePosition current = currentPosition;
|
||||||
|
currentPosition = currentPosition.getCaller();
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
enum Marker {
|
enum Marker {
|
||||||
None,
|
None,
|
||||||
Placeholder,
|
Placeholder,
|
||||||
@ -124,11 +143,19 @@ public class NodeSourcePosition extends BytecodePosition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static NodeSourcePosition substitution(ResolvedJavaMethod method) {
|
public static NodeSourcePosition substitution(ResolvedJavaMethod method) {
|
||||||
return substitution(null, method);
|
return substitution(null, method, BytecodeFrame.INVALID_FRAMESTATE_BCI);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NodeSourcePosition substitution(ResolvedJavaMethod method, int bci) {
|
||||||
|
return substitution(null, method, bci);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NodeSourcePosition substitution(NodeSourcePosition caller, ResolvedJavaMethod method) {
|
public static NodeSourcePosition substitution(NodeSourcePosition caller, ResolvedJavaMethod method) {
|
||||||
return new NodeSourcePosition(caller, method, BytecodeFrame.INVALID_FRAMESTATE_BCI, Substitution);
|
return substitution(caller, method, BytecodeFrame.INVALID_FRAMESTATE_BCI);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NodeSourcePosition substitution(NodeSourcePosition caller, ResolvedJavaMethod method, int bci) {
|
||||||
|
return new NodeSourcePosition(caller, method, bci, Substitution);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSubstitution() {
|
public boolean isSubstitution() {
|
||||||
@ -195,10 +222,10 @@ public class NodeSourcePosition extends BytecodePosition {
|
|||||||
return new NodeSourcePosition(newSourceLanguagePosition, link, getMethod(), 0);
|
return new NodeSourcePosition(newSourceLanguagePosition, link, getMethod(), 0);
|
||||||
}
|
}
|
||||||
assert link == null || isSubstitution || verifyCaller(this, link) : link;
|
assert link == null || isSubstitution || verifyCaller(this, link) : link;
|
||||||
|
assert !isSubstitution || marker == None;
|
||||||
return new NodeSourcePosition(newSourceLanguagePosition, link, getMethod(), getBCI());
|
return new NodeSourcePosition(newSourceLanguagePosition, link, getMethod(), getBCI(), isSubstitution ? Substitution : None);
|
||||||
} else {
|
} else {
|
||||||
return new NodeSourcePosition(getCaller().addCaller(newSourceLanguagePosition, link, isSubstitution), getMethod(), getBCI());
|
return new NodeSourcePosition(getCaller().addCaller(newSourceLanguagePosition, link, isSubstitution), getMethod(), getBCI(), marker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,6 +248,9 @@ public class NodeSourcePosition extends BytecodePosition {
|
|||||||
|
|
||||||
private static void format(StringBuilder sb, NodeSourcePosition pos) {
|
private static void format(StringBuilder sb, NodeSourcePosition pos) {
|
||||||
MetaUtil.appendLocation(sb.append("at "), pos.getMethod(), pos.getBCI());
|
MetaUtil.appendLocation(sb.append("at "), pos.getMethod(), pos.getBCI());
|
||||||
|
if (pos.marker != None) {
|
||||||
|
sb.append(" " + pos.marker);
|
||||||
|
}
|
||||||
if (SOURCE_POSITION_BYTECODES) {
|
if (SOURCE_POSITION_BYTECODES) {
|
||||||
String disassembly = BytecodeDisassembler.disassembleOne(pos.getMethod(), pos.getBCI());
|
String disassembly = BytecodeDisassembler.disassembleOne(pos.getMethod(), pos.getBCI());
|
||||||
if (disassembly != null && disassembly.length() > 0) {
|
if (disassembly != null && disassembly.length() > 0) {
|
||||||
|
@ -56,7 +56,6 @@ import org.graalvm.compiler.hotspot.meta.HotSpotStampProvider;
|
|||||||
import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider;
|
import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider;
|
||||||
import org.graalvm.compiler.hotspot.word.HotSpotWordTypes;
|
import org.graalvm.compiler.hotspot.word.HotSpotWordTypes;
|
||||||
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
|
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
|
||||||
import org.graalvm.compiler.nodes.spi.LoweringProvider;
|
|
||||||
import org.graalvm.compiler.nodes.spi.Replacements;
|
import org.graalvm.compiler.nodes.spi.Replacements;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.compiler.phases.Phase;
|
import org.graalvm.compiler.phases.Phase;
|
||||||
@ -148,7 +147,7 @@ public class AArch64HotSpotBackendFactory implements HotSpotBackendFactory {
|
|||||||
replacements = createReplacements(graalRuntime.getOptions(), p, snippetReflection, bytecodeProvider);
|
replacements = createReplacements(graalRuntime.getOptions(), p, snippetReflection, bytecodeProvider);
|
||||||
}
|
}
|
||||||
try (InitTimer rt = timer("create GraphBuilderPhase plugins")) {
|
try (InitTimer rt = timer("create GraphBuilderPhase plugins")) {
|
||||||
plugins = createGraphBuilderPlugins(compilerConfiguration, config, constantReflection, foreignCalls, lowerer, metaAccess, snippetReflection, replacements, wordTypes, stampProvider);
|
plugins = createGraphBuilderPlugins(compilerConfiguration, config, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes);
|
||||||
replacements.setGraphBuilderPlugins(plugins);
|
replacements.setGraphBuilderPlugins(plugins);
|
||||||
}
|
}
|
||||||
try (InitTimer rt = timer("create Suites provider")) {
|
try (InitTimer rt = timer("create Suites provider")) {
|
||||||
@ -164,10 +163,9 @@ public class AArch64HotSpotBackendFactory implements HotSpotBackendFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotConstantReflectionProvider constantReflection,
|
protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotConstantReflectionProvider constantReflection,
|
||||||
HotSpotHostForeignCallsProvider foreignCalls, LoweringProvider lowerer, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection,
|
HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection,
|
||||||
HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) {
|
HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes) {
|
||||||
Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, lowerer, stampProvider,
|
Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, replacements);
|
||||||
replacements);
|
|
||||||
AArch64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), false);
|
AArch64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), false);
|
||||||
return plugins;
|
return plugins;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ import static jdk.vm.ci.meta.JavaConstant.INT_0;
|
|||||||
import static jdk.vm.ci.meta.JavaConstant.LONG_0;
|
import static jdk.vm.ci.meta.JavaConstant.LONG_0;
|
||||||
|
|
||||||
import org.graalvm.compiler.core.aarch64.AArch64MoveFactory;
|
import org.graalvm.compiler.core.aarch64.AArch64MoveFactory;
|
||||||
import org.graalvm.compiler.lir.LIRInstruction;
|
import org.graalvm.compiler.lir.aarch64.AArch64LIRInstruction;
|
||||||
|
|
||||||
import jdk.vm.ci.hotspot.HotSpotCompressedNullConstant;
|
import jdk.vm.ci.hotspot.HotSpotCompressedNullConstant;
|
||||||
import jdk.vm.ci.hotspot.HotSpotConstant;
|
import jdk.vm.ci.hotspot.HotSpotConstant;
|
||||||
@ -52,7 +52,7 @@ public class AArch64HotSpotMoveFactory extends AArch64MoveFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LIRInstruction createLoad(AllocatableValue dst, Constant src) {
|
public AArch64LIRInstruction createLoad(AllocatableValue dst, Constant src) {
|
||||||
Constant usedSource;
|
Constant usedSource;
|
||||||
if (COMPRESSED_NULL.equals(src)) {
|
if (COMPRESSED_NULL.equals(src)) {
|
||||||
usedSource = INT_0;
|
usedSource = INT_0;
|
||||||
|
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package org.graalvm.compiler.hotspot.amd64.test;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests Bit Manipulation Instruction andn pattern matching and result.
|
||||||
|
*/
|
||||||
|
public class BmiAndn extends BmiCompilerTest {
|
||||||
|
// from Intel manual VEX.NDS.LZ.0F38.W0 F2 /r, example c4e260f2c2
|
||||||
|
private final byte[] instrMask = new byte[]{
|
||||||
|
(byte) 0xFF,
|
||||||
|
(byte) 0x1F,
|
||||||
|
(byte) 0x00,
|
||||||
|
(byte) 0xFF};
|
||||||
|
private final byte[] instrPattern = new byte[]{
|
||||||
|
(byte) 0xC4, // prefix for 3-byte VEX instruction
|
||||||
|
(byte) 0x02, // 00010 implied 0F 38 leading opcode bytes
|
||||||
|
(byte) 0x00,
|
||||||
|
(byte) 0xF2};
|
||||||
|
|
||||||
|
public int andni(int n1, int n2) {
|
||||||
|
return (n1 & (~n2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long andnl(long n1, long n2) {
|
||||||
|
return (n1 & (~n2));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pattern matching check for andni
|
||||||
|
@Test
|
||||||
|
public void test1() {
|
||||||
|
Assert.assertTrue(verifyPositive("andni", instrMask, instrPattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pattern matching check for andnl
|
||||||
|
@Test
|
||||||
|
public void test2() {
|
||||||
|
Assert.assertTrue(verifyPositive("andnl", instrMask, instrPattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Result correctness check
|
||||||
|
@Test
|
||||||
|
public void test3() {
|
||||||
|
int n1 = 42;
|
||||||
|
int n2 = 100;
|
||||||
|
test("andni", n1, n2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test4() {
|
||||||
|
long n1 = 420000000;
|
||||||
|
long n2 = 1000000000;
|
||||||
|
test("andnl", n1, n2);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package org.graalvm.compiler.hotspot.amd64.test;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests Bit Manipulation Instruction blsi pattern matching and result.
|
||||||
|
*/
|
||||||
|
public class BmiBlsi extends BmiCompilerTest {
|
||||||
|
// from Intel manual VEX.NDD.LZ.0F38.W0 F3 /3, example c4e260f2c2
|
||||||
|
private final byte[] instrMask = new byte[]{
|
||||||
|
(byte) 0xFF,
|
||||||
|
(byte) 0x1F,
|
||||||
|
(byte) 0x00,
|
||||||
|
(byte) 0xFF,
|
||||||
|
(byte) 0b0011_1000};
|
||||||
|
private final byte[] instrPattern = new byte[]{
|
||||||
|
(byte) 0xC4, // prefix for 3-byte VEX instruction
|
||||||
|
(byte) 0x02, // 00010 implied 0F 38 leading opcode bytes
|
||||||
|
(byte) 0x00,
|
||||||
|
(byte) 0xF3,
|
||||||
|
(byte) 0b0001_1000}; // bits 543 == 011 (3)
|
||||||
|
|
||||||
|
public int blsii(int n1) {
|
||||||
|
return (n1 & (-n1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long blsil(long n1) {
|
||||||
|
return (n1 & (-n1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pattern matching check for blsii
|
||||||
|
@Test
|
||||||
|
public void test1() {
|
||||||
|
Assert.assertTrue(verifyPositive("blsii", instrMask, instrPattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pattern matching check for blsil
|
||||||
|
@Test
|
||||||
|
public void test2() {
|
||||||
|
Assert.assertTrue(verifyPositive("blsil", instrMask, instrPattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Result correctness check
|
||||||
|
@Test
|
||||||
|
public void test3() {
|
||||||
|
int n1 = 42;
|
||||||
|
test("blsii", n1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test4() {
|
||||||
|
long n1 = 420000000;
|
||||||
|
test("blsil", n1);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package org.graalvm.compiler.hotspot.amd64.test;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests Bit Manipulation Instruction blsmsk pattern matching and result.
|
||||||
|
*/
|
||||||
|
public class BmiBlsmsk extends BmiCompilerTest {
|
||||||
|
// from Intel manual VEX.NDD.LZ.0F38.W0 F3 /2, example c4e260f2c2
|
||||||
|
private final byte[] instrMask = new byte[]{
|
||||||
|
(byte) 0xFF,
|
||||||
|
(byte) 0x1F,
|
||||||
|
(byte) 0x00,
|
||||||
|
(byte) 0xFF,
|
||||||
|
(byte) 0b0011_1000};
|
||||||
|
private final byte[] instrPattern = new byte[]{
|
||||||
|
(byte) 0xC4, // prefix for 3-byte VEX instruction
|
||||||
|
(byte) 0x02, // 00010 implied 0F 38 leading opcode bytes
|
||||||
|
(byte) 0x00,
|
||||||
|
(byte) 0xF3,
|
||||||
|
(byte) 0b0001_0000}; // bits 543 == 010 (2)
|
||||||
|
|
||||||
|
public int blsmski(int n1) {
|
||||||
|
return (n1 ^ (n1 - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long blsmskl(long n1) {
|
||||||
|
return (n1 ^ (n1 - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pattern matching check for blsmski
|
||||||
|
@Test
|
||||||
|
public void test1() {
|
||||||
|
Assert.assertTrue(verifyPositive("blsmski", instrMask, instrPattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pattern matching check for blsmskl
|
||||||
|
@Test
|
||||||
|
public void test2() {
|
||||||
|
Assert.assertTrue(verifyPositive("blsmskl", instrMask, instrPattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Result correctness check
|
||||||
|
@Test
|
||||||
|
public void test3() {
|
||||||
|
int n1 = 42;
|
||||||
|
test("blsmski", n1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test4() {
|
||||||
|
long n1 = 420000000;
|
||||||
|
test("blsmskl", n1);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package org.graalvm.compiler.hotspot.amd64.test;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests Bit Manipulation Instruction blsr pattern matching and result.
|
||||||
|
*/
|
||||||
|
public class BmiBlsr extends BmiCompilerTest {
|
||||||
|
// from Intel manual VEX.NDD.LZ.0F38.W0 F3 /3, example c4e260f2c2
|
||||||
|
private final byte[] instrMask = new byte[]{
|
||||||
|
(byte) 0xFF,
|
||||||
|
(byte) 0x1F,
|
||||||
|
(byte) 0x00,
|
||||||
|
(byte) 0xFF,
|
||||||
|
(byte) 0b0011_1000};
|
||||||
|
private final byte[] instrPattern = new byte[]{
|
||||||
|
(byte) 0xC4, // prefix for 3-byte VEX instruction
|
||||||
|
(byte) 0x02, // 00010 implied 0F 38 leading opcode bytes
|
||||||
|
(byte) 0x00,
|
||||||
|
(byte) 0xF3,
|
||||||
|
(byte) 0b0000_1000}; // bits 543 == 011 (3)
|
||||||
|
|
||||||
|
public int blsri(int n1) {
|
||||||
|
return (n1 & (n1 - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long blsrl(long n1) {
|
||||||
|
return (n1 & (n1 - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pattern matching check for blsri
|
||||||
|
@Test
|
||||||
|
public void test1() {
|
||||||
|
Assert.assertTrue(verifyPositive("blsri", instrMask, instrPattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pattern matching check for blsrl
|
||||||
|
@Test
|
||||||
|
public void test2() {
|
||||||
|
Assert.assertTrue(verifyPositive("blsrl", instrMask, instrPattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Result correctness check
|
||||||
|
@Test
|
||||||
|
public void test3() {
|
||||||
|
int n1 = 42;
|
||||||
|
test("blsri", n1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test4() {
|
||||||
|
long n1 = 420000000;
|
||||||
|
test("blsrl", n1);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package org.graalvm.compiler.hotspot.amd64.test;
|
||||||
|
|
||||||
|
import static org.junit.Assume.assumeTrue;
|
||||||
|
|
||||||
|
import org.graalvm.compiler.api.test.Graal;
|
||||||
|
import org.graalvm.compiler.code.CompilationResult;
|
||||||
|
import org.graalvm.compiler.core.test.GraalCompilerTest;
|
||||||
|
import org.graalvm.compiler.nodes.StructuredGraph;
|
||||||
|
import org.graalvm.compiler.runtime.RuntimeProvider;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
|
||||||
|
import jdk.vm.ci.amd64.AMD64;
|
||||||
|
import jdk.vm.ci.code.Architecture;
|
||||||
|
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||||
|
|
||||||
|
public abstract class BmiCompilerTest extends GraalCompilerTest {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void checkAMD64() {
|
||||||
|
Architecture arch = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getTarget().arch;
|
||||||
|
assumeTrue("skipping AMD64 specific test", arch instanceof AMD64);
|
||||||
|
assumeTrue("skipping BMI1 specific test", ((AMD64) arch).getFeatures().contains(AMD64.CPUFeature.BMI1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean verifyPositive(String methodName, byte[] instrMask, byte[] instrPattern) {
|
||||||
|
ResolvedJavaMethod method = getResolvedJavaMethod(methodName);
|
||||||
|
StructuredGraph graph = parseForCompile(method);
|
||||||
|
|
||||||
|
CompilationResult c = compile(method, graph);
|
||||||
|
byte[] targetCode = c.getTargetCode();
|
||||||
|
|
||||||
|
return countCpuInstructions(targetCode, instrMask, instrPattern) >= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int countCpuInstructions(byte[] nativeCode, byte[] instrMask, byte[] instrPattern) {
|
||||||
|
int count = 0;
|
||||||
|
int patternSize = Math.min(instrMask.length, instrPattern.length);
|
||||||
|
boolean found;
|
||||||
|
Assert.assertTrue(patternSize > 0);
|
||||||
|
for (int i = 0, n = nativeCode.length - patternSize; i < n;) {
|
||||||
|
found = true;
|
||||||
|
for (int j = 0; j < patternSize; j++) {
|
||||||
|
if ((nativeCode[i + j] & instrMask[j]) != instrPattern[j]) {
|
||||||
|
found = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) {
|
||||||
|
++count;
|
||||||
|
i += patternSize - 1;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
package org.graalvm.compiler.hotspot.amd64;
|
||||||
|
|
||||||
|
import jdk.vm.ci.meta.JavaKind;
|
||||||
|
import org.graalvm.compiler.api.replacements.Snippet;
|
||||||
|
import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
|
||||||
|
import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
|
||||||
|
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
|
||||||
|
import org.graalvm.compiler.hotspot.stubs.SnippetStub;
|
||||||
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
|
import org.graalvm.compiler.replacements.amd64.AMD64ArrayIndexOfNode;
|
||||||
|
import jdk.internal.vm.compiler.word.Pointer;
|
||||||
|
|
||||||
|
public class AMD64ArrayIndexOfStub extends SnippetStub {
|
||||||
|
|
||||||
|
public AMD64ArrayIndexOfStub(ForeignCallDescriptor foreignCallDescriptor, OptionValues options, HotSpotProviders providers, HotSpotForeignCallLinkage linkage) {
|
||||||
|
super(foreignCallDescriptor.getName(), options, providers, linkage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Snippet
|
||||||
|
private static int indexOfTwoConsecutiveBytes(Pointer arrayPointer, int arrayLength, int searchValue) {
|
||||||
|
return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Byte, true, arrayPointer, arrayLength, searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Snippet
|
||||||
|
private static int indexOfTwoConsecutiveChars(Pointer arrayPointer, int arrayLength, int searchValue) {
|
||||||
|
return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Char, true, arrayPointer, arrayLength, searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Snippet
|
||||||
|
private static int indexOf1Byte(Pointer arrayPointer, int arrayLength, byte b) {
|
||||||
|
return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Byte, arrayPointer, arrayLength, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Snippet
|
||||||
|
private static int indexOf2Bytes(Pointer arrayPointer, int arrayLength, byte b1, byte b2) {
|
||||||
|
return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Byte, arrayPointer, arrayLength, b1, b2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Snippet
|
||||||
|
private static int indexOf3Bytes(Pointer arrayPointer, int arrayLength, byte b1, byte b2, byte b3) {
|
||||||
|
return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Byte, arrayPointer, arrayLength, b1, b2, b3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Snippet
|
||||||
|
private static int indexOf4Bytes(Pointer arrayPointer, int arrayLength, byte b1, byte b2, byte b3, byte b4) {
|
||||||
|
return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Byte, arrayPointer, arrayLength, b1, b2, b3, b4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Snippet
|
||||||
|
private static int indexOf1Char(Pointer arrayPointer, int arrayLength, char c) {
|
||||||
|
return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Char, arrayPointer, arrayLength, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Snippet
|
||||||
|
private static int indexOf2Chars(Pointer arrayPointer, int arrayLength, char c1, char c2) {
|
||||||
|
return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Char, arrayPointer, arrayLength, c1, c2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Snippet
|
||||||
|
private static int indexOf3Chars(Pointer arrayPointer, int arrayLength, char c1, char c2, char c3) {
|
||||||
|
return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Char, arrayPointer, arrayLength, c1, c2, c3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Snippet
|
||||||
|
private static int indexOf4Chars(Pointer arrayPointer, int arrayLength, char c1, char c2, char c3, char c4) {
|
||||||
|
return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Char, arrayPointer, arrayLength, c1, c2, c3, c4);
|
||||||
|
}
|
||||||
|
}
|
@ -52,7 +52,6 @@ import org.graalvm.compiler.hotspot.meta.HotSpotStampProvider;
|
|||||||
import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider;
|
import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider;
|
||||||
import org.graalvm.compiler.hotspot.word.HotSpotWordTypes;
|
import org.graalvm.compiler.hotspot.word.HotSpotWordTypes;
|
||||||
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
|
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
|
||||||
import org.graalvm.compiler.nodes.spi.LoweringProvider;
|
|
||||||
import org.graalvm.compiler.nodes.spi.Replacements;
|
import org.graalvm.compiler.nodes.spi.Replacements;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.compiler.phases.common.AddressLoweringPhase;
|
import org.graalvm.compiler.phases.common.AddressLoweringPhase;
|
||||||
@ -142,8 +141,7 @@ public class AMD64HotSpotBackendFactory implements HotSpotBackendFactory {
|
|||||||
replacements = createReplacements(options, p, snippetReflection, bytecodeProvider);
|
replacements = createReplacements(options, p, snippetReflection, bytecodeProvider);
|
||||||
}
|
}
|
||||||
try (InitTimer rt = timer("create GraphBuilderPhase plugins")) {
|
try (InitTimer rt = timer("create GraphBuilderPhase plugins")) {
|
||||||
plugins = createGraphBuilderPlugins(compilerConfiguration, config, options, target, constantReflection, foreignCalls, lowerer, metaAccess, snippetReflection, replacements, wordTypes,
|
plugins = createGraphBuilderPlugins(compilerConfiguration, config, options, target, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes);
|
||||||
stampProvider);
|
|
||||||
replacements.setGraphBuilderPlugins(plugins);
|
replacements.setGraphBuilderPlugins(plugins);
|
||||||
}
|
}
|
||||||
try (InitTimer rt = timer("create Suites provider")) {
|
try (InitTimer rt = timer("create Suites provider")) {
|
||||||
@ -159,10 +157,9 @@ public class AMD64HotSpotBackendFactory implements HotSpotBackendFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, OptionValues options, TargetDescription target,
|
protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, OptionValues options, TargetDescription target,
|
||||||
HotSpotConstantReflectionProvider constantReflection, HotSpotHostForeignCallsProvider foreignCalls, LoweringProvider lowerer, HotSpotMetaAccessProvider metaAccess,
|
HotSpotConstantReflectionProvider constantReflection, HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess,
|
||||||
HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) {
|
HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes) {
|
||||||
Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, lowerer, stampProvider,
|
Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, replacements);
|
||||||
replacements);
|
|
||||||
AMD64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), (AMD64) target.arch, GraalArithmeticStubs.getValue(options), false);
|
AMD64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), (AMD64) target.arch, GraalArithmeticStubs.getValue(options), false);
|
||||||
return plugins;
|
return plugins;
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user