diff --git a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java
index bea29235506..96f18961a95 100644
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java
@@ -52,8 +52,8 @@ import jdk.tools.jaotc.binformat.pecoff.JPECoffRelocObject;
*
*
* This class holds information necessary to create platform-specific binary containers such as
- * ELFContainer for Linux or MachOContainer for Mac OS or PEContainer
- * for MS Windows operating systems.
+ * ELFContainer for Linux or MachOContainer for Mac OS or PEContainer for MS Windows operating
+ * systems.
*
*
* Method APIs provided by this class are used to construct and populate platform-independent
@@ -300,7 +300,7 @@ public final class BinaryContainer implements SymbolTable {
this.codeEntryAlignment = graalHotSpotVMConfig.codeEntryAlignment;
- this.threadLocalHandshakes = graalHotSpotVMConfig.threadLocalHandshakes;
+ this.threadLocalHandshakes = graalHotSpotVMConfig.useThreadLocalPolling;
// Section unique name is limited to 8 characters due to limitation on Windows.
// Name could be longer but only first 8 characters are stored on Windows.
@@ -354,7 +354,7 @@ public final class BinaryContainer implements SymbolTable {
graphBuilderConfig.omitAssertions()));
if (JavaVersionUtil.JAVA_SPEC < 14) {
// See JDK-8220049. Thread local handshakes are on by default since JDK14, the command line option has been removed.
- booleanFlagsList.add(graalHotSpotVMConfig.threadLocalHandshakes);
+ booleanFlagsList.add(graalHotSpotVMConfig.useThreadLocalPolling);
}
ArrayList intFlagsList = new ArrayList<>();
@@ -432,6 +432,10 @@ public final class BinaryContainer implements SymbolTable {
return "_aot_stub_routines_crc_table_adr";
}
+ public static String getPollingPageSymbolName() {
+ return "_aot_polling_page";
+ }
+
public static String getResolveStaticEntrySymbolName() {
return "_resolve_static_entry";
}
@@ -508,6 +512,7 @@ public final class BinaryContainer implements SymbolTable {
createGotSymbol(getHeapEndAddressSymbolName());
createGotSymbol(getNarrowKlassBaseAddressSymbolName());
createGotSymbol(getNarrowOopBaseAddressSymbolName());
+ createGotSymbol(getPollingPageSymbolName());
createGotSymbol(getLogOfHeapRegionGrainBytesSymbolName());
createGotSymbol(getInlineContiguousAllocationSupportedSymbolName());
diff --git a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompilationTask.java b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompilationTask.java
index 192e3ef863e..6c8a47e8f1f 100644
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompilationTask.java
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompilationTask.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2020, 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
@@ -33,6 +33,7 @@ import org.graalvm.compiler.code.CompilationResult;
import org.graalvm.compiler.core.GraalCompilerOptions;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugContext.Activation;
+import org.graalvm.compiler.debug.DebugContext.Builder;
import org.graalvm.compiler.debug.TTY;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.printer.GraalDebugHandlersFactory;
@@ -118,7 +119,7 @@ final class AOTCompilationTask implements Runnable, Comparable {
CompilationResult compResult = null;
final long startTime = System.currentTimeMillis();
SnippetReflectionProvider snippetReflection = aotBackend.getProviders().getSnippetReflection();
- try (DebugContext debug = DebugContext.create(graalOptions, new GraalDebugHandlersFactory(snippetReflection)); Activation a = debug.activate()) {
+ try (DebugContext debug = new Builder(graalOptions, new GraalDebugHandlersFactory(snippetReflection)).build(); Activation a = debug.activate()) {
compResult = aotBackend.compileMethod(method, debug);
}
final long endTime = System.currentTimeMillis();
diff --git a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CallInfo.java b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CallInfo.java
index ecff0cffe15..de8699c5e2d 100644
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CallInfo.java
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CallInfo.java
@@ -26,6 +26,7 @@
package jdk.tools.jaotc;
import org.graalvm.compiler.bytecode.Bytecodes;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
import jdk.vm.ci.code.BytecodePosition;
import jdk.vm.ci.code.site.Call;
@@ -67,11 +68,11 @@ final class CallInfo {
}
static boolean isVirtualCall(CompiledMethodInfo methodInfo, Call call) {
- return isInvokeVirtual(call) && !methodInfo.hasMark(call, MarkId.INVOKESPECIAL) && !isStaticTarget(call);
+ return isInvokeVirtual(call) && !methodInfo.hasMark(call, HotSpotMarkId.INVOKESPECIAL) && !isStaticTarget(call);
}
static boolean isOptVirtualCall(CompiledMethodInfo methodInfo, Call call) {
- return isInvokeVirtual(call) && methodInfo.hasMark(call, MarkId.INVOKESPECIAL);
+ return isInvokeVirtual(call) && methodInfo.hasMark(call, HotSpotMarkId.INVOKESPECIAL);
}
private static boolean isJavaCall(Call call) {
diff --git a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CodeOffsets.java b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CodeOffsets.java
index 243c8b4da40..d59df0123a4 100644
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CodeOffsets.java
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CodeOffsets.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2020, 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
@@ -27,7 +27,8 @@ package jdk.tools.jaotc;
import java.util.List;
-import jdk.vm.ci.code.site.Mark;
+import org.graalvm.compiler.code.CompilationResult;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
final class CodeOffsets {
private final int entry;
@@ -42,34 +43,32 @@ final class CodeOffsets {
this.deoptHandler = deoptHandler;
}
- static CodeOffsets buildFrom(List marks) {
+ static CodeOffsets buildFrom(List marks) {
int entry = 0;
int verifiedEntry = 0;
int exceptionHandler = -1;
int deoptHandler = -1;
- for (Mark mark : marks) {
- if (mark.id instanceof Integer) {
- MarkId markId = MarkId.getEnum((int) mark.id);
- switch (markId) {
- case UNVERIFIED_ENTRY:
- entry = mark.pcOffset;
- break;
- case VERIFIED_ENTRY:
- verifiedEntry = mark.pcOffset;
- break;
- case OSR_ENTRY:
- // Unhandled
- break;
- case EXCEPTION_HANDLER_ENTRY:
- exceptionHandler = mark.pcOffset;
- break;
- case DEOPT_HANDLER_ENTRY:
- deoptHandler = mark.pcOffset;
- break;
- default:
- break; // Ignore others
- }
+ for (CompilationResult.CodeMark mark : marks) {
+ HotSpotMarkId markId = (HotSpotMarkId) mark.id;
+ switch (markId) {
+ case UNVERIFIED_ENTRY:
+ entry = mark.pcOffset;
+ break;
+ case VERIFIED_ENTRY:
+ verifiedEntry = mark.pcOffset;
+ break;
+ case OSR_ENTRY:
+ // Unhandled
+ break;
+ case EXCEPTION_HANDLER_ENTRY:
+ exceptionHandler = mark.pcOffset;
+ break;
+ case DEOPT_HANDLER_ENTRY:
+ deoptHandler = mark.pcOffset;
+ break;
+ default:
+ break; // Ignore others
}
}
return new CodeOffsets(entry, verifiedEntry, exceptionHandler, deoptHandler);
diff --git a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CompiledMethodInfo.java b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CompiledMethodInfo.java
index 9486edac158..e044c3519da 100644
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CompiledMethodInfo.java
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CompiledMethodInfo.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,17 +25,17 @@
package jdk.tools.jaotc;
-import java.util.concurrent.atomic.AtomicInteger;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.graalvm.compiler.code.CompilationResult;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
+
+import jdk.tools.jaotc.AOTCompiledClass.AOTKlassData;
import jdk.tools.jaotc.binformat.BinaryContainer;
import jdk.tools.jaotc.binformat.ReadOnlyDataContainer;
-import jdk.tools.jaotc.AOTCompiledClass.AOTKlassData;
-import org.graalvm.compiler.code.CompilationResult;
-
-import jdk.vm.ci.code.site.Mark;
-import jdk.vm.ci.code.site.Site;
+import jdk.vm.ci.code.site.Call;
import jdk.vm.ci.hotspot.HotSpotCompiledCode;
import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
@@ -306,23 +306,11 @@ final class CompiledMethodInfo {
return null;
}
- boolean hasMark(Site call, MarkId id) {
- for (Mark m : compilationResult.getMarks()) {
- int adjOffset = m.pcOffset;
- if (archStr.equals("aarch64")) {
- // The mark is at the end of a group of three instructions:
- // adrp; add; ldr
- adjOffset += 12;
- } else {
- // X64-specific code.
- // Call instructions are aligned to 8
- // bytes - 1 on x86 to patch address atomically,
- adjOffset = (adjOffset & (-8)) + 7;
- }
- // Mark points before aligning nops.
- if ((call.pcOffset == adjOffset) && MarkId.getEnum((int) m.id) == id) {
- return true;
- }
+ boolean hasMark(Call call, HotSpotMarkId id) {
+ assert id == HotSpotMarkId.INVOKESTATIC || id == HotSpotMarkId.INVOKESPECIAL;
+ CompilationResult.CodeMark mark = compilationResult.getAssociatedMark(call);
+ if (mark != null) {
+ return mark.id == id;
}
return false;
}
diff --git a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/JavaCallSiteRelocationSymbol.java b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/JavaCallSiteRelocationSymbol.java
index 705851dbe50..8f7ad70cba1 100644
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/JavaCallSiteRelocationSymbol.java
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/JavaCallSiteRelocationSymbol.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
package jdk.tools.jaotc;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
+
import jdk.tools.jaotc.binformat.BinaryContainer;
import jdk.tools.jaotc.binformat.Symbol;
import jdk.vm.ci.code.site.Call;
@@ -136,7 +138,7 @@ final class JavaCallSiteRelocationSymbol extends CallSiteRelocationSymbol {
private static String getResolveSymbolName(CompiledMethodInfo mi, Call call) {
String resolveSymbolName;
if (CallInfo.isStaticCall(call)) {
- assert mi.hasMark(call, MarkId.INVOKESTATIC);
+ assert mi.hasMark(call, HotSpotMarkId.INVOKESTATIC);
resolveSymbolName = BinaryContainer.getResolveStaticEntrySymbolName();
} else if (CallInfo.isSpecialCall(call)) {
resolveSymbolName = BinaryContainer.getResolveOptVirtualEntrySymbolName();
diff --git a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java
index 6970f430292..64082155959 100644
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2020, 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
@@ -31,6 +31,8 @@ import static org.graalvm.compiler.hotspot.meta.HotSpotAOTProfilingPlugin.Option
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
@@ -39,13 +41,12 @@ import java.util.ListIterator;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.stream.Stream;
-import java.nio.file.Files;
-import java.nio.file.Paths;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
import org.graalvm.compiler.api.runtime.GraalJVMCICompiler;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugContext.Activation;
+import org.graalvm.compiler.debug.DebugContext.Builder;
import org.graalvm.compiler.hotspot.CompilerConfigurationFactory;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.HotSpotGraalCompilerFactory;
@@ -232,12 +233,12 @@ public final class Main {
// The GC names are spelled the same in both enums, so no clever remapping is needed
// here.
String name = "CollectedHeap::" + graalGC.name();
- int gc = graalHotSpotVMConfig.getConstant(name, Integer.class, def);
+ int gc = graalHotSpotVMConfig.getConstant(name, Integer.class, def, true);
BinaryContainer binaryContainer = new BinaryContainer(graalOptions, graalHotSpotVMConfig, graphBuilderConfig, gc, JVM_VERSION);
DataBuilder dataBuilder = new DataBuilder(this, backend, classes, binaryContainer);
- try (DebugContext debug = DebugContext.create(graalOptions, new GraalDebugHandlersFactory(snippetReflection)); Activation a = debug.activate()) {
+ try (DebugContext debug = new Builder(graalOptions, new GraalDebugHandlersFactory(snippetReflection)).build(); Activation a = debug.activate()) {
dataBuilder.prepareData(debug);
}
diff --git a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkId.java b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkId.java
deleted file mode 100644
index 80174be5768..00000000000
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkId.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2016, 2020, 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 jdk.tools.jaotc;
-
-import java.util.HashMap;
-import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
-
-/**
- * Constants used to mark special positions in code being installed into the code cache by Graal C++
- * code.
- */
-enum MarkId {
- VERIFIED_ENTRY("CodeInstaller::VERIFIED_ENTRY"),
- UNVERIFIED_ENTRY("CodeInstaller::UNVERIFIED_ENTRY"),
- OSR_ENTRY("CodeInstaller::OSR_ENTRY"),
- EXCEPTION_HANDLER_ENTRY("CodeInstaller::EXCEPTION_HANDLER_ENTRY"),
- DEOPT_HANDLER_ENTRY("CodeInstaller::DEOPT_HANDLER_ENTRY"),
- INVOKEINTERFACE("CodeInstaller::INVOKEINTERFACE"),
- INVOKEVIRTUAL("CodeInstaller::INVOKEVIRTUAL"),
- INVOKESTATIC("CodeInstaller::INVOKESTATIC"),
- INVOKESPECIAL("CodeInstaller::INVOKESPECIAL"),
- INLINE_INVOKE("CodeInstaller::INLINE_INVOKE"),
- POLL_NEAR("CodeInstaller::POLL_NEAR"),
- POLL_RETURN_NEAR("CodeInstaller::POLL_RETURN_NEAR"),
- POLL_FAR("CodeInstaller::POLL_FAR"),
- POLL_RETURN_FAR("CodeInstaller::POLL_RETURN_FAR"),
- CARD_TABLE_ADDRESS("CodeInstaller::CARD_TABLE_ADDRESS"),
- HEAP_TOP_ADDRESS("CodeInstaller::HEAP_TOP_ADDRESS"),
- HEAP_END_ADDRESS("CodeInstaller::HEAP_END_ADDRESS"),
- NARROW_KLASS_BASE_ADDRESS("CodeInstaller::NARROW_KLASS_BASE_ADDRESS"),
- NARROW_OOP_BASE_ADDRESS("CodeInstaller::NARROW_OOP_BASE_ADDRESS"),
- CRC_TABLE_ADDRESS("CodeInstaller::CRC_TABLE_ADDRESS"),
- LOG_OF_HEAP_REGION_GRAIN_BYTES("CodeInstaller::LOG_OF_HEAP_REGION_GRAIN_BYTES"),
- INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED("CodeInstaller::INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED");
-
- private final int value;
- private static HashMap lookup = new HashMap<>();
-
- static {
- for (MarkId e : values()) {
- lookup.put(e.value, e);
- }
- }
-
- MarkId(String name) {
- this.value = (int) (long) HotSpotJVMCIRuntime.runtime().getConfigStore().getConstants().get(name);
- }
-
- static MarkId getEnum(int value) {
- MarkId e = lookup.get(value);
- if (e == null) {
- throw new InternalError("Unknown enum value: " + value);
- }
- return e;
- }
-}
diff --git a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkProcessor.java b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkProcessor.java
index 606cc709ddd..32b80b653f5 100644
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkProcessor.java
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkProcessor.java
@@ -25,11 +25,13 @@
package jdk.tools.jaotc;
+import org.graalvm.compiler.code.CompilationResult;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
+
import jdk.tools.jaotc.binformat.BinaryContainer;
import jdk.tools.jaotc.binformat.Relocation;
import jdk.tools.jaotc.binformat.Relocation.RelocType;
import jdk.tools.jaotc.binformat.Symbol;
-
import jdk.vm.ci.code.site.Mark;
final class MarkProcessor {
@@ -48,8 +50,8 @@ final class MarkProcessor {
* @param mark mark being processed
*/
@SuppressWarnings("fallthrough")
- void process(CompiledMethodInfo methodInfo, Mark mark) {
- MarkId markId = MarkId.getEnum((int) mark.id);
+ void process(CompiledMethodInfo methodInfo, CompilationResult.CodeMark mark) {
+ HotSpotMarkId markId = (HotSpotMarkId) mark.id;
switch (markId) {
case EXCEPTION_HANDLER_ENTRY:
case DEOPT_HANDLER_ENTRY:
@@ -62,24 +64,19 @@ final class MarkProcessor {
}
// fallthrough
case CARD_TABLE_ADDRESS:
- case HEAP_TOP_ADDRESS:
- case HEAP_END_ADDRESS:
case NARROW_KLASS_BASE_ADDRESS:
case NARROW_OOP_BASE_ADDRESS:
case CRC_TABLE_ADDRESS:
case LOG_OF_HEAP_REGION_GRAIN_BYTES:
- case INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED:
String vmSymbolName;
switch (markId) {
+ case POLL_FAR:
+ case POLL_RETURN_FAR:
+ vmSymbolName = BinaryContainer.getPollingPageSymbolName();
+ break;
case CARD_TABLE_ADDRESS:
vmSymbolName = BinaryContainer.getCardTableAddressSymbolName();
break;
- case HEAP_TOP_ADDRESS:
- vmSymbolName = BinaryContainer.getHeapTopAddressSymbolName();
- break;
- case HEAP_END_ADDRESS:
- vmSymbolName = BinaryContainer.getHeapEndAddressSymbolName();
- break;
case NARROW_KLASS_BASE_ADDRESS:
vmSymbolName = BinaryContainer.getNarrowKlassBaseAddressSymbolName();
break;
@@ -92,9 +89,6 @@ final class MarkProcessor {
case LOG_OF_HEAP_REGION_GRAIN_BYTES:
vmSymbolName = BinaryContainer.getLogOfHeapRegionGrainBytesSymbolName();
break;
- case INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED:
- vmSymbolName = BinaryContainer.getInlineContiguousAllocationSupportedSymbolName();
- break;
default:
throw new InternalError("Unhandled mark: " + mark);
}
@@ -109,6 +103,7 @@ final class MarkProcessor {
case VERIFIED_ENTRY:
case UNVERIFIED_ENTRY:
case OSR_ENTRY:
+ case FRAME_COMPLETE:
case INVOKEINTERFACE:
case INVOKEVIRTUAL:
case INVOKESTATIC:
diff --git a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MetadataBuilder.java b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MetadataBuilder.java
index 562651b3f56..b68064e0947 100644
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MetadataBuilder.java
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MetadataBuilder.java
@@ -236,7 +236,7 @@ final class MetadataBuilder {
infopointProcessor.process(methodInfo, infoPoint);
}
- for (Mark mark : compilationResult.getMarks()) {
+ for (CompilationResult.CodeMark mark : compilationResult.getMarks()) {
markProcessor.process(methodInfo, mark);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicMap.java b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicMap.java
index 02af6d941c2..5fe2eb7bdcc 100644
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicMap.java
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicMap.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -45,7 +45,26 @@ import java.util.Map;
import java.util.function.BiFunction;
/**
- * Memory efficient map data structure.
+ * Memory efficient map data structure that dynamically changes its representation depending on the
+ * number of entries and is specially optimized for small number of entries. It keeps elements in a
+ * linear list without any hashing when the number of entries is small. Should an actual hash data
+ * structure be necessary, it tries to fit the hash value into as few bytes as possible. In contrast
+ * to {@link java.util.HashMap}, it avoids allocating an extra node object per entry and rather
+ * keeps values always in a plain array. See {@link EconomicMapImpl} for implementation details and
+ * exact thresholds when its representation changes.
+ *
+ * It supports a {@code null} value, but it does not support adding or looking up a {@code null}
+ * key. Operations {@code get} and {@code put} provide constant-time performance on average if
+ * repeatedly performed. They can however trigger an operation growing or compressing the data
+ * structure, which is linear in the number of elements. Iteration is also linear in the number of
+ * elements.
+ *
+ * The implementation is not synchronized. If multiple threads want to access the data structure, it
+ * requires manual synchronization, for example using {@link java.util.Collections#synchronizedMap}.
+ * There is also no extra precaution to detect concurrent modification while iterating.
+ *
+ * Different strategies for the equality comparison can be configured by providing a
+ * {@link Equivalence} configuration object.
*
* @since 19.0
*/
@@ -53,7 +72,8 @@ public interface EconomicMap extends UnmodifiableEconomicMap {
/**
* Associates {@code value} with {@code key} in this map. If the map previously contained a
- * mapping for {@code key}, the old value is replaced by {@code value}.
+ * mapping for {@code key}, the old value is replaced by {@code value}. While the {@code value}
+ * may be {@code null}, the {@code key} must not be {code null}.
*
* @return the previous value associated with {@code key}, or {@code null} if there was no
* mapping for {@code key}.
@@ -94,7 +114,7 @@ public interface EconomicMap extends UnmodifiableEconomicMap {
/**
* Removes the mapping for {@code key} from this map if it is present. The map will not contain
- * a mapping for {@code key} once the call returns.
+ * a mapping for {@code key} once the call returns. The {@code key} must not be {@code null}.
*
* @return the previous value associated with {@code key}, or {@code null} if there was no
* mapping for {@code key}.
diff --git a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicMapImpl.java b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicMapImpl.java
index 59560a250a0..3250ab52597 100644
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicMapImpl.java
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicMapImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, 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
@@ -41,7 +41,6 @@
package jdk.internal.vm.compiler.collections;
import java.util.Iterator;
-import java.util.Objects;
import java.util.function.BiFunction;
/**
@@ -240,7 +239,7 @@ final class EconomicMapImpl implements EconomicMap, EconomicSet {
@SuppressWarnings("unchecked")
@Override
public V get(K key) {
- Objects.requireNonNull(key);
+ checkKeyNonNull(key);
int index = find(key);
if (index != -1) {
@@ -420,9 +419,7 @@ final class EconomicMapImpl implements EconomicMap, EconomicSet {
@SuppressWarnings("unchecked")
@Override
public V put(K key, V value) {
- if (key == null) {
- throw new UnsupportedOperationException("null not supported as key!");
- }
+ checkKeyNonNull(key);
int index = find(key);
if (index != -1) {
Object oldValue = getValue(index);
@@ -622,9 +619,7 @@ final class EconomicMapImpl implements EconomicMap, EconomicSet {
@SuppressWarnings("unchecked")
@Override
public V removeKey(K key) {
- if (key == null) {
- throw new UnsupportedOperationException("null not supported as key!");
- }
+ checkKeyNonNull(key);
int index;
if (hasHashArray()) {
index = this.findAndRemoveHash(key);
@@ -640,6 +635,12 @@ final class EconomicMapImpl implements EconomicMap, EconomicSet {
return null;
}
+ private void checkKeyNonNull(K key) {
+ if (key == null) {
+ throw new UnsupportedOperationException("null not supported as key!");
+ }
+ }
+
/**
* Removes the element at the specific index and returns the index of the next element. This can
* be a different value if graph compression was triggered.
diff --git a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableEconomicMap.java b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableEconomicMap.java
index 8a1851a337b..4d22ab60261 100644
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableEconomicMap.java
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableEconomicMap.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, 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
@@ -41,7 +41,8 @@
package jdk.internal.vm.compiler.collections;
/**
- * Unmodifiable memory efficient map data structure.
+ * Unmodifiable memory efficient map. See {@link EconomicMap} for the underlying data structure and
+ * its properties.
*
* @since 19.0
*/
@@ -49,7 +50,7 @@ public interface UnmodifiableEconomicMap {
/**
* Returns the value to which {@code key} is mapped, or {@code null} if this map contains no
- * mapping for {@code key}.
+ * mapping for {@code key}. The {@code key} must not be {@code null}.
*
* @since 19.0
*/
@@ -57,7 +58,7 @@ public interface UnmodifiableEconomicMap {
/**
* Returns the value to which {@code key} is mapped, or {@code defaultValue} if this map
- * contains no mapping for {@code key}.
+ * contains no mapping for {@code key}. The {@code key} must not be {@code null}.
*
* @since 19.0
*/
@@ -70,7 +71,8 @@ public interface UnmodifiableEconomicMap {
}
/**
- * Returns {@code true} if this map contains a mapping for {@code key}.
+ * Returns {@code true} if this map contains a mapping for {@code key}. Returns always
+ * {@code false} if the {@code key} is {@code null}.
*
* @since 19.0
*/
diff --git a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/LibGraal.java b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/LibGraal.java
index 03cc1f93a04..33c8c67ee3c 100644
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/LibGraal.java
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/LibGraal.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,8 @@
package jdk.internal.vm.compiler.libgraal;
-import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
+
import jdk.vm.ci.hotspot.HotSpotSpeculationLog;
import jdk.vm.ci.services.Services;
@@ -33,8 +34,13 @@ import jdk.vm.ci.services.Services;
*/
public class LibGraal {
+ static {
+ // Initialize JVMCI to ensure JVMCI opens its packages to Graal.
+ Services.initializeJVMCI();
+ }
+
public static boolean isAvailable() {
- return inLibGraal() || isolate != 0L;
+ return inLibGraal() || theIsolate != 0L;
}
public static boolean isSupported() {
@@ -45,67 +51,63 @@ public class LibGraal {
return Services.IS_IN_NATIVE_IMAGE;
}
- public static void registerNativeMethods(HotSpotJVMCIRuntime runtime, Class> clazz) {
+ public static void registerNativeMethods(Class> clazz) {
if (clazz.isPrimitive()) {
throw new IllegalArgumentException();
}
if (inLibGraal() || !isAvailable()) {
throw new IllegalStateException();
}
- runtime.registerNativeMethods(clazz);
+ runtime().registerNativeMethods(clazz);
}
- public static long translate(HotSpotJVMCIRuntime runtime, Object obj) {
+ public static long translate(Object obj) {
if (!isAvailable()) {
throw new IllegalStateException();
}
if (!inLibGraal() && LibGraalScope.currentScope.get() == null) {
throw new IllegalStateException("Not within a " + LibGraalScope.class.getName());
}
- return runtime.translate(obj);
+ return runtime().translate(obj);
}
- public static T unhand(HotSpotJVMCIRuntime runtime, Class type, long handle) {
+ public static T unhand(Class type, long handle) {
if (!isAvailable()) {
throw new IllegalStateException();
}
if (!inLibGraal() && LibGraalScope.currentScope.get() == null) {
throw new IllegalStateException("Not within a " + LibGraalScope.class.getName());
}
- return runtime.unhand(type, handle);
+ return runtime().unhand(type, handle);
}
private static long initializeLibgraal() {
try {
- // Initialize JVMCI to ensure JVMCI opens its packages to
- // Graal otherwise the call to HotSpotJVMCIRuntime.runtime()
- // below will fail on JDK13+.
- Services.initializeJVMCI();
-
- HotSpotJVMCIRuntime runtime = HotSpotJVMCIRuntime.runtime();
- long[] nativeInterface = runtime.registerNativeMethods(LibGraal.class);
- return nativeInterface[1];
+ long[] javaVMInfo = runtime().registerNativeMethods(LibGraalScope.class);
+ return javaVMInfo[1];
} catch (UnsupportedOperationException e) {
return 0L;
}
}
- static final long isolate = Services.IS_BUILDING_NATIVE_IMAGE ? 0L : initializeLibgraal();
+ static final long theIsolate = Services.IS_BUILDING_NATIVE_IMAGE ? 0L : initializeLibgraal();
- static boolean isCurrentThreadAttached(HotSpotJVMCIRuntime runtime) {
- return runtime.isCurrentThreadAttached();
+ static boolean isCurrentThreadAttached() {
+ return runtime().isCurrentThreadAttached();
}
- public static boolean attachCurrentThread(HotSpotJVMCIRuntime runtime, boolean isDaemon) {
- return runtime.attachCurrentThread(isDaemon);
+ public static boolean attachCurrentThread(boolean isDaemon, long[] isolate) {
+ if (isolate != null) {
+ isolate[0] = LibGraal.theIsolate;
+ }
+ return runtime().attachCurrentThread(isDaemon);
}
- public static void detachCurrentThread(HotSpotJVMCIRuntime runtime) {
- runtime.detachCurrentThread();
+ public static boolean detachCurrentThread(boolean release) {
+ runtime().detachCurrentThread();
+ return false;
}
- static native long getCurrentIsolateThread(long iso);
-
public static long getFailedSpeculationsAddress(HotSpotSpeculationLog log) {
return log.getFailedSpeculationsAddress();
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/LibGraalIsolate.java b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/LibGraalIsolate.java
new file mode 100644
index 00000000000..b313ba53f77
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/LibGraalIsolate.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2020, 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 jdk.internal.vm.compiler.libgraal;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Supplier;
+
+/**
+ * Represents a single libgraal isolate. All {@link LibGraalObject}s have a {@link LibGraalIsolate}
+ * context.
+ */
+public final class LibGraalIsolate {
+
+ final long address;
+
+ private static final Map isolates = new HashMap<>();
+
+ static synchronized LibGraalIsolate forAddress(long isolateAddress) {
+ return isolates.computeIfAbsent(isolateAddress, a -> new LibGraalIsolate(a));
+ }
+
+ private LibGraalIsolate(long address) {
+ this.address = address;
+ }
+
+ /**
+ * Gets the isolate associated with the current thread. The current thread must be in an
+ * {@linkplain LibGraalScope opened} scope.
+ *
+ * @throws IllegalStateException if the current thread is not attached to libgraal
+ */
+ public static LibGraalIsolate current() {
+ return LibGraalScope.current().getIsolate();
+ }
+
+ /**
+ * Gets the value corresponding to {@code key} from a key-value store of singleton objects. If
+ * no value corresponding to {@code key} currently exists, then it is computed with
+ * {@code supplier} and inserted in the store.
+ *
+ * This is used to obtain objects whose lifetime is bound to the isolate represented by this
+ * object.
+ */
+ @SuppressWarnings("unchecked")
+ public synchronized T getSingleton(Class key, Supplier supplier) {
+ // Cannot use HahsMap.computeIfAbsent as it will throw a ConcurrentModificationException
+ // if supplier recurses here to compute another singleton.
+ if (!singletons.containsKey(key)) {
+ singletons.put(key, supplier.get());
+ }
+ return (T) singletons.get(key);
+ }
+
+ private final Map, Object> singletons = new HashMap<>();
+
+ /**
+ * Strong references to the {@link WeakReference} objects.
+ */
+ private final Set cleaners = Collections.newSetFromMap(new ConcurrentHashMap<>());
+
+ void register(LibGraalObject obj, long handle) {
+ cleanHandles();
+ Cleaner cref = new Cleaner(cleanersQueue, obj, handle);
+ cleaners.add(cref);
+ }
+
+ /**
+ * Processes {@link #cleanersQueue} to release any handles whose {@link LibGraalObject} objects
+ * are now unreachable.
+ */
+ private void cleanHandles() {
+ Cleaner cleaner;
+ while ((cleaner = (Cleaner) cleanersQueue.poll()) != null) {
+ cleaners.remove(cleaner);
+ if (!cleaner.clean()) {
+ new Exception(String.format("Error releasing handle %d in isolate 0x%x", cleaner.handle, address)).printStackTrace(System.out);
+ }
+ }
+ }
+
+ /**
+ * Queue into which a {@link Cleaner} is enqueued when its {@link LibGraalObject} referent
+ * becomes unreachable.
+ */
+ private final ReferenceQueue cleanersQueue = new ReferenceQueue<>();
+
+ private static final class Cleaner extends WeakReference {
+ private final long handle;
+
+ Cleaner(ReferenceQueue cleanersQueue, LibGraalObject referent, long handle) {
+ super(referent, cleanersQueue);
+ this.handle = handle;
+ }
+
+ boolean clean() {
+ return LibGraalObject.releaseHandle(LibGraalScope.getIsolateThread(), handle);
+ }
+ }
+
+ /**
+ * Notifies that the {@code JavaVM} associated with {@code isolate} has been destroyed. All
+ * subsequent accesses to objects in the isolate will throw an {@link IllegalArgumentException}.
+ */
+ static synchronized void remove(LibGraalIsolate isolate) {
+ isolate.destroyed = true;
+ LibGraalIsolate removed = isolates.remove(isolate.address);
+ assert removed == isolate : "isolate already removed or overwritten: " + isolate;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s[0x%x]", getClass().getSimpleName(), address);
+ }
+
+ private boolean destroyed;
+
+ public boolean isValid() {
+ return !destroyed;
+ }
+
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/LibGraalObject.java b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/LibGraalObject.java
new file mode 100644
index 00000000000..2bdf5bf0a29
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/LibGraalObject.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2020, 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 jdk.internal.vm.compiler.libgraal;
+
+/**
+ * Encapsulates a handle to an object in a libgraal isolate where the object's lifetime is bound to
+ * the lifetime of the {@link LibGraalObject} instance. At some point after a {@link LibGraalObject}
+ * is garbage collected, a call is made to release the handle, allowing the libgraal object to be
+ * collected.
+ */
+public class LibGraalObject {
+
+ static {
+ if (LibGraal.isAvailable()) {
+ LibGraal.registerNativeMethods(LibGraalObject.class);
+ }
+ }
+
+ /**
+ * Handle to an object in {@link #isolate}.
+ */
+ private final long handle;
+
+ /**
+ * The libgraal isolate containing {@link #handle}.
+ */
+ private final LibGraalIsolate isolate;
+
+ /**
+ * Creates a new {@link LibGraalObject}.
+ *
+ * @param handle handle to an object in a libgraal isolate
+ */
+ protected LibGraalObject(long handle) {
+ this.handle = handle;
+ isolate = LibGraalScope.current().getIsolate();
+ isolate.register(this, handle);
+ }
+
+ /**
+ * Gets the raw JNI handle wrapped by this object.
+ *
+ * @throw {@link IllegalArgumentException} if the isolate context for the handle has destroyed.
+ */
+ public long getHandle() {
+ if (!isolate.isValid()) {
+ throw new IllegalArgumentException(toString());
+ }
+ return handle;
+ }
+
+ /**
+ * Releases {@code handle} in the isolate denoted by {@code isolateThreadId}.
+ *
+ * @return {@code false} if {@code} is not a valid handle in the isolate
+ */
+ // Implementation:
+ // com.oracle.svm.graal.hotspot.libgraal.LibGraalEntryPoints.releaseHandle
+ static native boolean releaseHandle(long isolateThreadId, long handle);
+
+ @Override
+ public String toString() {
+ String name = getClass().getSimpleName();
+ Class> outer = getClass().getDeclaringClass();
+ while (outer != null) {
+ name = outer.getSimpleName() + '.' + name;
+ outer = outer.getDeclaringClass();
+ }
+ return String.format("%s[%d]", name, handle);
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/LibGraalScope.java b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/LibGraalScope.java
index 00395429b68..4450815e3da 100644
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/LibGraalScope.java
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/LibGraalScope.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,37 +24,92 @@
package jdk.internal.vm.compiler.libgraal;
-import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
+import java.lang.reflect.Method;
+import java.util.Arrays;
/**
- * Scope for calling CEntryPoints in libgraal. {@linkplain #LibGraalScope(HotSpotJVMCIRuntime)
- * Opening} a scope attaches the current thread to libgraal and {@linkplain #close() closing} it
+ * Scope for calling CEntryPoints in libgraal. {@linkplain #LibGraalScope() Opening} a scope ensures
+ * the current thread is attached to libgraal and {@linkplain #close() closing} the outer most scope
* detaches the current thread.
*/
public final class LibGraalScope implements AutoCloseable {
static final ThreadLocal currentScope = new ThreadLocal<>();
+ /**
+ * Shared state between a thread's nested scopes.
+ */
+ static class Shared {
+ final DetachAction detachAction;
+ final LibGraalIsolate isolate;
+ final long isolateThread;
+
+ Shared(DetachAction detachAction, LibGraalIsolate isolate, long isolateThread) {
+ this.detachAction = detachAction;
+ this.isolate = isolate;
+ this.isolateThread = isolateThread;
+ }
+ }
+
private final LibGraalScope parent;
- private final boolean topLevel;
- private final HotSpotJVMCIRuntime runtime;
- private final long isolateThread;
+ private final Shared shared;
+
+ /**
+ * Gets the current scope.
+ *
+ * @throws IllegalStateException if the current thread is not in an {@linkplain #LibGraalScope()
+ * opened} scope
+ */
+ public static LibGraalScope current() {
+ LibGraalScope scope = currentScope.get();
+ if (scope == null) {
+ throw new IllegalStateException("Not in an " + LibGraalScope.class.getSimpleName());
+ }
+ return scope;
+ }
/**
* Gets the isolate thread associated with the current thread. The current thread must be in an
- * {@linkplain #LibGraalScope(HotSpotJVMCIRuntime) opened} scope.
+ * {@linkplain #LibGraalScope() opened} scope.
*
* @returns a value that can be used for the IsolateThreadContext argument of a {@code native}
* method {@link LibGraal#registerNativeMethods linked} to a CEntryPoint function in
* libgraal
- * @throws IllegalStateException if not the current thread is not attached to libgraal
+ * @throws IllegalStateException if the current thread is not attached to libgraal
*/
public static long getIsolateThread() {
- LibGraalScope scope = currentScope.get();
- if (scope == null) {
- throw new IllegalStateException("Cannot get isolate thread outside of a " + LibGraalScope.class.getSimpleName());
- }
- return scope.isolateThread;
+ return current().shared.isolateThread;
+ }
+
+ /**
+ * Denotes the detach action to perform when closing a {@link LibGraalScope}.
+ */
+ public enum DetachAction {
+ /**
+ * Detach the thread from its libgraal isolate.
+ */
+ DETACH,
+
+ /**
+ * Detach the thread from its libgraal isolate and the associated {@code JVMCIRuntime}.
+ */
+ DETACH_RUNTIME,
+
+ /**
+ * Detach the thread from its libgraal isolate and the associated {@code JVMCIRuntime}. If
+ * the VM supports releasing the {@code JavaVM} associated with {@code JVMCIRuntime}s and
+ * this is the last thread attached to its {@code JVMCIRuntime}, then the
+ * {@code JVMCIRuntime} destroys its {@code JavaVM} instance.
+ */
+ DETACH_RUNTIME_AND_RELEASE
+ }
+
+ /**
+ * Shortcut for calling {@link #LibGraalScope(DetachAction)} with an argument of
+ * {@link DetachAction#DETACH_RUNTIME}.
+ */
+ public LibGraalScope() {
+ this(DetachAction.DETACH_RUNTIME);
}
/**
@@ -69,28 +124,183 @@ public final class LibGraalScope implements AutoCloseable {
* @throws IllegalStateException if libgraal is {@linkplain LibGraal#isAvailable() unavailable}
* or {@link LibGraal#inLibGraal()} returns true
*/
- public LibGraalScope(HotSpotJVMCIRuntime runtime) {
+ public LibGraalScope(DetachAction detachAction) {
if (LibGraal.inLibGraal() || !LibGraal.isAvailable()) {
throw new IllegalStateException();
}
- this.runtime = runtime;
parent = currentScope.get();
- boolean top = false;
if (parent == null) {
- top = LibGraal.attachCurrentThread(runtime, false);
- isolateThread = LibGraal.getCurrentIsolateThread(LibGraal.isolate);
+ long[] isolateBox = {0};
+ boolean firstAttach = LibGraal.attachCurrentThread(false, isolateBox);
+ long isolateAddress = isolateBox[0];
+ LibGraalIsolate isolate = LibGraalIsolate.forAddress(isolateAddress);
+ long isolateThread = getIsolateThreadIn(isolateAddress);
+ shared = new Shared(firstAttach ? detachAction : null, isolate, isolateThread);
} else {
- isolateThread = parent.isolateThread;
+ shared = parent.shared;
}
- topLevel = top;
currentScope.set(this);
}
+ /**
+ * Enters a scope for making calls into an existing libgraal isolate. If there is no existing
+ * libgraal scope for the current thread, the current thread is attached to libgraal. When the
+ * outer most scope is closed, the current thread is detached from libgraal.
+ *
+ * This must be used in a try-with-resources statement.
+ *
+ * This cannot be called from {@linkplain LibGraal#inLibGraal() within} libgraal.
+ *
+ * @throws IllegalStateException if libgraal is {@linkplain LibGraal#isAvailable() unavailable}
+ * or {@link LibGraal#inLibGraal()} returns true
+ */
+ public LibGraalScope(long isolateAddress) {
+ if (LibGraal.inLibGraal() || !LibGraal.isAvailable()) {
+ throw new IllegalStateException();
+ }
+ parent = currentScope.get();
+ if (parent == null) {
+ long isolateThread = getIsolateThreadIn(isolateAddress);
+ boolean alreadyAttached;
+ if (isolateThread == 0L) {
+ alreadyAttached = false;
+ isolateThread = attachThreadTo(isolateAddress);
+ } else {
+ alreadyAttached = true;
+ }
+ LibGraalIsolate isolate = LibGraalIsolate.forAddress(isolateAddress);
+ shared = new Shared(alreadyAttached ? null : DetachAction.DETACH, isolate, isolateThread);
+ } else {
+ shared = parent.shared;
+ }
+ currentScope.set(this);
+ }
+
+ /**
+ * Attaches the current thread to the isolate at {@code isolateAddress}.
+ *
+ * @return the address of the attached IsolateThread
+ */
+ // Implementation:
+ // com.oracle.svm.graal.hotspot.libgraal.LibGraalEntryPoints.attachThreadTo
+ static native long attachThreadTo(long isolateAddress);
+
+ /**
+ * Detaches the current thread from the isolate at {@code isolateAddress}.
+ */
+ // Implementation:
+ // com.oracle.svm.graal.hotspot.libgraal.LibGraalEntryPoints.detachThreadFrom
+ static native void detachThreadFrom(long isolateThreadAddress);
+
+ /**
+ * Gets the isolate thread for the current thread in the isolate at {@code isolateAddress}.
+ *
+ * @return 0L if the current thread is not attached to the isolate at {@code isolateAddress}
+ */
+ // Implementation:
+ // com.oracle.svm.graal.hotspot.libgraal.LibGraalEntryPoints.getIsolateThreadIn
+ @SuppressWarnings("unused")
+ static native long getIsolateThreadIn(long isolateAddress);
+
+ /**
+ * Gets the isolate associated with this scope.
+ */
+ public LibGraalIsolate getIsolate() {
+ return shared.isolate;
+ }
+
+ /**
+ * Gets the address of the isolate thread associated with this scope.
+ */
+ public long getIsolateThreadAddress() {
+ return shared.isolateThread;
+ }
+
@Override
public void close() {
- if (topLevel) {
- LibGraal.detachCurrentThread(runtime);
+ if (parent == null && shared.detachAction != null) {
+ if (shared.detachAction == DetachAction.DETACH) {
+ detachThreadFrom(shared.isolateThread);
+ } else {
+ boolean isolateDestroyed = LibGraal.detachCurrentThread(shared.detachAction == DetachAction.DETACH_RUNTIME_AND_RELEASE);
+ if (isolateDestroyed) {
+ LibGraalIsolate.remove(shared.isolate);
+ }
+ }
}
currentScope.set(parent);
}
+
+ // Shared support for the LibGraal overlays
+
+ /**
+ * Convenience function for wrapping varargs into an array for use in calls to
+ * {@link #method(Class, String, Class[][])}.
+ */
+ static Class>[] sig(Class>... types) {
+ return types;
+ }
+
+ /**
+ * Gets the method in {@code declaringClass} with the unique name {@code name}.
+ *
+ * @param sigs the signatures the method may have
+ */
+ static Method method(Class> declaringClass, String name, Class>[]... sigs) {
+ if (sigs.length == 1 || sigs.length == 0) {
+ try {
+ Class>[] sig = sigs.length == 1 ? sigs[0] : new Class>[0];
+ return declaringClass.getDeclaredMethod(name, sig);
+ } catch (NoSuchMethodException | SecurityException e) {
+ throw (NoSuchMethodError) new NoSuchMethodError(name).initCause(e);
+ }
+ }
+ Method match = null;
+ for (Method m : declaringClass.getDeclaredMethods()) {
+ if (m.getName().equals(name)) {
+ if (match != null) {
+ throw new InternalError(String.format("Expected single method named %s, found %s and %s",
+ name, match, m));
+ }
+ match = m;
+ }
+ }
+ if (match == null) {
+ throw new NoSuchMethodError("Cannot find method " + name + " in " + declaringClass.getName());
+ }
+ Class>[] parameterTypes = match.getParameterTypes();
+ for (Class>[] sig : sigs) {
+ if (Arrays.equals(parameterTypes, sig)) {
+ return match;
+ }
+ }
+ throw new NoSuchMethodError(String.format("Unexpected signature for %s: %s", name, Arrays.toString(parameterTypes)));
+ }
+
+ /**
+ * Gets the method in {@code declaringClass} with the unique name {@code name} or {@code null}
+ * if not found.
+ *
+ * @param sigs the signatures the method may have
+ */
+ static Method methodOrNull(Class> declaringClass, String name, Class>[]... sigs) {
+ try {
+ return method(declaringClass, name, sigs);
+ } catch (NoSuchMethodError e) {
+ return null;
+ }
+ }
+
+ /**
+ * Gets the method in {@code declaringClass} with the unique name {@code name} or {@code null}
+ * if {@code guard == null}.
+ *
+ * @param sigs the signatures the method may have
+ */
+ static Method methodIf(Object guard, Class> declaringClass, String name, Class>[]... sigs) {
+ if (guard == null) {
+ return null;
+ }
+ return method(declaringClass, name, sigs);
+ }
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64.test/src/org/graalvm/compiler/asm/aarch64/test/TestProtectedAssembler.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64.test/src/org/graalvm/compiler/asm/aarch64/test/TestProtectedAssembler.java
index 9b5ea0dfdf1..bbab79683ab 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64.test/src/org/graalvm/compiler/asm/aarch64/test/TestProtectedAssembler.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64.test/src/org/graalvm/compiler/asm/aarch64/test/TestProtectedAssembler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, 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
@@ -132,16 +132,6 @@ class TestProtectedAssembler extends AArch64Assembler {
super.stxr(size, rs, rt, rn);
}
- @Override
- protected void ldar(int size, Register rt, Register rn) {
- super.ldar(size, rt, rn);
- }
-
- @Override
- protected void stlr(int size, Register rt, Register rn) {
- super.stlr(size, rt, rn);
- }
-
@Override
public void ldaxr(int size, Register rt, Register rn) {
super.ldaxr(size, rt, rn);
@@ -258,7 +248,7 @@ class TestProtectedAssembler extends AArch64Assembler {
}
@Override
- protected void sub(int size, Register dst, Register src1, Register src2, ExtendType extendType, int shiftAmt) {
+ public void sub(int size, Register dst, Register src1, Register src2, ExtendType extendType, int shiftAmt) {
super.sub(size, dst, src1, src2, extendType, shiftAmt);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64Assembler.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64Assembler.java
index fc85ea90a48..db9a289e5ee 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64Assembler.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64Assembler.java
@@ -56,6 +56,7 @@ import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CSIN
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.CSNEG;
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.DC;
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.DMB;
+import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.DSB;
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.EON;
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.EOR;
import static org.graalvm.compiler.asm.aarch64.AArch64Assembler.Instruction.EXTR;
@@ -673,6 +674,7 @@ public abstract class AArch64Assembler extends Assembler {
CLREX(0xd5033f5f),
HINT(0xD503201F),
DMB(0x000000A0),
+ DSB(0x00000080),
MRS(0xD5300000),
MSR(0xD5100000),
@@ -1402,7 +1404,7 @@ public abstract class AArch64Assembler extends Assembler {
* @param rt general purpose register. May not be null or stackpointer.
* @param rn general purpose register.
*/
- protected void ldar(int size, Register rt, Register rn) {
+ public void ldar(int size, Register rt, Register rn) {
assert size == 8 || size == 16 || size == 32 || size == 64;
int transferSize = NumUtil.log2Ceil(size / 8);
exclusiveLoadInstruction(LDAR, rt, rn, transferSize);
@@ -1415,7 +1417,7 @@ public abstract class AArch64Assembler extends Assembler {
* @param rt general purpose register. May not be null or stackpointer.
* @param rn general purpose register.
*/
- protected void stlr(int size, Register rt, Register rn) {
+ public void stlr(int size, Register rt, Register rn) {
assert size == 8 || size == 16 || size == 32 || size == 64;
int transferSize = NumUtil.log2Ceil(size / 8);
// Hack: Passing the zero-register means it is ignored when building the encoding.
@@ -1471,7 +1473,7 @@ public abstract class AArch64Assembler extends Assembler {
*/
private void exclusiveStoreInstruction(Instruction instr, Register rs, Register rt, Register rn, int log2TransferSize) {
assert log2TransferSize >= 0 && log2TransferSize < 4;
- assert rt.getRegisterCategory().equals(CPU) && rs.getRegisterCategory().equals(CPU) && !rs.equals(rt);
+ assert rt.getRegisterCategory().equals(CPU) && rs.getRegisterCategory().equals(CPU) && (instr == STLR || !rs.equals(rt));
int transferSizeEncoding = log2TransferSize << LoadStoreTransferSizeOffset;
emitInt(transferSizeEncoding | instr.encoding | rs2(rs) | rn(rn) | rt(rt));
}
@@ -1992,7 +1994,7 @@ public abstract class AArch64Assembler extends Assembler {
* @param extendType defines how src2 is extended to the same size as src1.
* @param shiftAmt must be in range 0 to 4.
*/
- protected void sub(int size, Register dst, Register src1, Register src2, ExtendType extendType, int shiftAmt) {
+ public void sub(int size, Register dst, Register src1, Register src2, ExtendType extendType, int shiftAmt) {
assert !dst.equals(zr);
assert !src1.equals(zr);
assert !src2.equals(sp);
@@ -3012,6 +3014,15 @@ public abstract class AArch64Assembler extends Assembler {
emitInt(DMB.encoding | BarrierOp | barrierKind.encoding << BarrierKindOffset);
}
+ /**
+ * Data Synchronization Barrier.
+ *
+ * @param barrierKind barrier that is issued. May not be null.
+ */
+ public void dsb(BarrierKind barrierKind) {
+ emitInt(DSB.encoding | BarrierOp | barrierKind.encoding << BarrierKindOffset);
+ }
+
/**
* Instruction Synchronization Barrier.
*/
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64MacroAssembler.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64MacroAssembler.java
index 743fc0647c6..564d9a17718 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64MacroAssembler.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64MacroAssembler.java
@@ -2138,6 +2138,14 @@ public class AArch64MacroAssembler extends AArch64Assembler {
super.hint(SystemHint.CSDB);
}
+ /**
+ * Ensures current execution state is committed before continuing.
+ */
+ public void fullSystemBarrier() {
+ super.dsb(BarrierKind.SYSTEM);
+ super.isb();
+ }
+
/**
* Same as {@link #nop()}.
*/
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java
index 1813e003a46..ec13c045a67 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java
@@ -107,7 +107,8 @@ public class AMD64Assembler extends AMD64BaseAssembler {
public static class Options {
// @formatter:off
@Option(help = "Force branch instructions to align with 32-bytes boundary, to mitigate the jcc erratum. " +
- "See https://www.intel.com/content/dam/support/us/en/documents/processors/mitigations-jump-conditional-code-erratum.pdf for more details.", type = OptionType.User)
+ "See https://www.intel.com/content/dam/support/us/en/documents/processors/mitigations-jump-conditional-code-erratum.pdf for more details. " +
+ "If not set explicitly, the default value will be determined according to the CPU model.", type = OptionType.User)
public static final OptionKey UseBranchesWithin32ByteBoundary = new OptionKey<>(false);
// @formatter:on
}
@@ -120,19 +121,28 @@ public class AMD64Assembler extends AMD64BaseAssembler {
protected CodePatchShifter codePatchShifter = null;
+ /**
+ * Constructs an assembler for the AMD64 architecture.
+ */
public AMD64Assembler(TargetDescription target) {
super(target);
useBranchesWithin32ByteBoundary = false;
}
- /**
- * Constructs an assembler for the AMD64 architecture.
- */
public AMD64Assembler(TargetDescription target, OptionValues optionValues) {
super(target);
useBranchesWithin32ByteBoundary = Options.UseBranchesWithin32ByteBoundary.getValue(optionValues);
}
+ public AMD64Assembler(TargetDescription target, OptionValues optionValues, boolean hasIntelJccErratum) {
+ super(target);
+ if (Options.UseBranchesWithin32ByteBoundary.hasBeenSet(optionValues)) {
+ useBranchesWithin32ByteBoundary = Options.UseBranchesWithin32ByteBoundary.getValue(optionValues);
+ } else {
+ useBranchesWithin32ByteBoundary = hasIntelJccErratum;
+ }
+ }
+
public void setCodePatchShifter(CodePatchShifter codePatchShifter) {
assert this.codePatchShifter == null : "overwriting existing value";
this.codePatchShifter = codePatchShifter;
@@ -2269,6 +2279,12 @@ public class AMD64Assembler extends AMD64BaseAssembler {
emitModRM(dst, src);
}
+ public final void movb(Register dst, AMD64Address src) {
+ prefixb(src, dst);
+ emitByte(0x8A);
+ emitOperandHelper(dst, src, 0);
+ }
+
public final void movb(AMD64Address dst, int imm8) {
prefix(dst);
emitByte(0xC6);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64MacroAssembler.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64MacroAssembler.java
index ba00152725e..92e5438254d 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64MacroAssembler.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64MacroAssembler.java
@@ -63,6 +63,14 @@ public class AMD64MacroAssembler extends AMD64Assembler {
super(target, optionValues);
}
+ public AMD64MacroAssembler(TargetDescription target, OptionValues optionValues, boolean hasIntelJccErratum) {
+ super(target, optionValues, hasIntelJccErratum);
+ }
+
+ public final void decrementq(Register reg) {
+ decrementq(reg, 1);
+ }
+
public final void decrementq(Register reg, int value) {
if (value == Integer.MIN_VALUE) {
subq(reg, value);
@@ -101,6 +109,10 @@ public class AMD64MacroAssembler extends AMD64Assembler {
}
}
+ public final void incrementq(Register reg) {
+ incrementq(reg, 1);
+ }
+
public void incrementq(Register reg, int value) {
if (value == Integer.MIN_VALUE) {
addq(reg, value);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/AsmOptions.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/AsmOptions.java
index 93be335c38a..a9522058ecf 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/AsmOptions.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/AsmOptions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2020, 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
@@ -26,5 +26,5 @@ package org.graalvm.compiler.asm;
public class AsmOptions {
- public static int InitialCodeBufferSize = 232;
+ public static final int InitialCodeBufferSize = 232;
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/CompilationResult.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/CompilationResult.java
index b909702eccf..49659ddb298 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/CompilationResult.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/CompilationResult.java
@@ -36,7 +36,9 @@ import java.util.List;
import java.util.Objects;
import java.util.function.Function;
+import jdk.internal.vm.compiler.collections.EconomicMap;
import jdk.internal.vm.compiler.collections.EconomicSet;
+import jdk.internal.vm.compiler.collections.Equivalence;
import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.graph.NodeSourcePosition;
@@ -194,7 +196,7 @@ public class CompilationResult {
private final List sourceMapping = new ArrayList<>();
private final List dataPatches = new ArrayList<>();
private final List exceptionHandlers = new ArrayList<>();
- private final List marks = new ArrayList<>();
+ private final List marks = new ArrayList<>();
private int totalFrameSize = -1;
private int maxInterpreterFrameSize = -1;
@@ -523,11 +525,13 @@ public class CompilationResult {
* @param target the being called
* @param debugInfo the debug info for the call
* @param direct specifies if this is a {@linkplain Call#direct direct} call
+ * @return created call object
*/
- public void recordCall(int codePos, int size, InvokeTarget target, DebugInfo debugInfo, boolean direct) {
+ public Call recordCall(int codePos, int size, InvokeTarget target, DebugInfo debugInfo, boolean direct) {
checkOpen();
final Call call = new Call(target, codePos, size, direct, debugInfo);
addInfopoint(call);
+ return call;
}
/**
@@ -603,9 +607,9 @@ public class CompilationResult {
* @param codePos the position in the code that is covered by the handler
* @param markId the identifier for this mark
*/
- public Mark recordMark(int codePos, Object markId) {
+ public CodeMark recordMark(int codePos, MarkId markId) {
checkOpen();
- Mark mark = new Mark(codePos, markId);
+ CodeMark mark = new CodeMark(codePos, markId);
marks.add(mark);
return mark;
}
@@ -692,9 +696,78 @@ public class CompilationResult {
}
/**
- * @return the list of marks
+ * An identified mark in the generated code.
*/
- public List getMarks() {
+ public interface MarkId {
+
+ /**
+ * A human readable name for this mark.
+ */
+ String getName();
+
+ /**
+ * Return the object which should be used in the {@link Mark}. On some platforms that may be
+ * different than this object.
+ */
+ default Object getId() {
+ return this;
+ }
+
+ /**
+ * Indicates whether the mark is intended to identify the end of the last instruction or the
+ * beginning of the next instruction. This information is necessary if the backend needs to
+ * insert instructions after the normal assembly step.
+ */
+ boolean isMarkAfter();
+ }
+
+ /**
+ * An alternative to the existing {@link Mark} which isn't very flexible since it's final. This
+ * enforces some API for the mark object and can be converted into the standard mark for code
+ * installation if necessary.
+ */
+ public static class CodeMark extends Site {
+
+ /**
+ * An object denoting extra semantic information about the machine code position of this
+ * mark.
+ */
+ public final MarkId id;
+
+ /**
+ * Creates a mark that associates {@code id} with the machine code position
+ * {@code pcOffset}.
+ */
+ public CodeMark(int pcOffset, MarkId id) {
+ super(pcOffset);
+ this.id = id;
+ assert id != null : this;
+ }
+
+ @Override
+ public String toString() {
+ return id + "@" + pcOffset;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof CodeMark) {
+ CodeMark that = (CodeMark) obj;
+ if (this.pcOffset == that.pcOffset && Objects.equals(this.id, that.id)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * @return the list of {@link CodeMark code marks}.
+ */
+ public List getMarks() {
if (marks.isEmpty()) {
return emptyList();
}
@@ -750,6 +823,7 @@ public class CompilationResult {
if (annotations != null) {
annotations.clear();
}
+ callToMark.clear();
}
public void clearInfopoints() {
@@ -788,7 +862,7 @@ public class CompilationResult {
});
iterateAndReplace(dataPatches, pos, site -> new DataPatch(site.pcOffset + bytesToShift, site.reference, site.note));
iterateAndReplace(exceptionHandlers, pos, site -> new ExceptionHandler(site.pcOffset + bytesToShift, site.handlerPos));
- iterateAndReplace(marks, pos, site -> new Mark(site.pcOffset + bytesToShift, site.id));
+ iterateAndReplace(marks, pos, site -> new CodeMark(site.pcOffset + bytesToShift, site.id));
if (annotations != null) {
for (CodeAnnotation annotation : annotations) {
int annotationPos = annotation.position;
@@ -802,9 +876,29 @@ public class CompilationResult {
private static void iterateAndReplace(List sites, int pos, Function replacement) {
for (int i = 0; i < sites.size(); i++) {
T site = sites.get(i);
+ if (pos == site.pcOffset && site instanceof CodeMark) {
+ CodeMark mark = (CodeMark) site;
+ if (mark.id.isMarkAfter()) {
+ // The insert point is exactly on the mark but the mark is annotating the end of
+ // the last instruction, so leave it alone.
+ continue;
+ }
+ }
if (pos <= site.pcOffset) {
sites.set(i, replacement.apply(site));
}
}
}
+
+ private final EconomicMap callToMark = EconomicMap.create(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE);
+
+ public void recordCallContext(CodeMark mark, Call call) {
+ if (call != null) {
+ callToMark.put(call, mark);
+ }
+ }
+
+ public CodeMark getAssociatedMark(Call call) {
+ return callToMark.get(call);
+ }
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/HexCodeFileDisassemblerProvider.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/HexCodeFileDisassemblerProvider.java
index 4a5d7ea7a51..c02762dd75d 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/HexCodeFileDisassemblerProvider.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/HexCodeFileDisassemblerProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,8 @@ import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.util.Arrays;
+import org.graalvm.compiler.serviceprovider.ServiceProvider;
+
import jdk.vm.ci.code.CodeCacheProvider;
import jdk.vm.ci.code.CodeUtil;
import jdk.vm.ci.code.CodeUtil.DefaultRefMapFormatter;
@@ -40,9 +42,6 @@ import jdk.vm.ci.code.site.Call;
import jdk.vm.ci.code.site.DataPatch;
import jdk.vm.ci.code.site.ExceptionHandler;
import jdk.vm.ci.code.site.Infopoint;
-import jdk.vm.ci.code.site.Mark;
-
-import org.graalvm.compiler.serviceprovider.ServiceProvider;
/**
* {@link HexCodeFile} based implementation of {@link DisassemblerProvider}.
@@ -99,8 +98,8 @@ public class HexCodeFileDisassemblerProvider implements DisassemblerProvider {
for (DataPatch site : compResult.getDataPatches()) {
hcf.addOperandComment(site.pcOffset, "{" + site.reference.toString() + "}");
}
- for (Mark mark : compResult.getMarks()) {
- hcf.addComment(mark.pcOffset, codeCache.getMarkName(mark));
+ for (CompilationResult.CodeMark mark : compResult.getMarks()) {
+ hcf.addComment(mark.pcOffset, mark.id.getName());
}
}
String hcfEmbeddedString = hcf.toEmbeddedString();
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64.test/src/org/graalvm/compiler/core/aarch64/test/AArch64ArrayAddressTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64.test/src/org/graalvm/compiler/core/aarch64/test/AArch64ArrayAddressTest.java
index 918524b8049..71be63d9a6e 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64.test/src/org/graalvm/compiler/core/aarch64/test/AArch64ArrayAddressTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64.test/src/org/graalvm/compiler/core/aarch64/test/AArch64ArrayAddressTest.java
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2020, Arm Limited. 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
@@ -27,7 +27,7 @@ package org.graalvm.compiler.core.aarch64.test;
import org.graalvm.compiler.api.directives.GraalDirectives;
import org.graalvm.compiler.lir.LIRInstruction;
-import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticOp.ExtendedAddShiftOp;
+import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticOp.ExtendedAddSubShiftOp;
import org.junit.Test;
import java.util.ArrayDeque;
@@ -36,7 +36,7 @@ import java.util.Set;
import java.util.function.Predicate;
public class AArch64ArrayAddressTest extends AArch64MatchRuleTest {
- private static final Predicate predicate = op -> (op instanceof ExtendedAddShiftOp);
+ private static final Predicate predicate = op -> (op instanceof ExtendedAddSubShiftOp);
public static byte loadByte(byte[] arr, int n) {
return arr[n];
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64.test/src/org/graalvm/compiler/core/aarch64/test/AArch64MergeExtendWithAddSubTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64.test/src/org/graalvm/compiler/core/aarch64/test/AArch64MergeExtendWithAddSubTest.java
new file mode 100644
index 00000000000..88ad4d2653e
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64.test/src/org/graalvm/compiler/core/aarch64/test/AArch64MergeExtendWithAddSubTest.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, Arm Limited. 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.LIRInstruction;
+import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticOp;
+import org.junit.Test;
+
+import java.util.function.Predicate;
+
+public class AArch64MergeExtendWithAddSubTest extends AArch64MatchRuleTest {
+
+ private static final Predicate PRED_EXTEND_ADD_SHIFT = op -> (op instanceof AArch64ArithmeticOp.ExtendedAddSubShiftOp && op.name().equals("ADD"));
+ private static final Predicate PRED_EXTEND_SUB_SHIFT = op -> (op instanceof AArch64ArithmeticOp.ExtendedAddSubShiftOp && op.name().equals("SUB"));
+
+ private static final Long[] LONG_VALUES = {-1L, 0L, 0x1234567812345678L, 0xFFFFFFFFL, 0x12L, 0x1234L, Long.MIN_VALUE, Long.MAX_VALUE};
+ private static final Integer[] INT_VALUES = {-1, 0, 0x1234, 0x12345678, Integer.MIN_VALUE, Integer.MAX_VALUE};
+
+ private void predicateExist(String[] testCases, T[] values, Predicate predicate) {
+ for (String t : testCases) {
+ for (T value : values) {
+ test(t, value, value);
+ checkLIR(t, predicate, 1);
+ }
+ }
+ }
+
+ public long addI2LShift(long x, long y) {
+ int z = (int) y;
+ return x + (((long) z) << 3);
+ }
+
+ public long addB2LShift(long x, long y) {
+ byte z = (byte) y;
+ return x + (((long) z) << 2);
+ }
+
+ public long addC2LShift(long x, long y) {
+ char z = (char) y;
+ return x + (((long) z) << 1);
+ }
+
+ public long addS2LShift(long x, long y) {
+ short z = (short) y;
+ return x + (((long) z) << 4);
+ }
+
+ public long subI2LShift(long x, long y) {
+ int z = (int) y;
+ return x - (((long) z) << 1);
+ }
+
+ public long subB2LShift(long x, long y) {
+ byte z = (byte) y;
+ return x - (((long) z) << 2);
+ }
+
+ public long subC2LShift(long x, long y) {
+ char z = (char) y;
+ return x - (((long) z) << 3);
+ }
+
+ public long subS2LShift(long x, long y) {
+ short z = (short) y;
+ return x - (((long) z) << 4);
+ }
+
+ public long addI2L(long x, long y) {
+ int z = (int) y;
+ return x + z;
+ }
+
+ public long addB2L(long x, long y) {
+ byte z = (byte) y;
+ return x + z;
+ }
+
+ public long addC2L(long x, long y) {
+ char z = (char) y;
+ return x + z;
+ }
+
+ public long addS2L(long x, long y) {
+ short z = (short) y;
+ return x + z;
+ }
+
+ public int addB2S(int x, int y) {
+ short a = (short) x;
+ byte b = (byte) y;
+ return a + b;
+ }
+
+ public int addB2SShift(int x, int y) {
+ short a = (short) x;
+ byte b = (byte) y;
+ return a + (b << 2);
+ }
+
+ public int addB2I(int x, int y) {
+ byte z = (byte) y;
+ return x + z;
+ }
+
+ public int addB2IShift(int x, int y) {
+ byte z = (byte) y;
+ return x + (z << 3);
+ }
+
+ public int addS2I(int x, int y) {
+ short z = (short) y;
+ return x + z;
+ }
+
+ public int addS2IShift(int x, int y) {
+ short z = (short) y;
+ return x + (z << 2);
+ }
+
+ public int addC2I(int x, int y) {
+ char z = (char) y;
+ return x + z;
+ }
+
+ public int addC2IShift(int x, int y) {
+ char z = (char) y;
+ return x + (z << 1);
+ }
+
+ @Test
+ public void mergeSignExtendIntoAdd() {
+ predicateExist(new String[]{"addB2S", "addB2I", "addS2I", "addC2I"}, INT_VALUES, PRED_EXTEND_ADD_SHIFT);
+ predicateExist(new String[]{"addB2L", "addC2L", "addI2L", "addS2L"}, LONG_VALUES, PRED_EXTEND_ADD_SHIFT);
+ }
+
+ @Test
+ public void mergeSignExtendShiftIntoAdd() {
+ predicateExist(new String[]{"addB2SShift", "addB2IShift", "addS2IShift", "addC2IShift"}, INT_VALUES, PRED_EXTEND_ADD_SHIFT);
+ predicateExist(new String[]{"addB2LShift", "addC2LShift", "addI2LShift", "addS2LShift"}, LONG_VALUES, PRED_EXTEND_ADD_SHIFT);
+ }
+
+ public long subI2L(long x, long y) {
+ int z = (int) y;
+ return x - z;
+ }
+
+ public long subB2L(long x, long y) {
+ byte z = (byte) y;
+ return x - z;
+ }
+
+ public long subC2L(long x, long y) {
+ char z = (char) y;
+ return x - z;
+ }
+
+ public long subS2L(long x, long y) {
+ short z = (short) y;
+ return x - z;
+ }
+
+ public int subB2S(int x, int y) {
+ short a = (short) x;
+ byte b = (byte) y;
+ return a - b;
+ }
+
+ public int subB2SShift(int x, int y) {
+ short a = (short) x;
+ byte b = (byte) y;
+ return a - (b << 2);
+ }
+
+ public int subB2I(int x, int y) {
+ byte z = (byte) y;
+ return x - z;
+ }
+
+ public int subB2IShift(int x, int y) {
+ byte z = (byte) y;
+ return x - (z << 3);
+ }
+
+ public int subS2I(int x, int y) {
+ short z = (short) y;
+ return x - z;
+ }
+
+ public int subS2IShift(int x, int y) {
+ short z = (short) y;
+ return x - (z << 2);
+ }
+
+ public int subC2I(int x, int y) {
+ char z = (char) y;
+ return x - z;
+ }
+
+ public int subC2IShift(int x, int y) {
+ char z = (char) y;
+ return x - (z << 1);
+ }
+
+ @Test
+ public void mergeSignExtendShiftIntoSub() {
+ predicateExist(new String[]{"subB2SShift", "subB2IShift", "subS2IShift", "subC2IShift"}, INT_VALUES, PRED_EXTEND_SUB_SHIFT);
+ predicateExist(new String[]{"subB2LShift", "subC2LShift", "subI2LShift", "subS2LShift"}, LONG_VALUES, PRED_EXTEND_SUB_SHIFT);
+ }
+
+ @Test
+ public void mergeSignExtendIntoSub() {
+ predicateExist(new String[]{"subB2S", "subB2I", "subS2I", "subC2I"}, INT_VALUES, PRED_EXTEND_SUB_SHIFT);
+ predicateExist(new String[]{"subB2L", "subC2L", "subI2L", "subS2L"}, LONG_VALUES, PRED_EXTEND_SUB_SHIFT);
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64.test/src/org/graalvm/compiler/core/aarch64/test/AArch64MergeNarrowWithAddSubTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64.test/src/org/graalvm/compiler/core/aarch64/test/AArch64MergeNarrowWithAddSubTest.java
new file mode 100644
index 00000000000..5431d56e48a
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64.test/src/org/graalvm/compiler/core/aarch64/test/AArch64MergeNarrowWithAddSubTest.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, Arm Limited. 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.LIRInstruction;
+import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticOp;
+import org.junit.Test;
+
+import java.util.function.Predicate;
+
+public class AArch64MergeNarrowWithAddSubTest extends AArch64MatchRuleTest {
+
+ private static final Predicate PRED_EXTEND_ADD_SHIFT = op -> (op instanceof AArch64ArithmeticOp.ExtendedAddSubShiftOp && op.name().equals("ADD"));
+ private static final Predicate PRED_EXTEND_SUB_SHIFT = op -> (op instanceof AArch64ArithmeticOp.ExtendedAddSubShiftOp && op.name().equals("SUB"));
+
+ private static final Long[] LONG_VALUES = {-1L, 0L, 0x1234567812345678L, 0xFFFFFFFFL, 0x12L, 0x1234L, Long.MIN_VALUE, Long.MAX_VALUE};
+ private static final Integer[] INT_VALUES = {-1, 0, 0x1234, 0x12345678, Integer.MIN_VALUE, Integer.MAX_VALUE};
+
+ private void predicateExist(String[] testCases, T[] values, Predicate predicate) {
+ for (String t : testCases) {
+ for (T value : values) {
+ test(t, value, value);
+ checkLIR(t, predicate, 1);
+ }
+ }
+ }
+
+ public int addIB(int x, int y) {
+ return x + (y & 0xff);
+ }
+
+ public int addIH(int x, int y) {
+ return x + (y & 0xffff);
+ }
+
+ public long addLB(long x, long y) {
+ return x + (y & 0xff);
+ }
+
+ public long addLH(long x, long y) {
+ return x + (y & 0xffff);
+ }
+
+ public long addLW(long x, long y) {
+ return x + (y & 0xffffffffL);
+ }
+
+ @Test
+ public void mergeDowncastIntoAdd() {
+ predicateExist(new String[]{"addIB", "addIH"}, INT_VALUES, PRED_EXTEND_ADD_SHIFT);
+ predicateExist(new String[]{"addLB", "addLH", "addLW"}, LONG_VALUES, PRED_EXTEND_ADD_SHIFT);
+ }
+
+ public int subIB(int x, int y) {
+ return x - (y & 0xff);
+ }
+
+ public int subIH(int x, int y) {
+ return x - (y & 0xffff);
+ }
+
+ public long subLB(long x, long y) {
+ return x - (y & 0xff);
+ }
+
+ public long subLH(long x, long y) {
+ return x - (y & 0xffff);
+ }
+
+ public long subLW(long x, long y) {
+ return x - (y & 0xffffffffL);
+ }
+
+ @Test
+ public void mergeDowncastIntoSub() {
+ predicateExist(new String[]{"subIB", "subIH"}, INT_VALUES, PRED_EXTEND_SUB_SHIFT);
+ predicateExist(new String[]{"subLB", "subLH", "subLW"}, LONG_VALUES, PRED_EXTEND_SUB_SHIFT);
+ }
+
+ public int addIBShift(int x, int y) {
+ return x + ((y & 0xff) << 3);
+ }
+
+ public int addIHShift(int x, int y) {
+ return x + ((y & 0xffff) << 3);
+ }
+
+ public long addLBShift(long x, long y) {
+ return x + ((y & 0xffL) << 3);
+ }
+
+ public long addLHShift(long x, long y) {
+ return x + ((y & 0xffffL) << 3);
+ }
+
+ public long addLWShift(long x, long y) {
+ return x + ((y & 0xffffffffL) << 3);
+ }
+
+ @Test
+ public void mergeShiftDowncastIntoAdd() {
+ predicateExist(new String[]{"addIBShift", "addIHShift"}, INT_VALUES, PRED_EXTEND_ADD_SHIFT);
+ predicateExist(new String[]{"addLBShift", "addLHShift", "addLWShift"}, LONG_VALUES, PRED_EXTEND_ADD_SHIFT);
+ }
+
+ public int subIBShift(int x, int y) {
+ return x - ((y & 0xff) << 3);
+ }
+
+ public int subIHShift(int x, int y) {
+ return x - ((y & 0xffff) << 3);
+ }
+
+ public long subLBShift(long x, long y) {
+ return x - ((y & 0xffL) << 3);
+ }
+
+ public long subLHShift(long x, long y) {
+ return x - ((y & 0xffffL) << 3);
+ }
+
+ public long subLWShift(long x, long y) {
+ return x - ((y & 0xffffffffL) << 3);
+ }
+
+ @Test
+ public void mergeShiftDowncastIntoSub() {
+ predicateExist(new String[]{"subIBShift", "subIHShift"}, INT_VALUES, PRED_EXTEND_SUB_SHIFT);
+ predicateExist(new String[]{"subLBShift", "subLHShift", "subLWShift"}, LONG_VALUES, PRED_EXTEND_SUB_SHIFT);
+ }
+
+ public int addIntExtractShort(int x, int y) {
+ return x + ((y << 16) >> 16);
+ }
+
+ public int addIntExtractByte(int x, int y) {
+ return x + ((y << 24) >> 24);
+ }
+
+ public long addLongExtractInt(long x, long y) {
+ return x + ((y << 32) >> 32);
+ }
+
+ public long addLongExtractShort(long x, long y) {
+ return x + ((y << 48) >> 48);
+ }
+
+ public long addLongExtractByte(long x, long y) {
+ return x + ((y << 56) >> 56);
+ }
+
+ @Test
+ public void addSignExtractTest() {
+ predicateExist(new String[]{"addIntExtractShort", "addIntExtractByte"}, INT_VALUES, PRED_EXTEND_ADD_SHIFT);
+ predicateExist(new String[]{"addLongExtractInt", "addLongExtractShort", "addLongExtractByte"}, LONG_VALUES, PRED_EXTEND_ADD_SHIFT);
+ }
+
+ public int addIntExtractShortByShift(int x, int y) {
+ return x + (((y << 16) >> 16) << 3);
+ }
+
+ public int addIntExtractByteByShift(int x, int y) {
+ return x + (((y << 24) >> 24) << 3);
+ }
+
+ public long addLongExtractIntByShift(long x, long y) {
+ return x + (((y << 32) >> 32) << 3);
+ }
+
+ public long addLongExtractShortByShift(long x, long y) {
+ return x + (((y << 48) >> 48) << 3);
+ }
+
+ public long addLongExtractByteByShift(long x, long y) {
+ return x + (((y << 56) >> 56) << 3);
+ }
+
+ @Test
+ public void addExtractByShiftTest() {
+ predicateExist(new String[]{"addIntExtractShortByShift", "addIntExtractByteByShift"}, INT_VALUES, PRED_EXTEND_ADD_SHIFT);
+ predicateExist(new String[]{"addLongExtractIntByShift", "addLongExtractShortByShift", "addLongExtractByteByShift"}, LONG_VALUES, PRED_EXTEND_ADD_SHIFT);
+ }
+
+ public int addIntUnsignedExtractByte(int x, int y) {
+ return x + ((y << 24) >>> 24);
+ }
+
+ public long addLongUnsignedExtractByte(long x, long y) {
+ return x + ((y << 56) >>> 56);
+ }
+
+ @Test
+ public void addUnsignedExtractTest() {
+ predicateExist(new String[]{"addIntUnsignedExtractByte"}, INT_VALUES, PRED_EXTEND_ADD_SHIFT);
+ predicateExist(new String[]{"addLongUnsignedExtractByte"}, LONG_VALUES, PRED_EXTEND_ADD_SHIFT);
+ }
+
+ public int addIntUnsignedExtractByteByShift(int x, int y) {
+ return x + (((y << 24) >>> 24) << 2);
+ }
+
+ public long addLongUnsignedExtractByteByShift(long x, long y) {
+ return x + (((y << 56) >>> 56) << 1);
+ }
+
+ @Test
+ public void addUnsignedExtractByShiftTest() {
+ predicateExist(new String[]{"addIntUnsignedExtractByteByShift"}, INT_VALUES, PRED_EXTEND_ADD_SHIFT);
+ predicateExist(new String[]{"addLongUnsignedExtractByteByShift"}, LONG_VALUES, PRED_EXTEND_ADD_SHIFT);
+ }
+
+ public int subIntExtractShort(int x, int y) {
+ return x - ((y << 16) >> 16);
+ }
+
+ public int subIntExtractByte(int x, int y) {
+ return x - ((y << 24) >> 24);
+ }
+
+ public long subLongExtractInt(long x, long y) {
+ return x - ((y << 32) >> 32);
+ }
+
+ public long subLongExtractShort(long x, long y) {
+ return x - ((y << 48) >> 48);
+ }
+
+ public long subLongExtractByte(long x, long y) {
+ return x - ((y << 56) >> 56);
+ }
+
+ @Test
+ public void subExtractTest() {
+ predicateExist(new String[]{"subIntExtractShort", "subIntExtractByte"}, INT_VALUES, PRED_EXTEND_SUB_SHIFT);
+ predicateExist(new String[]{"subLongExtractInt", "subLongExtractShort", "subLongExtractByte"}, LONG_VALUES, PRED_EXTEND_SUB_SHIFT);
+ }
+
+ public int subIntExtractShortByShift(int x, int y) {
+ return x - (((y << 16) >> 16) << 3);
+ }
+
+ public int subIntExtractByteByShift(int x, int y) {
+ return x - (((y << 24) >> 24) << 3);
+ }
+
+ public long subLongExtractIntByShift(long x, long y) {
+ return x - (((y << 32) >> 32) << 3);
+ }
+
+ public long subLongExtractShortByShift(long x, long y) {
+ return x - (((y << 48) >> 48) << 3);
+ }
+
+ public long subLongExtractByteByShift(long x, long y) {
+ return x - (((y << 56) >> 56) << 3);
+ }
+
+ @Test
+ public void subExtractByShiftTest() {
+ predicateExist(new String[]{"subIntExtractShortByShift", "subIntExtractByteByShift"}, INT_VALUES, PRED_EXTEND_SUB_SHIFT);
+ predicateExist(new String[]{"subLongExtractIntByShift", "subLongExtractShortByShift", "subLongExtractByteByShift"}, LONG_VALUES, PRED_EXTEND_SUB_SHIFT);
+ }
+
+ public int subIntUnsignedExtractByte(int x, int y) {
+ return x - ((y << 24) >>> 24);
+ }
+
+ public long subLongUnsignedExtractByte(long x, long y) {
+ return x - ((y << 56) >>> 56);
+ }
+
+ @Test
+ public void subUnsignedExtractTest() {
+ predicateExist(new String[]{"subIntUnsignedExtractByte"}, INT_VALUES, PRED_EXTEND_SUB_SHIFT);
+ predicateExist(new String[]{"subLongUnsignedExtractByte"}, LONG_VALUES, PRED_EXTEND_SUB_SHIFT);
+ }
+
+ public int subIntUnsignedExtractByteByShift(int x, int y) {
+ return x - (((y << 24) >>> 24) << 1);
+ }
+
+ public long subLongUnsignedExtractByteByShift(long x, long y) {
+ return x - (((y << 56) >>> 56) << 2);
+ }
+
+ @Test
+ public void subUnsignedExtractByShiftTest() {
+ predicateExist(new String[]{"subIntUnsignedExtractByteByShift"}, INT_VALUES, PRED_EXTEND_SUB_SHIFT);
+ predicateExist(new String[]{"subLongUnsignedExtractByteByShift"}, LONG_VALUES, PRED_EXTEND_SUB_SHIFT);
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64.test/src/org/graalvm/compiler/core/aarch64/test/AArch64TestBitAndBranchTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64.test/src/org/graalvm/compiler/core/aarch64/test/AArch64TestBitAndBranchTest.java
index ae07d293a1f..1526a3949d7 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64.test/src/org/graalvm/compiler/core/aarch64/test/AArch64TestBitAndBranchTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64.test/src/org/graalvm/compiler/core/aarch64/test/AArch64TestBitAndBranchTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, 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
@@ -62,7 +62,7 @@ public class AArch64TestBitAndBranchTest extends LIRTest {
public static long testBit42Snippet(long a, long b, long c) {
if ((a & (1L << 42)) == 0) {
- return b;
+ return b + c;
} else {
return c;
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64.test/src/org/graalvm/compiler/core/aarch64/test/AArch64VolatileAccessesTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64.test/src/org/graalvm/compiler/core/aarch64/test/AArch64VolatileAccessesTest.java
new file mode 100644
index 00000000000..461ae186166
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64.test/src/org/graalvm/compiler/core/aarch64/test/AArch64VolatileAccessesTest.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, Red Hat Inc. 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.aarch64.AArch64Kind;
+import org.graalvm.compiler.core.test.MatchRuleTest;
+import org.graalvm.compiler.lir.LIRInstruction;
+import org.graalvm.compiler.lir.aarch64.AArch64Move;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.function.Predicate;
+
+import static org.junit.Assume.assumeTrue;
+
+public class AArch64VolatileAccessesTest extends MatchRuleTest {
+ private static volatile byte volatileByteField;
+ private static volatile short volatileShortField;
+ private static volatile int volatileIntField;
+ private static volatile long volatileLongField;
+ private static volatile float volatileFloatField;
+ private static volatile double volatileDoubleField;
+
+ private static Predicate storePredicate(AArch64Kind kind) {
+ return op -> (op instanceof AArch64Move.VolatileStoreOp && ((AArch64Move.VolatileStoreOp) op).getKind() == kind);
+ }
+
+ private static Predicate loadPredicate(AArch64Kind kind) {
+ return op -> (op instanceof AArch64Move.VolatileLoadOp && ((AArch64Move.VolatileLoadOp) op).getKind() == kind);
+ }
+
+ @Before
+ public void checkAArch64() {
+ assumeTrue("skipping AArch64 specific test", getTarget().arch instanceof AArch64);
+ }
+
+ public static byte volatileByteFieldLoad() {
+ return volatileByteField;
+ }
+
+ @Test
+ public void test01() {
+ checkLIR("volatileByteFieldLoad", loadPredicate(AArch64Kind.BYTE), 1);
+ volatileByteField = 42;
+ test("volatileByteFieldLoad");
+ }
+
+ public static short volatileShortFieldLoad() {
+ return volatileShortField;
+ }
+
+ @Test
+ public void test02() {
+ checkLIR("volatileShortFieldLoad", loadPredicate(AArch64Kind.WORD), 1);
+ volatileShortField = 42;
+ test("volatileShortFieldLoad");
+ }
+
+ public static int volatileIntFieldLoad() {
+ return volatileIntField;
+ }
+
+ @Test
+ public void test03() {
+ checkLIR("volatileIntFieldLoad", loadPredicate(AArch64Kind.DWORD), 1);
+ volatileIntField = 42;
+ test("volatileIntFieldLoad");
+ }
+
+ public static long volatileLongFieldLoad() {
+ return volatileLongField;
+ }
+
+ @Test
+ public void test04() {
+ checkLIR("volatileLongFieldLoad", loadPredicate(AArch64Kind.QWORD), 1);
+ volatileLongField = 42;
+ test("volatileLongFieldLoad");
+ }
+
+ public static float volatileFloatFieldLoad() {
+ return volatileFloatField;
+ }
+
+ @Test
+ public void test05() {
+ checkLIR("volatileFloatFieldLoad", loadPredicate(AArch64Kind.SINGLE), 1);
+ volatileFloatField = 42;
+ test("volatileFloatFieldLoad");
+ }
+
+ public static double volatileDoubleFieldLoad() {
+ return volatileDoubleField;
+ }
+
+ @Test
+ public void test06() {
+ checkLIR("volatileDoubleFieldLoad", loadPredicate(AArch64Kind.DOUBLE), 1);
+ volatileDoubleField = 42;
+ test("volatileDoubleFieldLoad");
+ }
+
+ public static void volatileByteFieldStore(byte v) {
+ volatileByteField = v;
+ }
+
+ @Test
+ public void test07() {
+ checkLIR("volatileByteFieldStore", storePredicate(AArch64Kind.BYTE), 1);
+ executeActual(getResolvedJavaMethod("volatileByteFieldStore"), (byte) 0x42);
+ Assert.assertEquals(volatileByteField, 0x42);
+ }
+
+ public static void volatileShortFieldStore(short v) {
+ volatileShortField = v;
+ }
+
+ @Test
+ public void test08() {
+ checkLIR("volatileShortFieldStore", storePredicate(AArch64Kind.WORD), 1);
+ executeActual(getResolvedJavaMethod("volatileShortFieldStore"), (short) 0x42);
+ Assert.assertEquals(volatileShortField, 0x42);
+ }
+
+ public static void volatileIntFieldStore(int v) {
+ volatileIntField = v;
+ }
+
+ @Test
+ public void test09() {
+ checkLIR("volatileIntFieldStore", storePredicate(AArch64Kind.DWORD), 1);
+ executeActual(getResolvedJavaMethod("volatileIntFieldStore"), 0x42);
+ Assert.assertEquals(volatileIntField, 0x42);
+ }
+
+ public static void volatileLongFieldStore(int v) {
+ volatileLongField = v;
+ }
+
+ @Test
+ public void test10() {
+ checkLIR("volatileLongFieldStore", storePredicate(AArch64Kind.QWORD), 1);
+ executeActual(getResolvedJavaMethod("volatileLongFieldStore"), 0x42);
+ Assert.assertEquals(volatileLongField, 0x42);
+ }
+
+ public static void volatileFloatFieldStore(float v) {
+ volatileFloatField = v;
+ }
+
+ @Test
+ public void test11() {
+ checkLIR("volatileFloatFieldStore", storePredicate(AArch64Kind.SINGLE), 1);
+ executeActual(getResolvedJavaMethod("volatileFloatFieldStore"), (float) 0x42);
+ Assert.assertEquals(volatileFloatField, 0x42, 0);
+ }
+
+ public static void volatileDoubleFieldStore(double v) {
+ volatileDoubleField = v;
+ }
+
+ @Test
+ public void test12() {
+ checkLIR("volatileDoubleFieldStore", storePredicate(AArch64Kind.DOUBLE), 1);
+ executeActual(getResolvedJavaMethod("volatileDoubleFieldStore"), (double) 0x42);
+ Assert.assertEquals(volatileDoubleField, 0x42, 0);
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ArithmeticLIRGenerator.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ArithmeticLIRGenerator.java
index 0f71a0e397f..3af4f1d9c20 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ArithmeticLIRGenerator.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ArithmeticLIRGenerator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,6 +46,7 @@ import org.graalvm.compiler.lir.aarch64.AArch64AddressValue;
import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticLIRGeneratorTool;
import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticOp;
import org.graalvm.compiler.lir.aarch64.AArch64BitManipulationOp;
+import org.graalvm.compiler.lir.aarch64.AArch64Move;
import org.graalvm.compiler.lir.aarch64.AArch64Move.LoadOp;
import org.graalvm.compiler.lir.aarch64.AArch64Move.StoreConstantOp;
import org.graalvm.compiler.lir.aarch64.AArch64Move.StoreOp;
@@ -237,7 +238,7 @@ public class AArch64ArithmeticLIRGenerator extends ArithmeticLIRGenerator implem
result = getLIRGen().newVariable(LIRKind.combine(c));
} else {
assert a.getPlatformKind() == c.getPlatformKind();
- if (op == AArch64ArithmeticOp.FADD) {
+ if (op == AArch64ArithmeticOp.FMADD) {
// For floating-point Math.fma intrinsic.
assert a.getPlatformKind() == AArch64Kind.SINGLE || a.getPlatformKind() == AArch64Kind.DOUBLE;
} else {
@@ -506,6 +507,14 @@ public class AArch64ArithmeticLIRGenerator extends ArithmeticLIRGenerator implem
return result;
}
+ @Override
+ public Variable emitVolatileLoad(LIRKind kind, Value address, LIRFrameState state) {
+ AllocatableValue loadAddress = asAllocatable(address);
+ Variable result = getLIRGen().newVariable(getLIRGen().toRegisterKind(kind));
+ getLIRGen().append(new AArch64Move.VolatileLoadOp((AArch64Kind) kind.getPlatformKind(), result, loadAddress, state));
+ return result;
+ }
+
@Override
public void emitStore(ValueKind> lirKind, Value address, Value inputVal, LIRFrameState state) {
AArch64AddressValue storeAddress = getLIRGen().asAddressValue(address);
@@ -523,6 +532,14 @@ public class AArch64ArithmeticLIRGenerator extends ArithmeticLIRGenerator implem
getLIRGen().append(new StoreOp(kind, storeAddress, input, state));
}
+ @Override
+ public void emitVolatileStore(ValueKind> lirKind, Value addressVal, Value inputVal, LIRFrameState state) {
+ AArch64Kind kind = (AArch64Kind) lirKind.getPlatformKind();
+ AllocatableValue input = asAllocatable(inputVal);
+ AllocatableValue address = asAllocatable(addressVal);
+ getLIRGen().append(new AArch64Move.VolatileStoreOp(kind, address, input, state));
+ }
+
@Override
public Value emitRound(Value value, RoundingMode mode) {
AArch64ArithmeticOp op;
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64NodeMatchRules.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64NodeMatchRules.java
index 8af1e40d45c..cfc21263a89 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64NodeMatchRules.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64NodeMatchRules.java
@@ -141,6 +141,22 @@ public class AArch64NodeMatchRules extends NodeMatchRules {
}
}
+ private static ExtendType getSignExtendType(int fromBits) {
+ switch (fromBits) {
+ case Byte.SIZE:
+ return ExtendType.SXTB;
+ case Short.SIZE:
+ return ExtendType.SXTH;
+ case Integer.SIZE:
+ return ExtendType.SXTW;
+ case Long.SIZE:
+ return ExtendType.SXTX;
+ default:
+ GraalError.shouldNotReachHere("extended from " + fromBits + "bits is not supported!");
+ return null;
+ }
+ }
+
private AllocatableValue moveSp(AllocatableValue value) {
return getLIRGeneratorTool().moveSp(value);
}
@@ -190,7 +206,83 @@ public class AArch64NodeMatchRules extends NodeMatchRules {
}
private static boolean isNarrowingLongToInt(NarrowNode narrow) {
- return narrow.getInputBits() == 64 && narrow.getResultBits() == 32;
+ return narrow.getInputBits() == Long.SIZE && narrow.getResultBits() == Integer.SIZE;
+ }
+
+ private ComplexMatchResult emitExtendedAddSubShift(BinaryNode op, ValueNode x, ValueNode y, ExtendType extType, int shiftAmt) {
+ assert op instanceof AddNode || op instanceof SubNode;
+ return builder -> {
+ AllocatableValue src1 = moveSp(gen.asAllocatable(operand(x)));
+ AllocatableValue src2 = moveSp(gen.asAllocatable(operand(y)));
+ Variable result = gen.newVariable(LIRKind.combine(operand(x), operand(y)));
+ AArch64ArithmeticOp arithmeticOp = op instanceof AddNode ? AArch64ArithmeticOp.ADD : AArch64ArithmeticOp.SUB;
+ gen.append(new AArch64ArithmeticOp.ExtendedAddSubShiftOp(arithmeticOp, result, src1, src2, extType, shiftAmt));
+ return result;
+ };
+ }
+
+ @MatchRule("(Add=op x (LeftShift (SignExtend=ext y) Constant=lshift))")
+ @MatchRule("(Sub=op x (LeftShift (SignExtend=ext y) Constant=lshift))")
+ @MatchRule("(Add=op x (LeftShift (ZeroExtend=ext y) Constant=lshift))")
+ @MatchRule("(Sub=op x (LeftShift (ZeroExtend=ext y) Constant=lshift))")
+ public ComplexMatchResult mergeSignExtendByShiftIntoAddSub(BinaryNode op, UnaryNode ext, ValueNode x, ValueNode y, ConstantNode lshift) {
+ assert lshift.getStackKind().isNumericInteger();
+ int shiftAmt = lshift.asJavaConstant().asInt();
+ if (shiftAmt > 4 || shiftAmt < 0) {
+ return null;
+ }
+ ExtendType extType;
+ if (ext instanceof SignExtendNode) {
+ extType = getSignExtendType(((SignExtendNode) ext).getInputBits());
+ } else {
+ extType = getZeroExtendType(((ZeroExtendNode) ext).getInputBits());
+ }
+ return emitExtendedAddSubShift(op, x, y, extType, shiftAmt);
+ }
+
+ @MatchRule("(Add=op x (LeftShift (And y Constant=constant) Constant=lshift))")
+ @MatchRule("(Sub=op x (LeftShift (And y Constant=constant) Constant=lshift))")
+ public ComplexMatchResult mergeShiftDowncastIntoAddSub(BinaryNode op, ValueNode x, ValueNode y, ConstantNode constant, ConstantNode lshift) {
+ assert lshift.getStackKind().isNumericInteger();
+ assert constant.getStackKind().isNumericInteger();
+ int shiftAmt = lshift.asJavaConstant().asInt();
+ long mask = constant.asJavaConstant().asLong();
+ if (shiftAmt > 4 || shiftAmt < 0) {
+ return null;
+ }
+ if (mask != 0xff && mask != 0xffff && mask != 0xffffffffL) {
+ return null;
+ }
+ ExtendType extType = getZeroExtendType(Long.toBinaryString(mask).length());
+ return emitExtendedAddSubShift(op, x, y, extType, shiftAmt);
+ }
+
+ @MatchRule("(Add=op x (RightShift (LeftShift y Constant=shiftConst) Constant=shiftConst))")
+ @MatchRule("(Sub=op x (RightShift (LeftShift y Constant=shiftConst) Constant=shiftConst))")
+ public ComplexMatchResult mergePairShiftIntoAddSub(BinaryNode op, ValueNode x, ValueNode y, ConstantNode shiftConst) {
+ assert shiftConst.getStackKind().isNumericInteger();
+ int shift = shiftConst.asJavaConstant().asInt();
+ if (shift != 16 && shift != 24 && shift != 32 && shift != 48 && shift != 56) {
+ return null;
+ }
+ int extractBits = shift >= 32 ? Long.SIZE - shift : Integer.SIZE - shift;
+ return emitExtendedAddSubShift(op, x, y, getSignExtendType(extractBits), 0);
+ }
+
+ @MatchRule("(Add=op x (LeftShift (RightShift (LeftShift y Constant=shiftConst) Constant=shiftConst) Constant=lshift))")
+ @MatchRule("(Sub=op x (LeftShift (RightShift (LeftShift y Constant=shiftConst) Constant=shiftConst) Constant=lshift))")
+ public ComplexMatchResult mergeShiftedPairShiftIntoAddSub(BinaryNode op, ValueNode x, ValueNode y, ConstantNode shiftConst, ConstantNode lshift) {
+ assert shiftConst.getStackKind().isNumericInteger();
+ int shift = shiftConst.asJavaConstant().asInt();
+ int shiftAmt = lshift.asJavaConstant().asInt();
+ if (shiftAmt > 4 || shiftAmt < 0) {
+ return null;
+ }
+ if (shift != 16 && shift != 24 && shift != 32 && shift != 48 && shift != 56) {
+ return null;
+ }
+ int extractBits = shift >= 32 ? Long.SIZE - shift : Integer.SIZE - shift;
+ return emitExtendedAddSubShift(op, x, y, getSignExtendType(extractBits), shiftAmt);
}
@MatchRule("(AArch64PointerAdd=addP base ZeroExtend)")
@@ -225,7 +317,7 @@ public class AArch64NodeMatchRules extends NodeMatchRules {
LIRKind kind = LIRKind.combineDerived(gen.getLIRKind(addP.stamp(NodeView.DEFAULT)),
baseReference, null);
Variable result = gen.newVariable(kind);
- gen.append(new AArch64ArithmeticOp.ExtendedAddShiftOp(result, x, moveSp(y),
+ gen.append(new AArch64ArithmeticOp.ExtendedAddSubShiftOp(AArch64ArithmeticOp.ADD, result, x, moveSp(y),
extendType, shiftNum));
return result;
};
@@ -469,6 +561,32 @@ public class AArch64NodeMatchRules extends NodeMatchRules {
resultKind, op, commutative, operand(src2), operand(src1));
}
+ @MatchRule("(Add=op x (And y Constant=constant))")
+ @MatchRule("(Sub=op x (And y Constant=constant))")
+ public ComplexMatchResult mergeDowncastIntoAddSub(BinaryNode op, ValueNode x, ValueNode y, ConstantNode constant) {
+ assert constant.getStackKind().isNumericInteger();
+ long mask = constant.asJavaConstant().asLong();
+ if (mask != 0xff && mask != 0xffff && mask != 0xffffffffL) {
+ return null;
+ }
+ ExtendType extType = getZeroExtendType(Long.toBinaryString(mask).length());
+ return emitExtendedAddSubShift(op, x, y, extType, 0);
+ }
+
+ @MatchRule("(Add=op x (SignExtend=ext y))")
+ @MatchRule("(Sub=op x (SignExtend=ext y))")
+ @MatchRule("(Add=op x (ZeroExtend=ext y))")
+ @MatchRule("(Sub=op x (ZeroExtend=ext y))")
+ public ComplexMatchResult mergeSignExtendIntoAddSub(BinaryNode op, UnaryNode ext, ValueNode x, ValueNode y) {
+ ExtendType extType;
+ if (ext instanceof SignExtendNode) {
+ extType = getSignExtendType(((SignExtendNode) ext).getInputBits());
+ } else {
+ extType = getZeroExtendType(((ZeroExtendNode) ext).getInputBits());
+ }
+ return emitExtendedAddSubShift(op, x, y, extType, 0);
+ }
+
@MatchRule("(Negate=unary (Narrow=narrow value))")
@MatchRule("(Not=unary (Narrow=narrow value))")
public ComplexMatchResult elideL2IForUnary(UnaryNode unary, NarrowNode narrow) {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ReadReplacementPhase.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ReadReplacementPhase.java
index 99612b639e2..ffb91d584c9 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ReadReplacementPhase.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ReadReplacementPhase.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -31,6 +31,7 @@ import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.calc.SignExtendNode;
import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
import org.graalvm.compiler.nodes.memory.ReadNode;
+import org.graalvm.compiler.nodes.memory.VolatileReadNode;
import org.graalvm.compiler.phases.Phase;
/**
@@ -46,7 +47,7 @@ public class AArch64ReadReplacementPhase extends Phase {
if (node instanceof AArch64ReadNode) {
continue;
}
- if (node instanceof ReadNode) {
+ if (node instanceof ReadNode && !(node instanceof VolatileReadNode)) {
ReadNode readNode = (ReadNode) node;
if (readNode.hasExactlyOneUsage()) {
Node usage = readNode.usages().first();
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java
index ce05b25e9e3..9d70e2d2771 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java
@@ -1177,6 +1177,16 @@ public class AMD64ArithmeticLIRGenerator extends ArithmeticLIRGenerator implemen
return result;
}
+ @Override
+ public Variable emitVolatileLoad(LIRKind kind, Value address, LIRFrameState state) {
+ throw GraalError.shouldNotReachHere();
+ }
+
+ @Override
+ public void emitVolatileStore(ValueKind> kind, Value address, Value input, LIRFrameState state) {
+ throw GraalError.shouldNotReachHere();
+ }
+
protected void emitStoreConst(AMD64Kind kind, AMD64AddressValue address, ConstantValue value, LIRFrameState state) {
Constant c = value.getConstant();
if (JavaConstant.isNull(c)) {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java
index 77175981957..b2e3dcab42b 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java
@@ -107,7 +107,7 @@ import org.graalvm.compiler.lir.amd64.AMD64ZeroMemoryOp;
import org.graalvm.compiler.lir.amd64.vector.AMD64VectorCompareOp;
import org.graalvm.compiler.lir.gen.LIRGenerationResult;
import org.graalvm.compiler.lir.gen.LIRGenerator;
-import org.graalvm.compiler.lir.hashing.Hasher;
+import org.graalvm.compiler.lir.hashing.IntHasher;
import org.graalvm.compiler.phases.util.Providers;
import jdk.vm.ci.amd64.AMD64;
@@ -317,8 +317,9 @@ public abstract class AMD64LIRGenerator extends LIRGenerator {
@Override
public void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueLabel, LabelRef falseLabel, double trueLabelProbability) {
if (cmpKind == AMD64Kind.SINGLE || cmpKind == AMD64Kind.DOUBLE) {
+ boolean isSelfEqualsCheck = cond == Condition.EQ && !unorderedIsTrue && left.equals(right);
Condition finalCondition = emitCompare(cmpKind, left, right, cond);
- append(new FloatBranchOp(finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability));
+ append(new FloatBranchOp(finalCondition, unorderedIsTrue, trueLabel, falseLabel, trueLabelProbability, isSelfEqualsCheck));
return;
}
@@ -459,10 +460,15 @@ public abstract class AMD64LIRGenerator extends LIRGenerator {
finalCondition = emitCompare(cmpKind, left, right, cond);
}
- return emitCondMoveOp(finalCondition, finalTrueValue, finalFalseValue, isFloatComparison, unorderedIsTrue);
+ boolean isSelfEqualsCheck = isFloatComparison && finalCondition == Condition.EQ && left.equals(right);
+ return emitCondMoveOp(finalCondition, finalTrueValue, finalFalseValue, isFloatComparison, unorderedIsTrue, isSelfEqualsCheck);
}
private Variable emitCondMoveOp(Condition condition, Value trueValue, Value falseValue, boolean isFloatComparison, boolean unorderedIsTrue) {
+ return emitCondMoveOp(condition, trueValue, falseValue, isFloatComparison, unorderedIsTrue, false);
+ }
+
+ private Variable emitCondMoveOp(Condition condition, Value trueValue, Value falseValue, boolean isFloatComparison, boolean unorderedIsTrue, boolean isSelfEqualsCheck) {
boolean isParityCheckNecessary = isFloatComparison && unorderedIsTrue != AMD64ControlFlow.trueOnUnordered(condition);
Variable result = newVariable(trueValue.getValueKind());
if (!isParityCheckNecessary && isIntConstant(trueValue, 1) && isIntConstant(falseValue, 0)) {
@@ -485,7 +491,7 @@ public abstract class AMD64LIRGenerator extends LIRGenerator {
append(new CondSetOp(result, condition.negate()));
}
} else if (isFloatComparison) {
- append(new FloatCondMoveOp(result, condition, unorderedIsTrue, load(trueValue), load(falseValue)));
+ append(new FloatCondMoveOp(result, condition, unorderedIsTrue, load(trueValue), load(falseValue), isSelfEqualsCheck));
} else {
append(new CondMoveOp(result, condition, load(trueValue), loadNonConst(falseValue)));
}
@@ -686,16 +692,31 @@ public abstract class AMD64LIRGenerator extends LIRGenerator {
}
@Override
- protected Optional hasherFor(JavaConstant[] keyConstants, double minDensity) {
- return Hasher.forKeys(keyConstants, minDensity);
+ protected Optional hasherFor(JavaConstant[] keyConstants, double minDensity) {
+ int[] keys = new int[keyConstants.length];
+ for (int i = 0; i < keyConstants.length; i++) {
+ keys[i] = keyConstants[i].asInt();
+ }
+ return IntHasher.forKeys(keys);
}
@Override
- protected void emitHashTableSwitch(Hasher hasher, JavaConstant[] keys, LabelRef defaultTarget, LabelRef[] targets, Value value) {
- Value index = hasher.hash(value, arithmeticLIRGen);
+ protected void emitHashTableSwitch(IntHasher hasher, JavaConstant[] keys, LabelRef defaultTarget, LabelRef[] targets, Value value) {
+ Value hash = value;
+ if (hasher.factor > 1) {
+ Value factor = emitJavaConstant(JavaConstant.forShort(hasher.factor));
+ hash = arithmeticLIRGen.emitMul(hash, factor, false);
+ }
+ if (hasher.shift > 0) {
+ Value shift = emitJavaConstant(JavaConstant.forByte(hasher.shift));
+ hash = arithmeticLIRGen.emitShr(hash, shift);
+ }
+ Value cardinalityAnd = emitJavaConstant(JavaConstant.forInt(hasher.cardinality - 1));
+ hash = arithmeticLIRGen.emitAnd(hash, cardinalityAnd);
+
Variable scratch = newVariable(LIRKind.value(target().arch.getWordKind()));
Variable entryScratch = newVariable(LIRKind.value(target().arch.getWordKind()));
- append(new HashTableSwitchOp(keys, defaultTarget, targets, value, index, scratch, entryScratch));
+ append(new HashTableSwitchOp(keys, defaultTarget, targets, value, hash, scratch, entryScratch));
}
@Override
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/CompilationListenerProfiler.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/CompilationListenerProfiler.java
new file mode 100644
index 00000000000..9b76964c447
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/CompilationListenerProfiler.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2020, 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.debug.CompilationListener;
+import org.graalvm.compiler.debug.DebugContext.CompilerPhaseScope;
+
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+/**
+ * Connects a {@link CompilationListener} to a {@link CompilerProfiler}.
+ */
+public class CompilationListenerProfiler implements CompilationListener {
+ private final int compileId;
+ private final CompilerProfiler profiler;
+
+ /**
+ * Creates a compilation listener that passes events for a specific compilation identified by
+ * {@code compileId} onto {@code profiler}.
+ */
+ public CompilationListenerProfiler(CompilerProfiler profiler, int compileId) {
+ this.profiler = profiler;
+ this.compileId = compileId;
+ }
+
+ @Override
+ public void notifyInlining(ResolvedJavaMethod caller, ResolvedJavaMethod callee, boolean succeeded, CharSequence message, int bci) {
+ profiler.notifyCompilerInlingEvent(compileId, caller, callee, succeeded, message.toString(), bci);
+ }
+
+ @Override
+ public CompilerPhaseScope enterPhase(CharSequence name, int nesting) {
+ long start = profiler.getTicks();
+ return new CompilerPhaseScope() {
+
+ @Override
+ public void close() {
+ profiler.notifyCompilerPhaseEvent(compileId, start, name.toString(), nesting);
+ }
+ };
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/CompilerProfiler.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/CompilerProfiler.java
new file mode 100644
index 00000000000..01d492784fc
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/CompilerProfiler.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2020, 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 jdk.vm.ci.meta.ResolvedJavaMethod;
+
+/**
+ * A profiling service that consumes compilation related events. The Java Flight Recorder (JFR) is
+ * an example of such a service that can be exposed via this interface.
+ */
+public interface CompilerProfiler {
+
+ /**
+ * Get current value of the profiler's time counter.
+ *
+ * @return the number of profile-defined time units that have elapsed
+ */
+ long getTicks();
+
+ /**
+ * Notifies JFR when a compiler phase ends.
+ *
+ * @param compileId current computation unit id
+ * @param startTime when the phase started
+ * @param name name of the phase
+ * @param nestingLevel how many ancestor phases there are of the phase
+ */
+ void notifyCompilerPhaseEvent(int compileId, long startTime, String name, int nestingLevel);
+
+ /**
+ * Notifies JFR when the compiler considers inlining {@code callee} into {@code caller}.
+ *
+ * @param compileId current computation unit id
+ * @param caller caller method
+ * @param callee callee method considered for inlining into {@code caller}
+ * @param succeeded true if {@code callee} was inlined into {@code caller}
+ * @param message extra information about inlining decision
+ * @param bci byte code index of call site
+ */
+ void notifyCompilerInlingEvent(int compileId, ResolvedJavaMethod caller, ResolvedJavaMethod callee, boolean succeeded, String message, int bci);
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java
index 20511c4067d..a3751cc0c87 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2020, 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
@@ -271,6 +271,6 @@ public final class GraalOptions {
@Option(help = "Alignment in bytes for loop header blocks.", type = OptionType.Expert)
public static final OptionKey LoopHeaderAlignment = new OptionKey<>(16);
- @Option(help = "Do not include membars for volatile accesses until the end of optimizations.", type = OptionType.Expert)
- public static final OptionKey LateMembars = new OptionKey<>(true);
+ @Option(help = "String.indexOf invocations will be evaluated at compile time if the receiver is a constant and its length is lower than this value.", type = OptionType.Expert)
+ public static final OptionKey StringIndexOfLimit = new OptionKey<>(4096);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/NumUtil.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/NumUtil.java
index e7d1f8aed15..523465d2704 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/NumUtil.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/NumUtil.java
@@ -136,6 +136,14 @@ public class NumUtil {
return number / mod * mod;
}
+ public static int divideAndRoundUp(int number, int divisor) {
+ return (number + divisor - 1) / divisor;
+ }
+
+ public static long divideAndRoundUp(long number, long divisor) {
+ return (number + divisor - 1L) / divisor;
+ }
+
public static int log2Ceil(int val) {
int x = 1;
int log2 = 0;
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/calc/Condition.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/calc/Condition.java
index c2864312a7c..2b841798ed9 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/calc/Condition.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/calc/Condition.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2020, 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
@@ -533,6 +533,130 @@ public enum Condition {
}
}
+ private static boolean in(Condition needle, Condition... haystack) {
+ for (Condition c : haystack) {
+ if (c == needle) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if this condition and {@code other} will never both return true for the same
+ * arguments. This means that tests using these conditions can be safely reordered.
+ */
+ public boolean trueIsDisjoint(Condition other) {
+ if (other == this) {
+ return false;
+ }
+ switch (this) {
+ case EQ: {
+ // 0 EQ 0 is not disjoint from 0 LE 0
+ // 0 EQ 0 is not disjoint from 0 GE 0
+ // 0 EQ 0 is not disjoint from 0 AE 0
+ // 0 EQ 0 is not disjoint from 0 BE 0
+ return in(other, NE, LT, GT, AT, BT);
+ }
+ case NE: {
+ // 0 NE 1 is not disjoint from 0 LT 1
+ // 0 NE 1 is not disjoint from 0 LE 1
+ // 0 NE -1 is not disjoint from 0 GT -1
+ // 0 NE -1 is not disjoint from 0 GE -1
+ // 1 NE 0 is not disjoint from 1 AE 0
+ // 0 NE 1 is not disjoint from 0 BE 1
+ // 1 NE 0 is not disjoint from 1 AT 0
+ // 0 NE 1 is not disjoint from 0 BT 1
+ return other == EQ;
+ }
+ case LT: {
+ // 0 LT 1 is not disjoint from 0 NE 1
+ // 0 LT 1 is not disjoint from 0 LE 1
+ // -1 LT 0 is not disjoint from -1 AE 0
+ // 0 LT 1 is not disjoint from 0 BE 1
+ // -1 LT 0 is not disjoint from -1 AT 0
+ // 0 LT 1 is not disjoint from 0 BT 1
+ return in(other, EQ, GT, GE);
+ }
+ case LE: {
+ // 0 LE 0 is not disjoint from 0 EQ 0
+ // 0 LE 1 is not disjoint from 0 NE 1
+ // 0 LE 1 is not disjoint from 0 LT 1
+ // 0 LE 0 is not disjoint from 0 GE 0
+ // 0 LE 0 is not disjoint from 0 AE 0
+ // 0 LE 0 is not disjoint from 0 BE 0
+ // -1 LE 0 is not disjoint from -1 AT 0
+ // 0 LE 1 is not disjoint from 0 BT 1
+ return other == GT;
+ }
+ case GT: {
+ // 0 GT -1 is not disjoint from 0 NE -1
+ // 0 GT -1 is not disjoint from 0 GE -1
+ // 1 GT 0 is not disjoint from 1 AE 0
+ // 0 GT -1 is not disjoint from 0 BE -1
+ // 1 GT 0 is not disjoint from 1 AT 0
+ // 0 GT -1 is not disjoint from 0 BT -1
+ return in(other, EQ, LT, LE);
+ }
+ case GE: {
+ // 0 GE 0 is not disjoint from 0 EQ 0
+ // 0 GE -1 is not disjoint from 0 NE -1
+ // 0 GE 0 is not disjoint from 0 LE 0
+ // 0 GE -1 is not disjoint from 0 GT -1
+ // 0 GE 0 is not disjoint from 0 AE 0
+ // 0 GE 0 is not disjoint from 0 BE 0
+ // 1 GE 0 is not disjoint from 1 AT 0
+ // 0 GE -1 is not disjoint from 0 BT -1
+ return other == LT;
+ }
+ case AE: {
+ // 0 AE 0 is not disjoint from 0 EQ 0
+ // 1 AE 0 is not disjoint from 1 NE 0
+ // -1 AE 0 is not disjoint from -1 LT 0
+ // 0 AE 0 is not disjoint from 0 LE 0
+ // 1 AE 0 is not disjoint from 1 GT 0
+ // 0 AE 0 is not disjoint from 0 GE 0
+ // 0 AE 0 is not disjoint from 0 BE 0
+ // 1 AE 0 is not disjoint from 1 AT 0
+ return other == BT;
+ }
+ case BE: {
+ // 0 BE 0 is not disjoint from 0 EQ 0
+ // 0 BE 1 is not disjoint from 0 NE 1
+ // 0 BE 1 is not disjoint from 0 LT 1
+ // 0 BE 0 is not disjoint from 0 LE 0
+ // 0 BE -1 is not disjoint from 0 GT -1
+ // 0 BE 0 is not disjoint from 0 GE 0
+ // 0 BE 0 is not disjoint from 0 AE 0
+ // 0 BE 1 is not disjoint from 0 BT 1
+ return other == AT;
+ }
+ case AT: {
+ // 1 AT 0 is not disjoint from 1 NE 0
+ // -1 AT 0 is not disjoint from -1 LT 0
+ // -1 AT 0 is not disjoint from -1 LE 0
+ // 1 AT 0 is not disjoint from 1 GT 0
+ // 1 AT 0 is not disjoint from 1 GE 0
+ // 1 AT 0 is not disjoint from 1 AE 0
+ return in(other, EQ, BE, BT);
+ }
+ case BT: {
+ // 0 BT 1 is not disjoint from 0 NE 1
+ // 0 BT 1 is not disjoint from 0 LT 1
+ // 0 BT 1 is not disjoint from 0 LE 1
+ // 0 BT -1 is not disjoint from 0 GT -1
+ // 0 BT -1 is not disjoint from 0 GE -1
+ // 0 BT 1 is not disjoint from 0 BE 1
+ return in(other, EQ, AE, AT);
+ }
+ }
+ throw new IllegalArgumentException(this.toString());
+ }
+
+ /**
+ * Return the join of this condition and {@code other}. Only non-null return values are
+ * meaningful.
+ */
public Condition join(Condition other) {
if (other == this) {
return this;
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/CodeGenProviders.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/CodeGenProviders.java
index f927b86bab3..12071cf0bb1 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/CodeGenProviders.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/CodeGenProviders.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, 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
@@ -41,4 +41,6 @@ public interface CodeGenProviders {
ForeignCallsProvider getForeignCalls();
ConstantReflectionProvider getConstantReflection();
+
+ MetaAccessExtensionProvider getMetaAccessExtensionProvider();
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/ForeignCallDescriptor.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/ForeignCallDescriptor.java
index d9c42660cca..e87aef91d2e 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/ForeignCallDescriptor.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/ForeignCallDescriptor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2020, 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
@@ -26,9 +26,11 @@ package org.graalvm.compiler.core.common.spi;
import java.util.Arrays;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+
/**
- * The name and signature of a foreign call. A foreign call differs from a normal compiled Java call
- * in at least one of these aspects:
+ * The information required for high level code generation of a foreign call. A foreign call differs
+ * from a normal compiled Java call in at least one of these aspects:
*
* The call is to C/C++/assembler code.
* The call uses different conventions for passing parameters or returning values.
@@ -42,59 +44,86 @@ import java.util.Arrays;
*/
public class ForeignCallDescriptor {
- private final String name;
- private final Class> resultType;
- private final Class>[] argumentTypes;
+ protected final ForeignCallSignature signature;
+ protected final boolean isReexecutable;
+ protected final boolean canDeoptimize;
+ protected final boolean isGuaranteedSafepoint;
+ protected final LocationIdentity[] killedLocations;
+
+ public ForeignCallDescriptor(String name, Class> resultType, Class>[] argumentTypes, boolean isReexecutable, LocationIdentity[] killedLocations, boolean canDeoptimize,
+ boolean isGuaranteedSafepoint) {
+ this.isReexecutable = isReexecutable;
+ this.killedLocations = killedLocations;
+ this.canDeoptimize = canDeoptimize;
+ this.isGuaranteedSafepoint = isGuaranteedSafepoint;
+ this.signature = new ForeignCallSignature(name, resultType, argumentTypes);
- public ForeignCallDescriptor(String name, Class> resultType, Class>... argumentTypes) {
- this.name = name;
- this.resultType = resultType;
- this.argumentTypes = argumentTypes;
}
- /**
- * Gets the name of this foreign call.
- */
+ public ForeignCallSignature getSignature() {
+ return signature;
+ }
+
public String getName() {
- return name;
+ return signature.getName();
}
- /**
- * Gets the return type of this foreign call.
- */
public Class> getResultType() {
- return resultType;
+ return signature.getResultType();
}
- /**
- * Gets the argument types of this foreign call.
- */
public Class>[] getArgumentTypes() {
- return argumentTypes.clone();
+ return signature.getArgumentTypes();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return this == o;
}
@Override
public int hashCode() {
- return name.hashCode();
+ return signature.hashCode();
}
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof ForeignCallDescriptor) {
- ForeignCallDescriptor other = (ForeignCallDescriptor) obj;
- return other.name.equals(name) && other.resultType.equals(resultType) && Arrays.equals(other.argumentTypes, argumentTypes);
- }
- return false;
+ /**
+ * Determines if a given foreign call is side-effect free. Deoptimization cannot return
+ * execution to a point before a foreign call that has a side effect.
+ */
+ public boolean isReexecutable() {
+ return isReexecutable;
+ }
+
+ /**
+ * Gets the set of memory locations killed by a given foreign call. Returning the special value
+ * {@link LocationIdentity#any()} denotes that the call kills all memory locations. Returning
+ * any empty array denotes that the call does not kill any memory locations.
+ */
+ public LocationIdentity[] getKilledLocations() {
+ return killedLocations;
+ }
+
+ /**
+ * Determines if deoptimization can occur during a given foreign call.
+ */
+ public boolean canDeoptimize() {
+ return canDeoptimize;
+ }
+
+ /**
+ * Identifies foreign calls which are guaranteed to include a safepoint check.
+ */
+ public boolean isGuaranteedSafepoint() {
+ return isGuaranteedSafepoint;
}
@Override
public String toString() {
- StringBuilder sb = new StringBuilder(name).append('(');
- String sep = "";
- for (Class> arg : argumentTypes) {
- sb.append(sep).append(arg.getSimpleName());
- sep = ",";
- }
- return sb.append(')').append(resultType.getSimpleName()).toString();
+ return getClass().getSimpleName() + "{" + signature +
+ ", isReexecutable=" + isReexecutable +
+ ", canDeoptimize=" + canDeoptimize +
+ ", isGuaranteedSafepoint=" + isGuaranteedSafepoint +
+ ", killedLocations=" + Arrays.toString(killedLocations) +
+ '}';
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/ForeignCallSignature.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/ForeignCallSignature.java
new file mode 100644
index 00000000000..a8a814d5bdb
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/ForeignCallSignature.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2009, 2020, 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.spi;
+
+import java.util.Arrays;
+
+/**
+ * The name and signature of a {@link ForeignCallDescriptor foreign call}.
+ */
+public final class ForeignCallSignature {
+
+ private final String name;
+ private final Class> resultType;
+ private final Class>[] argumentTypes;
+
+ public ForeignCallSignature(String name, Class> resultType, Class>... argumentTypes) {
+ this.name = name;
+ this.resultType = resultType;
+ this.argumentTypes = argumentTypes;
+ }
+
+ /**
+ * Gets the name of this foreign call.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Gets the return type of this foreign call.
+ */
+ public Class> getResultType() {
+ return resultType;
+ }
+
+ /**
+ * Gets the argument types of this foreign call.
+ */
+ public Class>[] getArgumentTypes() {
+ return argumentTypes.clone();
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof ForeignCallSignature) {
+ ForeignCallSignature other = (ForeignCallSignature) obj;
+ return other.name.equals(name) && other.resultType.equals(resultType) && Arrays.equals(other.argumentTypes, argumentTypes);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder(name).append('(');
+ String sep = "";
+ for (Class> arg : argumentTypes) {
+ sb.append(sep).append(arg.getSimpleName());
+ sep = ",";
+ }
+ return sb.append(')').append(resultType.getSimpleName()).toString();
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/ForeignCallsProvider.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/ForeignCallsProvider.java
index 50912139949..e9405cad09c 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/ForeignCallsProvider.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/ForeignCallsProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
package org.graalvm.compiler.core.common.spi;
import org.graalvm.compiler.core.common.LIRKind;
-import jdk.internal.vm.compiler.word.LocationIdentity;
import jdk.vm.ci.code.ValueKindFactory;
@@ -34,36 +33,20 @@ import jdk.vm.ci.code.ValueKindFactory;
*/
public interface ForeignCallsProvider extends ValueKindFactory {
- /**
- * Determines if a given foreign call is side-effect free. Deoptimization cannot return
- * execution to a point before a foreign call that has a side effect.
- */
- boolean isReexecutable(ForeignCallDescriptor descriptor);
-
- /**
- * Gets the set of memory locations killed by a given foreign call. Returning the special value
- * {@link LocationIdentity#any()} denotes that the call kills all memory locations. Returning
- * any empty array denotes that the call does not kill any memory locations.
- */
- LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor);
-
- /**
- * Determines if deoptimization can occur during a given foreign call.
- */
- boolean canDeoptimize(ForeignCallDescriptor descriptor);
-
- /**
- * Identifies foreign calls which are guaranteed to include a safepoint check.
- */
- boolean isGuaranteedSafepoint(ForeignCallDescriptor descriptor);
-
/**
* Gets the linkage for a foreign call.
*/
ForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor);
/**
- * Return true if the foreign call has a binding.
+ * Gets the linkage for a foreign call.
*/
- boolean isAvailable(ForeignCallDescriptor descriptor);
+ default ForeignCallLinkage lookupForeignCall(ForeignCallSignature signature) {
+ return lookupForeignCall(getDescriptor(signature));
+ }
+
+ /**
+ * Gets the descriptor for a foreign call.
+ */
+ ForeignCallDescriptor getDescriptor(ForeignCallSignature signature);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/MetaAccessExtensionProvider.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/MetaAccessExtensionProvider.java
new file mode 100644
index 00000000000..a798de84bc7
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/spi/MetaAccessExtensionProvider.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2020, 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.spi;
+
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.ResolvedJavaType;
+
+/**
+ * Provides additional meta data about JVMCI objects that is not provided by the VM itself, and
+ * therefore does not need to be in JVMCI itself.
+ */
+public interface MetaAccessExtensionProvider {
+
+ /**
+ * The {@link JavaKind} used to store the provided type in a field or array element. This can be
+ * different than the {@link JavaType#getJavaKind} for types that are intercepted and
+ * transformed by the compiler.
+ */
+ JavaKind getStorageKind(JavaType type);
+
+ /**
+ * Checks if a dynamic allocation of the provided type can be canonicalized to a regular
+ * allocation node. If the method returns false, then the dynamic allocation would throw an
+ * exception at run time and therefore canonicalization would miss that exception.
+ */
+ boolean canConstantFoldDynamicAllocation(ResolvedJavaType type);
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java
index d1a83db912a..a854834677e 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020, 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
@@ -339,14 +339,14 @@ public class FloatStamp extends PrimitiveStamp {
if (Float.isNaN(value.asFloat())) {
result = new FloatStamp(32, Double.NaN, Double.NaN, false);
} else {
- result = new FloatStamp(32, value.asFloat(), value.asFloat(), !Float.isNaN(value.asFloat()));
+ result = new FloatStamp(32, value.asFloat(), value.asFloat(), true);
}
break;
case Double:
if (Double.isNaN(value.asDouble())) {
result = new FloatStamp(64, Double.NaN, Double.NaN, false);
} else {
- result = new FloatStamp(64, value.asDouble(), value.asDouble(), !Double.isNaN(value.asDouble()));
+ result = new FloatStamp(64, value.asDouble(), value.asDouble(), true);
}
break;
default:
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/BitMap2D.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/BitMap2D.java
index af0ff871b4e..da6ef1c9951 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/BitMap2D.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/BitMap2D.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,6 +44,11 @@ public final class BitMap2D {
}
public BitMap2D(int sizeInSlots, int bitsPerSlot) {
+ long nBits = (long) sizeInSlots * bitsPerSlot;
+ if (nBits > Integer.MAX_VALUE) {
+ // Avoids issues where (sizeInSlots * bitsPerSlot) wraps around to a positive integer
+ throw new OutOfMemoryError("Cannot allocate a BitSet for " + nBits + " bits");
+ }
map = new BitSet(sizeInSlots * bitsPerSlot);
this.bitsPerSlot = bitsPerSlot;
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.match.processor/src/org/graalvm/compiler/core/match/processor/MatchProcessor.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.match.processor/src/org/graalvm/compiler/core/match/processor/MatchProcessor.java
index 208724deb78..b77cb641919 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.match.processor/src/org/graalvm/compiler/core/match/processor/MatchProcessor.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.match.processor/src/org/graalvm/compiler/core/match/processor/MatchProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2020, 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
@@ -548,7 +548,7 @@ public class MatchProcessor extends AbstractProcessor {
}
out.printf(" private static final String[] %s = new String[] {%s};\n", invoker.argumentsListName(), args);
out.printf(" private static final class %s implements MatchGenerator {\n", invoker.wrapperClass());
- out.printf(" static MatchGenerator instance = new %s();\n", invoker.wrapperClass());
+ out.printf(" static final MatchGenerator instance = new %s();\n", invoker.wrapperClass());
out.printf(" @Override\n");
out.printf(" public ComplexMatchResult match(NodeMatchRules nodeMatchRules, Object...args) {\n");
out.printf(" return ((%s) nodeMatchRules).%s(%s);\n", invoker.nodeLIRBuilderClass, invoker.methodName, types);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ArrayCopyVirtualizationTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ArrayCopyVirtualizationTest.java
new file mode 100644
index 00000000000..edc3cb96547
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ArrayCopyVirtualizationTest.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+
+package org.graalvm.compiler.core.test;
+
+import org.junit.Test;
+
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.java.NewArrayNode;
+
+public class ArrayCopyVirtualizationTest extends GraalCompilerTest {
+
+ @Override
+ protected void checkMidTierGraph(StructuredGraph graph) {
+ assertTrue(graph.getNodes().filter(node -> node instanceof NewArrayNode).count() == 0, "shouldn't require allocation in %s", graph);
+ super.checkMidTierGraph(graph);
+ }
+
+ public byte byteCopyVirtualization() {
+ byte[] array = new byte[]{1, 2, 3, 4};
+ System.arraycopy(array, 1, array, 0, 3);
+ return array[0];
+ }
+
+ public short shortCopyVirtualization() {
+ short[] array = new short[]{1, 2, 3, 4};
+ System.arraycopy(array, 1, array, 0, 2);
+ return array[0];
+ }
+
+ public char charCopyVirtualization() {
+ char[] array = new char[]{1, 2, 3, 4};
+ System.arraycopy(array, 1, array, 0, 3);
+ return array[0];
+ }
+
+ public int intCopyVirtualization() {
+ int[] array = new int[]{1, 2, 3, 4};
+ System.arraycopy(array, 1, array, 0, 3);
+ return array[0];
+ }
+
+ public long longCopyVirtualization() {
+ long[] array = new long[]{1, 2, 3, 4};
+ System.arraycopy(array, 1, array, 0, 3);
+ return array[0];
+ }
+
+ public float floatCopyVirtualization() {
+ float[] array = new float[]{1, 2, 3, 4};
+ System.arraycopy(array, 1, array, 0, 3);
+ return array[0];
+ }
+
+ public double doubleCopyVirtualization() {
+ double[] array = new double[]{1, 2, 3, 4};
+ System.arraycopy(array, 1, array, 0, 3);
+ return array[0];
+ }
+
+ public Object objectCopyVirtualization() {
+ Object[] array = new Object[]{1, 2, 3, 4};
+ System.arraycopy(array, 1, array, 0, 3);
+ return array[0];
+ }
+
+ @Test
+ public void testCopyVirtualization() {
+ test("byteCopyVirtualization");
+ test("shortCopyVirtualization");
+ test("charCopyVirtualization");
+ test("intCopyVirtualization");
+ test("longCopyVirtualization");
+ test("floatCopyVirtualization");
+ test("doubleCopyVirtualization");
+ test("objectCopyVirtualization");
+ }
+
+ public byte byteCopyBackwardsVirtualization() {
+ byte[] array = new byte[]{1, 2, 3, 4};
+ System.arraycopy(array, 0, array, 1, 3);
+ return array[3];
+ }
+
+ public short shortCopyBackwardsVirtualization() {
+ short[] array = new short[]{1, 2, 3, 4};
+ System.arraycopy(array, 0, array, 1, 3);
+ return array[3];
+ }
+
+ public char charCopyBackwardsVirtualization() {
+ char[] array = new char[]{1, 2, 3, 4};
+ System.arraycopy(array, 0, array, 1, 3);
+ return array[3];
+ }
+
+ public int intCopyBackwardsVirtualization() {
+ int[] array = new int[]{1, 2, 3, 4};
+ System.arraycopy(array, 0, array, 1, 3);
+ return array[3];
+ }
+
+ public long longCopyBackwardsVirtualization() {
+ long[] array = new long[]{1, 2, 3, 4};
+ System.arraycopy(array, 0, array, 1, 3);
+ return array[3];
+ }
+
+ public float floatCopyBackwardsVirtualization() {
+ float[] array = new float[]{1, 2, 3, 4};
+ System.arraycopy(array, 0, array, 1, 3);
+ return array[3];
+ }
+
+ public double doubleCopyBackwardsVirtualization() {
+ double[] array = new double[]{1, 2, 3, 4};
+ System.arraycopy(array, 0, array, 1, 3);
+ return array[3];
+ }
+
+ public Object objectCopyBackwardsVirtualization() {
+ Object[] array = new Object[]{1, 2, 3, 4};
+ System.arraycopy(array, 0, array, 1, 3);
+ return array[3];
+ }
+
+ @Test
+ public void testCopyBackwardsVirtualization() {
+ test("byteCopyBackwardsVirtualization");
+ test("shortCopyBackwardsVirtualization");
+ test("charCopyBackwardsVirtualization");
+ test("intCopyBackwardsVirtualization");
+ test("longCopyBackwardsVirtualization");
+ test("floatCopyBackwardsVirtualization");
+ test("doubleCopyBackwardsVirtualization");
+ test("objectCopyBackwardsVirtualization");
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/BoxingEliminationTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/BoxingEliminationTest.java
index c130e94a5d6..d11505efa18 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/BoxingEliminationTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/BoxingEliminationTest.java
@@ -252,6 +252,21 @@ public class BoxingEliminationTest extends GraalCompilerTest {
test("materializeTest1Snippet", 1);
}
+ public static Float materializeTest2Snippet(float a) {
+ Float v = a;
+
+ if (v == a) {
+ return v;
+ } else {
+ return null;
+ }
+ }
+
+ @Test
+ public void materializeTest2() {
+ test("materializeTest2Snippet", 1f);
+ }
+
public static int intTest1Snippet() {
return Integer.valueOf(1);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java
index 390c378bef6..92f037939ae 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java
@@ -40,6 +40,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.ServiceLoader;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
@@ -60,7 +61,7 @@ import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.DebugContext;
-import org.graalvm.compiler.debug.DebugHandlersFactory;
+import org.graalvm.compiler.debug.DebugContext.Builder;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
@@ -150,13 +151,23 @@ public class CheckGraalInvariants extends GraalCompilerTest {
}
protected String getClassPath() {
- String bootclasspath;
+ String classpath;
if (JavaVersionUtil.JAVA_SPEC <= 8) {
- bootclasspath = System.getProperty("sun.boot.class.path");
+ classpath = System.getProperty("sun.boot.class.path");
} else {
- bootclasspath = JRT_CLASS_PATH_ENTRY;
+ classpath = JRT_CLASS_PATH_ENTRY;
}
- return bootclasspath;
+
+ // Also process classes that go into the libgraal native image.
+ String javaClassPath = System.getProperty("java.class.path");
+ if (javaClassPath != null) {
+ for (String path : javaClassPath.split(File.pathSeparator)) {
+ if (path.contains("libgraal") && !path.contains("processor")) {
+ classpath += File.pathSeparator + path;
+ }
+ }
+ }
+ return classpath;
}
protected boolean shouldLoadClass(String className) {
@@ -345,6 +356,8 @@ public class CheckGraalInvariants extends GraalCompilerTest {
verifiers.add(new VerifyGetOptionsUsage());
verifiers.add(new VerifyUnsafeAccess());
+ loadVerifiers(verifiers);
+
VerifyFoldableMethods foldableMethodsVerifier = new VerifyFoldableMethods();
if (tool.shouldVerifyFoldableMethods()) {
verifiers.add(foldableMethodsVerifier);
@@ -354,7 +367,7 @@ public class CheckGraalInvariants extends GraalCompilerTest {
for (Method m : BadUsageWithEquals.class.getDeclaredMethods()) {
ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m);
- try (DebugContext debug = DebugContext.create(options, DebugHandlersFactory.LOADER)) {
+ try (DebugContext debug = new Builder(options).build()) {
StructuredGraph graph = new StructuredGraph.Builder(options, debug, AllowAssumptions.YES).method(method).build();
try (DebugCloseable s = debug.disableIntercept(); DebugContext.Scope ds = debug.scope("CheckingGraph", graph, method)) {
graphBuilderSuite.apply(graph, context);
@@ -408,7 +421,7 @@ public class CheckGraalInvariants extends GraalCompilerTest {
String methodName = className + "." + method.getName();
if (matches(filters, methodName)) {
executor.execute(() -> {
- try (DebugContext debug = DebugContext.create(options, DebugHandlersFactory.LOADER)) {
+ try (DebugContext debug = new Builder(options).build()) {
boolean isSubstitution = method.getAnnotation(Snippet.class) != null || method.getAnnotation(MethodSubstitution.class) != null;
StructuredGraph graph = new StructuredGraph.Builder(options, debug).method(method).setIsSubstitution(isSubstitution).build();
try (DebugCloseable s = debug.disableIntercept(); DebugContext.Scope ds = debug.scope("CheckingGraph", graph, method)) {
@@ -471,6 +484,13 @@ public class CheckGraalInvariants extends GraalCompilerTest {
}
}
+ @SuppressWarnings("unchecked")
+ private static void loadVerifiers(List> verifiers) {
+ for (VerifyPhase verifier : ServiceLoader.load(VerifyPhase.class)) {
+ verifiers.add(verifier);
+ }
+ }
+
/**
* Initializes a map from a field annotated by {@link Option} to a set that will be used to
* collect methods that accesses the option field.
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionTest.java
index 450a61f239b..575125ddd27 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020, 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
@@ -108,4 +108,27 @@ public class ConditionTest {
}
}
+ static int[] intBoundaryValues = new int[]{-1, 0, 1, Integer.MIN_VALUE, Integer.MIN_VALUE + 1, Integer.MAX_VALUE - 1, Integer.MAX_VALUE};
+
+ @Test
+ public void testTrueIsDisjoint() {
+ for (Condition c1 : Condition.values()) {
+ for (Condition c2 : Condition.values()) {
+ if (c1.trueIsDisjoint(c2)) {
+ for (int v1 : intBoundaryValues) {
+ for (int v2 : intBoundaryValues) {
+ JavaConstant a = JavaConstant.forInt(v1);
+ JavaConstant b = JavaConstant.forInt(v2);
+ boolean result1 = c1.foldCondition(a, b, null, false);
+ boolean result2 = c2.foldCondition(a, b, null, false);
+ // If these conditions are disjoint then both conditions can't evaluate
+ // to true for the same inputs.
+ assertFalse(String.format("%s %s %s (%s) is not disjoint from %s %s %s (%s)", a, c1, b, result1, a, c2, b, result2), result1 && result2);
+ }
+ }
+ }
+ }
+ }
+ }
+
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GuardPrioritiesTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GuardPrioritiesTest.java
index 61a23420b6d..de2f08855ca 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GuardPrioritiesTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GuardPrioritiesTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, 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
@@ -93,7 +93,7 @@ public class GuardPrioritiesTest extends GraphScheduleTest {
return graph;
}
- public int unknownCondition(Integer c, Object o, int[] a, Integer i) {
+ public int unknownCondition(int c, Object o, int[] a, int i) {
if (o != null) {
GraalDirectives.deoptimizeAndInvalidate();
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/IfCanonicalizerSwapTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/IfCanonicalizerSwapTest.java
new file mode 100644
index 00000000000..f1712737472
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/IfCanonicalizerSwapTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.core.test;
+
+import static org.graalvm.compiler.api.directives.GraalDirectives.injectBranchProbability;
+
+import org.junit.Test;
+
+/**
+ * Test extracted from reproducer in https://github.com/oracle/graal/issues/2493.
+ */
+public class IfCanonicalizerSwapTest extends GraalCompilerTest {
+ public static String testSnippet1(long value) {
+ if (injectBranchProbability(0.50, value >= 0L) && injectBranchProbability(0.00, value <= 35L)) {
+ return "JustRight";
+ } else {
+ if (injectBranchProbability(0.50, value > 35L)) {
+ return "TooHot";
+ } else {
+ return "TooCold";
+ }
+ }
+ }
+
+ @Test
+ public void test1() {
+ test("testSnippet1", -1L);
+ test("testSnippet1", 100L);
+ test("testSnippet1", 10L);
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LateMembarInsertionTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LateMembarInsertionTest.java
index b8a0c3eff2e..591de0a36cf 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LateMembarInsertionTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LateMembarInsertionTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -26,17 +26,20 @@
package org.graalvm.compiler.core.test;
+import jdk.vm.ci.aarch64.AArch64;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.internal.vm.compiler.collections.EconomicMap;
import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.cfg.Block;
import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
+import org.graalvm.compiler.nodes.extended.MembarNode;
import org.graalvm.compiler.nodes.memory.FixedAccessNode;
import org.graalvm.compiler.nodes.memory.MemoryAccess;
import org.graalvm.compiler.nodes.memory.ReadNode;
@@ -78,7 +81,7 @@ public class LateMembarInsertionTest extends GraalCompilerTest {
@Test
public void test01() {
- List accesses = compile("volatileFieldLoadFieldLoad", stressTestEarlyReads());
+ List accesses = getAccesses("volatileFieldLoadFieldLoad", stressTestEarlyReads());
Assert.assertEquals(accesses.size(), 2);
Assert.assertEquals(accesses.get(0).getType(), volatileAccessType);
@@ -95,7 +98,7 @@ public class LateMembarInsertionTest extends GraalCompilerTest {
@Test
public void test02() {
- List accesses = compile("volatileFieldLoadVolatileFieldLoad", stressTestEarlyReads());
+ List accesses = getAccesses("volatileFieldLoadVolatileFieldLoad", stressTestEarlyReads());
Assert.assertEquals(accesses.size(), 2);
Assert.assertEquals(accesses.get(0).getType(), volatileAccessType);
@@ -112,7 +115,7 @@ public class LateMembarInsertionTest extends GraalCompilerTest {
@Test
public void test03() {
- List accesses = compile("volatileFieldLoadVolatileFieldStore");
+ List accesses = getAccesses("volatileFieldLoadVolatileFieldStore");
Assert.assertEquals(accesses.size(), 2);
Assert.assertEquals(accesses.get(0).getType(), volatileAccessType);
@@ -128,7 +131,7 @@ public class LateMembarInsertionTest extends GraalCompilerTest {
@Test
public void test04() {
- List accesses = compile("volatileFieldStoreVolatileFieldLoad", stressTestEarlyReads());
+ List accesses = getAccesses("volatileFieldStoreVolatileFieldLoad", stressTestEarlyReads());
Assert.assertEquals(accesses.size(), 2);
Assert.assertEquals(accesses.get(0).getType(), volatileAccessType);
@@ -145,7 +148,7 @@ public class LateMembarInsertionTest extends GraalCompilerTest {
@Test
public void test05() {
- List accesses = compile("fieldLoadVolatileFieldStore");
+ List accesses = getAccesses("fieldLoadVolatileFieldStore");
Assert.assertEquals(accesses.size(), 2);
Assert.assertEquals(accesses.get(0).getType(), regularAccessField);
@@ -161,7 +164,7 @@ public class LateMembarInsertionTest extends GraalCompilerTest {
@Test
public void test06() {
- List accesses = compile("volatileFieldStoreVolatileFieldStore");
+ List accesses = getAccesses("volatileFieldStoreVolatileFieldStore");
Assert.assertEquals(accesses.size(), 2);
Assert.assertEquals(accesses.get(0).getType(), volatileAccessType);
@@ -170,6 +173,119 @@ public class LateMembarInsertionTest extends GraalCompilerTest {
Assert.assertTrue(accesses.get(1).isWrite());
}
+ public static int volatileFieldLoad() {
+ return VolatileAccess.field;
+ }
+
+ @Test
+ public void test07() {
+ verifyMembars("volatileFieldLoad", membarsExpected());
+ }
+
+ private boolean membarsExpected() {
+ return !(getTarget().arch instanceof AArch64);
+ }
+
+ public static void volatileFieldStore(int v) {
+ VolatileAccess.field = v;
+ }
+
+ @Test
+ public void test08() {
+ verifyMembars("volatileFieldStore", membarsExpected());
+ }
+
+ // Unused field load should be optimized out and leave no barrier behind
+ @SuppressWarnings("unused")
+ public static void volatileFieldStoreUnusedVolatileFieldLoadVolatileFieldStore(int v2) {
+ VolatileAccess2.field = v2;
+ int v1 = VolatileAccess.field;
+ VolatileAccess2.field = v2;
+ }
+
+ @Test
+ public void test09() {
+ StructuredGraph graph = getFinalGraph(getResolvedJavaMethod("volatileFieldStoreUnusedVolatileFieldLoadVolatileFieldStore"));
+ List accesses = getAccesses(graph);
+
+ Assert.assertEquals(accesses.size(), 2);
+ Assert.assertEquals(accesses.get(0).getType(), volatileAccess2Type);
+ Assert.assertEquals(accesses.get(1).getType(), volatileAccess2Type);
+ Assert.assertTrue(accesses.get(0).isWrite());
+ Assert.assertTrue(accesses.get(1).isWrite());
+ Assert.assertEquals(membarsExpected() ? 4 : 0, getMembars(graph).size());
+ }
+
+ // Unused field load should be optimized out and leave no barrier behind
+ @SuppressWarnings("unused")
+ public static void unusedVolatileFieldLoadVolatileFieldStore(int v2) {
+ int v1 = VolatileAccess.field;
+ VolatileAccess2.field = v2;
+ }
+
+ @Test
+ public void test10() {
+ StructuredGraph graph = getFinalGraph(getResolvedJavaMethod("unusedVolatileFieldLoadVolatileFieldStore"));
+ List accesses = getAccesses(graph);
+
+ Assert.assertEquals(accesses.size(), 1);
+ Assert.assertEquals(accesses.get(0).getType(), volatileAccess2Type);
+ Assert.assertTrue(accesses.get(0).isWrite());
+ Assert.assertEquals(membarsExpected() ? 2 : 0, getMembars(graph).size());
+ }
+
+ public static int unsafeVolatileFieldLoad(Object o, long offset) {
+ return UNSAFE.getIntVolatile(o, offset);
+ }
+
+ @Test
+ public void test11() {
+ verifyMembars("unsafeVolatileFieldLoad", membarsExpected());
+ }
+
+ public static void unsafeVolatileFieldStore(Object o, long offset, int v) {
+ UNSAFE.putIntVolatile(o, offset, v);
+ }
+
+ @Test
+ public void test12() {
+ verifyMembars("unsafeVolatileFieldStore", membarsExpected());
+ }
+
+ private void verifyMembars(String method, boolean expectsMembar) {
+ StructuredGraph graph = getFinalGraph(getResolvedJavaMethod(method));
+ StructuredGraph.ScheduleResult schedule = graph.getLastSchedule();
+ ControlFlowGraph cfg = schedule.getCFG();
+ Block[] blocks = cfg.getBlocks();
+ Assert.assertEquals(blocks.length, 1);
+ Block block = blocks[0];
+ List nodes = schedule.nodesFor(block);
+ Node preBarrier = null;
+ Node postBarrier = null;
+ Node mem = null;
+ for (int i = 0; i < nodes.size(); i++) {
+ Node node = nodes.get(i);
+ if (node instanceof MembarNode) {
+ if (preBarrier == null) {
+ Assert.assertNull(mem);
+ preBarrier = node;
+ } else {
+ Assert.assertNull(postBarrier);
+ Assert.assertNotNull(mem);
+ postBarrier = node;
+ }
+ } else if (node instanceof MemoryAccess) {
+ Assert.assertEquals(preBarrier != null, expectsMembar);
+ Assert.assertNull(postBarrier);
+ Assert.assertNull(mem);
+ mem = node;
+ }
+ }
+ Assert.assertEquals(preBarrier != null, expectsMembar);
+ Assert.assertEquals(postBarrier != null, expectsMembar);
+ Assert.assertNotNull(mem);
+ }
+
private static OptionValues stressTestEarlyReads() {
EconomicMap, Object> overrides = OptionValues.newOptionMap();
overrides.put(StressTestEarlyReads, true);
@@ -198,7 +314,7 @@ public class LateMembarInsertionTest extends GraalCompilerTest {
}
}
- private List compile(String test, OptionValues options) {
+ private List getAccesses(String test, OptionValues options) {
StructuredGraph graph = getFinalGraph(getResolvedJavaMethod(test), options);
return getAccesses(graph);
}
@@ -212,7 +328,7 @@ public class LateMembarInsertionTest extends GraalCompilerTest {
n -> new TypePair(n instanceof ReadNode, classForAccess((FixedAccessNode) n))).collect(Collectors.toList());
}
- private List compile(String test) {
+ private List getAccesses(String test) {
StructuredGraph graph = getFinalGraph(getResolvedJavaMethod(test));
return getAccesses(graph);
}
@@ -230,4 +346,11 @@ public class LateMembarInsertionTest extends GraalCompilerTest {
return javaType;
}
+ private static List getMembars(StructuredGraph graph) {
+ StructuredGraph.ScheduleResult schedule = graph.getLastSchedule();
+ ControlFlowGraph cfg = schedule.getCFG();
+ Block[] blocks = cfg.getBlocks();
+
+ return Arrays.stream(blocks).flatMap(b -> schedule.nodesFor(b).stream()).filter(n -> n instanceof MembarNode).collect(Collectors.toList());
+ }
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LockEliminationTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LockEliminationTest.java
index cfcf2094c01..a42cfecdba2 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LockEliminationTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LockEliminationTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,8 +28,8 @@ import org.graalvm.compiler.loop.DefaultLoopPolicies;
import org.graalvm.compiler.loop.phases.LoopFullUnrollPhase;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.java.MonitorEnterNode;
import org.graalvm.compiler.nodes.java.MonitorExitNode;
-import org.graalvm.compiler.nodes.java.RawMonitorEnterNode;
import org.graalvm.compiler.nodes.spi.LoweringTool;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
@@ -71,7 +71,7 @@ public class LockEliminationTest extends GraalCompilerTest {
StructuredGraph graph = getGraph("testSynchronizedSnippet", false);
createCanonicalizerPhase().apply(graph, getProviders());
new LockEliminationPhase().apply(graph);
- assertDeepEquals(1, graph.getNodes().filter(RawMonitorEnterNode.class).count());
+ assertDeepEquals(1, graph.getNodes().filter(MonitorEnterNode.class).count());
assertDeepEquals(1, graph.getNodes().filter(MonitorExitNode.class).count());
}
@@ -89,7 +89,7 @@ public class LockEliminationTest extends GraalCompilerTest {
StructuredGraph graph = getGraph("testSynchronizedMethodSnippet", false);
createCanonicalizerPhase().apply(graph, getProviders());
new LockEliminationPhase().apply(graph);
- assertDeepEquals(1, graph.getNodes().filter(RawMonitorEnterNode.class).count());
+ assertDeepEquals(1, graph.getNodes().filter(MonitorEnterNode.class).count());
assertDeepEquals(1, graph.getNodes().filter(MonitorExitNode.class).count());
}
@@ -109,7 +109,7 @@ public class LockEliminationTest extends GraalCompilerTest {
HighTierContext context = getDefaultHighTierContext();
new LoopFullUnrollPhase(canonicalizer, new DefaultLoopPolicies()).apply(graph, context);
new LockEliminationPhase().apply(graph);
- assertDeepEquals(1, graph.getNodes().filter(RawMonitorEnterNode.class).count());
+ assertDeepEquals(1, graph.getNodes().filter(MonitorEnterNode.class).count());
assertDeepEquals(1, graph.getNodes().filter(MonitorExitNode.class).count());
}
@@ -157,12 +157,12 @@ public class LockEliminationTest extends GraalCompilerTest {
public void testEscapeAnalysis() {
StructuredGraph graph = getGraph("testEscapeAnalysisSnippet", true);
- assertDeepEquals(3, graph.getNodes().filter(RawMonitorEnterNode.class).count());
+ assertDeepEquals(3, graph.getNodes().filter(MonitorEnterNode.class).count());
assertDeepEquals(3, graph.getNodes().filter(MonitorExitNode.class).count());
new LockEliminationPhase().apply(graph);
- assertDeepEquals(2, graph.getNodes().filter(RawMonitorEnterNode.class).count());
+ assertDeepEquals(2, graph.getNodes().filter(MonitorEnterNode.class).count());
assertDeepEquals(2, graph.getNodes().filter(MonitorExitNode.class).count());
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LongNodeChainTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LongNodeChainTest.java
index aa54d3fad3b..8b4f34d9421 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LongNodeChainTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LongNodeChainTest.java
@@ -24,12 +24,7 @@
package org.graalvm.compiler.core.test;
-import jdk.vm.ci.meta.JavaConstant;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.graalvm.compiler.debug.DebugHandlersFactory;
-import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugContext.Builder;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.ReturnNode;
import org.graalvm.compiler.nodes.StructuredGraph;
@@ -40,6 +35,10 @@ import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.schedule.SchedulePhase;
import org.graalvm.compiler.phases.schedule.SchedulePhase.SchedulingStrategy;
import org.graalvm.compiler.phases.tiers.HighTierContext;
+import org.junit.Assert;
+import org.junit.Test;
+
+import jdk.vm.ci.meta.JavaConstant;
public class LongNodeChainTest extends GraalCompilerTest {
@@ -56,7 +55,7 @@ public class LongNodeChainTest extends GraalCompilerTest {
private void longAddChain(boolean reverse) {
HighTierContext context = getDefaultHighTierContext();
OptionValues options = getInitialOptions();
- StructuredGraph graph = new StructuredGraph.Builder(options, DebugContext.create(options, DebugHandlersFactory.LOADER)).build();
+ StructuredGraph graph = new StructuredGraph.Builder(options, new Builder(options).build()).build();
ValueNode constant = graph.unique(ConstantNode.forPrimitive(JavaConstant.INT_1));
ValueNode value = null;
if (reverse) {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MemoryGraphCanonicalizeTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MemoryGraphCanonicalizeTest.java
index 6236a750073..b26f86d82d3 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MemoryGraphCanonicalizeTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MemoryGraphCanonicalizeTest.java
@@ -25,13 +25,11 @@
package org.graalvm.compiler.core.test;
+import org.graalvm.compiler.api.test.Graal;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.memory.WriteNode;
-import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.compiler.phases.common.FloatingReadPhase;
-import org.graalvm.compiler.phases.common.IncrementalCanonicalizerPhase;
-import org.graalvm.compiler.phases.common.LoweringPhase;
-import org.graalvm.compiler.phases.tiers.HighTierContext;
+import org.graalvm.compiler.phases.tiers.Suites;
+import org.graalvm.compiler.runtime.RuntimeProvider;
import org.junit.Test;
public class MemoryGraphCanonicalizeTest extends GraalCompilerTest {
@@ -69,15 +67,15 @@ public class MemoryGraphCanonicalizeTest extends GraalCompilerTest {
@Test
public void testComplexElimination() {
- testGraph("complexElimination", 6);
+ testGraph("complexElimination", 5);
}
public void testGraph(String name, int expectedWrites) {
StructuredGraph graph = parseEager(name, StructuredGraph.AllowAssumptions.YES);
- HighTierContext context = getDefaultHighTierContext();
- new LoweringPhase(createCanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
- new IncrementalCanonicalizerPhase<>(createCanonicalizerPhase(), new FloatingReadPhase()).apply(graph, context);
- createCanonicalizerPhase().apply(graph, context);
+ Suites s = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getSuites().getDefaultSuites(getInitialOptions());
+ s.getHighTier().apply(graph, getDefaultHighTierContext());
+ s.getMidTier().apply(graph, getDefaultMidTierContext());
+
int writes = graph.getNodes().filter(WriteNode.class).count();
assertTrue(writes == expectedWrites, "Expected %d writes, found %d", expectedWrites, writes);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MemoryScheduleTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MemoryScheduleTest.java
index df1e4fcfdd1..5e27ff4d984 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MemoryScheduleTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MemoryScheduleTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2020, 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
@@ -40,6 +40,7 @@ import org.graalvm.compiler.graph.iterators.NodeIterable;
import org.graalvm.compiler.nodes.ReturnNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.StructuredGraph.GuardsStage;
import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
import org.graalvm.compiler.nodes.cfg.Block;
import org.graalvm.compiler.nodes.memory.FloatingReadNode;
@@ -699,16 +700,20 @@ public class MemoryScheduleTest extends GraphScheduleTest {
createInliningPhase(canonicalizer).apply(graph, context);
}
new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
- if (mode == TestMode.WITHOUT_FRAMESTATES || mode == TestMode.INLINED_WITHOUT_FRAMESTATES) {
- graph.clearAllStateAfter();
- }
- debug.dump(DebugContext.BASIC_LEVEL, graph, "after removal of framestates");
new FloatingReadPhase().apply(graph);
new RemoveValueProxyPhase().apply(graph);
MidTierContext midContext = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo());
new GuardLoweringPhase().apply(graph, midContext);
+
+ if (mode == TestMode.WITHOUT_FRAMESTATES || mode == TestMode.INLINED_WITHOUT_FRAMESTATES) {
+ graph.clearAllStateAfter();
+ // disable stat split verification
+ graph.setGuardsStage(GuardsStage.AFTER_FSA);
+ }
+ debug.dump(DebugContext.BASIC_LEVEL, graph, "after removal of framestates");
+
new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext);
new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.LOW_TIER).apply(graph, midContext);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/NegateCanonicalizationTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/NegateCanonicalizationTest.java
new file mode 100644
index 00000000000..5b8f08bff2b
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/NegateCanonicalizationTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 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.test;
+
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.calc.NegateNode;
+import org.graalvm.compiler.nodes.calc.RightShiftNode;
+import org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode;
+import org.junit.Test;
+
+public class NegateCanonicalizationTest extends GraalCompilerTest {
+
+ public static int negateInt(int x) {
+ return -(x >> 31);
+ }
+
+ public static long negateLong(long x) {
+ return -(x >> 63);
+ }
+
+ public static int signExtractInt(int x) {
+ return (x >> 31) >>> 31;
+ }
+
+ public static long signExtractLong(long x) {
+ return (x >> 63) >>> 63;
+ }
+
+ private void checkNodes(String methodName) {
+ StructuredGraph graph = parseForCompile(getResolvedJavaMethod(methodName));
+ createCanonicalizerPhase().apply(graph, getProviders());
+ assertTrue(graph.getNodes().filter(NegateNode.class).count() == 0);
+ assertTrue(graph.getNodes().filter(RightShiftNode.class).count() == 0);
+ assertTrue(graph.getNodes().filter(UnsignedRightShiftNode.class).count() == 1);
+ }
+
+ @Test
+ public void testNegate() {
+ checkNodes("negateInt");
+ checkNodes("negateLong");
+ checkNodes("signExtractInt");
+ checkNodes("signExtractLong");
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/NodePosIteratorTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/NodePosIteratorTest.java
index 11920b25f39..35df3db7971 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/NodePosIteratorTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/NodePosIteratorTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020, 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
@@ -29,9 +29,8 @@ import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED;
import java.util.Iterator;
-import org.junit.Assert;
-import org.junit.Test;
-
+import org.graalvm.compiler.core.common.PermanentBailoutException;
+import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.NodeInputList;
@@ -39,10 +38,15 @@ import org.graalvm.compiler.graph.NodeSuccessorList;
import org.graalvm.compiler.graph.Position;
import org.graalvm.compiler.graph.iterators.NodeIterable;
import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.AbstractMergeNode;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.EndNode;
+import org.graalvm.compiler.nodes.MergeNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.FloatingNode;
+import org.junit.Assert;
+import org.junit.Test;
public class NodePosIteratorTest extends GraalCompilerTest {
@@ -63,6 +67,27 @@ public class NodePosIteratorTest extends GraalCompilerTest {
}
+ @Test
+ public void testNodeInputIteratorLimit() {
+ DebugContext debug = getDebugContext();
+ StructuredGraph graph = new StructuredGraph.Builder(debug.getOptions(), debug,
+ StructuredGraph.AllowAssumptions.YES).build();
+
+ AbstractMergeNode merge = graph.add(new MergeNode());
+ for (int i = 0; i < 65536; i++) {
+ EndNode end = graph.add(new EndNode());
+ merge.addForwardEnd(end);
+ }
+ merge.inputs().count();
+ EndNode end = graph.add(new EndNode());
+ try {
+ merge.addForwardEnd(end);
+ } catch (PermanentBailoutException e) {
+ return;
+ }
+ Assert.fail("Expected a permanent bailout exception due to too high number of inputs");
+ }
+
@Test
public void testInputs() {
TestNode n = new TestNode();
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SchedulingTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SchedulingTest.java
index 8195e18651b..b626bed73ef 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SchedulingTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SchedulingTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, 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
@@ -62,6 +62,7 @@ public class SchedulingTest extends GraphScheduleTest {
fs.replaceAtUsages(null);
GraphUtil.killWithUnusedFloatingInputs(fs);
}
+ graph.clearAllStateAfter();
SchedulePhase schedulePhase = new SchedulePhase(SchedulingStrategy.LATEST);
schedulePhase.apply(graph);
ScheduleResult schedule = graph.getLastSchedule();
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SimpleCFGTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SimpleCFGTest.java
index 89e789188a2..1e724860e40 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SimpleCFGTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SimpleCFGTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
package org.graalvm.compiler.core.test;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugContext.Builder;
import org.graalvm.compiler.nodes.AbstractBeginNode;
import org.graalvm.compiler.nodes.AbstractMergeNode;
import org.graalvm.compiler.nodes.BeginNode;
@@ -51,7 +52,7 @@ public class SimpleCFGTest extends GraalCompilerTest {
@Test
public void testImplies() {
OptionValues options = getInitialOptions();
- DebugContext debug = DebugContext.create(options, new GraalDebugHandlersFactory(getSnippetReflection()));
+ DebugContext debug = new Builder(options, new GraalDebugHandlersFactory(getSnippetReflection())).build();
StructuredGraph graph = new StructuredGraph.Builder(options, debug, AllowAssumptions.YES).build();
EndNode trueEnd = graph.add(new EndNode());
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/StaticInterfaceFieldTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/StaticInterfaceFieldTest.java
index 1ba8f5fc16f..7ee69e1b740 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/StaticInterfaceFieldTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/StaticInterfaceFieldTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, 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
@@ -30,8 +30,8 @@ import java.lang.reflect.Method;
import org.graalvm.compiler.api.test.Graal;
import org.graalvm.compiler.debug.DebugCloseable;
-import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugContext.Builder;
import org.graalvm.compiler.java.GraphBuilderPhase;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
@@ -93,7 +93,7 @@ public class StaticInterfaceFieldTest extends GraalTest {
final Method m = getMethod(clazz, methodName);
ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m);
OptionValues options = getInitialOptions();
- DebugContext debug = DebugContext.create(options, DebugHandlersFactory.LOADER);
+ DebugContext debug = new Builder(options).build();
StructuredGraph graph = new StructuredGraph.Builder(options, debug).method(method).build();
try (DebugCloseable s = debug.disableIntercept(); DebugContext.Scope ds = debug.scope("GraphBuilding", graph, method)) {
graphBuilderSuite.apply(graph, context);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeVirtualizationTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeVirtualizationTest.java
index a70ebe82544..9373458d859 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeVirtualizationTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeVirtualizationTest.java
@@ -282,6 +282,7 @@ public class UnsafeVirtualizationTest extends GraalCompilerTest {
} else {
UNSAFE.putLong(t, getUnsafeByteArrayOffset(0), l2);
}
+ sideEffect();
if (c) {
GraalDirectives.deoptimize();
}
@@ -495,7 +496,7 @@ public class UnsafeVirtualizationTest extends GraalCompilerTest {
VirtualObjectNode virtual = graph.getNodes().filter(VirtualObjectNode.class).first();
if (virtual instanceof VirtualArrayNode) {
VirtualArrayNode array = (VirtualArrayNode) virtual;
- if (array.isVirtualByteArray()) {
+ if (array.isVirtualByteArray(context.getMetaAccessExtensionProvider())) {
canVirtualize = context.getPlatformConfigurationProvider().canVirtualizeLargeByteArrayAccess();
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnschedulableGraphTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnschedulableGraphTest.java
new file mode 100644
index 00000000000..7d858de3aab
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnschedulableGraphTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.core.test;
+
+import static org.graalvm.compiler.debug.DebugOptions.DumpOnError;
+
+import java.util.List;
+
+import org.graalvm.compiler.api.directives.GraalDirectives;
+import org.graalvm.compiler.core.common.cfg.BlockMap;
+import org.graalvm.compiler.debug.DebugCloseable;
+import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.TTY;
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.graph.NodeMap;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
+import org.graalvm.compiler.nodes.calc.NegateNode;
+import org.graalvm.compiler.nodes.cfg.Block;
+import org.graalvm.compiler.nodes.extended.OpaqueNode;
+import org.graalvm.compiler.options.OptionValues;
+import org.junit.Assert;
+import org.junit.Test;
+
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+/**
+ * This test verifies that the backend detects graphs for which the scheduling is broken, i.e. input
+ * values are scheduled in non-dominating blocks causing illegal flow of values in the control flow
+ * graph.
+ */
+public class UnschedulableGraphTest extends GraalCompilerTest {
+
+ public static int snippet01(int a, int b, int c) {
+ if (GraalDirectives.sideEffect(a) == b) {
+ GraalDirectives.sideEffect(b);
+ GraalDirectives.controlFlowAnchor();
+ } else {
+ GraalDirectives.sideEffect(c);
+ GraalDirectives.controlFlowAnchor();
+ }
+ GraalDirectives.sideEffect();
+ GraalDirectives.controlFlowAnchor();
+ return GraalDirectives.opaque(-a) + GraalDirectives.opaque(-b);
+ }
+
+ @Override
+ protected void checkLowTierGraph(StructuredGraph graph) {
+ super.checkLowTierGraph(graph);
+ ScheduleResult res = graph.getLastSchedule();
+ BlockMap> blockToNode = res.getBlockToNodesMap();
+ NodeMap nodeToBlock = res.getNodeToBlockMap();
+ Assert.assertEquals(4, res.getCFG().getBlocks().length);
+ Block split = res.getCFG().getStartBlock();
+ Assert.assertEquals(2, split.getSuccessorCount());
+ Block trueSucc = split.getSuccessors()[0];
+ Block falseSucc = split.getSuccessors()[1];
+ Block merge = trueSucc.getFirstSuccessor();
+ Assert.assertEquals(merge, falseSucc.getFirstSuccessor());
+ for (OpaqueNode op : graph.getNodes().filter(OpaqueNode.class)) {
+ Assert.assertEquals(merge, res.getNodeToBlockMap().get(op));
+ }
+ int k = 0;
+ // destroy dominance relation for NegateNode nodes, they no longer dominate the addition
+ for (NegateNode op : graph.getNodes().filter(NegateNode.class)) {
+ final Block nonDominatingBlock = k++ % 2 == 0 ? trueSucc : falseSucc;
+ blockToNode.get(merge).remove(op);
+ blockToNode.get(nonDominatingBlock).add(0, op);
+ nodeToBlock.set(op, nonDominatingBlock);
+ }
+ graph.getDebug().dump(DebugContext.VERBOSE_LEVEL, graph, "After changing constant schedule");
+ }
+
+ private DebugContext getDebugContext(ResolvedJavaMethod method) {
+ OptionValues options = new OptionValues(getInitialOptions(), DumpOnError, false);
+ return getDebugContext(options, null, method);
+ }
+
+ @Test
+ @SuppressWarnings("try")
+ public void test01() {
+ ResolvedJavaMethod method = getResolvedJavaMethod("snippet01");
+ try (AutoCloseable c = new TTY.Filter();
+ DebugContext debug = getDebugContext(method);
+ DebugCloseable s = debug.disableIntercept()) {
+ test("snippet01", 0, 1, 2);
+ Assert.fail("Compilation should not reach this point, must throw an exception before");
+ } catch (Throwable t) {
+ if (t.getMessage().contains("liveIn set of first block must be empty")) {
+ return;
+ }
+ throw new AssertionError(t);
+ }
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyBailoutUsageTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyBailoutUsageTest.java
index 427bf523490..267f1ffb042 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyBailoutUsageTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyBailoutUsageTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2020, 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
@@ -33,8 +33,8 @@ import org.graalvm.compiler.api.test.Graal;
import org.graalvm.compiler.core.common.PermanentBailoutException;
import org.graalvm.compiler.core.common.RetryableBailoutException;
import org.graalvm.compiler.debug.DebugCloseable;
-import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugContext.Builder;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.java.GraphBuilderPhase;
import org.graalvm.compiler.nodes.StructuredGraph;
@@ -128,7 +128,7 @@ public class VerifyBailoutUsageTest {
graphBuilderSuite.appendPhase(new GraphBuilderPhase(config));
HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE);
OptionValues options = getInitialOptions();
- DebugContext debug = DebugContext.create(options, DebugHandlersFactory.LOADER);
+ DebugContext debug = new Builder(options).build();
for (Method m : c.getDeclaredMethods()) {
if (!Modifier.isNative(m.getModifiers()) && !Modifier.isAbstract(m.getModifiers())) {
ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyDebugUsage.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyDebugUsage.java
index e840d107068..ede9a59e1ec 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyDebugUsage.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyDebugUsage.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, 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
@@ -144,8 +144,8 @@ public class VerifyDebugUsage extends VerifyPhase {
"org.graalvm.compiler.phases.BasePhase.dumpAfter",
"org.graalvm.compiler.phases.BasePhase.dumpBefore",
"org.graalvm.compiler.core.GraalCompiler.emitFrontEnd",
- "org.graalvm.compiler.truffle.compiler.PartialEvaluator.fastPartialEvaluation",
- "org.graalvm.compiler.truffle.compiler.PartialEvaluator$PerformanceInformationHandler.reportPerformanceWarnings",
+ "org.graalvm.compiler.truffle.compiler.PartialEvaluator.inliningGraphPE",
+ "org.graalvm.compiler.truffle.compiler.PerformanceInformationHandler.reportPerformanceWarnings",
"org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl.compilePEGraph",
"org.graalvm.compiler.core.test.VerifyDebugUsageTest$ValidDumpUsagePhase.run",
"org.graalvm.compiler.core.test.VerifyDebugUsageTest$InvalidConcatDumpUsagePhase.run",
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyDebugUsageTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyDebugUsageTest.java
index cfed3ec4086..4ab782499df 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyDebugUsageTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyDebugUsageTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, 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
@@ -31,8 +31,8 @@ import java.lang.reflect.Modifier;
import org.graalvm.compiler.api.test.Graal;
import org.graalvm.compiler.debug.DebugCloseable;
-import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugContext.Builder;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.debug.Indent;
import org.graalvm.compiler.graph.Node;
@@ -349,7 +349,7 @@ public class VerifyDebugUsageTest {
graphBuilderSuite.appendPhase(new GraphBuilderPhase(config));
HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE);
OptionValues options = getInitialOptions();
- DebugContext debug = DebugContext.create(options, DebugHandlersFactory.LOADER);
+ DebugContext debug = new Builder(options).build();
for (Method m : c.getDeclaredMethods()) {
if (!Modifier.isNative(m.getModifiers()) && !Modifier.isAbstract(m.getModifiers())) {
ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyVirtualizableTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyVirtualizableTest.java
index b04f67acbaf..aa269da38a2 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyVirtualizableTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyVirtualizableTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, 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
@@ -34,8 +34,8 @@ import java.lang.reflect.Modifier;
import org.graalvm.compiler.api.test.Graal;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.debug.DebugCloseable;
-import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugContext.Builder;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.java.GraphBuilderPhase;
import org.graalvm.compiler.nodeinfo.NodeInfo;
@@ -273,7 +273,7 @@ public class VerifyVirtualizableTest {
graphBuilderSuite.appendPhase(new GraphBuilderPhase(config));
HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE);
OptionValues options = getInitialOptions();
- DebugContext debug = DebugContext.create(options, DebugHandlersFactory.LOADER);
+ DebugContext debug = new Builder(options).build();
for (Method m : c.getDeclaredMethods()) {
if (!Modifier.isNative(m.getModifiers()) && !Modifier.isAbstract(m.getModifiers())) {
ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EATestBase.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EATestBase.java
index 87cc336f526..cde9141018f 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EATestBase.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/EATestBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2020, 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
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PartialEscapeAnalysisTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PartialEscapeAnalysisTest.java
index 4b57eb7a1dd..5093c980519 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PartialEscapeAnalysisTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PartialEscapeAnalysisTest.java
@@ -26,14 +26,9 @@ package org.graalvm.compiler.core.test.ea;
import java.lang.ref.SoftReference;
-import org.junit.Assert;
-import org.junit.Ignore;
-import org.junit.Test;
-
import org.graalvm.compiler.api.directives.GraalDirectives;
import org.graalvm.compiler.core.test.TypeSystemTest;
import org.graalvm.compiler.graph.Node;
-import org.graalvm.compiler.nodes.AbstractMergeNode;
import org.graalvm.compiler.nodes.ReturnNode;
import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
import org.graalvm.compiler.nodes.extended.BoxNode;
@@ -45,6 +40,9 @@ import org.graalvm.compiler.nodes.java.NewInstanceNode;
import org.graalvm.compiler.nodes.java.StoreFieldNode;
import org.graalvm.compiler.nodes.virtual.CommitAllocationNode;
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
/**
* The PartialEscapeAnalysisPhase is expected to remove all allocations and return the correct
@@ -282,9 +280,7 @@ public class PartialEscapeAnalysisTest extends EATestBase {
@SafeVarargs
protected final void testPartialEscapeAnalysis(String snippet, double expectedProbability, int expectedCount, Class extends Node>... invalidNodeClasses) {
prepareGraph(snippet, false);
- for (AbstractMergeNode merge : graph.getNodes(AbstractMergeNode.TYPE)) {
- merge.setStateAfter(null);
- }
+ graph.clearAllStateAfter();
new DeadCodeEliminationPhase().apply(graph);
createCanonicalizerPhase().apply(graph, context);
try {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/InvokeGraal.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/InvokeGraal.java
index 362b5f3bd10..81075f1d8d3 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/InvokeGraal.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/InvokeGraal.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, 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
@@ -34,8 +34,8 @@ import org.graalvm.compiler.code.CompilationResult;
import org.graalvm.compiler.core.GraalCompiler;
import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.core.target.Backend;
-import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugContext.Builder;
import org.graalvm.compiler.debug.DebugDumpScope;
import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory;
import org.graalvm.compiler.lir.phases.LIRSuites;
@@ -88,7 +88,7 @@ public class InvokeGraal {
/* Create a unique compilation identifier, visible in IGV. */
CompilationIdentifier compilationId = backend.getCompilationIdentifier(method);
OptionValues options = getInitialOptions();
- DebugContext debug = DebugContext.create(options, DebugHandlersFactory.LOADER);
+ DebugContext debug = new Builder(options).build();
try (DebugContext.Scope s = debug.scope("compileAndInstallMethod", new DebugDumpScope(String.valueOf(compilationId), true))) {
/*
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/StaticAnalysis.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/StaticAnalysis.java
index fcedb865eec..d1a00198466 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/StaticAnalysis.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/tutorial/StaticAnalysis.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, 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
@@ -35,7 +35,7 @@ import java.util.Map;
import java.util.Set;
import org.graalvm.compiler.debug.DebugContext;
-import org.graalvm.compiler.debug.DebugHandlersFactory;
+import org.graalvm.compiler.debug.DebugContext.Builder;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeMap;
@@ -246,7 +246,7 @@ public class StaticAnalysis {
*/
OptionValues options = getInitialOptions();
- DebugContext debug = DebugContext.create(options, DebugHandlersFactory.LOADER);
+ DebugContext debug = new Builder(options).build();
StructuredGraph graph = new StructuredGraph.Builder(options, debug).method(method).build();
/*
* Support for graph dumping, IGV uses this information to show the method name of a
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java
index 7c27cb18869..0d34bc0e002 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, 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
@@ -30,7 +30,6 @@ import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationFailureA
import static org.graalvm.compiler.core.GraalCompilerOptions.ExitVMOnException;
import static org.graalvm.compiler.core.GraalCompilerOptions.MaxCompilationProblemsPerAction;
import static org.graalvm.compiler.core.common.GraalOptions.TrackNodeSourcePosition;
-import static org.graalvm.compiler.debug.DebugContext.VERBOSE_LEVEL;
import static org.graalvm.compiler.debug.DebugOptions.Dump;
import static org.graalvm.compiler.debug.DebugOptions.DumpPath;
import static org.graalvm.compiler.debug.DebugOptions.MethodFilter;
@@ -43,6 +42,7 @@ import java.io.PrintStream;
import java.util.Map;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugOptions;
import org.graalvm.compiler.debug.DiagnosticsOutputDirectory;
import org.graalvm.compiler.debug.PathUtilities;
import org.graalvm.compiler.debug.TTY;
@@ -276,7 +276,7 @@ public abstract class CompilationWrapper {
}
OptionValues retryOptions = new OptionValues(initialOptions,
- Dump, ":" + VERBOSE_LEVEL,
+ Dump, ":" + DebugOptions.DiagnoseDumpLevel.getValue(initialOptions),
MethodFilter, null,
DumpPath, dumpPath.getPath(),
TrackNodeSourcePosition, true);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompiler.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompiler.java
index 31c5df284e1..ba49fff899a 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompiler.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompiler.java
@@ -31,6 +31,7 @@ import org.graalvm.compiler.core.common.util.CompilationAlarm;
import org.graalvm.compiler.core.target.Backend;
import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugContext.CompilerPhaseScope;
import org.graalvm.compiler.debug.MethodFilter;
import org.graalvm.compiler.debug.TimerKey;
import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory;
@@ -208,9 +209,11 @@ public class GraalCompiler {
try (DebugContext.Scope s = debug.scope("FrontEnd"); DebugCloseable a = FrontEnd.start(debug)) {
HighTierContext highTierContext = new HighTierContext(providers, graphBuilderSuite, optimisticOpts);
if (graph.start().next() == null) {
- graphBuilderSuite.apply(graph, highTierContext);
- new DeadCodeEliminationPhase(DeadCodeEliminationPhase.Optionality.Optional).apply(graph);
- debug.dump(DebugContext.BASIC_LEVEL, graph, "After parsing");
+ try (CompilerPhaseScope cps = debug.enterCompilerPhase("Parsing")) {
+ graphBuilderSuite.apply(graph, highTierContext);
+ new DeadCodeEliminationPhase(DeadCodeEliminationPhase.Optionality.Optional).apply(graph);
+ debug.dump(DebugContext.BASIC_LEVEL, graph, "After parsing");
+ }
} else {
debug.dump(DebugContext.INFO_LEVEL, graph, "initial state");
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalServiceThread.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalServiceThread.java
index 23dca78c5dd..b96801a398e 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalServiceThread.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalServiceThread.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2020, 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
@@ -49,16 +49,16 @@ public class GraalServiceThread extends Thread {
/**
* Substituted by {@code com.oracle.svm.graal.hotspot.libgraal.
- * Target_org_graalvm_compiler_truffle_common_TruffleCompilerRuntimeInstance} to attach to the
- * peer runtime if required.
+ * Target_org_graalvm_compiler_core_GraalServiceThread} to attach to the peer runtime if
+ * required.
*/
private void afterRun() {
}
/**
* Substituted by {@code com.oracle.svm.graal.hotspot.libgraal.
- * Target_org_graalvm_compiler_truffle_common_TruffleCompilerRuntimeInstance} to attach to the
- * peer runtime if required.
+ * Target_org_graalvm_compiler_core_GraalServiceThread} to attach to the peer runtime if
+ * required.
*/
private void beforeRun() {
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/doc-files/CompilationFailureActionHelp.txt b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/doc-files/CompilationFailureActionHelp.txt
index b8a739e411f..76572b4092d 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/doc-files/CompilationFailureActionHelp.txt
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/doc-files/CompilationFailureActionHelp.txt
@@ -1,6 +1,11 @@
Specifies the action to take when compilation fails.
+
The accepted values are:
- Silent - Print nothing to the console.
- Print - Print a stack trace to the console.
- Diagnose - Retry the compilation with extra diagnostics.
- ExitVM - Same as Diagnose except that the VM process exits after retrying.
\ No newline at end of file
+ Silent - Print nothing to the console.
+ Print - Print a stack trace to the console.
+ Diagnose* - Retry the compilation with extra diagnostics.
+ ExitVM - Same as Diagnose except that the VM process exits after retrying.
+
+* If "Diagnose" is set compilation will be retried with extra diagnostics enabled including dumping (see file:doc-files/DumpHelp.txt).
+ In such a scenario DiagnoseDumpLevel can be used to specify the dump level (DebugContext dump levels) accordingly.
+
\ No newline at end of file
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/DebugInfoBuilder.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/DebugInfoBuilder.java
index 49c26cbe60f..43e126b4dc0 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/DebugInfoBuilder.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/DebugInfoBuilder.java
@@ -30,6 +30,7 @@ import java.util.Queue;
import jdk.internal.vm.compiler.collections.EconomicMap;
import jdk.internal.vm.compiler.collections.Equivalence;
+import org.graalvm.compiler.core.common.spi.MetaAccessExtensionProvider;
import org.graalvm.compiler.debug.CounterKey;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.GraalError;
@@ -66,10 +67,12 @@ import jdk.vm.ci.meta.Value;
public class DebugInfoBuilder {
protected final NodeValueMap nodeValueMap;
+ protected final MetaAccessExtensionProvider metaAccessExtensionProvider;
protected final DebugContext debug;
- public DebugInfoBuilder(NodeValueMap nodeValueMap, DebugContext debug) {
+ public DebugInfoBuilder(NodeValueMap nodeValueMap, MetaAccessExtensionProvider metaAccessExtensionProvider, DebugContext debug) {
this.nodeValueMap = nodeValueMap;
+ this.metaAccessExtensionProvider = metaAccessExtensionProvider;
this.debug = debug;
}
@@ -129,7 +132,7 @@ public class DebugInfoBuilder {
for (int i = 0; i < entryCount; i++) {
ValueNode value = currentField.values().get(i);
if (value == null) {
- JavaKind entryKind = vobjNode.entryKind(i);
+ JavaKind entryKind = vobjNode.entryKind(metaAccessExtensionProvider, i);
values[pos] = JavaConstant.defaultForKind(entryKind.getStackKind());
slotKinds[pos] = entryKind.getStackKind();
pos++;
@@ -140,9 +143,9 @@ public class DebugInfoBuilder {
} else {
assert value.getStackKind() == JavaKind.Illegal;
ValueNode previousValue = currentField.values().get(i - 1);
- assert (previousValue != null && (previousValue.getStackKind().needsTwoSlots()) || vobjNode.isVirtualByteArray()) : vobjNode + " " + i +
+ assert (previousValue != null && (previousValue.getStackKind().needsTwoSlots()) || vobjNode.isVirtualByteArray(metaAccessExtensionProvider)) : vobjNode + " " + i +
" " + previousValue + " " + currentField.values().snapshot();
- if (vobjNode.isVirtualByteArray()) {
+ if (vobjNode.isVirtualByteArray(metaAccessExtensionProvider)) {
/*
* Let Illegals pass through to help knowing the number of bytes to
* write. For example, writing a short to index 2 of a byte array of
@@ -158,7 +161,7 @@ public class DebugInfoBuilder {
pos++;
} else if (previousValue == null || !previousValue.getStackKind().needsTwoSlots()) {
// Don't allow the IllegalConstant to leak into the debug info
- JavaKind entryKind = vobjNode.entryKind(i);
+ JavaKind entryKind = vobjNode.entryKind(metaAccessExtensionProvider, i);
values[pos] = JavaConstant.defaultForKind(entryKind.getStackKind());
slotKinds[pos] = entryKind.getStackKind();
pos++;
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/LIRCompilerBackend.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/LIRCompilerBackend.java
index 8f2f2886318..4db96954afa 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/LIRCompilerBackend.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/LIRCompilerBackend.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, 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
@@ -39,6 +39,7 @@ import org.graalvm.compiler.core.target.Backend;
import org.graalvm.compiler.debug.CounterKey;
import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugContext.CompilerPhaseScope;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.debug.TimerKey;
import org.graalvm.compiler.lir.LIR;
@@ -200,7 +201,7 @@ public class LIRCompilerBackend {
ResolvedJavaMethod installedCodeOwner,
CompilationResultBuilderFactory factory) {
DebugContext debug = lirGenRes.getLIR().getDebug();
- try (DebugCloseable a = EmitCode.start(debug)) {
+ try (DebugCloseable a = EmitCode.start(debug); CompilerPhaseScope cps = debug.enterCompilerPhase("Emit code");) {
LIRGenerationProvider lirBackend = (LIRGenerationProvider) backend;
FrameMap frameMap = lirGenRes.getFrameMap();
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java
index e3dfa5d7a63..07725a45a56 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java
@@ -43,6 +43,7 @@ import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.calc.Condition;
import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
import org.graalvm.compiler.core.common.cfg.BlockMap;
+import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.core.match.ComplexMatchValue;
import org.graalvm.compiler.core.match.MatchPattern;
@@ -99,6 +100,8 @@ import org.graalvm.compiler.nodes.calc.IntegerTestNode;
import org.graalvm.compiler.nodes.calc.IsNullNode;
import org.graalvm.compiler.nodes.cfg.Block;
import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
+import org.graalvm.compiler.nodes.extended.ForeignCall;
+import org.graalvm.compiler.nodes.extended.ForeignCallWithExceptionNode;
import org.graalvm.compiler.nodes.extended.IntegerSwitchNode;
import org.graalvm.compiler.nodes.extended.SwitchNode;
import org.graalvm.compiler.nodes.spi.LIRLowerable;
@@ -155,7 +158,7 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
}
protected DebugInfoBuilder createDebugInfoBuilder(StructuredGraph graph, NodeValueMap nodeValueMap) {
- return new DebugInfoBuilder(nodeValueMap, graph.getDebug());
+ return new DebugInfoBuilder(nodeValueMap, gen.getProviders().getMetaAccessExtensionProvider(), graph.getDebug());
}
/**
@@ -620,6 +623,28 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
}
}
+ @Override
+ public void emitForeignCall(ForeignCall x) {
+ ForeignCallLinkage linkage = gen.getForeignCalls().lookupForeignCall(x.getDescriptor());
+
+ LabelRef exceptionEdge = null;
+ if (x instanceof ForeignCallWithExceptionNode) {
+ exceptionEdge = getLIRBlock(((ForeignCallWithExceptionNode) x).exceptionEdge());
+ }
+ LIRFrameState callState = stateWithExceptionEdge(x, exceptionEdge);
+
+ Value[] args = x.operands(this);
+
+ Value result = gen.emitForeignCall(linkage, callState, args);
+ if (result != null) {
+ setResult(x.asNode(), result);
+ }
+
+ if (x instanceof ForeignCallWithExceptionNode) {
+ gen.emitJump(getLIRBlock(((ForeignCallWithExceptionNode) x).next()));
+ }
+ }
+
protected abstract void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState);
protected abstract void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState);
@@ -735,7 +760,7 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
if (gen.needOnlyOopMaps()) {
return new LIRFrameState(null, null, null);
}
- assert state != null : deopt;
+ assert state != null : "Deopt node=" + deopt + " needs a state ";
return getDebugInfoBuilder().build(deopt, state, exceptionEdge);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/LowTier.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/LowTier.java
index 98b85df66e1..fe70e10dca0 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/LowTier.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/LowTier.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,6 @@
package org.graalvm.compiler.core.phases;
-import static org.graalvm.compiler.core.common.GraalOptions.LateMembars;
import static org.graalvm.compiler.phases.common.DeadCodeEliminationPhase.Optionality.Required;
import org.graalvm.compiler.core.common.GraalOptions;
@@ -37,7 +36,6 @@ import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
import org.graalvm.compiler.phases.common.ExpandLogicPhase;
import org.graalvm.compiler.phases.common.FixReadsPhase;
-import org.graalvm.compiler.phases.common.InsertMembarsPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
import org.graalvm.compiler.phases.common.ProfileCompiledMethodsPhase;
import org.graalvm.compiler.phases.common.PropagateDeoptimizeProbabilityPhase;
@@ -80,9 +78,6 @@ public class LowTier extends BaseTier {
appendPhase(new PropagateDeoptimizeProbabilityPhase());
- if (LateMembars.getValue(options)) {
- appendPhase(new InsertMembarsPhase());
- }
appendPhase(new SchedulePhase(SchedulePhase.SchedulingStrategy.LATEST_OUT_OF_LOOPS));
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java
index 500e3ded4c7..94da07336ab 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/target/Backend.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2020, 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
@@ -30,7 +30,7 @@ import org.graalvm.compiler.code.CompilationResult;
import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
-import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
+import org.graalvm.compiler.core.common.spi.ForeignCallSignature;
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
import org.graalvm.compiler.core.gen.LIRCompilerBackend;
import org.graalvm.compiler.debug.DebugContext;
@@ -63,8 +63,8 @@ public abstract class Backend implements TargetProvider, ValueKindFactory codeInstallationTaskFactories;
- public static final ForeignCallDescriptor ARITHMETIC_FREM = new ForeignCallDescriptor("arithmeticFrem", float.class, float.class, float.class);
- public static final ForeignCallDescriptor ARITHMETIC_DREM = new ForeignCallDescriptor("arithmeticDrem", double.class, double.class, double.class);
+ public static final ForeignCallSignature ARITHMETIC_FREM = new ForeignCallSignature("arithmeticFrem", float.class, float.class, float.class);
+ public static final ForeignCallSignature ARITHMETIC_DREM = new ForeignCallSignature("arithmeticDrem", double.class, double.class, double.class);
protected Backend(Providers providers) {
this.providers = providers;
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/DebugContextTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/DebugContextTest.java
index 989ca81b467..4bf5ad29fb0 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/DebugContextTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/DebugContextTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, 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
@@ -33,7 +33,6 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.Arrays;
-import java.util.Collections;
import java.util.Formatter;
import java.util.List;
import java.util.stream.Collectors;
@@ -43,6 +42,7 @@ import org.graalvm.compiler.debug.Assertions;
import org.graalvm.compiler.debug.CounterKey;
import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugContext.Builder;
import org.graalvm.compiler.debug.DebugContext.Scope;
import org.graalvm.compiler.debug.DebugDumpHandler;
import org.graalvm.compiler.debug.DebugHandler;
@@ -80,7 +80,7 @@ public class DebugContextTest {
};
DebugContext openDebugContext(OptionValues options) {
- return DebugContext.create(options, NO_DESCRIPTION, NO_GLOBAL_METRIC_VALUES, new PrintStream(logOutput), Collections.singletonList(handlers));
+ return new Builder(options, handlers).logStream(new PrintStream(logOutput)).build();
}
}
@@ -203,7 +203,7 @@ public class DebugContextTest {
map.put(DebugOptions.DumpOnError, true);
OptionValues options = new OptionValues(map);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- DebugContext debug = DebugContext.create(options, NO_DESCRIPTION, NO_GLOBAL_METRIC_VALUES, new PrintStream(baos), DebugHandlersFactory.LOADER);
+ DebugContext debug = new Builder(options).globalMetrics(NO_GLOBAL_METRIC_VALUES).description(NO_DESCRIPTION).logStream(new PrintStream(baos)).build();
Exception e = new Exception("testEnabledSandbox");
String scopeName = "";
try {
@@ -233,7 +233,7 @@ public class DebugContextTest {
map.put(DebugOptions.DumpOnError, true);
OptionValues options = new OptionValues(map);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- DebugContext debug = DebugContext.create(options, NO_DESCRIPTION, NO_GLOBAL_METRIC_VALUES, new PrintStream(baos), DebugHandlersFactory.LOADER);
+ DebugContext debug = new Builder(options).globalMetrics(NO_GLOBAL_METRIC_VALUES).description(NO_DESCRIPTION).logStream(new PrintStream(baos)).build();
Exception e = new Exception("testDisabledSandbox");
try {
// Test a disabled sandbox scope
@@ -263,7 +263,7 @@ public class DebugContextTest {
// Configure with an option that enables counters
map.put(DebugOptions.Counters, "");
OptionValues options = new OptionValues(map);
- DebugContext debug = DebugContext.create(options, DebugHandlersFactory.LOADER);
+ DebugContext debug = new Builder(options).build();
CounterKey counter = DebugContext.counter("DebugContextTestCounter");
AssertionError[] result = {null};
Thread thread = new Thread() {
@@ -291,7 +291,7 @@ public class DebugContextTest {
map.put(DebugOptions.DumpOnError, true);
OptionValues options = new OptionValues(map);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- DebugContext debug = DebugContext.create(options, NO_DESCRIPTION, NO_GLOBAL_METRIC_VALUES, new PrintStream(baos), DebugHandlersFactory.LOADER);
+ DebugContext debug = new Builder(options).globalMetrics(NO_GLOBAL_METRIC_VALUES).description(NO_DESCRIPTION).logStream(new PrintStream(baos)).build();
Exception e = new Exception();
try {
try (DebugCloseable disabled = debug.disableIntercept(); Scope s1 = debug.scope("ScopeWithDisabledIntercept")) {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/TimerKeyTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/TimerKeyTest.java
index 5398dad15db..02d1300dc3e 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/TimerKeyTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug.test/src/org/graalvm/compiler/debug/test/TimerKeyTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,15 +24,13 @@
package org.graalvm.compiler.debug.test;
-import static org.graalvm.compiler.debug.DebugContext.DEFAULT_LOG_STREAM;
import static org.graalvm.compiler.debug.DebugContext.NO_CONFIG_CUSTOMIZERS;
-import static org.graalvm.compiler.debug.DebugContext.NO_DESCRIPTION;
-import static org.graalvm.compiler.debug.DebugContext.NO_GLOBAL_METRIC_VALUES;
import static org.junit.Assert.assertEquals;
import jdk.internal.vm.compiler.collections.EconomicMap;
import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugContext.Builder;
import org.graalvm.compiler.debug.DebugOptions;
import org.graalvm.compiler.debug.TimerKey;
import org.graalvm.compiler.options.OptionKey;
@@ -88,7 +86,7 @@ public class TimerKeyTest {
EconomicMap, Object> map = EconomicMap.create();
map.put(DebugOptions.Time, "");
OptionValues options = new OptionValues(map);
- DebugContext debug = DebugContext.create(options, NO_DESCRIPTION, NO_GLOBAL_METRIC_VALUES, DEFAULT_LOG_STREAM, NO_CONFIG_CUSTOMIZERS);
+ DebugContext debug = new Builder(options, NO_CONFIG_CUSTOMIZERS).build();
TimerKey timerC = DebugContext.timer("TimerC");
try (DebugCloseable c1 = timerC.start(debug)) {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/CompilationListener.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/CompilationListener.java
new file mode 100644
index 00000000000..1a0f61a9bd8
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/CompilationListener.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2020, 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.debug;
+
+import org.graalvm.compiler.debug.DebugContext.CompilerPhaseScope;
+
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+/**
+ * Implemented by clients interested in when the compiler starts/ends a {@linkplain #enterPhase
+ * phase} or {@linkplain #notifyInlining considers inlining} a method.
+ */
+public interface CompilationListener {
+
+ /**
+ * Notifies this listener that the compiler is starting a compiler phase.
+ *
+ * @param name the name of the phase
+ * @return an object whose {@link CompilerPhaseScope#close()} method will be called when the
+ * phase completes
+ */
+ CompilerPhaseScope enterPhase(CharSequence name, int nesting);
+
+ /**
+ * Notifies this listener when the compiler considers inlining {@code callee} into
+ * {@code caller}.
+ *
+ * @param caller caller method
+ * @param callee callee method considered for inlining into {@code caller}
+ * @param succeeded true if {@code callee} was inlined into {@code caller}
+ * @param message extra information about inlining decision
+ * @param bci byte code index of call site
+ */
+ void notifyInlining(ResolvedJavaMethod caller, ResolvedJavaMethod callee, boolean succeeded, CharSequence message, int bci);
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java
index d4bddbc3d49..df5b7dfe223 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugContext.java
@@ -59,6 +59,7 @@ import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
+import java.util.function.Supplier;
import jdk.internal.vm.compiler.collections.EconomicMap;
import jdk.internal.vm.compiler.collections.EconomicSet;
@@ -68,7 +69,9 @@ import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.serviceprovider.GraalServices;
import org.graalvm.graphio.GraphOutput;
+import jdk.vm.ci.common.NativeImageReinitialize;
import jdk.vm.ci.meta.JavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
* A facility for logging and dumping as well as a container for values associated with
@@ -86,8 +89,6 @@ public final class DebugContext implements AutoCloseable {
public static final GlobalMetrics NO_GLOBAL_METRIC_VALUES = null;
public static final Iterable NO_CONFIG_CUSTOMIZERS = Collections.emptyList();
- public static final PrintStream DEFAULT_LOG_STREAM = TTY.out;
-
/**
* Contains the immutable parts of a debug context. This separation allows the immutable parts
* to be shared and reduces the overhead of initialization since most immutable fields are
@@ -114,6 +115,10 @@ public final class DebugContext implements AutoCloseable {
*/
private long[] metricValues;
+ public static PrintStream getDefaultLogStream() {
+ return TTY.out;
+ }
+
/**
* Determines if dynamic scopes are enabled.
*/
@@ -128,6 +133,7 @@ public final class DebugContext implements AutoCloseable {
if (sharedChannel == null) {
sharedChannel = new IgvDumpChannel(() -> getDumpPath(".bgv", false), immutable.options);
}
+ builder.attr(GraphOutput.ATTR_VM_ID, GraalServices.getExecutionID());
final GraphOutput output = builder.build(sharedChannel);
parentOutput = output;
return output;
@@ -315,7 +321,7 @@ public final class DebugContext implements AutoCloseable {
/**
* Singleton used to represent a disabled debug context.
*/
- private static final DebugContext DISABLED = new DebugContext(NO_DESCRIPTION, NO_GLOBAL_METRIC_VALUES, DEFAULT_LOG_STREAM, new Immutable(), NO_CONFIG_CUSTOMIZERS);
+ private static final DebugContext DISABLED = new DebugContext(NO_DESCRIPTION, null, NO_GLOBAL_METRIC_VALUES, getDefaultLogStream(), new Immutable(), NO_CONFIG_CUSTOMIZERS);
/**
* Create a DebugContext with debugging disabled.
@@ -324,7 +330,7 @@ public final class DebugContext implements AutoCloseable {
if (options == null || options.getMap().isEmpty()) {
return DISABLED;
}
- return new DebugContext(NO_DESCRIPTION, NO_GLOBAL_METRIC_VALUES, DEFAULT_LOG_STREAM, Immutable.create(options), NO_CONFIG_CUSTOMIZERS);
+ return new DebugContext(NO_DESCRIPTION, null, NO_GLOBAL_METRIC_VALUES, getDefaultLogStream(), Immutable.create(options), NO_CONFIG_CUSTOMIZERS);
}
/**
@@ -377,6 +383,8 @@ public final class DebugContext implements AutoCloseable {
private final Description description;
+ private final CompilationListener compilationListener;
+
/**
* Gets a description of the computation associated with this debug context.
*
@@ -386,6 +394,89 @@ public final class DebugContext implements AutoCloseable {
return description;
}
+ /**
+ * Determines if {@link #enterCompilerPhase} and {@link #notifyInlining} do anything.
+ *
+ * @return {@code true} if there is a listener for compiler phase and inlining events attached
+ * to this object, {@code false} otherwise
+ */
+ public boolean hasCompilationListener() {
+ return compilationListener != null;
+ }
+
+ private int compilerPhaseNesting = 0;
+
+ /**
+ * Scope for a compiler phase event.
+ */
+ public interface CompilerPhaseScope extends AutoCloseable {
+ /**
+ * Notifies the listener that the phase has ended.
+ */
+ @Override
+ void close();
+ }
+
+ /**
+ * Notifies this object that the compiler is entering a phase.
+ *
+ * It is recommended to use this method in a try-with-resource statement.
+ *
+ * @param phaseName name of the phase being entered
+ * @return {@code null} if {@link #hasCompilationListener()} returns {@code false} otherwise an
+ * object whose {@link CompilerPhaseScope#close()} method must be called when the phase
+ * ends
+ */
+ public CompilerPhaseScope enterCompilerPhase(CharSequence phaseName) {
+ if (compilationListener != null) {
+ return enterCompilerPhase(() -> phaseName);
+ }
+ return null;
+ }
+
+ /**
+ * Notifies this object that the compiler is entering a phase.
+ *
+ * It is recommended to use this method in a try-with-resource statement.
+ *
+ * @param phaseName name of the phase being entered
+ * @return {@code null} if {@link #hasCompilationListener()} returns {@code false} otherwise an
+ * object whose {@link CompilerPhaseScope#close()} method must be called when the phase
+ * ends
+ */
+ public CompilerPhaseScope enterCompilerPhase(Supplier phaseName) {
+ CompilationListener l = compilationListener;
+ if (l != null) {
+ CompilerPhaseScope scope = l.enterPhase(phaseName.get(), compilerPhaseNesting++);
+ return new CompilerPhaseScope() {
+
+ @Override
+ public void close() {
+ --compilerPhaseNesting;
+ scope.close();
+ }
+ };
+ }
+ return null;
+ }
+
+ /**
+ * Notifies this object when the compiler considers inlining {@code callee} into {@code caller}.
+ * A call to this method should be guarded with {@link #hasCompilationListener()} if
+ * {@code message} is not a string literal or pre-computed value
+ *
+ * @param caller caller method
+ * @param callee callee method considered for inlining into {@code caller}
+ * @param succeeded true if {@code callee} was inlined into {@code caller}
+ * @param message extra information about inlining decision
+ * @param bci byte code index of call site
+ */
+ public void notifyInlining(ResolvedJavaMethod caller, ResolvedJavaMethod callee, boolean succeeded, CharSequence message, int bci) {
+ if (compilationListener != null) {
+ compilationListener.notifyInlining(caller, callee, succeeded, message, bci);
+ }
+ }
+
/**
* Gets the global metrics associated with this debug context.
*
@@ -396,43 +487,91 @@ public final class DebugContext implements AutoCloseable {
}
/**
- * Creates a {@link DebugContext} based on a given set of option values and {@code factory}.
+ * Object used to create a {@link DebugContext}.
*/
- public static DebugContext create(OptionValues options, DebugHandlersFactory factory) {
- return new DebugContext(NO_DESCRIPTION, NO_GLOBAL_METRIC_VALUES, DEFAULT_LOG_STREAM, Immutable.create(options), Collections.singletonList(factory));
+ public static class Builder {
+ private final OptionValues options;
+ private Description description = NO_DESCRIPTION;
+ private CompilationListener compilationListener;
+ private GlobalMetrics globalMetrics = NO_GLOBAL_METRIC_VALUES;
+ private PrintStream logStream = getDefaultLogStream();
+ private final Iterable factories;
+
+ /**
+ * Builder for a {@link DebugContext} based on {@code options} and
+ * {@link DebugHandlersFactory#LOADER}.
+ */
+ public Builder(OptionValues options) {
+ this.options = options;
+ this.factories = DebugHandlersFactory.LOADER;
+ }
+
+ /**
+ * Builder for a {@link DebugContext} based on {@code options} and {@code factories}. The
+ * {@link DebugHandlersFactory#LOADER} value can be used for the latter.
+ */
+ public Builder(OptionValues options, Iterable factories) {
+ this.options = options;
+ this.factories = factories;
+ }
+
+ /**
+ * Builder for a {@link DebugContext} based {@code options} and {@code factory}. The latter
+ * can be null in which case {@link DebugContext#NO_CONFIG_CUSTOMIZERS} is used.
+ */
+ public Builder(OptionValues options, DebugHandlersFactory factory) {
+ this.options = options;
+ this.factories = factory == null ? NO_CONFIG_CUSTOMIZERS : Collections.singletonList(factory);
+ }
+
+ /**
+ * Sets the description for the debug context. The default is for a context to have no
+ * description.
+ */
+ public Builder description(Description desc) {
+ this.description = desc;
+ return this;
+ }
+
+ /**
+ * Sets the compilation listener for the debug context. The default is for a context to have
+ * no compilation listener.
+ */
+ public Builder compilationListener(CompilationListener listener) {
+ this.compilationListener = listener;
+ return this;
+ }
+
+ public Builder globalMetrics(GlobalMetrics metrics) {
+ this.globalMetrics = metrics;
+ return this;
+ }
+
+ public Builder logStream(PrintStream stream) {
+ this.logStream = stream;
+ return this;
+ }
+
+ public DebugContext build() {
+ return new DebugContext(description,
+ compilationListener,
+ globalMetrics,
+ logStream,
+ Immutable.create(options),
+ factories);
+ }
}
- /**
- * 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, Iterable 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 factories) {
- return new DebugContext(description, NO_GLOBAL_METRIC_VALUES, DEFAULT_LOG_STREAM, Immutable.create(options), factories);
- }
-
- /**
- * Creates a {@link DebugContext}.
- */
- public static DebugContext create(OptionValues options, Description description, GlobalMetrics globalMetrics, PrintStream logStream, Iterable factories) {
- return new DebugContext(description, globalMetrics, logStream, Immutable.create(options), factories);
- }
-
- private DebugContext(Description description, GlobalMetrics globalMetrics, PrintStream logStream, Immutable immutable, Iterable factories) {
+ private DebugContext(Description description,
+ CompilationListener compilationListener,
+ GlobalMetrics globalMetrics,
+ PrintStream logStream,
+ Immutable immutable,
+ Iterable factories) {
this.immutable = immutable;
this.description = description;
this.globalMetrics = globalMetrics;
+ this.compilationListener = compilationListener;
if (immutable.scopesEnabled) {
OptionValues options = immutable.options;
List dumpHandlers = new ArrayList<>();
@@ -653,7 +792,11 @@ public final class DebugContext implements AutoCloseable {
}
}
- private final Invariants invariants = Assertions.assertionsEnabled() ? new Invariants() : null;
+ /**
+ * Arbitrary threads cannot be in the image so null out {@code DebugContext.invariants} which
+ * holds onto a thread and is only used for assertions.
+ */
+ @NativeImageReinitialize private final Invariants invariants = Assertions.assertionsEnabled() ? new Invariants() : null;
static StackTraceElement[] getStackTrace(Thread thread) {
return thread.getStackTrace();
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java
index 827476ae3b6..5c50b60d171 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java
@@ -115,13 +115,16 @@ public class DebugOptions {
@Option(help = "file:doc-files/MetricsFileHelp.txt", type = OptionType.Debug)
public static final OptionKey MetricsFile = new OptionKey<>(null);
@Option(help = "File to which aggregated metrics are dumped at shutdown. A CSV format is used if the file ends with .csv " +
- "otherwise a more human readable format is used. If not specified, metrics are dumped to the console.", type = OptionType.Debug)
+ "otherwise a more human readable format is used. If not specified, metrics are dumped to the console.", type = OptionType.Debug)
public static final OptionKey AggregatedMetricsFile = new OptionKey<>(null);
@Option(help = "Enable debug output for stub code generation and snippet preparation.", type = OptionType.Debug)
public static final OptionKey DebugStubsAndSnippets = new OptionKey<>(false);
@Option(help = "Send compiler IR to dump handlers on error.", type = OptionType.Debug)
public static final OptionKey DumpOnError = new OptionKey<>(false);
+ @Option(help = "Specify the DumpLevel if CompilationFailureAction#Diagnose is used." +
+ "See CompilationFailureAction for details. file:doc-files/CompilationFailureActionHelp.txt", type = OptionType.Debug)
+ public static final OptionKey DiagnoseDumpLevel = new OptionKey<>(DebugContext.VERBOSE_LEVEL);
@Option(help = "Disable intercepting exceptions in debug scopes.", type = OptionType.Debug)
public static final OptionKey DisableIntercept = new OptionKey<>(false);
@Option(help = "Intercept also bailout exceptions", type = OptionType.Debug)
@@ -137,7 +140,9 @@ public class DebugOptions {
@Option(help = "Enable dumping to the C1Visualizer. Enabling this option implies PrintBackendCFG.", type = OptionType.Debug)
public static final OptionKey PrintCFG = new OptionKey<>(false);
@Option(help = "Enable dumping LIR, register allocation and code generation info to the C1Visualizer.", type = OptionType.Debug)
- public static final OptionKey PrintBackendCFG = new OptionKey<>(true);
+ public static final OptionKey PrintBackendCFG = new OptionKey<>(false);
+ @Option(help = "Enable dumping CFG built during initial BciBlockMapping", type = OptionType.Debug)
+ public static final OptionKey PrintBlockMapping = new OptionKey<>(false);
@Option(help = "file:doc-files/PrintGraphHelp.txt", type = OptionType.Debug)
public static final EnumOptionKey PrintGraph = new EnumOptionKey<>(PrintGraphTarget.File);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DiagnosticsOutputDirectory.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DiagnosticsOutputDirectory.java
index beac60e6ff3..607ec6a83f7 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DiagnosticsOutputDirectory.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DiagnosticsOutputDirectory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, 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
@@ -42,6 +42,7 @@ import java.util.zip.ZipOutputStream;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.serviceprovider.GraalServices;
+import org.graalvm.compiler.serviceprovider.IsolateUtil;
/**
* Manages a directory into which diagnostics such crash reports and dumps should be written. The
@@ -107,7 +108,7 @@ public class DiagnosticsOutputDirectory {
// directory specified by the DumpPath option.
baseDir = Paths.get(".");
}
- return baseDir.resolve("graal_diagnostics_" + GraalServices.getExecutionID()).toAbsolutePath().toString();
+ return baseDir.resolve("graal_diagnostics_" + GraalServices.getExecutionID() + '@' + IsolateUtil.getIsolateID()).toAbsolutePath().toString();
}
/**
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/GlobalMetrics.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/GlobalMetrics.java
index 38294ecd9f6..2b498bee476 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/GlobalMetrics.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/GlobalMetrics.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, 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
@@ -27,6 +27,7 @@ package org.graalvm.compiler.debug;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
+import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
@@ -35,6 +36,7 @@ import jdk.internal.vm.compiler.collections.EconomicMap;
import jdk.internal.vm.compiler.collections.MapCursor;
import jdk.internal.vm.compiler.collections.Pair;
import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.serviceprovider.IsolateUtil;
/**
* Metric values that can be {@linkplain #add(DebugContext) updated} by multiple threads.
@@ -75,10 +77,30 @@ public class GlobalMetrics {
return res;
}
+ private static PrintStream openPrintStream(String metricsFile) throws IOException {
+ if (metricsFile == null) {
+ return DebugContext.getDefaultLogStream();
+ } else {
+ long isolateID = IsolateUtil.getIsolateID();
+ Path path;
+ if (isolateID != 0L) {
+ int lastDot = metricsFile.lastIndexOf('.');
+ if (lastDot != -1) {
+ path = Paths.get(metricsFile.substring(0, lastDot) + '@' + isolateID + metricsFile.substring(lastDot));
+ } else {
+ path = Paths.get(metricsFile + isolateID);
+ }
+ } else {
+ path = Paths.get(metricsFile);
+ }
+ return new PrintStream(Files.newOutputStream(path));
+ }
+ }
+
/**
* Prints the values in the object to the file specified by
* {@link DebugOptions#AggregatedMetricsFile} if present otherwise to
- * {@link DebugContext#DEFAULT_LOG_STREAM}.
+ * {@link DebugContext#getDefaultLogStream()}.
*/
public void print(OptionValues options) {
long[] vals = values;
@@ -88,10 +110,11 @@ public class GlobalMetrics {
boolean csv = metricsFile != null && (metricsFile.endsWith(".csv") || metricsFile.endsWith(".CSV"));
PrintStream p = null;
try {
- p = metricsFile == null ? DebugContext.DEFAULT_LOG_STREAM : new PrintStream(Files.newOutputStream(Paths.get(metricsFile)));
+ p = openPrintStream(metricsFile);
+ String isolateID = IsolateUtil.getIsolateID(false);
if (!csv) {
if (!map.isEmpty()) {
- p.println("++ Aggregated Metrics ++");
+ p.printf("++ Aggregated Metrics %s ++%n", isolateID);
}
}
String csvFormat = CSVUtil.buildFormatString("%s", "%s", "%s");
@@ -107,7 +130,7 @@ public class GlobalMetrics {
}
if (!csv) {
if (!map.isEmpty()) {
- p.println("-- Aggregated Metrics --");
+ p.printf("-- Aggregated Metrics %s --%n", isolateID);
}
}
} catch (IOException e) {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/GraphTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/GraphTest.java
index 1812c2448b5..24a91e27e60 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/GraphTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/GraphTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,8 @@
package org.graalvm.compiler.graph.test;
import org.graalvm.compiler.api.test.Graal;
-import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugContext.Builder;
import org.graalvm.compiler.options.OptionValues;
import org.junit.After;
@@ -46,7 +46,7 @@ public abstract class GraphTest {
}
throw new AssertionError("At most one " + DebugContext.class.getName() + " object should be created per test");
}
- DebugContext debug = DebugContext.create(options, DebugHandlersFactory.LOADER);
+ DebugContext debug = new Builder(options).build();
cachedDebug.set(debug);
return debug;
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/GraphOutputTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/GraphOutputTest.java
index 532b9ab1b30..d79219119eb 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/GraphOutputTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/GraphOutputTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,6 +44,7 @@ import org.graalvm.graphio.GraphTypes;
import static org.junit.Assert.assertSame;
import org.junit.Test;
import java.lang.reflect.Field;
+import static org.junit.Assert.assertEquals;
public final class GraphOutputTest {
@@ -131,6 +132,96 @@ public final class GraphOutputTest {
assertSame(CustomEnum.class, clazz);
}
+ @Test
+ @SuppressWarnings({"static-method", "unchecked"})
+ public void testBuilderPromotesVersion() throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try (WritableByteChannel channel = Channels.newChannel(out)) {
+ GraphOutput.Builder builder = GraphOutput.newBuilder(new MockGraphStructure()).attr("test", "failed");
+ try (GraphOutput graphOutput = builder.build(channel)) {
+ graphOutput.print(new MockGraph(), Collections.emptyMap(), 0, "Mock Graph");
+ } catch (IllegalStateException ise) {
+ // expected exception
+ }
+ }
+ byte[] bytes = out.toByteArray();
+ // there's B-I-G-V, major, minor
+ assertEquals("Major version 7 must be auto-selected", 7, bytes[4]);
+ }
+
+ @Test
+ @SuppressWarnings({"static-method", "unchecked"})
+ public void testTooOldVersionFails() throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try (WritableByteChannel channel = Channels.newChannel(out)) {
+ GraphOutput.Builder builder = GraphOutput.newBuilder(new MockGraphStructure()).protocolVersion(6, 1);
+ try {
+ builder.attr("test", "failed");
+ fail("Should have failed, attr() requires version 7.0");
+ } catch (IllegalStateException ex) {
+ // expected
+ }
+ try (GraphOutput graphOutput = builder.build(channel)) {
+ graphOutput.print(new MockGraph(), Collections.emptyMap(), 0, "Mock Graph");
+ } catch (IllegalStateException ise) {
+ // expected exception
+ }
+ }
+ }
+
+ @Test
+ @SuppressWarnings({"static-method", "unchecked"})
+ public void testVersionDowngradeFails() throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try (WritableByteChannel channel = Channels.newChannel(out)) {
+ GraphOutput.Builder builder = GraphOutput.newBuilder(new MockGraphStructure());
+ builder.attr("test", "failed");
+ try {
+ builder.protocolVersion(6, 0);
+ fail("Should fail, cannot downgrade from required version.");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ try (GraphOutput graphOutput = builder.build(channel)) {
+ graphOutput.print(new MockGraph(), Collections.emptyMap(), 0, "Mock Graph");
+ } catch (IllegalStateException ise) {
+ // expected exception
+ }
+ }
+ }
+
+ @Test
+ @SuppressWarnings({"static-method", "unchecked"})
+ public void testManualAncientVersion() throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try (WritableByteChannel channel = Channels.newChannel(out)) {
+ GraphOutput.Builder builder = GraphOutput.newBuilder(new MockGraphStructure()).protocolVersion(3, 0);
+ try (GraphOutput graphOutput = builder.build(channel)) {
+ graphOutput.print(new MockGraph(), Collections.emptyMap(), 0, "Mock Graph");
+ }
+ }
+ byte[] bytes = out.toByteArray();
+ // there's B-I-G-V, major, minor
+ assertEquals("Protocol version 3 was requested", 3, bytes[4]);
+ }
+
+ @Test
+ @SuppressWarnings({"static-method", "unchecked"})
+ public void testManualVersionUpgradeOK() throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try (WritableByteChannel channel = Channels.newChannel(out)) {
+ GraphOutput.Builder builder = GraphOutput.newBuilder(new MockGraphStructure());
+ builder.attr("some", "thing");
+ builder.protocolVersion(7, 0);
+ try (GraphOutput graphOutput = builder.build(channel)) {
+ graphOutput.print(new MockGraph(), Collections.emptyMap(), 0, "Mock Graph");
+ }
+ }
+ byte[] bytes = out.toByteArray();
+ // there's B-I-G-V, major, minor
+ assertEquals("Protocol version 7 was requested", 7, bytes[4]);
+ }
+
private static ByteBuffer generateData(int size) {
ByteBuffer buffer = ByteBuffer.allocate(size);
for (int i = 0; i < size; i++) {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/NodeEncodingTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/NodeEncodingTest.java
index d73f4b4b7a5..8c865d4f82b 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/NodeEncodingTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/NodeEncodingTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, 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
@@ -56,8 +56,8 @@ public final class NodeEncodingTest {
}
@Test
- public void defaultVersionTheNodeIsntDumpedWithItsID() throws Exception {
- runTheNodeIsntDumpedWithItsID(false);
+ public void defaultVersionTheNodeIsDumpedWithItsID() throws Exception {
+ runTheNodeIsTreatedPoolEntry(false);
}
private void runTheNodeIsntDumpedWithItsID(boolean explicitVersion) throws Exception {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java
index 5e64672d9f6..af6ec435d58 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java
@@ -427,12 +427,30 @@ public abstract class Node implements Cloneable, Formattable, NodeInterface {
}
/**
- * Checks whether this node has exactly one usgae.
+ * Checks whether this node has exactly one usage.
*/
public final boolean hasExactlyOneUsage() {
return hasUsages() && !hasMoreThanOneUsage();
}
+ /**
+ * Checks whether this node has only usages of that type.
+ *
+ * @param type the type of usages to look for
+ */
+ public final boolean hasOnlyUsagesOfType(InputType type) {
+ for (Node usage : usages()) {
+ for (Position pos : usage.inputPositions()) {
+ if (pos.get(usage) == this) {
+ if (pos.getInputType() != type) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
/**
* Adds a given node to this node's {@linkplain #usages() usages}.
*
@@ -858,7 +876,7 @@ public abstract class Node implements Cloneable, Formattable, NodeInterface {
}
}
- public void replaceAtUsages(InputType type, Node other) {
+ public void replaceAtUsages(Node other, InputType type) {
checkReplaceWith(other);
int i = 0;
int usageCount = this.getUsageCount();
@@ -882,6 +900,32 @@ public abstract class Node implements Cloneable, Formattable, NodeInterface {
}
}
+ public void replaceAtUsages(Node other, InputType... inputTypes) {
+ checkReplaceWith(other);
+ int i = 0;
+ int usageCount = this.getUsageCount();
+ if (usageCount == 0) {
+ return;
+ }
+ usages: while (i < usageCount) {
+ Node usage = this.getUsageAt(i);
+ for (Position pos : usage.inputPositions()) {
+ for (InputType type : inputTypes) {
+ if (pos.getInputType() == type && pos.get(usage) == this) {
+ replaceAtUsagePos(other, usage, pos);
+ this.movUsageFromEndTo(i);
+ usageCount--;
+ continue usages;
+ }
+ }
+ }
+ i++;
+ }
+ if (hasNoUsages()) {
+ maybeNotifyZeroUsages(this);
+ }
+ }
+
private void maybeNotifyInputChanged(Node node) {
if (graph != null) {
assert !graph.isFrozen();
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java
index ac963df837b..5dd0f4581ef 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java
@@ -164,8 +164,8 @@ public final class NodeClass extends FieldIntrospection {
private static final Class> INPUT_LIST_CLASS = NodeInputList.class;
private static final Class> SUCCESSOR_LIST_CLASS = NodeSuccessorList.class;
- private static AtomicInteger nextIterableId = new AtomicInteger();
- private static AtomicInteger nextLeafId = new AtomicInteger();
+ private static final AtomicInteger nextIterableId = new AtomicInteger();
+ private static final AtomicInteger nextLeafId = new AtomicInteger();
private final InputEdges inputs;
private final SuccessorEdges successors;
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeList.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeList.java
index e9a93d23454..34333c14564 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeList.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2020, 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
@@ -31,10 +31,20 @@ import java.util.Iterator;
import java.util.List;
import java.util.RandomAccess;
+import org.graalvm.compiler.core.common.PermanentBailoutException;
import org.graalvm.compiler.graph.iterators.NodeIterable;
public abstract class NodeList extends AbstractList implements NodeIterable, RandomAccess {
+ /**
+ * This constant limits the maximum number of entries in a node list. The reason for the
+ * limitations is the constraints of the code iterating over a node's inputs and successors. It
+ * uses a bit data structure where only 16 bits are available for the current index into the
+ * list. See the methods {@link NodeClass#getSuccessorIterable(Node)} and
+ * {@link NodeClass#getInputIterable(Node)}.
+ */
+ private static final int MAX_ENTRIES = 65536;
+
protected static final Node[] EMPTY_NODE_ARRAY = new Node[0];
protected final Node self;
@@ -50,6 +60,7 @@ public abstract class NodeList extends AbstractList implement
protected NodeList(Node self, int initialSize) {
this.self = self;
+ checkMaxSize(initialSize);
this.size = initialSize;
this.initialSize = initialSize;
this.nodes = new Node[initialSize];
@@ -62,8 +73,9 @@ public abstract class NodeList extends AbstractList implement
this.nodes = EMPTY_NODE_ARRAY;
this.initialSize = 0;
} else {
+ checkMaxSize(elements.length);
this.size = elements.length;
- this.initialSize = elements.length;
+ this.initialSize = this.size;
this.nodes = new Node[elements.length];
for (int i = 0; i < elements.length; i++) {
this.nodes[i] = elements[i];
@@ -79,8 +91,10 @@ public abstract class NodeList extends AbstractList implement
this.nodes = EMPTY_NODE_ARRAY;
this.initialSize = 0;
} else {
- this.size = elements.size();
- this.initialSize = elements.size();
+ int newSize = elements.size();
+ checkMaxSize(newSize);
+ this.size = newSize;
+ this.initialSize = newSize;
this.nodes = new Node[elements.size()];
for (int i = 0; i < elements.size(); i++) {
this.nodes[i] = elements.get(i);
@@ -89,6 +103,12 @@ public abstract class NodeList extends AbstractList implement
}
}
+ private static void checkMaxSize(int value) {
+ if (value > MAX_ENTRIES) {
+ throw new PermanentBailoutException("Number of elements in a node list too high: %d", value);
+ }
+ }
+
protected NodeList(Node self, Collection extends NodeInterface> elements) {
this.self = self;
if (elements == null || elements.isEmpty()) {
@@ -96,8 +116,10 @@ public abstract class NodeList extends AbstractList implement
this.nodes = EMPTY_NODE_ARRAY;
this.initialSize = 0;
} else {
- this.size = elements.size();
- this.initialSize = elements.size();
+ int newSize = elements.size();
+ checkMaxSize(newSize);
+ this.size = newSize;
+ this.initialSize = newSize;
this.nodes = new Node[elements.size()];
int i = 0;
for (NodeInterface n : elements) {
@@ -109,7 +131,7 @@ public abstract class NodeList extends AbstractList implement
}
/**
- * Removes null values from the list.
+ * Removes {@code null} values from the list.
*/
public void trim() {
int newSize = 0;
@@ -150,10 +172,15 @@ public abstract class NodeList extends AbstractList implement
modCount++;
}
+ /**
+ * Adds a new node to the list. The total number of nodes in the list must not exceed
+ * {@link #MAX_ENTRIES}, otherwise a {@link PermanentBailoutException} is thrown.
+ */
@SuppressWarnings("unchecked")
@Override
public boolean add(Node node) {
assert node == null || !node.isDeleted() : node;
+ checkMaxSize(size + 1);
self.incModCount();
incModCount();
int length = nodes.length;
@@ -169,6 +196,9 @@ public abstract class NodeList extends AbstractList implement
return true;
}
+ /**
+ * Get a node from the list given an {@code index}.
+ */
@Override
@SuppressWarnings("unchecked")
public T get(int index) {
@@ -185,6 +215,9 @@ public abstract class NodeList extends AbstractList implement
return get(size() - 1);
}
+ /**
+ * Set the node of the list at the given {@code index} to a new value.
+ */
@Override
@SuppressWarnings("unchecked")
public T set(int index, Node node) {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/spi/CanonicalizerTool.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/spi/CanonicalizerTool.java
index db390f142af..4e38500678f 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/spi/CanonicalizerTool.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/spi/CanonicalizerTool.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,14 +24,15 @@
package org.graalvm.compiler.graph.spi;
+import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
+import org.graalvm.compiler.core.common.spi.MetaAccessExtensionProvider;
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.options.OptionValues;
+
import jdk.vm.ci.meta.Assumptions;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.MetaAccessProvider;
-import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
-import org.graalvm.compiler.graph.Node;
-import org.graalvm.compiler.options.OptionValues;
-
public interface CanonicalizerTool {
Assumptions getAssumptions();
@@ -42,6 +43,8 @@ public interface CanonicalizerTool {
ConstantFieldProvider getConstantFieldProvider();
+ MetaAccessExtensionProvider getMetaAccessExtensionProvider();
+
boolean canonicalizeReads();
/**
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackend.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackend.java
index 9da0e5a9cd5..fe1d3a69880 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackend.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackend.java
@@ -54,6 +54,7 @@ import org.graalvm.compiler.hotspot.HotSpotDataBuilder;
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
import org.graalvm.compiler.hotspot.HotSpotHostBackend;
import org.graalvm.compiler.hotspot.HotSpotLIRGenerationResult;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
import org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction;
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
@@ -81,7 +82,6 @@ import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.StackSlot;
-import jdk.vm.ci.code.site.Mark;
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
import jdk.vm.ci.hotspot.HotSpotSentinelConstant;
import jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig;
@@ -152,9 +152,8 @@ public class AArch64HotSpotBackend extends HotSpotHostBackend implements LIRGene
private boolean hasInvalidatePlaceholder(CompilationResult compilationResult) {
byte[] targetCode = compilationResult.getTargetCode();
int verifiedEntryOffset = 0;
- for (Mark mark : compilationResult.getMarks()) {
- Object markId = mark.id;
- if (markId instanceof Integer && (int) markId == config.MARKID_VERIFIED_ENTRY) {
+ for (CompilationResult.CodeMark mark : compilationResult.getMarks()) {
+ if (mark.id == HotSpotMarkId.VERIFIED_ENTRY || mark.id == HotSpotMarkId.OSR_ENTRY) {
// The nmethod verified entry is located at some pc offset.
verifiedEntryOffset = mark.pcOffset;
break;
@@ -203,6 +202,9 @@ public class AArch64HotSpotBackend extends HotSpotHostBackend implements LIRGene
}
}
}
+ if (HotSpotMarkId.FRAME_COMPLETE.isAvailable()) {
+ crb.recordMark(HotSpotMarkId.FRAME_COMPLETE);
+ }
if (ZapStackOnMethodEntry.getValue(crb.getOptions())) {
try (ScratchRegister sc = masm.getScratchRegister()) {
Register scratch = sc.getRegister();
@@ -312,7 +314,7 @@ public class AArch64HotSpotBackend extends HotSpotHostBackend implements LIRGene
private void emitCodePrefix(CompilationResultBuilder crb, ResolvedJavaMethod installedCodeOwner, AArch64MacroAssembler masm, RegisterConfig regConfig, Label verifiedStub) {
HotSpotProviders providers = getProviders();
if (installedCodeOwner != null && !isStatic(installedCodeOwner.getModifiers())) {
- crb.recordMark(config.MARKID_UNVERIFIED_ENTRY);
+ crb.recordMark(HotSpotMarkId.UNVERIFIED_ENTRY);
CallingConvention cc = regConfig.getCallingConvention(HotSpotCallingConventionType.JavaCallee, null, new JavaType[]{providers.getMetaAccess().lookupJavaType(Object.class)}, this);
// See definition of IC_Klass in c1_LIRAssembler_aarch64.cpp
// equal to scratch(1) careful!
@@ -325,7 +327,7 @@ public class AArch64HotSpotBackend extends HotSpotHostBackend implements LIRGene
Register klass = r10;
if (config.useCompressedClassPointers) {
masm.ldr(32, klass, klassAddress);
- AArch64HotSpotMove.decodeKlassPointer(crb, masm, klass, klass, config.getKlassEncoding(), config);
+ AArch64HotSpotMove.decodeKlassPointer(crb, masm, klass, klass, config.getKlassEncoding());
} else {
masm.ldr(64, klass, klassAddress);
}
@@ -338,9 +340,8 @@ public class AArch64HotSpotBackend extends HotSpotHostBackend implements LIRGene
AArch64Call.directJmp(crb, masm, getForeignCalls().lookupForeignCall(IC_MISS_HANDLER));
}
masm.align(config.codeEntryAlignment);
- crb.recordMark(config.MARKID_OSR_ENTRY);
masm.bind(verifiedStub);
- crb.recordMark(config.MARKID_VERIFIED_ENTRY);
+ crb.recordMark(crb.compilationResult.getEntryBCI() != -1 ? HotSpotMarkId.OSR_ENTRY : HotSpotMarkId.VERIFIED_ENTRY);
if (GeneratePIC.getValue(crb.getOptions())) {
// Check for method state
@@ -385,12 +386,12 @@ public class AArch64HotSpotBackend extends HotSpotHostBackend implements LIRGene
HotSpotForeignCallsProvider foreignCalls = providers.getForeignCalls();
try (ScratchRegister sc = masm.getScratchRegister()) {
Register scratch = sc.getRegister();
- crb.recordMark(config.MARKID_EXCEPTION_HANDLER_ENTRY);
+ crb.recordMark(HotSpotMarkId.EXCEPTION_HANDLER_ENTRY);
ForeignCallLinkage linkage = foreignCalls.lookupForeignCall(EXCEPTION_HANDLER);
Register helper = AArch64Call.isNearCall(linkage) ? null : scratch;
AArch64Call.directCall(crb, masm, linkage, helper, null);
}
- crb.recordMark(config.MARKID_DEOPT_HANDLER_ENTRY);
+ crb.recordMark(HotSpotMarkId.DEOPT_HANDLER_ENTRY);
ForeignCallLinkage linkage = foreignCalls.lookupForeignCall(DEOPT_BLOB_UNPACK);
masm.adr(lr, 0); // Warning: the argument is an offset from the instruction!
AArch64Call.directJmp(crb, masm, linkage);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java
index 25acce51957..4b4fb072421 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java
@@ -36,6 +36,7 @@ import org.graalvm.compiler.bytecode.BytecodeProvider;
import org.graalvm.compiler.core.aarch64.AArch64AddressLoweringByUse;
import org.graalvm.compiler.core.aarch64.AArch64LIRKindTool;
import org.graalvm.compiler.core.aarch64.AArch64SuitesCreator;
+import org.graalvm.compiler.core.common.spi.MetaAccessExtensionProvider;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.HotSpotBackend;
import org.graalvm.compiler.hotspot.HotSpotBackendFactory;
@@ -44,11 +45,12 @@ import org.graalvm.compiler.hotspot.HotSpotReplacementsImpl;
import org.graalvm.compiler.hotspot.meta.AddressLoweringHotSpotSuitesProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotConstantFieldProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
-import org.graalvm.compiler.hotspot.meta.HotSpotPlatformConfigurationProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotGraalConstantFieldProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins;
import org.graalvm.compiler.hotspot.meta.HotSpotHostForeignCallsProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotLoweringProvider;
+import org.graalvm.compiler.hotspot.meta.HotSpotMetaAccessExtensionProvider;
+import org.graalvm.compiler.hotspot.meta.HotSpotPlatformConfigurationProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.hotspot.meta.HotSpotRegisters;
import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider;
@@ -116,6 +118,7 @@ public class AArch64HotSpotBackendFactory extends HotSpotBackendFactory {
HotSpotLoweringProvider lowerer;
HotSpotStampProvider stampProvider;
HotSpotPlatformConfigurationProvider platformConfigurationProvider;
+ HotSpotMetaAccessExtensionProvider metaAccessExtensionProvider;
HotSpotSnippetReflectionProvider snippetReflection;
HotSpotReplacementsImpl replacements;
HotSpotSuitesProvider suites;
@@ -141,11 +144,15 @@ public class AArch64HotSpotBackendFactory extends HotSpotBackendFactory {
try (InitTimer rt = timer("create platform configuration provider")) {
platformConfigurationProvider = createConfigInfoProvider(config, metaAccess);
}
+ try (InitTimer rt = timer("create MetaAccessExtensionProvider")) {
+ metaAccessExtensionProvider = createMetaAccessExtensionProvider();
+ }
try (InitTimer rt = timer("create Lowerer provider")) {
- lowerer = createLowerer(graalRuntime, metaAccess, foreignCalls, registers, constantReflection, platformConfigurationProvider, target);
+ lowerer = createLowerer(graalRuntime, metaAccess, foreignCalls, registers, constantReflection, platformConfigurationProvider, metaAccessExtensionProvider, target);
}
- Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider, platformConfigurationProvider);
+ Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider, platformConfigurationProvider,
+ metaAccessExtensionProvider);
try (InitTimer rt = timer("create SnippetReflection provider")) {
snippetReflection = createSnippetReflection(graalRuntime, constantReflection, wordTypes);
@@ -165,7 +172,7 @@ public class AArch64HotSpotBackendFactory extends HotSpotBackendFactory {
suites = createSuites(config, graalRuntime, compilerConfiguration, plugins, replacements);
}
providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers,
- snippetReflection, wordTypes, plugins, platformConfigurationProvider);
+ snippetReflection, wordTypes, plugins, platformConfigurationProvider, metaAccessExtensionProvider);
replacements.setProviders(providers);
replacements.maybeInitializeEncoder(options);
}
@@ -197,7 +204,7 @@ public class AArch64HotSpotBackendFactory extends HotSpotBackendFactory {
options,
target);
AArch64GraphBuilderPlugins.register(plugins, replacements, false, //
- /* registerMathPlugins */true, /* emitJDK9StringSubstitutions */true, config.useFMAIntrinsics);
+ /* registerForeignCallMath */true, /* emitJDK9StringSubstitutions */true, config.useFMAIntrinsics);
return plugins;
}
@@ -222,8 +229,10 @@ public class AArch64HotSpotBackendFactory extends HotSpotBackendFactory {
}
protected HotSpotLoweringProvider createLowerer(HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, HotSpotForeignCallsProvider foreignCalls,
- HotSpotRegistersProvider registers, HotSpotConstantReflectionProvider constantReflection, PlatformConfigurationProvider platformConfig, TargetDescription target) {
- return new AArch64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers, constantReflection, platformConfig, target);
+ HotSpotRegistersProvider registers, HotSpotConstantReflectionProvider constantReflection, PlatformConfigurationProvider platformConfig,
+ MetaAccessExtensionProvider metaAccessExtensionProvider,
+ TargetDescription target) {
+ return new AArch64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers, constantReflection, platformConfig, metaAccessExtensionProvider, target);
}
protected static Value[] createNativeABICallerSaveRegisters(@SuppressWarnings("unused") GraalHotSpotVMConfig config, RegisterConfig regConfig) {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotDirectStaticCallOp.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotDirectStaticCallOp.java
index 5daf4a32dbc..845d0ee7898 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotDirectStaticCallOp.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotDirectStaticCallOp.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@ import static jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig.inlineCache
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
import org.graalvm.compiler.lir.LIRFrameState;
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.Opcode;
@@ -58,14 +59,17 @@ final class AArch64HotSpotDirectStaticCallOp extends DirectCallOp {
}
@Override
+ @SuppressWarnings("try")
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
- // The mark for an invocation that uses an inline cache must be placed at the
- // instruction that loads the Klass from the inline cache.
- // For the first invocation this is set to a bitpattern that is guaranteed to never be a
- // valid object which causes the called function to call a handler that installs the
- // correct inline cache value here.
- crb.recordMark(invokeKind == InvokeKind.Static ? config.MARKID_INVOKESTATIC : config.MARKID_INVOKESPECIAL);
- masm.movNativeAddress(inlineCacheRegister, config.nonOopBits);
- super.emitCode(crb, masm);
+ try (CompilationResultBuilder.CallContext callContext = crb.openCallContext(invokeKind.isDirect())) {
+ // The mark for an invocation that uses an inline cache must be placed at the
+ // instruction that loads the Klass from the inline cache.
+ // For the first invocation this is set to a bitpattern that is guaranteed to never be a
+ // valid object which causes the called function to call a handler that installs the
+ // correct inline cache value here.
+ crb.recordMark(invokeKind == InvokeKind.Static ? HotSpotMarkId.INVOKESTATIC : HotSpotMarkId.INVOKESPECIAL);
+ masm.movNativeAddress(inlineCacheRegister, config.nonOopBits);
+ super.emitCode(crb, masm);
+ }
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotDirectVirtualCallOp.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotDirectVirtualCallOp.java
index 2f3c6d95f90..9a5decc1567 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotDirectVirtualCallOp.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotDirectVirtualCallOp.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@ import static jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig.inlineCache
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
import org.graalvm.compiler.lir.LIRFrameState;
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.Opcode;
@@ -58,14 +59,17 @@ final class AArch64HotSpotDirectVirtualCallOp extends DirectCallOp {
}
@Override
+ @SuppressWarnings("try")
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
- // The mark for an invocation that uses an inline cache must be placed at the
- // instruction that loads the Klass from the inline cache.
- // For the first invocation this is set to a bitpattern that is guaranteed to never be a
- // valid object which causes the called function to call a handler that installs the
- // correct inline cache value here.
- crb.recordMark(invokeKind == InvokeKind.Virtual ? config.MARKID_INVOKEVIRTUAL : config.MARKID_INVOKEINTERFACE);
- masm.movNativeAddress(inlineCacheRegister, config.nonOopBits);
- super.emitCode(crb, masm);
+ try (CompilationResultBuilder.CallContext callContext = crb.openCallContext(invokeKind.isDirect())) {
+ // The mark for an invocation that uses an inline cache must be placed at the
+ // instruction that loads the Klass from the inline cache.
+ // For the first invocation this is set to a bitpattern that is guaranteed to never be a
+ // valid object which causes the called function to call a handler that installs the
+ // correct inline cache value here.
+ crb.recordMark(invokeKind == InvokeKind.Virtual ? HotSpotMarkId.INVOKEVIRTUAL : HotSpotMarkId.INVOKEINTERFACE);
+ masm.movNativeAddress(inlineCacheRegister, config.nonOopBits);
+ super.emitCode(crb, masm);
+ }
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotForeignCallsProvider.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotForeignCallsProvider.java
index 7138cb45aa0..8154ef09973 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotForeignCallsProvider.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotForeignCallsProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, 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
@@ -29,12 +29,9 @@ import static jdk.vm.ci.aarch64.AArch64.r3;
import static jdk.vm.ci.hotspot.HotSpotCallingConventionType.NativeCall;
import static jdk.vm.ci.meta.Value.ILLEGAL;
import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.JUMP_ADDRESS;
-import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability.NOT_REEXECUTABLE;
import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.DESTROYS_ALL_CALLER_SAVE_REGISTERS;
-import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.LEAF;
import static org.graalvm.compiler.hotspot.replacements.CRC32CSubstitutions.UPDATE_BYTES_CRC32C;
import static org.graalvm.compiler.hotspot.replacements.CRC32Substitutions.UPDATE_BYTES_CRC32;
-import static jdk.internal.vm.compiler.word.LocationIdentity.any;
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
@@ -76,17 +73,16 @@ public class AArch64HotSpotForeignCallsProvider extends HotSpotHostForeignCallsP
RegisterValue exception = r0.asValue(LIRKind.reference(word));
RegisterValue exceptionPc = r3.asValue(LIRKind.value(word));
CallingConvention exceptionCc = new CallingConvention(0, ILLEGAL, exception, exceptionPc);
- register(new HotSpotForeignCallLinkageImpl(HotSpotBackend.EXCEPTION_HANDLER, 0L, DESTROYS_ALL_CALLER_SAVE_REGISTERS, LEAF, NOT_REEXECUTABLE, exceptionCc, null, any()));
- register(new HotSpotForeignCallLinkageImpl(HotSpotBackend.EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, DESTROYS_ALL_CALLER_SAVE_REGISTERS, LEAF, NOT_REEXECUTABLE, exceptionCc,
- null,
- any()));
+ register(new HotSpotForeignCallLinkageImpl(HotSpotBackend.EXCEPTION_HANDLER, 0L, DESTROYS_ALL_CALLER_SAVE_REGISTERS, exceptionCc, null));
+ register(new HotSpotForeignCallLinkageImpl(HotSpotBackend.EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, DESTROYS_ALL_CALLER_SAVE_REGISTERS, exceptionCc,
+ null));
// These stubs do callee saving
if (config.useCRC32Intrinsics) {
- registerForeignCall(UPDATE_BYTES_CRC32, config.updateBytesCRC32Stub, NativeCall, LEAF, NOT_REEXECUTABLE, any());
+ registerForeignCall(UPDATE_BYTES_CRC32, config.updateBytesCRC32Stub, NativeCall);
}
if (config.useCRC32CIntrinsics) {
- registerForeignCall(UPDATE_BYTES_CRC32C, config.updateBytesCRC32C, NativeCall, LEAF, NOT_REEXECUTABLE, any());
+ registerForeignCall(UPDATE_BYTES_CRC32C, config.updateBytesCRC32C, NativeCall);
}
super.initialize(providers, options);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java
index 7876f5f1266..6f197f47d5e 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java
@@ -63,6 +63,7 @@ import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
import org.graalvm.compiler.hotspot.HotSpotLIRGenerationResult;
import org.graalvm.compiler.hotspot.HotSpotLIRGenerator;
import org.graalvm.compiler.hotspot.HotSpotLockStack;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
import org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider;
@@ -270,7 +271,7 @@ public class AArch64HotSpotLIRGenerator extends AArch64LIRGenerator implements H
if (encoding.hasBase() || GeneratePIC.getValue(options)) {
if (GeneratePIC.getValue(options)) {
Variable baseAddress = newVariable(lirKindTool.getWordKind());
- AArch64HotSpotMove.BaseMove move = new AArch64HotSpotMove.BaseMove(baseAddress, config);
+ AArch64HotSpotMove.BaseMove move = new AArch64HotSpotMove.BaseMove(baseAddress);
append(move);
base = baseAddress;
} else {
@@ -299,7 +300,7 @@ public class AArch64HotSpotLIRGenerator extends AArch64LIRGenerator implements H
if (encoding.hasBase() || GeneratePIC.getValue(options)) {
if (GeneratePIC.getValue(options)) {
Variable baseAddress = newVariable(LIRKind.value(AArch64Kind.QWORD));
- AArch64HotSpotMove.BaseMove move = new AArch64HotSpotMove.BaseMove(baseAddress, config);
+ AArch64HotSpotMove.BaseMove move = new AArch64HotSpotMove.BaseMove(baseAddress);
append(move);
base = baseAddress;
} else {
@@ -472,7 +473,7 @@ public class AArch64HotSpotLIRGenerator extends AArch64LIRGenerator implements H
}
@Override
- public Value emitLoadConfigValue(int markId, LIRKind kind) {
+ public Value emitLoadConfigValue(HotSpotMarkId markId, LIRKind kind) {
Variable result = newVariable(kind);
append(new AArch64HotSpotLoadConfigValueOp(markId, result));
return result;
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLoadConfigValueOp.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLoadConfigValueOp.java
index b2ff3c5f927..7864f5cc7fe 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLoadConfigValueOp.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLoadConfigValueOp.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -25,28 +25,29 @@
package org.graalvm.compiler.hotspot.aarch64;
-import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
import static jdk.vm.ci.code.ValueUtil.asRegister;
-
-import jdk.vm.ci.aarch64.AArch64Kind;
-import jdk.vm.ci.code.Register;
-import jdk.vm.ci.meta.AllocatableValue;
+import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
import org.graalvm.compiler.asm.aarch64.AArch64Address;
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
import org.graalvm.compiler.debug.GraalError;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.aarch64.AArch64LIRInstruction;
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
+import jdk.vm.ci.aarch64.AArch64Kind;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.meta.AllocatableValue;
+
public final class AArch64HotSpotLoadConfigValueOp extends AArch64LIRInstruction {
public static final LIRInstructionClass TYPE = LIRInstructionClass.create(AArch64HotSpotLoadConfigValueOp.class);
@Def({OperandFlag.REG}) protected AllocatableValue result;
- private final int markId;
+ private final HotSpotMarkId markId;
- public AArch64HotSpotLoadConfigValueOp(int markId, AllocatableValue result) {
+ public AArch64HotSpotLoadConfigValueOp(HotSpotMarkId markId, AllocatableValue result) {
super(TYPE);
this.result = result;
this.markId = markId;
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLoweringProvider.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLoweringProvider.java
index 0a7f3ce43d3..9b7819cb8e5 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLoweringProvider.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLoweringProvider.java
@@ -27,6 +27,7 @@ package org.graalvm.compiler.hotspot.aarch64;
import org.graalvm.compiler.core.aarch64.AArch64LoweringProviderMixin;
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
+import org.graalvm.compiler.core.common.spi.MetaAccessExtensionProvider;
import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
@@ -37,6 +38,8 @@ import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider;
import org.graalvm.compiler.nodes.calc.FloatConvertNode;
import org.graalvm.compiler.nodes.calc.IntegerDivRemNode;
import org.graalvm.compiler.nodes.calc.RemNode;
+import org.graalvm.compiler.nodes.memory.VolatileReadNode;
+import org.graalvm.compiler.nodes.memory.VolatileWriteNode;
import org.graalvm.compiler.nodes.spi.LoweringTool;
import org.graalvm.compiler.nodes.spi.PlatformConfigurationProvider;
import org.graalvm.compiler.options.OptionValues;
@@ -53,8 +56,9 @@ public class AArch64HotSpotLoweringProvider extends DefaultHotSpotLoweringProvid
private AArch64FloatArithmeticSnippets floatArithmeticSnippets;
public AArch64HotSpotLoweringProvider(HotSpotGraalRuntimeProvider runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers,
- HotSpotConstantReflectionProvider constantReflection, PlatformConfigurationProvider platformConfig, TargetDescription target) {
- super(runtime, metaAccess, foreignCalls, registers, constantReflection, platformConfig, target);
+ HotSpotConstantReflectionProvider constantReflection, PlatformConfigurationProvider platformConfig, MetaAccessExtensionProvider metaAccessExtensionProvider,
+ TargetDescription target) {
+ super(runtime, metaAccess, foreignCalls, registers, constantReflection, platformConfig, metaAccessExtensionProvider, target);
}
@Override
@@ -73,6 +77,9 @@ public class AArch64HotSpotLoweringProvider extends DefaultHotSpotLoweringProvid
} else if (n instanceof FloatConvertNode) {
// AMD64 has custom lowerings for ConvertNodes, HotSpotLoweringProvider does not expect
// to see a ConvertNode and throws an error, just do nothing here.
+ } else if (n instanceof VolatileReadNode || n instanceof VolatileWriteNode) {
+ // AArch64 emits its own code sequence for volatile accesses. We don't want it lowered
+ // to memory barriers + a regular access.
} else {
super.lower(n, tool);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotMove.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotMove.java
index 22320ad4964..d0fb2da6c12 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotMove.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotMove.java
@@ -38,7 +38,7 @@ import org.graalvm.compiler.asm.aarch64.AArch64Address;
import org.graalvm.compiler.asm.aarch64.AArch64Assembler;
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
import org.graalvm.compiler.core.common.CompressEncoding;
-import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
import org.graalvm.compiler.lir.LIRInstruction;
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.StandardOp.LoadConstantOp;
@@ -90,12 +90,10 @@ public class AArch64HotSpotMove {
public static final LIRInstructionClass TYPE = LIRInstructionClass.create(BaseMove.class);
@LIRInstruction.Def({REG, HINT}) protected AllocatableValue result;
- private final GraalHotSpotVMConfig config;
- public BaseMove(AllocatableValue result, GraalHotSpotVMConfig config) {
+ public BaseMove(AllocatableValue result) {
super(TYPE);
this.result = result;
- this.config = config;
}
@Override
@@ -106,7 +104,7 @@ public class AArch64HotSpotMove {
masm.add(64, scratch, scratch, 1);
masm.ldr(64, asRegister(result), AArch64Address.createBaseRegisterOnlyAddress(scratch));
masm.nop();
- crb.recordMark(config.MARKID_NARROW_KLASS_BASE_ADDRESS);
+ crb.recordMark(HotSpotMarkId.NARROW_KLASS_BASE_ADDRESS);
}
}
@@ -236,7 +234,7 @@ public class AArch64HotSpotMove {
// masm.cmov(64, result, result, ARMv8.zr, ARMv8Assembler.ConditionFlag.NE);
// }
- public static void decodeKlassPointer(CompilationResultBuilder crb, AArch64MacroAssembler masm, Register result, Register ptr, CompressEncoding encoding, GraalHotSpotVMConfig config) {
+ public static void decodeKlassPointer(CompilationResultBuilder crb, AArch64MacroAssembler masm, Register result, Register ptr, CompressEncoding encoding) {
try (AArch64MacroAssembler.ScratchRegister sc = masm.getScratchRegister()) {
Register scratch = sc.getRegister();
boolean pic = GeneratePIC.getValue(crb.getOptions());
@@ -245,7 +243,7 @@ public class AArch64HotSpotMove {
masm.addressOf(scratch);
masm.ldr(64, scratch, AArch64Address.createBaseRegisterOnlyAddress(scratch));
masm.add(64, result, scratch, ptr, AArch64Assembler.ExtendType.UXTX, encoding.getShift());
- crb.recordMark(config.MARKID_NARROW_KLASS_BASE_ADDRESS);
+ crb.recordMark(HotSpotMarkId.NARROW_KLASS_BASE_ADDRESS);
} else {
masm.mov(scratch, encoding.getBase());
masm.add(64, result, scratch, ptr, AArch64Assembler.ExtendType.UXTX, encoding.getShift());
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotNodeLIRBuilder.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotNodeLIRBuilder.java
index 9aab14666af..5d1d0b2ddef 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotNodeLIRBuilder.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotNodeLIRBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, 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
@@ -147,7 +147,7 @@ public class AArch64HotSpotNodeLIRBuilder extends AArch64NodeLIRBuilder implemen
AllocatableValue targetAddressDst = inlineCacheRegister.asValue(targetAddressSrc.getValueKind());
gen.emitMove(metaspaceMethodDst, metaspaceMethodSrc);
gen.emitMove(targetAddressDst, targetAddressSrc);
- append(new AArch64IndirectCallOp(callTarget.targetMethod(), result, parameters, temps, metaspaceMethodDst, targetAddressDst, callState, getGen().config));
+ append(new AArch64IndirectCallOp(callTarget.targetMethod(), result, parameters, temps, metaspaceMethodDst, targetAddressDst, callState));
}
@Override
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotSafepointOp.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotSafepointOp.java
index fadf20eead8..2ea9f37e5ed 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotSafepointOp.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotSafepointOp.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, 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
@@ -27,10 +27,11 @@ package org.graalvm.compiler.hotspot.aarch64;
import static jdk.vm.ci.aarch64.AArch64.zr;
import static jdk.vm.ci.code.ValueUtil.asRegister;
-import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.asm.aarch64.AArch64Address;
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
+import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
import org.graalvm.compiler.lir.LIRFrameState;
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.Opcode;
@@ -81,7 +82,7 @@ public class AArch64HotSpotSafepointOp extends AArch64LIRInstruction {
}
public static void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm, GraalHotSpotVMConfig config, boolean onReturn, Register thread, Register scratch, LIRFrameState state) {
- if (config.threadLocalHandshakes) {
+ if (config.useThreadLocalPolling) {
emitThreadLocalPoll(crb, masm, config, onReturn, thread, scratch, state);
} else {
emitGlobalPoll(crb, masm, config, onReturn, scratch, state);
@@ -90,15 +91,15 @@ public class AArch64HotSpotSafepointOp extends AArch64LIRInstruction {
private static void emitGlobalPoll(CompilationResultBuilder crb, AArch64MacroAssembler masm, GraalHotSpotVMConfig config, boolean onReturn, Register scratch, LIRFrameState state) {
if (isPollingPageFar(config)) {
- crb.recordMark(onReturn ? config.MARKID_POLL_RETURN_FAR : config.MARKID_POLL_FAR);
+ crb.recordMark(onReturn ? HotSpotMarkId.POLL_RETURN_FAR : HotSpotMarkId.POLL_FAR);
masm.movNativeAddress(scratch, config.safepointPollingAddress);
- crb.recordMark(onReturn ? config.MARKID_POLL_RETURN_FAR : config.MARKID_POLL_FAR);
+ crb.recordMark(onReturn ? HotSpotMarkId.POLL_RETURN_FAR : HotSpotMarkId.POLL_FAR);
if (state != null) {
crb.recordInfopoint(masm.position(), state, InfopointReason.SAFEPOINT);
}
masm.ldr(32, zr, AArch64Address.createBaseRegisterOnlyAddress(scratch));
} else {
- crb.recordMark(onReturn ? config.MARKID_POLL_RETURN_NEAR : config.MARKID_POLL_NEAR);
+ crb.recordMark(onReturn ? HotSpotMarkId.POLL_RETURN_NEAR : HotSpotMarkId.POLL_NEAR);
if (state != null) {
crb.recordInfopoint(masm.position(), state, InfopointReason.SAFEPOINT);
}
@@ -110,7 +111,7 @@ public class AArch64HotSpotSafepointOp extends AArch64LIRInstruction {
LIRFrameState state) {
assert config.threadPollingPageOffset >= 0;
masm.ldr(64, scratch, masm.makeAddress(thread, config.threadPollingPageOffset, 8));
- crb.recordMark(onReturn ? config.MARKID_POLL_RETURN_FAR : config.MARKID_POLL_FAR);
+ crb.recordMark(onReturn ? HotSpotMarkId.POLL_RETURN_FAR : HotSpotMarkId.POLL_FAR);
if (state != null) {
crb.recordInfopoint(masm.position(), state, InfopointReason.SAFEPOINT);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64IndirectCallOp.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64IndirectCallOp.java
index 5763b37d01f..018960c74d9 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64IndirectCallOp.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64IndirectCallOp.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, 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
@@ -29,7 +29,7 @@ import static jdk.vm.ci.code.ValueUtil.asRegister;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
-import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
import org.graalvm.compiler.lir.LIRFrameState;
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.Opcode;
@@ -59,21 +59,20 @@ final class AArch64IndirectCallOp extends IndirectCallOp {
@Use({REG}) private Value metaspaceMethod;
- private final GraalHotSpotVMConfig config;
-
- AArch64IndirectCallOp(ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, Value metaspaceMethod, Value targetAddress, LIRFrameState state,
- GraalHotSpotVMConfig config) {
+ AArch64IndirectCallOp(ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, Value metaspaceMethod, Value targetAddress, LIRFrameState state) {
super(TYPE, callTarget, result, parameters, temps, targetAddress, state);
this.metaspaceMethod = metaspaceMethod;
- this.config = config;
}
@Override
+ @SuppressWarnings("try")
public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
- crb.recordMark(config.MARKID_INLINE_INVOKE);
- Register callReg = asRegister(targetAddress);
- assert !callReg.equals(METHOD);
- AArch64Call.indirectCall(crb, masm, callReg, callTarget, state);
+ try (CompilationResultBuilder.CallContext callContext = crb.openCallContext(false)) {
+ crb.recordMark(HotSpotMarkId.INLINE_INVOKE);
+ Register callReg = asRegister(targetAddress);
+ assert !callReg.equals(METHOD);
+ AArch64Call.indirectCall(crb, masm, callReg, callTarget, state);
+ }
}
@Override
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/StubAVXTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/StubAVXTest.java
index ef8a1ca3f35..16aa81c9601 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/StubAVXTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64.test/src/org/graalvm/compiler/hotspot/amd64/test/StubAVXTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2020, 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
@@ -34,11 +34,12 @@ import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
import org.graalvm.compiler.bytecode.BytecodeProvider;
import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.core.common.LIRKind;
-import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
+import org.graalvm.compiler.core.common.spi.ForeignCallSignature;
import org.graalvm.compiler.core.common.type.DataPointerConstant;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.hotspot.HotSpotBackend;
import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
+import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor;
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.hotspot.stubs.SnippetStub;
@@ -200,7 +201,7 @@ public class StubAVXTest extends LIRTest {
}
}
- public static final ForeignCallDescriptor TEST_STUB = new ForeignCallDescriptor("test_stub", void.class);
+ public static final ForeignCallSignature TEST_STUB = new ForeignCallSignature("test_stub", void.class);
@LIRIntrinsic
public static int compareAVXRegister(@SuppressWarnings("unused") LIRTestSpecification spec, Object left, Object right) {
@@ -235,7 +236,8 @@ public class StubAVXTest extends LIRTest {
public void test() {
HotSpotProviders providers = (HotSpotProviders) getProviders();
HotSpotForeignCallsProviderImpl foreignCalls = (HotSpotForeignCallsProviderImpl) providers.getForeignCalls();
- HotSpotForeignCallLinkage linkage = foreignCalls.registerStubCall(TEST_STUB, HotSpotForeignCallLinkage.Transition.LEAF_NO_VZERO, HotSpotForeignCallLinkage.Reexecutability.REEXECUTABLE,
+ HotSpotForeignCallLinkage linkage = foreignCalls.registerStubCall(TEST_STUB, HotSpotForeignCallDescriptor.Transition.LEAF_NO_VZERO,
+ HotSpotForeignCallDescriptor.Reexecutability.REEXECUTABLE,
COMPUTES_REGISTERS_KILLED);
linkage.setCompiledStub(new TestStub(getInitialOptions(), providers, linkage));
runTest("testStub");
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayCompareToStub.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayCompareToStub.java
index a491d66987c..66fb0075a1c 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayCompareToStub.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayCompareToStub.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,9 +24,14 @@
package org.graalvm.compiler.hotspot.amd64;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Reexecutability.REEXECUTABLE;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Transition.LEAF;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl.NO_LOCATIONS;
+
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.HotSpotForeignCallDescriptor;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.hotspot.stubs.SnippetStub;
import org.graalvm.compiler.options.OptionValues;
@@ -37,13 +42,13 @@ import jdk.vm.ci.meta.JavaKind;
public final class AMD64ArrayCompareToStub extends SnippetStub {
- public static final ForeignCallDescriptor STUB_BYTE_ARRAY_COMPARE_TO_BYTE_ARRAY = new ForeignCallDescriptor(
+ public static final HotSpotForeignCallDescriptor STUB_BYTE_ARRAY_COMPARE_TO_BYTE_ARRAY = new HotSpotForeignCallDescriptor(LEAF, REEXECUTABLE, NO_LOCATIONS,
"byteArrayCompareToByteArray", int.class, Pointer.class, Pointer.class, int.class, int.class);
- public static final ForeignCallDescriptor STUB_BYTE_ARRAY_COMPARE_TO_CHAR_ARRAY = new ForeignCallDescriptor(
+ public static final HotSpotForeignCallDescriptor STUB_BYTE_ARRAY_COMPARE_TO_CHAR_ARRAY = new HotSpotForeignCallDescriptor(LEAF, REEXECUTABLE, NO_LOCATIONS,
"byteArrayCompareToCharArray", int.class, Pointer.class, Pointer.class, int.class, int.class);
- public static final ForeignCallDescriptor STUB_CHAR_ARRAY_COMPARE_TO_BYTE_ARRAY = new ForeignCallDescriptor(
+ public static final HotSpotForeignCallDescriptor STUB_CHAR_ARRAY_COMPARE_TO_BYTE_ARRAY = new HotSpotForeignCallDescriptor(LEAF, REEXECUTABLE, NO_LOCATIONS,
"charArrayCompareToByteArray", int.class, Pointer.class, Pointer.class, int.class, int.class);
- public static final ForeignCallDescriptor STUB_CHAR_ARRAY_COMPARE_TO_CHAR_ARRAY = new ForeignCallDescriptor(
+ public static final HotSpotForeignCallDescriptor STUB_CHAR_ARRAY_COMPARE_TO_CHAR_ARRAY = new HotSpotForeignCallDescriptor(LEAF, REEXECUTABLE, NO_LOCATIONS,
"charArrayCompareToCharArray", int.class, Pointer.class, Pointer.class, int.class, int.class);
public AMD64ArrayCompareToStub(ForeignCallDescriptor foreignCallDescriptor, OptionValues options, HotSpotProviders providers, HotSpotForeignCallLinkage linkage) {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayEqualsStub.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayEqualsStub.java
index 8488c0247c9..d35ca5f9bb4 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayEqualsStub.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayEqualsStub.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,9 +24,14 @@
package org.graalvm.compiler.hotspot.amd64;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Reexecutability.REEXECUTABLE;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Transition.LEAF;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl.NO_LOCATIONS;
+
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.HotSpotForeignCallDescriptor;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.hotspot.stubs.SnippetStub;
import org.graalvm.compiler.options.OptionValues;
@@ -38,28 +43,28 @@ import jdk.vm.ci.meta.JavaKind;
public final class AMD64ArrayEqualsStub extends SnippetStub {
- public static final ForeignCallDescriptor STUB_BOOLEAN_ARRAY_EQUALS = new ForeignCallDescriptor(
+ public static final HotSpotForeignCallDescriptor STUB_BOOLEAN_ARRAY_EQUALS = new HotSpotForeignCallDescriptor(LEAF, REEXECUTABLE, NO_LOCATIONS,
"booleanArraysEquals", boolean.class, Pointer.class, Pointer.class, int.class);
- public static final ForeignCallDescriptor STUB_BYTE_ARRAY_EQUALS = new ForeignCallDescriptor(
+ public static final HotSpotForeignCallDescriptor STUB_BYTE_ARRAY_EQUALS = new HotSpotForeignCallDescriptor(LEAF, REEXECUTABLE, NO_LOCATIONS,
"byteArraysEquals", boolean.class, Pointer.class, Pointer.class, int.class);
- public static final ForeignCallDescriptor STUB_CHAR_ARRAY_EQUALS = new ForeignCallDescriptor(
+ public static final HotSpotForeignCallDescriptor STUB_CHAR_ARRAY_EQUALS = new HotSpotForeignCallDescriptor(LEAF, REEXECUTABLE, NO_LOCATIONS,
"charArraysEquals", boolean.class, Pointer.class, Pointer.class, int.class);
- public static final ForeignCallDescriptor STUB_SHORT_ARRAY_EQUALS = new ForeignCallDescriptor(
+ public static final HotSpotForeignCallDescriptor STUB_SHORT_ARRAY_EQUALS = new HotSpotForeignCallDescriptor(LEAF, REEXECUTABLE, NO_LOCATIONS,
"shortArraysEquals", boolean.class, Pointer.class, Pointer.class, int.class);
- public static final ForeignCallDescriptor STUB_INT_ARRAY_EQUALS = new ForeignCallDescriptor(
+ public static final HotSpotForeignCallDescriptor STUB_INT_ARRAY_EQUALS = new HotSpotForeignCallDescriptor(LEAF, REEXECUTABLE, NO_LOCATIONS,
"intArraysEquals", boolean.class, Pointer.class, Pointer.class, int.class);
- public static final ForeignCallDescriptor STUB_LONG_ARRAY_EQUALS = new ForeignCallDescriptor(
+ public static final HotSpotForeignCallDescriptor STUB_LONG_ARRAY_EQUALS = new HotSpotForeignCallDescriptor(LEAF, REEXECUTABLE, NO_LOCATIONS,
"longArraysEquals", boolean.class, Pointer.class, Pointer.class, int.class);
- public static final ForeignCallDescriptor STUB_FLOAT_ARRAY_EQUALS = new ForeignCallDescriptor(
+ public static final HotSpotForeignCallDescriptor STUB_FLOAT_ARRAY_EQUALS = new HotSpotForeignCallDescriptor(LEAF, REEXECUTABLE, NO_LOCATIONS,
"floatArraysEquals", boolean.class, Pointer.class, Pointer.class, int.class);
- public static final ForeignCallDescriptor STUB_DOUBLE_ARRAY_EQUALS = new ForeignCallDescriptor(
+ public static final HotSpotForeignCallDescriptor STUB_DOUBLE_ARRAY_EQUALS = new HotSpotForeignCallDescriptor(LEAF, REEXECUTABLE, NO_LOCATIONS,
"doubleArraysEquals", boolean.class, Pointer.class, Pointer.class, int.class);
- public static final ForeignCallDescriptor STUB_BYTE_ARRAY_EQUALS_DIRECT = new ForeignCallDescriptor(
+ public static final HotSpotForeignCallDescriptor STUB_BYTE_ARRAY_EQUALS_DIRECT = new HotSpotForeignCallDescriptor(LEAF, REEXECUTABLE, NO_LOCATIONS,
"byteArraysEqualsDirect", boolean.class, Pointer.class, Pointer.class, int.class);
- public static final ForeignCallDescriptor STUB_CHAR_ARRAY_EQUALS_DIRECT = new ForeignCallDescriptor(
+ public static final HotSpotForeignCallDescriptor STUB_CHAR_ARRAY_EQUALS_DIRECT = new HotSpotForeignCallDescriptor(LEAF, REEXECUTABLE, NO_LOCATIONS,
"charArraysEqualsDirect", boolean.class, Pointer.class, Pointer.class, int.class);
- public static final ForeignCallDescriptor STUB_CHAR_ARRAY_EQUALS_BYTE_ARRAY = new ForeignCallDescriptor(
+ public static final HotSpotForeignCallDescriptor STUB_CHAR_ARRAY_EQUALS_BYTE_ARRAY = new HotSpotForeignCallDescriptor(LEAF, REEXECUTABLE, NO_LOCATIONS,
"charArrayEqualsByteArray", boolean.class, Pointer.class, Pointer.class, int.class);
public AMD64ArrayEqualsStub(ForeignCallDescriptor foreignCallDescriptor, OptionValues options, HotSpotProviders providers, HotSpotForeignCallLinkage linkage) {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayIndexOfStub.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayIndexOfStub.java
index 0b758fb7eaf..bb689f9ae81 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayIndexOfStub.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayIndexOfStub.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
package org.graalvm.compiler.hotspot.amd64;
import org.graalvm.compiler.api.replacements.Snippet;
-import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.hotspot.stubs.SnippetStub;
@@ -34,8 +33,8 @@ import org.graalvm.compiler.replacements.amd64.AMD64ArrayIndexOfNode;
public class AMD64ArrayIndexOfStub extends SnippetStub {
- public AMD64ArrayIndexOfStub(ForeignCallDescriptor foreignCallDescriptor, OptionValues options, HotSpotProviders providers, HotSpotForeignCallLinkage linkage) {
- super(foreignCallDescriptor.getName(), options, providers, linkage);
+ public AMD64ArrayIndexOfStub(OptionValues options, HotSpotProviders providers, HotSpotForeignCallLinkage linkage) {
+ super(linkage.getDescriptor().getName(), options, providers, linkage);
}
@Snippet
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java
index d3a4194dade..a19c1793e17 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotAddressLowering.java
@@ -36,6 +36,7 @@ import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.core.common.type.ObjectStamp;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode;
import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp;
import org.graalvm.compiler.loop.BasicInductionVariable;
@@ -100,7 +101,7 @@ public class AMD64HotSpotAddressLowering extends AMD64CompressAddressLowering {
} else if (encoding.getBase() != 0 || (generatePIC && compression.stamp(NodeView.DEFAULT) instanceof KlassPointerStamp)) {
if (generatePIC) {
if (other == null) {
- ValueNode base = compression.graph().unique(new GraalHotSpotVMConfigNode(config, config.MARKID_NARROW_KLASS_BASE_ADDRESS, JavaKind.Long));
+ ValueNode base = compression.graph().unique(new GraalHotSpotVMConfigNode(config, HotSpotMarkId.NARROW_KLASS_BASE_ADDRESS, JavaKind.Long));
addr.setBase(base);
} else {
return false;
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackend.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackend.java
index 56724ae4830..8e8cd772354 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackend.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackend.java
@@ -34,7 +34,6 @@ import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
import static org.graalvm.compiler.core.common.GraalOptions.ZapStackOnMethodEntry;
import jdk.internal.vm.compiler.collections.EconomicSet;
-import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.amd64.AMD64Address;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag;
import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
@@ -49,6 +48,7 @@ import org.graalvm.compiler.hotspot.HotSpotDataBuilder;
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
import org.graalvm.compiler.hotspot.HotSpotHostBackend;
import org.graalvm.compiler.hotspot.HotSpotLIRGenerationResult;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
import org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction;
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
@@ -170,6 +170,9 @@ public class AMD64HotSpotBackend extends HotSpotHostBackend implements LIRGenera
} else {
asm.decrementq(rsp, frameSize);
}
+ if (HotSpotMarkId.FRAME_COMPLETE.isAvailable()) {
+ crb.recordMark(HotSpotMarkId.FRAME_COMPLETE);
+ }
if (ZapStackOnMethodEntry.getValue(crb.getOptions())) {
final int intSize = 4;
for (int i = 0; i < frameSize / intSize; ++i) {
@@ -210,10 +213,11 @@ public class AMD64HotSpotBackend extends HotSpotHostBackend implements LIRGenera
assert gen.getDeoptimizationRescueSlot() == null || frameMap.frameNeedsAllocating() : "method that can deoptimize must have a frame";
OptionValues options = lir.getOptions();
DebugContext debug = lir.getDebug();
- boolean omitFrame = CanOmitFrame.getValue(options) && !frameMap.frameNeedsAllocating() && !lir.hasArgInCallerFrame() && !gen.hasForeignCall();
+ boolean omitFrame = CanOmitFrame.getValue(options) && !frameMap.frameNeedsAllocating() && !lir.hasArgInCallerFrame() && !gen.hasForeignCall() &&
+ !((AMD64FrameMap) frameMap).useStandardFrameProlog();
Stub stub = gen.getStub();
- AMD64MacroAssembler masm = new AMD64MacroAssembler(getTarget(), options);
+ AMD64MacroAssembler masm = new AMD64MacroAssembler(getTarget(), options, config.CPU_HAS_INTEL_JCC_ERRATUM);
masm.setCodePatchShifter(compilationResult::shiftCodePatch);
HotSpotFrameContext frameContext = new HotSpotFrameContext(stub != null, omitFrame, config.preserveFramePointer);
DataBuilder dataBuilder = new HotSpotDataBuilder(getCodeCache().getTarget());
@@ -237,10 +241,9 @@ public class AMD64HotSpotBackend extends HotSpotHostBackend implements LIRGenera
AMD64MacroAssembler asm = (AMD64MacroAssembler) crb.asm;
FrameMap frameMap = crb.frameMap;
RegisterConfig regConfig = frameMap.getRegisterConfig();
- Label verifiedEntry = new Label();
// Emit the prefix
- emitCodePrefix(installedCodeOwner, crb, asm, regConfig, verifiedEntry);
+ emitCodePrefix(installedCodeOwner, crb, asm, regConfig);
// Emit code for the LIR
emitCodeBody(installedCodeOwner, crb, lir);
@@ -257,10 +260,10 @@ public class AMD64HotSpotBackend extends HotSpotHostBackend implements LIRGenera
*
* @param installedCodeOwner see {@link LIRGenerationProvider#emitCode}
*/
- public void emitCodePrefix(ResolvedJavaMethod installedCodeOwner, CompilationResultBuilder crb, AMD64MacroAssembler asm, RegisterConfig regConfig, Label verifiedEntry) {
+ public void emitCodePrefix(ResolvedJavaMethod installedCodeOwner, CompilationResultBuilder crb, AMD64MacroAssembler asm, RegisterConfig regConfig) {
HotSpotProviders providers = getProviders();
if (installedCodeOwner != null && !installedCodeOwner.isStatic()) {
- crb.recordMark(config.MARKID_UNVERIFIED_ENTRY);
+ crb.recordMark(HotSpotMarkId.UNVERIFIED_ENTRY);
CallingConvention cc = regConfig.getCallingConvention(HotSpotCallingConventionType.JavaCallee, null, new JavaType[]{providers.getMetaAccess().lookupJavaType(Object.class)}, this);
Register inlineCacheKlass = rax; // see definition of IC_Klass in
// c1_LIRAssembler_x86.cpp
@@ -274,7 +277,7 @@ public class AMD64HotSpotBackend extends HotSpotHostBackend implements LIRGenera
AMD64HotSpotMove.decodeKlassPointer(crb, asm, register, heapBase, src, config);
if (GeneratePIC.getValue(crb.getOptions())) {
asm.movq(heapBase, asm.getPlaceholder(-1));
- crb.recordMark(config.MARKID_NARROW_OOP_BASE_ADDRESS);
+ crb.recordMark(HotSpotMarkId.NARROW_OOP_BASE_ADDRESS);
} else {
if (config.narrowKlassBase != 0) {
// The heap base register was destroyed above, so restore it
@@ -293,9 +296,7 @@ public class AMD64HotSpotBackend extends HotSpotHostBackend implements LIRGenera
}
asm.align(config.codeEntryAlignment);
- crb.recordMark(config.MARKID_OSR_ENTRY);
- asm.bind(verifiedEntry);
- crb.recordMark(config.MARKID_VERIFIED_ENTRY);
+ crb.recordMark(crb.compilationResult.getEntryBCI() != -1 ? HotSpotMarkId.OSR_ENTRY : HotSpotMarkId.VERIFIED_ENTRY);
if (GeneratePIC.getValue(crb.getOptions())) {
// Check for method state
@@ -326,9 +327,9 @@ public class AMD64HotSpotBackend extends HotSpotHostBackend implements LIRGenera
HotSpotFrameContext frameContext = (HotSpotFrameContext) crb.frameContext;
if (!frameContext.isStub) {
HotSpotForeignCallsProvider foreignCalls = providers.getForeignCalls();
- crb.recordMark(config.MARKID_EXCEPTION_HANDLER_ENTRY);
+ crb.recordMark(HotSpotMarkId.EXCEPTION_HANDLER_ENTRY);
AMD64Call.directCall(crb, asm, foreignCalls.lookupForeignCall(EXCEPTION_HANDLER), null, false, null);
- crb.recordMark(config.MARKID_DEOPT_HANDLER_ENTRY);
+ crb.recordMark(HotSpotMarkId.DEOPT_HANDLER_ENTRY);
AMD64Call.directCall(crb, asm, foreignCalls.lookupForeignCall(DEOPT_BLOB_UNPACK), null, false, null);
} else {
// No need to emit the stubs for entries back into the method since
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java
index 0132af2ea02..db5f47b7a8b 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java
@@ -31,6 +31,7 @@ import java.util.List;
import org.graalvm.compiler.bytecode.BytecodeProvider;
import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
+import org.graalvm.compiler.core.common.spi.MetaAccessExtensionProvider;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.HotSpotBackend;
import org.graalvm.compiler.hotspot.HotSpotBackendFactory;
@@ -38,11 +39,12 @@ import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
import org.graalvm.compiler.hotspot.HotSpotReplacementsImpl;
import org.graalvm.compiler.hotspot.meta.AddressLoweringHotSpotSuitesProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
-import org.graalvm.compiler.hotspot.meta.HotSpotPlatformConfigurationProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotGraalConstantFieldProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins;
import org.graalvm.compiler.hotspot.meta.HotSpotHostForeignCallsProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotLoweringProvider;
+import org.graalvm.compiler.hotspot.meta.HotSpotMetaAccessExtensionProvider;
+import org.graalvm.compiler.hotspot.meta.HotSpotPlatformConfigurationProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.hotspot.meta.HotSpotRegisters;
import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider;
@@ -108,6 +110,7 @@ public class AMD64HotSpotBackendFactory extends HotSpotBackendFactory {
HotSpotLoweringProvider lowerer;
HotSpotStampProvider stampProvider;
HotSpotPlatformConfigurationProvider platformConfigurationProvider;
+ HotSpotMetaAccessExtensionProvider metaAccessExtensionProvider;
HotSpotSnippetReflectionProvider snippetReflection;
HotSpotReplacementsImpl replacements;
HotSpotSuitesProvider suites;
@@ -130,14 +133,18 @@ public class AMD64HotSpotBackendFactory extends HotSpotBackendFactory {
try (InitTimer rt = timer("create platform configuration provider")) {
platformConfigurationProvider = createConfigInfoProvider(config, metaAccess);
}
+ try (InitTimer rt = timer("create MetaAccessExtensionProvider")) {
+ metaAccessExtensionProvider = createMetaAccessExtensionProvider();
+ }
try (InitTimer rt = timer("create stamp provider")) {
stampProvider = createStampProvider();
}
try (InitTimer rt = timer("create Lowerer provider")) {
- lowerer = createLowerer(graalRuntime, metaAccess, foreignCalls, registers, constantReflection, platformConfigurationProvider, target);
+ lowerer = createLowerer(graalRuntime, metaAccess, foreignCalls, registers, constantReflection, platformConfigurationProvider, metaAccessExtensionProvider, target);
}
- Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider, platformConfigurationProvider);
+ Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider, platformConfigurationProvider,
+ metaAccessExtensionProvider);
try (InitTimer rt = timer("create SnippetReflection provider")) {
snippetReflection = createSnippetReflection(graalRuntime, constantReflection, wordTypes);
@@ -157,7 +164,7 @@ public class AMD64HotSpotBackendFactory extends HotSpotBackendFactory {
suites = createSuites(config, graalRuntime, compilerConfiguration, plugins, registers, replacements, options);
}
providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers,
- snippetReflection, wordTypes, plugins, platformConfigurationProvider);
+ snippetReflection, wordTypes, plugins, platformConfigurationProvider, metaAccessExtensionProvider);
replacements.setProviders(providers);
replacements.maybeInitializeEncoder(options);
}
@@ -216,13 +223,15 @@ public class AMD64HotSpotBackendFactory extends HotSpotBackendFactory {
}
protected HotSpotLoweringProvider createLowerer(HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, HotSpotForeignCallsProvider foreignCalls,
- HotSpotRegistersProvider registers, HotSpotConstantReflectionProvider constantReflection, PlatformConfigurationProvider platformConfig, TargetDescription target) {
- return new AMD64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers, constantReflection, platformConfig, target);
+ HotSpotRegistersProvider registers, HotSpotConstantReflectionProvider constantReflection, PlatformConfigurationProvider platformConfig,
+ MetaAccessExtensionProvider metaAccessExtensionProvider,
+ TargetDescription target) {
+ return new AMD64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers, constantReflection, platformConfig, metaAccessExtensionProvider, target);
}
protected Value[] createNativeABICallerSaveRegisters(GraalHotSpotVMConfig config, RegisterConfig regConfig) {
List callerSave = new ArrayList<>(regConfig.getAllocatableRegisters().asList());
- if (config.windowsOs) {
+ if (config.osName.equals("windows")) {
// http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx
callerSave.remove(AMD64.rdi);
callerSave.remove(AMD64.rsi);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotDirectStaticCallOp.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotDirectStaticCallOp.java
index a9c8db1fb4c..2afe2606f94 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotDirectStaticCallOp.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotDirectStaticCallOp.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
package org.graalvm.compiler.hotspot.amd64;
import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
-import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
import org.graalvm.compiler.lir.LIRFrameState;
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.Opcode;
@@ -45,18 +45,19 @@ final class AMD64HotSpotDirectStaticCallOp extends DirectCallOp {
public static final LIRInstructionClass TYPE = LIRInstructionClass.create(AMD64HotSpotDirectStaticCallOp.class);
private final InvokeKind invokeKind;
- private final GraalHotSpotVMConfig config;
- AMD64HotSpotDirectStaticCallOp(ResolvedJavaMethod target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind, GraalHotSpotVMConfig config) {
+ AMD64HotSpotDirectStaticCallOp(ResolvedJavaMethod target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind) {
super(TYPE, target, result, parameters, temps, state);
assert invokeKind.isDirect();
this.invokeKind = invokeKind;
- this.config = config;
}
@Override
+ @SuppressWarnings("try")
public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
- crb.recordMark(invokeKind == InvokeKind.Static ? config.MARKID_INVOKESTATIC : config.MARKID_INVOKESPECIAL);
- super.emitCode(crb, masm);
+ try (CompilationResultBuilder.CallContext callContext = crb.openCallContext(invokeKind.isDirect())) {
+ crb.recordMark(invokeKind == InvokeKind.Static ? HotSpotMarkId.INVOKESTATIC : HotSpotMarkId.INVOKESPECIAL);
+ super.emitCode(crb, masm);
+ }
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java
index 9f9101bf486..80b49fc2637 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,12 +32,10 @@ import static org.graalvm.compiler.hotspot.HotSpotBackend.EXCEPTION_HANDLER;
import static org.graalvm.compiler.hotspot.HotSpotBackend.EXCEPTION_HANDLER_IN_CALLER;
import static org.graalvm.compiler.hotspot.HotSpotBackend.Options.GraalArithmeticStubs;
import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.JUMP_ADDRESS;
-import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability.NOT_REEXECUTABLE;
-import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability.REEXECUTABLE;
import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.COMPUTES_REGISTERS_KILLED;
import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.DESTROYS_ALL_CALLER_SAVE_REGISTERS;
-import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.LEAF;
-import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.LEAF_NO_VZERO;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Reexecutability.REEXECUTABLE;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Transition.LEAF;
import static org.graalvm.compiler.hotspot.replacements.CRC32CSubstitutions.UPDATE_BYTES_CRC32C;
import static org.graalvm.compiler.hotspot.replacements.CRC32Substitutions.UPDATE_BYTES_CRC32;
import static org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode.BinaryOperation.POW;
@@ -47,7 +45,6 @@ import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.Una
import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.LOG10;
import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.SIN;
import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.TAN;
-import static jdk.internal.vm.compiler.word.LocationIdentity.any;
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
@@ -90,80 +87,79 @@ public class AMD64HotSpotForeignCallsProvider extends HotSpotHostForeignCallsPro
RegisterValue exception = rax.asValue(LIRKind.reference(word));
RegisterValue exceptionPc = rdx.asValue(LIRKind.value(word));
CallingConvention exceptionCc = new CallingConvention(0, ILLEGAL, exception, exceptionPc);
- register(new HotSpotForeignCallLinkageImpl(EXCEPTION_HANDLER, 0L, DESTROYS_ALL_CALLER_SAVE_REGISTERS, LEAF_NO_VZERO, NOT_REEXECUTABLE, exceptionCc, null, any()));
- register(new HotSpotForeignCallLinkageImpl(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, DESTROYS_ALL_CALLER_SAVE_REGISTERS, LEAF_NO_VZERO, NOT_REEXECUTABLE, exceptionCc, null,
- any()));
+ register(new HotSpotForeignCallLinkageImpl(EXCEPTION_HANDLER, 0L, DESTROYS_ALL_CALLER_SAVE_REGISTERS, exceptionCc, null));
+ register(new HotSpotForeignCallLinkageImpl(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, DESTROYS_ALL_CALLER_SAVE_REGISTERS, exceptionCc, null));
if (config.useCRC32Intrinsics) {
// This stub does callee saving
- registerForeignCall(UPDATE_BYTES_CRC32, config.updateBytesCRC32Stub, NativeCall, LEAF_NO_VZERO, NOT_REEXECUTABLE, any());
+ registerForeignCall(UPDATE_BYTES_CRC32, config.updateBytesCRC32Stub, NativeCall);
}
if (config.useCRC32CIntrinsics) {
- registerForeignCall(UPDATE_BYTES_CRC32C, config.updateBytesCRC32C, NativeCall, LEAF_NO_VZERO, NOT_REEXECUTABLE, any());
+ registerForeignCall(UPDATE_BYTES_CRC32C, config.updateBytesCRC32C, NativeCall);
}
- link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_TWO_CONSECUTIVE_BYTES, options, providers,
+ link(new AMD64ArrayIndexOfStub(options, providers,
registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_TWO_CONSECUTIVE_BYTES, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
- link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_TWO_CONSECUTIVE_CHARS, options, providers,
+ link(new AMD64ArrayIndexOfStub(options, providers,
registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_TWO_CONSECUTIVE_CHARS, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
- link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_TWO_CONSECUTIVE_CHARS_COMPACT, options, providers,
+ link(new AMD64ArrayIndexOfStub(options, providers,
registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_TWO_CONSECUTIVE_CHARS_COMPACT, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
- link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_1_BYTE, options, providers,
+ link(new AMD64ArrayIndexOfStub(options, providers,
registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_1_BYTE, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
- link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_2_BYTES, options, providers,
+ link(new AMD64ArrayIndexOfStub(options, providers,
registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_2_BYTES, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
- link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_3_BYTES, options, providers,
+ link(new AMD64ArrayIndexOfStub(options, providers,
registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_3_BYTES, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
- link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_4_BYTES, options, providers,
+ link(new AMD64ArrayIndexOfStub(options, providers,
registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_4_BYTES, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
- link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_1_CHAR, options, providers,
+ link(new AMD64ArrayIndexOfStub(options, providers,
registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_1_CHAR, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
- link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_2_CHARS, options, providers,
+ link(new AMD64ArrayIndexOfStub(options, providers,
registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_2_CHARS, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
- link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_3_CHARS, options, providers,
+ link(new AMD64ArrayIndexOfStub(options, providers,
registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_3_CHARS, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
- link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_4_CHARS, options, providers,
+ link(new AMD64ArrayIndexOfStub(options, providers,
registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_4_CHARS, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
- link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_1_CHAR_COMPACT, options, providers,
+ link(new AMD64ArrayIndexOfStub(options, providers,
registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_1_CHAR_COMPACT, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
- link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_2_CHARS_COMPACT, options, providers,
+ link(new AMD64ArrayIndexOfStub(options, providers,
registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_2_CHARS_COMPACT, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
- link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_3_CHARS_COMPACT, options, providers,
+ link(new AMD64ArrayIndexOfStub(options, providers,
registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_3_CHARS_COMPACT, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
- link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_4_CHARS_COMPACT, options, providers,
+ link(new AMD64ArrayIndexOfStub(options, providers,
registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_4_CHARS_COMPACT, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_BOOLEAN_ARRAY_EQUALS, options, providers,
- registerStubCall(AMD64ArrayEqualsStub.STUB_BOOLEAN_ARRAY_EQUALS, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ registerStubCall(AMD64ArrayEqualsStub.STUB_BOOLEAN_ARRAY_EQUALS, COMPUTES_REGISTERS_KILLED)));
link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_BYTE_ARRAY_EQUALS, options, providers,
- registerStubCall(AMD64ArrayEqualsStub.STUB_BYTE_ARRAY_EQUALS, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ registerStubCall(AMD64ArrayEqualsStub.STUB_BYTE_ARRAY_EQUALS, COMPUTES_REGISTERS_KILLED)));
link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_CHAR_ARRAY_EQUALS, options, providers,
- registerStubCall(AMD64ArrayEqualsStub.STUB_CHAR_ARRAY_EQUALS, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ registerStubCall(AMD64ArrayEqualsStub.STUB_CHAR_ARRAY_EQUALS, COMPUTES_REGISTERS_KILLED)));
link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_SHORT_ARRAY_EQUALS, options, providers,
- registerStubCall(AMD64ArrayEqualsStub.STUB_SHORT_ARRAY_EQUALS, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ registerStubCall(AMD64ArrayEqualsStub.STUB_SHORT_ARRAY_EQUALS, COMPUTES_REGISTERS_KILLED)));
link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_INT_ARRAY_EQUALS, options, providers,
- registerStubCall(AMD64ArrayEqualsStub.STUB_INT_ARRAY_EQUALS, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ registerStubCall(AMD64ArrayEqualsStub.STUB_INT_ARRAY_EQUALS, COMPUTES_REGISTERS_KILLED)));
link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_LONG_ARRAY_EQUALS, options, providers,
- registerStubCall(AMD64ArrayEqualsStub.STUB_LONG_ARRAY_EQUALS, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ registerStubCall(AMD64ArrayEqualsStub.STUB_LONG_ARRAY_EQUALS, COMPUTES_REGISTERS_KILLED)));
link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_FLOAT_ARRAY_EQUALS, options, providers,
- registerStubCall(AMD64ArrayEqualsStub.STUB_FLOAT_ARRAY_EQUALS, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ registerStubCall(AMD64ArrayEqualsStub.STUB_FLOAT_ARRAY_EQUALS, COMPUTES_REGISTERS_KILLED)));
link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_DOUBLE_ARRAY_EQUALS, options, providers,
- registerStubCall(AMD64ArrayEqualsStub.STUB_DOUBLE_ARRAY_EQUALS, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ registerStubCall(AMD64ArrayEqualsStub.STUB_DOUBLE_ARRAY_EQUALS, COMPUTES_REGISTERS_KILLED)));
link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_BYTE_ARRAY_EQUALS_DIRECT, options, providers,
- registerStubCall(AMD64ArrayEqualsStub.STUB_BYTE_ARRAY_EQUALS_DIRECT, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ registerStubCall(AMD64ArrayEqualsStub.STUB_BYTE_ARRAY_EQUALS_DIRECT, COMPUTES_REGISTERS_KILLED)));
link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_CHAR_ARRAY_EQUALS_DIRECT, options, providers,
- registerStubCall(AMD64ArrayEqualsStub.STUB_CHAR_ARRAY_EQUALS_DIRECT, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ registerStubCall(AMD64ArrayEqualsStub.STUB_CHAR_ARRAY_EQUALS_DIRECT, COMPUTES_REGISTERS_KILLED)));
link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_CHAR_ARRAY_EQUALS_BYTE_ARRAY, options, providers,
- registerStubCall(AMD64ArrayEqualsStub.STUB_CHAR_ARRAY_EQUALS_BYTE_ARRAY, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ registerStubCall(AMD64ArrayEqualsStub.STUB_CHAR_ARRAY_EQUALS_BYTE_ARRAY, COMPUTES_REGISTERS_KILLED)));
link(new AMD64ArrayCompareToStub(AMD64ArrayCompareToStub.STUB_BYTE_ARRAY_COMPARE_TO_BYTE_ARRAY, options, providers,
- registerStubCall(AMD64ArrayCompareToStub.STUB_BYTE_ARRAY_COMPARE_TO_BYTE_ARRAY, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ registerStubCall(AMD64ArrayCompareToStub.STUB_BYTE_ARRAY_COMPARE_TO_BYTE_ARRAY, COMPUTES_REGISTERS_KILLED)));
link(new AMD64ArrayCompareToStub(AMD64ArrayCompareToStub.STUB_BYTE_ARRAY_COMPARE_TO_CHAR_ARRAY, options, providers,
- registerStubCall(AMD64ArrayCompareToStub.STUB_BYTE_ARRAY_COMPARE_TO_CHAR_ARRAY, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ registerStubCall(AMD64ArrayCompareToStub.STUB_BYTE_ARRAY_COMPARE_TO_CHAR_ARRAY, COMPUTES_REGISTERS_KILLED)));
link(new AMD64ArrayCompareToStub(AMD64ArrayCompareToStub.STUB_CHAR_ARRAY_COMPARE_TO_BYTE_ARRAY, options, providers,
- registerStubCall(AMD64ArrayCompareToStub.STUB_CHAR_ARRAY_COMPARE_TO_BYTE_ARRAY, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ registerStubCall(AMD64ArrayCompareToStub.STUB_CHAR_ARRAY_COMPARE_TO_BYTE_ARRAY, COMPUTES_REGISTERS_KILLED)));
link(new AMD64ArrayCompareToStub(AMD64ArrayCompareToStub.STUB_CHAR_ARRAY_COMPARE_TO_CHAR_ARRAY, options, providers,
- registerStubCall(AMD64ArrayCompareToStub.STUB_CHAR_ARRAY_COMPARE_TO_CHAR_ARRAY, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ registerStubCall(AMD64ArrayCompareToStub.STUB_CHAR_ARRAY_COMPARE_TO_CHAR_ARRAY, COMPUTES_REGISTERS_KILLED)));
super.initialize(providers, options);
}
@@ -176,13 +172,13 @@ public class AMD64HotSpotForeignCallsProvider extends HotSpotHostForeignCallsPro
@Override
protected void registerMathStubs(GraalHotSpotVMConfig hotSpotVMConfig, HotSpotProviders providers, OptionValues options) {
if (GraalArithmeticStubs.getValue(options)) {
- link(new AMD64MathStub(SIN, options, providers, registerStubCall(SIN.foreignCallDescriptor, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
- link(new AMD64MathStub(COS, options, providers, registerStubCall(COS.foreignCallDescriptor, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
- link(new AMD64MathStub(TAN, options, providers, registerStubCall(TAN.foreignCallDescriptor, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
- link(new AMD64MathStub(EXP, options, providers, registerStubCall(EXP.foreignCallDescriptor, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
- link(new AMD64MathStub(LOG, options, providers, registerStubCall(LOG.foreignCallDescriptor, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
- link(new AMD64MathStub(LOG10, options, providers, registerStubCall(LOG10.foreignCallDescriptor, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
- link(new AMD64MathStub(POW, options, providers, registerStubCall(POW.foreignCallDescriptor, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ link(new AMD64MathStub(SIN, options, providers, registerStubCall(SIN.foreignCallSignature, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ link(new AMD64MathStub(COS, options, providers, registerStubCall(COS.foreignCallSignature, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ link(new AMD64MathStub(TAN, options, providers, registerStubCall(TAN.foreignCallSignature, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ link(new AMD64MathStub(EXP, options, providers, registerStubCall(EXP.foreignCallSignature, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ link(new AMD64MathStub(LOG, options, providers, registerStubCall(LOG.foreignCallSignature, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ link(new AMD64MathStub(LOG10, options, providers, registerStubCall(LOG10.foreignCallSignature, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
+ link(new AMD64MathStub(POW, options, providers, registerStubCall(POW.foreignCallSignature, LEAF, REEXECUTABLE, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS)));
} else {
super.registerMathStubs(hotSpotVMConfig, providers, options);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java
index d7a4532d214..2f944e8f38f 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLIRGenerator.java
@@ -56,6 +56,7 @@ import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
import org.graalvm.compiler.hotspot.HotSpotLIRGenerationResult;
import org.graalvm.compiler.hotspot.HotSpotLIRGenerator;
import org.graalvm.compiler.hotspot.HotSpotLockStack;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
import org.graalvm.compiler.hotspot.debug.BenchmarkCounters;
import org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
@@ -476,7 +477,7 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSp
}
@Override
- public Value emitLoadConfigValue(int markId, LIRKind kind) {
+ public Value emitLoadConfigValue(HotSpotMarkId markId, LIRKind kind) {
Variable result = newVariable(kind);
append(new AMD64HotSpotLoadConfigValueOp(markId, result));
return result;
@@ -602,7 +603,7 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSp
if (encoding.hasBase() || GeneratePIC.getValue(options)) {
if (GeneratePIC.getValue(options)) {
Variable baseAddress = newVariable(lirKindTool.getWordKind());
- AMD64HotSpotMove.BaseMove move = new AMD64HotSpotMove.BaseMove(baseAddress, config);
+ AMD64HotSpotMove.BaseMove move = new AMD64HotSpotMove.BaseMove(baseAddress);
append(move);
base = baseAddress;
} else {
@@ -633,7 +634,7 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSp
if (encoding.hasBase() || GeneratePIC.getValue(options)) {
if (GeneratePIC.getValue(options)) {
Variable baseAddress = newVariable(uncompressedKind);
- AMD64HotSpotMove.BaseMove move = new AMD64HotSpotMove.BaseMove(baseAddress, config);
+ AMD64HotSpotMove.BaseMove move = new AMD64HotSpotMove.BaseMove(baseAddress);
append(move);
base = baseAddress;
} else {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoadConfigValueOp.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoadConfigValueOp.java
index 0bf0abfd910..ec1bf57a669 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoadConfigValueOp.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoadConfigValueOp.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,28 +24,29 @@
package org.graalvm.compiler.hotspot.amd64;
-import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
import static jdk.vm.ci.code.ValueUtil.asRegister;
-
-import jdk.vm.ci.amd64.AMD64Kind;
-import jdk.vm.ci.code.Register;
-import jdk.vm.ci.meta.AllocatableValue;
+import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
import org.graalvm.compiler.asm.amd64.AMD64Address;
import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
import org.graalvm.compiler.debug.GraalError;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
+import jdk.vm.ci.amd64.AMD64Kind;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.meta.AllocatableValue;
+
public final class AMD64HotSpotLoadConfigValueOp extends AMD64LIRInstruction {
public static final LIRInstructionClass TYPE = LIRInstructionClass.create(AMD64HotSpotLoadConfigValueOp.class);
@Def({OperandFlag.REG}) protected AllocatableValue result;
- private final int markId;
+ private final HotSpotMarkId markId;
- public AMD64HotSpotLoadConfigValueOp(int markId, AllocatableValue result) {
+ public AMD64HotSpotLoadConfigValueOp(HotSpotMarkId markId, AllocatableValue result) {
super(TYPE);
this.result = result;
this.markId = markId;
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java
index 26024d63120..54b2912dc37 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java
@@ -26,9 +26,9 @@ package org.graalvm.compiler.hotspot.amd64;
import static org.graalvm.compiler.hotspot.HotSpotBackend.Options.GraalArithmeticStubs;
-import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.core.amd64.AMD64LoweringProviderMixin;
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
+import org.graalvm.compiler.core.common.spi.MetaAccessExtensionProvider;
import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
@@ -62,8 +62,9 @@ public class AMD64HotSpotLoweringProvider extends DefaultHotSpotLoweringProvider
private AMD64X87MathSnippets.Templates mathSnippets;
public AMD64HotSpotLoweringProvider(HotSpotGraalRuntimeProvider runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers,
- HotSpotConstantReflectionProvider constantReflection, PlatformConfigurationProvider platformConfig, TargetDescription target) {
- super(runtime, metaAccess, foreignCalls, registers, constantReflection, platformConfig, target);
+ HotSpotConstantReflectionProvider constantReflection, PlatformConfigurationProvider platformConfig, MetaAccessExtensionProvider metaAccessExtensionProvider,
+ TargetDescription target) {
+ super(runtime, metaAccess, foreignCalls, registers, constantReflection, platformConfig, metaAccessExtensionProvider, target);
}
@Override
@@ -100,12 +101,10 @@ public class AMD64HotSpotLoweringProvider extends DefaultHotSpotLoweringProvider
}
StructuredGraph graph = math.graph();
ResolvedJavaMethod method = graph.method();
- if (method != null) {
- if (method.getAnnotation(Snippet.class) != null) {
- // In the context of SnippetStub, i.e., Graal-generated stubs, use the LIR
- // lowering to emit the stub assembly code instead of the Node lowering.
- return;
- }
+ if (method != null && getReplacements().isSnippet(method)) {
+ // In the context of SnippetStub, i.e., Graal-generated stubs, use the LIR
+ // lowering to emit the stub assembly code instead of the Node lowering.
+ return;
}
if (!GraalArithmeticStubs.getValue(graph.getOptions())) {
switch (math.getOperation()) {
@@ -127,7 +126,7 @@ public class AMD64HotSpotLoweringProvider extends DefaultHotSpotLoweringProvider
}
}
- ForeignCallNode call = graph.add(new ForeignCallNode(foreignCalls, math.getOperation().foreignCallDescriptor, math.getValue()));
+ ForeignCallNode call = graph.add(new ForeignCallNode(foreignCalls, math.getOperation().foreignCallSignature, math.getValue()));
graph.addAfterFixed(tool.lastFixedNode(), call);
math.replaceAtUsages(call);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotMove.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotMove.java
index 0a8eb54740a..62e82e2006b 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotMove.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotMove.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,19 +24,20 @@
package org.graalvm.compiler.hotspot.amd64;
+import static jdk.vm.ci.code.ValueUtil.asRegister;
+import static jdk.vm.ci.code.ValueUtil.isRegister;
+import static jdk.vm.ci.code.ValueUtil.isStackSlot;
import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.HINT;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
-import static jdk.vm.ci.code.ValueUtil.asRegister;
-import static jdk.vm.ci.code.ValueUtil.isRegister;
-import static jdk.vm.ci.code.ValueUtil.isStackSlot;
import org.graalvm.compiler.asm.amd64.AMD64Address;
-import org.graalvm.compiler.core.common.CompressEncoding;
import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
+import org.graalvm.compiler.core.common.CompressEncoding;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.StandardOp.LoadConstantOp;
import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
@@ -113,18 +114,16 @@ public class AMD64HotSpotMove {
public static final LIRInstructionClass TYPE = LIRInstructionClass.create(BaseMove.class);
@Def({REG, HINT}) protected AllocatableValue result;
- private final GraalHotSpotVMConfig config;
- public BaseMove(AllocatableValue result, GraalHotSpotVMConfig config) {
+ public BaseMove(AllocatableValue result) {
super(TYPE);
this.result = result;
- this.config = config;
}
@Override
public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
masm.movq(asRegister(result), masm.getPlaceholder(-1));
- crb.recordMark(config.MARKID_NARROW_KLASS_BASE_ADDRESS);
+ crb.recordMark(HotSpotMarkId.NARROW_KLASS_BASE_ADDRESS);
}
}
@@ -187,7 +186,7 @@ public class AMD64HotSpotMove {
if (pic || encoding.hasBase()) {
if (pic) {
masm.movq(scratch, masm.getPlaceholder(-1));
- crb.recordMark(config.MARKID_NARROW_KLASS_BASE_ADDRESS);
+ crb.recordMark(HotSpotMarkId.NARROW_KLASS_BASE_ADDRESS);
} else {
assert encoding.getBase() != 0;
masm.movq(scratch, encoding.getBase());
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java
index 107cb372cea..14c949c117e 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,6 @@ import static jdk.vm.ci.amd64.AMD64.rbp;
import static jdk.vm.ci.code.ValueUtil.isStackSlot;
import static org.graalvm.compiler.hotspot.HotSpotBackend.EXCEPTION_HANDLER_IN_CALLER;
-import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.core.amd64.AMD64NodeLIRBuilder;
import org.graalvm.compiler.core.amd64.AMD64NodeMatchRules;
import org.graalvm.compiler.core.common.LIRKind;
@@ -58,6 +57,7 @@ import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.spi.NodeValueMap;
import org.graalvm.compiler.replacements.nodes.ArrayCompareToNode;
import org.graalvm.compiler.replacements.nodes.ArrayEqualsNode;
+import org.graalvm.compiler.replacements.nodes.ArrayRegionEqualsNode;
import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.amd64.AMD64Kind;
@@ -72,9 +72,7 @@ import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.Value;
-import org.graalvm.compiler.replacements.nodes.ArrayRegionEqualsNode;
/**
* LIR generator specialized for AMD64 HotSpot.
@@ -144,7 +142,7 @@ public class AMD64HotSpotNodeLIRBuilder extends AMD64NodeLIRBuilder implements H
assert invokeKind.isDirect();
HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod();
assert resolvedMethod.isConcrete() : "Cannot make direct call to abstract method.";
- append(new AMD64HotSpotDirectStaticCallOp(callTarget.targetMethod(), result, parameters, temps, callState, invokeKind, getGen().config));
+ append(new AMD64HotSpotDirectStaticCallOp(callTarget.targetMethod(), result, parameters, temps, callState, invokeKind));
}
}
@@ -157,7 +155,7 @@ public class AMD64HotSpotNodeLIRBuilder extends AMD64NodeLIRBuilder implements H
AllocatableValue targetAddressDst = AMD64.rax.asValue(targetAddressSrc.getValueKind());
gen.emitMove(metaspaceMethodDst, metaspaceMethodSrc);
gen.emitMove(targetAddressDst, targetAddressSrc);
- append(new AMD64IndirectCallOp(callTarget.targetMethod(), result, parameters, temps, metaspaceMethodDst, targetAddressDst, callState, getGen().config));
+ append(new AMD64IndirectCallOp(callTarget.targetMethod(), result, parameters, temps, metaspaceMethodDst, targetAddressDst, callState));
} else {
super.emitIndirectCall(callTarget, result, parameters, temps, callState);
}
@@ -210,8 +208,7 @@ public class AMD64HotSpotNodeLIRBuilder extends AMD64NodeLIRBuilder implements H
@Override
public ForeignCallLinkage lookupGraalStub(ValueNode valueNode) {
- ResolvedJavaMethod method = valueNode.graph().method();
- if (method == null || method.getAnnotation(Snippet.class) != null) {
+ if (getGen().getResult().getStub() != null) {
// Emit assembly for snippet stubs
return null;
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotSafepointOp.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotSafepointOp.java
index 84ec50d6235..2915dec0122 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotSafepointOp.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotSafepointOp.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,16 +24,17 @@
package org.graalvm.compiler.hotspot.amd64;
-import static org.graalvm.compiler.core.common.NumUtil.isInt;
-import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
-import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
import static jdk.vm.ci.amd64.AMD64.rax;
import static jdk.vm.ci.amd64.AMD64.rip;
+import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
+import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
+import static org.graalvm.compiler.core.common.NumUtil.isInt;
import org.graalvm.compiler.asm.amd64.AMD64Address;
import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
import org.graalvm.compiler.lir.LIRFrameState;
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.Opcode;
@@ -67,7 +68,7 @@ public final class AMD64HotSpotSafepointOp extends AMD64LIRInstruction {
this.state = state;
this.config = config;
this.thread = thread;
- if (config.threadLocalHandshakes || isPollingPageFar(config) || ImmutableCode.getValue(tool.getOptions())) {
+ if (config.useThreadLocalPolling || isPollingPageFar(config) || ImmutableCode.getValue(tool.getOptions())) {
temp = tool.getLIRGeneratorTool().newVariable(LIRKind.value(tool.getLIRGeneratorTool().target().arch.getWordKind()));
} else {
// Don't waste a register if it's unneeded
@@ -81,7 +82,7 @@ public final class AMD64HotSpotSafepointOp extends AMD64LIRInstruction {
}
public static void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler asm, GraalHotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register thread, Register scratch) {
- if (config.threadLocalHandshakes) {
+ if (config.useThreadLocalPolling) {
emitThreadLocalPoll(crb, asm, config, atReturn, state, thread, scratch);
} else {
emitGlobalPoll(crb, asm, config, atReturn, state, scratch);
@@ -111,21 +112,21 @@ public final class AMD64HotSpotSafepointOp extends AMD64LIRInstruction {
asm.movq(scratch, (AMD64Address) crb.recordDataReferenceInCode(pollingPageAddress, alignment));
}
final int pos = asm.position();
- crb.recordMark(atReturn ? config.MARKID_POLL_RETURN_FAR : config.MARKID_POLL_FAR);
+ crb.recordMark(atReturn ? HotSpotMarkId.POLL_RETURN_FAR : HotSpotMarkId.POLL_FAR);
if (state != null) {
crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
}
asm.testl(rax, new AMD64Address(scratch));
} else if (isPollingPageFar(config)) {
asm.movq(scratch, config.safepointPollingAddress);
- crb.recordMark(atReturn ? config.MARKID_POLL_RETURN_FAR : config.MARKID_POLL_FAR);
+ crb.recordMark(atReturn ? HotSpotMarkId.POLL_RETURN_FAR : HotSpotMarkId.POLL_FAR);
final int pos = asm.position();
if (state != null) {
crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
}
asm.testl(rax, new AMD64Address(scratch));
} else {
- crb.recordMark(atReturn ? config.MARKID_POLL_RETURN_NEAR : config.MARKID_POLL_NEAR);
+ crb.recordMark(atReturn ? HotSpotMarkId.POLL_RETURN_NEAR : HotSpotMarkId.POLL_NEAR);
final int pos = asm.position();
if (state != null) {
crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
@@ -142,7 +143,7 @@ public final class AMD64HotSpotSafepointOp extends AMD64LIRInstruction {
assert config.threadPollingPageOffset >= 0;
asm.movptr(scratch, new AMD64Address(thread, config.threadPollingPageOffset));
- crb.recordMark(atReturn ? config.MARKID_POLL_RETURN_FAR : config.MARKID_POLL_FAR);
+ crb.recordMark(atReturn ? HotSpotMarkId.POLL_RETURN_FAR : HotSpotMarkId.POLL_FAR);
final int pos = asm.position();
if (state != null) {
crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java
index 33d22e7f4e2..62d176d0ded 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020, 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
@@ -26,6 +26,7 @@ package org.graalvm.compiler.hotspot.amd64;
import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
import org.graalvm.compiler.lir.LIRFrameState;
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.Opcode;
@@ -56,12 +57,15 @@ final class AMD64HotspotDirectVirtualCallOp extends DirectCallOp {
}
@Override
+ @SuppressWarnings("try")
public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
- // The mark for an invocation that uses an inline cache must be placed at the
- // instruction that loads the Klass from the inline cache.
- crb.recordMark(invokeKind == InvokeKind.Virtual ? config.MARKID_INVOKEVIRTUAL : config.MARKID_INVOKEINTERFACE);
- // This must be emitted exactly like this to ensure it's patchable
- masm.movq(AMD64.rax, config.nonOopBits);
- super.emitCall(crb, masm);
+ try (CompilationResultBuilder.CallContext callContext = crb.openCallContext(invokeKind.isDirect())) {
+ // The mark for an invocation that uses an inline cache must be placed at the
+ // instruction that loads the Klass from the inline cache.
+ crb.recordMark(invokeKind == InvokeKind.Virtual ? HotSpotMarkId.INVOKEVIRTUAL : HotSpotMarkId.INVOKEINTERFACE);
+ // This must be emitted exactly like this to ensure it's patchable
+ masm.movq(AMD64.rax, config.nonOopBits);
+ super.emitCall(crb, masm);
+ }
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64IndirectCallOp.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64IndirectCallOp.java
index 8769121764b..d2512f8b603 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64IndirectCallOp.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64IndirectCallOp.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@ import static jdk.vm.ci.code.ValueUtil.asRegister;
import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
-import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.hotspot.HotSpotMarkId;
import org.graalvm.compiler.lir.LIRFrameState;
import org.graalvm.compiler.lir.LIRInstructionClass;
import org.graalvm.compiler.lir.Opcode;
@@ -58,21 +58,20 @@ final class AMD64IndirectCallOp extends IndirectCallOp {
@Use({REG}) protected Value metaspaceMethod;
- private final GraalHotSpotVMConfig config;
-
- AMD64IndirectCallOp(ResolvedJavaMethod targetMethod, Value result, Value[] parameters, Value[] temps, Value metaspaceMethod, Value targetAddress, LIRFrameState state,
- GraalHotSpotVMConfig config) {
+ AMD64IndirectCallOp(ResolvedJavaMethod targetMethod, Value result, Value[] parameters, Value[] temps, Value metaspaceMethod, Value targetAddress, LIRFrameState state) {
super(TYPE, targetMethod, result, parameters, temps, targetAddress, state);
this.metaspaceMethod = metaspaceMethod;
- this.config = config;
}
@Override
+ @SuppressWarnings("try")
public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
- crb.recordMark(config.MARKID_INLINE_INVOKE);
- Register callReg = asRegister(targetAddress);
- assert !callReg.equals(METHOD);
- AMD64Call.indirectCall(crb, masm, callReg, callTarget, state);
+ try (CompilationResultBuilder.CallContext callContext = crb.openCallContext(false)) {
+ crb.recordMark(HotSpotMarkId.INLINE_INVOKE);
+ Register callReg = asRegister(targetAddress);
+ assert !callReg.equals(METHOD);
+ AMD64Call.indirectCall(crb, masm, callReg, callTarget, state);
+ }
}
@Override
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64X87MathSnippets.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64X87MathSnippets.java
index bb4903aa9f8..caa9a20df88 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64X87MathSnippets.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64X87MathSnippets.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@ import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER
import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
-import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
+import org.graalvm.compiler.core.common.spi.ForeignCallSignature;
import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
@@ -55,7 +55,7 @@ public class AMD64X87MathSnippets implements Snippets {
if (Math.abs(input) < PI_4) {
return AMD64X87MathIntrinsicNode.compute(input, UnaryOperation.SIN);
}
- return callDouble1(UnaryOperation.SIN.foreignCallDescriptor, input);
+ return callDouble1(UnaryOperation.SIN.foreignCallSignature, input);
}
@Snippet
@@ -63,7 +63,7 @@ public class AMD64X87MathSnippets implements Snippets {
if (Math.abs(input) < PI_4) {
return AMD64X87MathIntrinsicNode.compute(input, UnaryOperation.COS);
}
- return callDouble1(UnaryOperation.COS.foreignCallDescriptor, input);
+ return callDouble1(UnaryOperation.COS.foreignCallSignature, input);
}
@Snippet
@@ -71,11 +71,11 @@ public class AMD64X87MathSnippets implements Snippets {
if (Math.abs(input) < PI_4) {
return AMD64X87MathIntrinsicNode.compute(input, UnaryOperation.TAN);
}
- return callDouble1(UnaryOperation.TAN.foreignCallDescriptor, input);
+ return callDouble1(UnaryOperation.TAN.foreignCallSignature, input);
}
@NodeIntrinsic(value = ForeignCallNode.class)
- private static native double callDouble1(@ConstantNodeParameter ForeignCallDescriptor descriptor, double value);
+ private static native double callDouble1(@ConstantNodeParameter ForeignCallSignature signature, double value);
public static class Templates extends AbstractTemplates {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/MathDoubleFMATest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/MathDoubleFMATest.java
index f956883a7f9..1e9ea691da3 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/MathDoubleFMATest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/MathDoubleFMATest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
package org.graalvm.compiler.hotspot.jdk9.test;
+import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import java.util.ArrayList;
@@ -41,14 +42,12 @@ import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
-import jdk.vm.ci.amd64.AMD64;
-
@RunWith(Parameterized.class)
public final class MathDoubleFMATest extends GraalCompilerTest {
@Before
- public void checkAMD64() {
- assumeTrue("skipping AMD64 specific test", getTarget().arch instanceof AMD64);
+ public void checkNotSPARC() {
+ assumeFalse("skipping tests on SPARC", isSPARC(getTarget().arch));
HotSpotGraalRuntimeProvider rt = (HotSpotGraalRuntimeProvider) Graal.getRequiredCapability(RuntimeProvider.class);
assumeTrue("skipping FMA specific test", rt.getVMConfig().useFMAIntrinsics);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/MathFMAConstantInputTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/MathFMAConstantInputTest.java
index 45aba029bd3..de885952ba8 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/MathFMAConstantInputTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/MathFMAConstantInputTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,19 +24,17 @@
package org.graalvm.compiler.hotspot.jdk9.test;
-import static org.junit.Assume.assumeTrue;
+import static org.junit.Assume.assumeFalse;
import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.junit.Before;
import org.junit.Test;
-import jdk.vm.ci.amd64.AMD64;
-
public final class MathFMAConstantInputTest extends GraalCompilerTest {
@Before
- public void checkAMD64() {
- assumeTrue("skipping AMD64 specific test", getTarget().arch instanceof AMD64);
+ public void checkNotSPARC() {
+ assumeFalse("skipping test on SPARC ", isSPARC(getTarget().arch));
}
public static float floatFMA() {
@@ -48,6 +46,16 @@ public final class MathFMAConstantInputTest extends GraalCompilerTest {
test("floatFMA");
}
+ public static float floatFMAWithPi() {
+ float[] input = {Float.MAX_VALUE, 2.0F, -Float.MAX_VALUE};
+ return Math.fma(input[0], input[1], input[2]);
+ }
+
+ @Test
+ public void testFloatFMAWithPi() {
+ test("floatFMAWithPi");
+ }
+
public static double doubleFMA() {
return Math.fma(2.0d, 2.0d, 2.0d);
}
@@ -57,4 +65,14 @@ public final class MathFMAConstantInputTest extends GraalCompilerTest {
test("doubleFMA");
}
+ public static double doubleFMAWithPi() {
+ double[] input = {Double.MAX_VALUE, 2.0D, -Double.MAX_VALUE};
+ return Math.fma(input[0], input[1], input[2]);
+ }
+
+ @Test
+ public void testDoubleFMAWithPi() {
+ test("doubleFMAWithPi");
+ }
+
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/MathFloatFMATest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/MathFloatFMATest.java
index 597bff5d933..e4990aca5b3 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/MathFloatFMATest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/MathFloatFMATest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
package org.graalvm.compiler.hotspot.jdk9.test;
+import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import java.util.ArrayList;
@@ -41,14 +42,12 @@ import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
-import jdk.vm.ci.amd64.AMD64;
-
@RunWith(Parameterized.class)
public final class MathFloatFMATest extends GraalCompilerTest {
@Before
- public void checkAMD64() {
- assumeTrue("skipping AMD64 specific test", getTarget().arch instanceof AMD64);
+ public void checkNotSPARC() {
+ assumeFalse("skipping test on SPARC", isSPARC(getTarget().arch));
HotSpotGraalRuntimeProvider rt = (HotSpotGraalRuntimeProvider) Graal.getRequiredCapability(RuntimeProvider.class);
assumeTrue("skipping FMA specific tests", rt.getVMConfig().useFMAIntrinsics);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/StringUTF16ToBytesGetCharsTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/StringUTF16ToBytesGetCharsTest.java
index 1be0dd9eed0..ec75f2a83e4 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/StringUTF16ToBytesGetCharsTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/StringUTF16ToBytesGetCharsTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, 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
@@ -29,6 +29,7 @@ import static org.junit.Assume.assumeFalse;
import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.hotspot.replacements.StringUTF16Substitutions;
import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.nodes.java.NewArrayNode;
import org.graalvm.compiler.replacements.arraycopy.ArrayCopyCallNode;
import org.graalvm.compiler.replacements.test.MethodSubstitutionTest;
@@ -58,7 +59,7 @@ public final class StringUTF16ToBytesGetCharsTest extends MethodSubstitutionTest
Class> javaclass = Class.forName("java.lang.StringUTF16");
ResolvedJavaMethod caller = getResolvedJavaMethod(javaclass, "toBytes", char[].class, int.class, int.class);
- StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext(), null);
+ StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext(), AllowAssumptions.YES, null);
assertInGraph(graph, NewArrayNode.class);
assertInGraph(graph, ArrayCopyCallNode.class);
@@ -89,7 +90,7 @@ public final class StringUTF16ToBytesGetCharsTest extends MethodSubstitutionTest
Class> javaclass = Class.forName("java.lang.StringUTF16");
ResolvedJavaMethod caller = getResolvedJavaMethod(javaclass, "getChars", byte[].class, int.class, int.class, char[].class, int.class);
- StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext(), null);
+ StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext(), AllowAssumptions.YES, null);
assertInGraph(graph, ArrayCopyCallNode.class);
InstalledCode code = getCode(caller, graph);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/AheadOfTimeCompilationTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/AheadOfTimeCompilationTest.java
index 8afc68f1b62..6dcf0b7035d 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/AheadOfTimeCompilationTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/AheadOfTimeCompilationTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -67,7 +67,7 @@ public class AheadOfTimeCompilationTest extends HotSpotGraalCompilerTest {
@Before
public void setUp() {
- // Ignore on AArch64
+ // Ignore on SPARC
Assume.assumeFalse("skipping on AArch64", getTarget().arch instanceof AArch64);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ArrayCopyIntrinsificationTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ArrayCopyIntrinsificationTest.java
index fa44400f3f0..84e0c85d6c2 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ArrayCopyIntrinsificationTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ArrayCopyIntrinsificationTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2020, 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
@@ -216,11 +216,71 @@ public class ArrayCopyIntrinsificationTest extends GraalCompilerTest {
return dst;
}
+ public static Object genericArraycopyCatchNullException(Object src, int srcPos, Object dst, int dstPos, int length) {
+ boolean caught = false;
+ try {
+ System.arraycopy(src, srcPos, dst, dstPos, length);
+ } catch (NullPointerException e) {
+ caught = true;
+ }
+ return caught;
+ }
+
+ public static Object genericArraycopyCatchArrayStoreException(Object src, int srcPos, Object dst, int dstPos, int length) {
+ boolean caught = false;
+ try {
+ System.arraycopy(src, srcPos, dst, dstPos, length);
+ } catch (ArrayStoreException e) {
+ caught = true;
+ }
+ return caught;
+ }
+
+ public static Object genericArraycopyCatchArrayIndexException(Object src, int srcPos, Object dst, int dstPos, int length) {
+ boolean caught = false;
+ try {
+ System.arraycopy(src, srcPos, dst, dstPos, length);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ caught = true;
+ }
+ return caught;
+ }
+
public static Object[] objectArraycopy(Object[] src, int srcPos, Object[] dst, int dstPos, int length) {
System.arraycopy(src, srcPos, dst, dstPos, length);
return dst;
}
+ public static Object objectArraycopyCatchNullException(Object[] src, int srcPos, Object[] dst, int dstPos, int length) {
+ boolean caught = false;
+ try {
+ System.arraycopy(src, srcPos, dst, dstPos, length);
+ } catch (NullPointerException e) {
+ caught = true;
+ }
+ return caught;
+ }
+
+ public static Object objectArraycopyCatchArrayStoreException(Object[] src, int srcPos, Object[] dst, int dstPos, int length) {
+ boolean caught = false;
+ try {
+ System.arraycopy(src, srcPos, dst, dstPos, length);
+ } catch (ArrayStoreException e) {
+ caught = true;
+ }
+ return caught;
+ }
+
+ public static Object objectArraycopyCatchArrayIndexException(Object[] src, int srcPos, Object[] dst, int dstPos, int length) {
+ boolean caught = false;
+ try {
+ System.arraycopy(src, srcPos, dst, dstPos, length);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ caught = true;
+ }
+ return caught;
+ }
+
public static Object[] objectArraycopyExact(Integer[] src, int srcPos, Integer[] dst, int dstPos, int length) {
System.arraycopy(src, srcPos, dst, dstPos, length);
return dst;
@@ -284,4 +344,30 @@ public class ArrayCopyIntrinsificationTest extends GraalCompilerTest {
}
return copy;
}
+
+ @Test
+ public void testGenericExceptions() {
+ test("genericArraycopyCatchNullException", null, 4, new byte[128], 2, 3);
+ test("genericArraycopyCatchNullException", new byte[128], 4, null, 2, 3);
+ Object[] integerDest = new Integer[128];
+ Object[] longSource = new Object[128];
+ for (int i = 0; i < longSource.length; i++) {
+ longSource[i] = Long.valueOf(i);
+ }
+ test("genericArraycopyCatchArrayStoreException", longSource, 4, integerDest, 2, 3);
+ test("genericArraycopyCatchArrayIndexException", new int[128], 0, new int[128], Integer.MAX_VALUE, 1);
+ }
+
+ @Test
+ public void testObjectArrayExceptions() {
+ test("objectArraycopyCatchNullException", null, 4, new Byte[128], 2, 3);
+ test("objectArraycopyCatchNullException", new Byte[128], 4, null, 2, 3);
+ Object[] integerDest = new Integer[128];
+ Object[] longSource = new Object[128];
+ for (int i = 0; i < longSource.length; i++) {
+ longSource[i] = Long.valueOf(i);
+ }
+ test("objectArraycopyCatchArrayStoreException", longSource, 4, integerDest, 2, 3);
+ test("objectArraycopyCatchArrayIndexException", new Integer[128], 0, new Integer[128], Integer.MAX_VALUE, 1);
+ }
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java
index 723f4032af8..d54fd5ce41d 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java
@@ -277,8 +277,6 @@ public class CheckGraalIntrinsics extends GraalTest {
"jdk/jfr/internal/JVM.getClassId(Ljava/lang/Class;)J");
add(toBeInvestigated,
- // Just check if the argument is a compile time constant
- "java/lang/invoke/MethodHandleImpl.isCompileConstant(Ljava/lang/Object;)Z",
// Only used as a marker for vectorization?
"java/util/stream/Streams$RangeIntSpliterator.forEachRemaining(Ljava/util/function/IntConsumer;)V",
// Only implemented on non-AMD64 platforms (some logic and runtime call)
@@ -372,6 +370,10 @@ public class CheckGraalIntrinsics extends GraalTest {
add(ignore,
"java/lang/Math.fma(DDD)D",
"java/lang/Math.fma(FFF)F");
+ } else if (isSPARC(arch)) {
+ add(toBeInvestigated,
+ "java/lang/Math.fma(DDD)D",
+ "java/lang/Math.fma(FFF)F");
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java
index 77e1fd907d2..66bccbb8fc5 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java
@@ -67,6 +67,7 @@ import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
@@ -78,8 +79,8 @@ import java.util.regex.Pattern;
import jdk.internal.vm.compiler.collections.EconomicMap;
import jdk.internal.vm.compiler.collections.UnmodifiableMapCursor;
import org.graalvm.compiler.api.replacements.Snippet;
+import org.graalvm.compiler.api.test.ModuleSupport;
import org.graalvm.compiler.bytecode.Bytecodes;
-import org.graalvm.compiler.core.CompilerThreadFactory;
import org.graalvm.compiler.core.phases.HighTier;
import org.graalvm.compiler.core.test.ReflectionOptionDescriptors;
import org.graalvm.compiler.debug.GlobalMetrics;
@@ -99,7 +100,6 @@ import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.options.OptionsParser;
import org.graalvm.compiler.serviceprovider.GraalUnsafeAccess;
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
-import org.graalvm.compiler.api.test.ModuleSupport;
import jdk.internal.vm.compiler.libgraal.LibGraal;
import jdk.internal.vm.compiler.libgraal.LibGraalScope;
import org.graalvm.util.OptionsEncoder;
@@ -232,7 +232,7 @@ public final class CompileTheWorld {
static class LibGraalParams implements AutoCloseable {
static {
- LibGraal.registerNativeMethods(HotSpotJVMCIRuntime.runtime(), CompileTheWorld.class);
+ LibGraal.registerNativeMethods(CompileTheWorld.class);
}
/**
@@ -667,6 +667,40 @@ public final class CompileTheWorld {
}
}
+ static final class CTWThread extends Thread {
+ private final LibGraalParams libgraal;
+
+ CTWThread(Runnable r, LibGraalParams libgraal) {
+ super(r);
+ this.libgraal = libgraal;
+ setName("CTWThread-" + getId());
+ setPriority(Thread.MAX_PRIORITY);
+ setDaemon(true);
+ }
+
+ @SuppressWarnings("try")
+ @Override
+ public void run() {
+ setContextClassLoader(getClass().getClassLoader());
+ try (LibGraalScope scope = libgraal == null ? null : new LibGraalScope()) {
+ super.run();
+ }
+ }
+ }
+
+ static final class CTWThreadFactory implements ThreadFactory {
+ private final LibGraalParams libgraal;
+
+ CTWThreadFactory(LibGraalParams libgraal) {
+ this.libgraal = libgraal;
+ }
+
+ @Override
+ public Thread newThread(Runnable r) {
+ return new CTWThread(r, libgraal);
+ }
+ }
+
/**
* Compiles all methods in all classes in a given class path.
*
@@ -709,7 +743,7 @@ public final class CompileTheWorld {
running = true;
}
- threadPool = new ThreadPoolExecutor(threadCount, threadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), new CompilerThreadFactory("CompileTheWorld"));
+ threadPool = new ThreadPoolExecutor(threadCount, threadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), new CTWThreadFactory(libgraal));
int compileStartAt = startAt;
int compileStopAt = stopAt;
@@ -972,33 +1006,30 @@ public final class CompileTheWorld {
boolean installAsDefault = false;
HotSpotInstalledCode installedCode;
if (libgraal != null) {
- HotSpotJVMCIRuntime runtime = HotSpotJVMCIRuntime.runtime();
- try (LibGraalScope scope = new LibGraalScope(runtime)) {
- long methodHandle = LibGraal.translate(runtime, method);
- long isolateThread = LibGraalScope.getIsolateThread();
+ long methodHandle = LibGraal.translate(method);
+ long isolateThread = LibGraalScope.getIsolateThread();
- StackTraceBuffer stackTraceBuffer = libgraal.getStackTraceBuffer();
+ StackTraceBuffer stackTraceBuffer = libgraal.getStackTraceBuffer();
- long stackTraceBufferAddress = stackTraceBuffer.getAddress();
- long installedCodeHandle = compileMethodInLibgraal(isolateThread,
- methodHandle,
- useProfilingInfo,
- installAsDefault,
- libgraal.options.getAddress(),
- libgraal.options.size,
- libgraal.options.hash,
- stackTraceBufferAddress,
- stackTraceBuffer.size);
+ long stackTraceBufferAddress = stackTraceBuffer.getAddress();
+ long installedCodeHandle = compileMethodInLibgraal(isolateThread,
+ methodHandle,
+ useProfilingInfo,
+ installAsDefault,
+ libgraal.options.getAddress(),
+ libgraal.options.size,
+ libgraal.options.hash,
+ stackTraceBufferAddress,
+ stackTraceBuffer.size);
- installedCode = LibGraal.unhand(runtime, HotSpotInstalledCode.class, installedCodeHandle);
- if (installedCode == null) {
- int length = UNSAFE.getInt(stackTraceBufferAddress);
- byte[] data = new byte[length];
- UNSAFE.copyMemory(null, stackTraceBufferAddress + Integer.BYTES, data, ARRAY_BYTE_BASE_OFFSET, length);
- String stackTrace = new String(data).trim();
- println(true, String.format("CompileTheWorld (%d) : Error compiling method: %s", counter, method.format("%H.%n(%p):%r")));
- println(true, stackTrace);
- }
+ installedCode = LibGraal.unhand(HotSpotInstalledCode.class, installedCodeHandle);
+ if (installedCode == null) {
+ int length = UNSAFE.getInt(stackTraceBufferAddress);
+ byte[] data = new byte[length];
+ UNSAFE.copyMemory(null, stackTraceBufferAddress + Integer.BYTES, data, ARRAY_BYTE_BASE_OFFSET, length);
+ String stackTrace = new String(data).trim();
+ println(true, String.format("CompileTheWorld (%d) : Error compiling method: %s", counter, method.format("%H.%n(%p):%r")));
+ println(true, stackTrace);
}
} else {
int entryBCI = JVMCICompiler.INVOCATION_ENTRY_BCI;
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ForeignCallDeoptimizeTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ForeignCallDeoptimizeTest.java
index c914125cc50..0a50e0f61b8 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ForeignCallDeoptimizeTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ForeignCallDeoptimizeTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,17 +24,14 @@
package org.graalvm.compiler.hotspot.test;
-import org.junit.Test;
-
-import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl;
-import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.extended.ForeignCallNode;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
+import org.junit.Test;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.ResolvedJavaMethod;
@@ -46,12 +43,11 @@ public class ForeignCallDeoptimizeTest extends GraalCompilerTest {
@Override
protected void registerInvocationPlugins(InvocationPlugins invocationPlugins) {
- ForeignCallsProvider foreignCalls = ((HotSpotProviders) getProviders()).getForeignCalls();
invocationPlugins.register(new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
- ForeignCallNode node = new ForeignCallNode(foreignCalls, HotSpotForeignCallsProviderImpl.TEST_DEOPTIMIZE_CALL_INT, arg);
+ ForeignCallNode node = new ForeignCallNode(HotSpotForeignCallsProviderImpl.TEST_DEOPTIMIZE_CALL_INT, arg);
b.addPush(JavaKind.Int, node);
return true;
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRTestBase.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRTestBase.java
index 5c3f229f5c1..85223b28a62 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRTestBase.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/GraalOSRTestBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2020, 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
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotCryptoSubstitutionTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotCryptoSubstitutionTest.java
index e610a14e683..a7a1c1248db 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotCryptoSubstitutionTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotCryptoSubstitutionTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,122 +24,103 @@
package org.graalvm.compiler.hotspot.test;
-import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.AlgorithmParameters;
-import java.security.SecureRandom;
+import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
-import org.graalvm.compiler.code.CompilationResult;
-import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins;
import org.junit.Assert;
+import org.junit.Assume;
import org.junit.Test;
import jdk.vm.ci.code.InstalledCode;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
* Tests the intrinsification of certain crypto methods.
*/
public class HotSpotCryptoSubstitutionTest extends HotSpotGraalCompilerTest {
- @Override
- protected InstalledCode addMethod(DebugContext debug, ResolvedJavaMethod method, CompilationResult compResult) {
- return getBackend().createDefaultInstalledCode(debug, method, compResult);
- }
-
- SecretKey aesKey;
- SecretKey desKey;
- byte[] input;
- ByteArrayOutputStream aesExpected = new ByteArrayOutputStream();
- ByteArrayOutputStream desExpected = new ByteArrayOutputStream();
+ private final byte[] input;
public HotSpotCryptoSubstitutionTest() throws Exception {
- byte[] seed = {0x4, 0x7, 0x1, 0x1};
- SecureRandom random = new SecureRandom(seed);
- KeyGenerator aesKeyGen = KeyGenerator.getInstance("AES");
- KeyGenerator desKeyGen = KeyGenerator.getInstance("DESede");
- aesKeyGen.init(128, random);
- desKeyGen.init(168, random);
- aesKey = aesKeyGen.generateKey();
- desKey = desKeyGen.generateKey();
input = readClassfile16(getClass());
-
- aesExpected.write(runEncryptDecrypt(aesKey, "AES/CBC/NoPadding"));
- aesExpected.write(runEncryptDecrypt(aesKey, "AES/CBC/PKCS5Padding"));
-
- desExpected.write(runEncryptDecrypt(desKey, "DESede/CBC/NoPadding"));
- desExpected.write(runEncryptDecrypt(desKey, "DESede/CBC/PKCS5Padding"));
}
- @Test
- public void testAESCryptIntrinsics() throws Exception {
- String aesEncryptName = HotSpotGraphBuilderPlugins.lookupIntrinsicName(runtime().getVMConfig(), "com/sun/crypto/provider/AESCrypt", "implEncryptBlock", "encryptBlock");
- String aesDecryptName = HotSpotGraphBuilderPlugins.lookupIntrinsicName(runtime().getVMConfig(), "com/sun/crypto/provider/AESCrypt", "implDecryptBlock", "decryptBlock");
- if (compileAndInstall("com.sun.crypto.provider.AESCrypt", aesEncryptName, aesDecryptName)) {
- ByteArrayOutputStream actual = new ByteArrayOutputStream();
- actual.write(runEncryptDecrypt(aesKey, "AES/CBC/NoPadding"));
- actual.write(runEncryptDecrypt(aesKey, "AES/CBC/PKCS5Padding"));
- Assert.assertArrayEquals(aesExpected.toByteArray(), actual.toByteArray());
- }
- }
-
- @Test
- public void testCipherBlockChainingIntrinsics() throws Exception {
- String cbcEncryptName = HotSpotGraphBuilderPlugins.lookupIntrinsicName(runtime().getVMConfig(), "com/sun/crypto/provider/CipherBlockChaining", "implEncrypt", "encrypt");
- String cbcDecryptName = HotSpotGraphBuilderPlugins.lookupIntrinsicName(runtime().getVMConfig(), "com/sun/crypto/provider/CipherBlockChaining", "implDecrypt", "decrypt");
- if (compileAndInstall("com.sun.crypto.provider.CipherBlockChaining", cbcEncryptName, cbcDecryptName)) {
- ByteArrayOutputStream actual = new ByteArrayOutputStream();
- actual.write(runEncryptDecrypt(aesKey, "AES/CBC/NoPadding"));
- actual.write(runEncryptDecrypt(aesKey, "AES/CBC/PKCS5Padding"));
- Assert.assertArrayEquals(aesExpected.toByteArray(), actual.toByteArray());
-
- actual.reset();
- actual.write(runEncryptDecrypt(desKey, "DESede/CBC/NoPadding"));
- actual.write(runEncryptDecrypt(desKey, "DESede/CBC/PKCS5Padding"));
- Assert.assertArrayEquals(desExpected.toByteArray(), actual.toByteArray());
- }
- }
-
- /**
- * Compiles and installs the substitution for some specified methods. Once installed, the next
- * execution of the methods will use the newly installed code.
- *
- * @param className the name of the class for which substitutions are available
- * @param methodNames the names of the substituted methods
- * @return true if at least one substitution was compiled and installed
- */
- private boolean compileAndInstall(String className, String... methodNames) {
- if (!runtime().getVMConfig().useAESIntrinsics) {
- return false;
- }
- Class> c;
+ private void testEncryptDecrypt(String className, String methodName, String generatorAlgorithm, int keySize, String algorithm) throws Exception {
+ Class> klass = null;
try {
- c = Class.forName(className);
+ klass = Class.forName(className);
} catch (ClassNotFoundException e) {
// It's ok to not find the class - a different security provider
// may have been installed
- return false;
+ return;
}
- boolean atLeastOneCompiled = false;
- for (String methodName : methodNames) {
- if (compileAndInstallSubstitution(c, methodName) != null) {
- atLeastOneCompiled = true;
- }
+ KeyGenerator gen = KeyGenerator.getInstance(generatorAlgorithm);
+ gen.init(keySize);
+ SecretKey key = gen.generateKey();
+ Result expected = runEncryptDecrypt(key, algorithm);
+ InstalledCode intrinsic = compileAndInstallSubstitution(klass, methodName);
+ if (intrinsic != null) {
+ Result actual = runEncryptDecrypt(key, algorithm);
+ assertEquals(expected, actual);
+ intrinsic.invalidate();
}
- return atLeastOneCompiled;
+ }
+
+ @Test
+ public void testAESencryptBlock() throws Exception {
+ Assume.assumeTrue(runtime().getVMConfig().useAESIntrinsics);
+ String aesEncryptName = HotSpotGraphBuilderPlugins.lookupIntrinsicName(runtime().getVMConfig(), "com/sun/crypto/provider/AESCrypt", "implEncryptBlock", "encryptBlock");
+ testEncryptDecrypt("com.sun.crypto.provider.AESCrypt", aesEncryptName, "AES", 128, "AES/CBC/NoPadding");
+ testEncryptDecrypt("com.sun.crypto.provider.AESCrypt", aesEncryptName, "AES", 128, "AES/CBC/PKCS5Padding");
+ }
+
+ @Test
+ public void testAESDecryptBlock() throws Exception {
+ Assume.assumeTrue(runtime().getVMConfig().useAESIntrinsics);
+ String aesDecryptName = HotSpotGraphBuilderPlugins.lookupIntrinsicName(runtime().getVMConfig(), "com/sun/crypto/provider/AESCrypt", "implDecryptBlock", "decryptBlock");
+ testEncryptDecrypt("com.sun.crypto.provider.AESCrypt", aesDecryptName, "AES", 128, "AES/CBC/NoPadding");
+ testEncryptDecrypt("com.sun.crypto.provider.AESCrypt", aesDecryptName, "AES", 128, "AES/CBC/PKCS5Padding");
+ }
+
+ @Test
+ public void testCipherBlockChainingEncrypt() throws Exception {
+ Assume.assumeTrue(runtime().getVMConfig().useAESIntrinsics);
+ String cbcEncryptName = HotSpotGraphBuilderPlugins.lookupIntrinsicName(runtime().getVMConfig(), "com/sun/crypto/provider/CipherBlockChaining", "implEncrypt", "encrypt");
+ testEncryptDecrypt("com.sun.crypto.provider.CipherBlockChaining", cbcEncryptName, "AES", 128, "AES/CBC/NoPadding");
+ testEncryptDecrypt("com.sun.crypto.provider.CipherBlockChaining", cbcEncryptName, "AES", 128, "AES/CBC/PKCS5Padding");
+ testEncryptDecrypt("com.sun.crypto.provider.CipherBlockChaining", cbcEncryptName, "DESede", 168, "DESede/CBC/NoPadding");
+ testEncryptDecrypt("com.sun.crypto.provider.CipherBlockChaining", cbcEncryptName, "DESede", 168, "DESede/CBC/PKCS5Padding");
+ }
+
+ @Test
+ public void testCipherBlockChainingDecrypt() throws Exception {
+ Assume.assumeTrue(runtime().getVMConfig().useAESIntrinsics);
+ String cbcDecryptName = HotSpotGraphBuilderPlugins.lookupIntrinsicName(runtime().getVMConfig(), "com/sun/crypto/provider/CipherBlockChaining", "implDecrypt", "decrypt");
+ testEncryptDecrypt("com.sun.crypto.provider.CipherBlockChaining", cbcDecryptName, "AES", 128, "AES/CBC/NoPadding");
+ testEncryptDecrypt("com.sun.crypto.provider.CipherBlockChaining", cbcDecryptName, "AES", 128, "AES/CBC/PKCS5Padding");
+ testEncryptDecrypt("com.sun.crypto.provider.CipherBlockChaining", cbcDecryptName, "DESede", 168, "DESede/CBC/NoPadding");
+ testEncryptDecrypt("com.sun.crypto.provider.CipherBlockChaining", cbcDecryptName, "DESede", 168, "DESede/CBC/PKCS5Padding");
+ }
+
+ @Test
+ public void testCounterModeEncrypt() throws Exception {
+ Assume.assumeTrue(runtime().getVMConfig().useAESCTRIntrinsics);
+ testEncryptDecrypt("com.sun.crypto.provider.CounterMode", "implCrypt", "AES", 128, "AES/CTR/NoPadding");
+ testEncryptDecrypt("com.sun.crypto.provider.CounterMode", "implCrypt", "AES", 128, "AES/CTR/PKCS5Padding");
+ testEncryptDecrypt("com.sun.crypto.provider.CounterMode", "implCrypt", "DESede", 168, "DESede/CTR/NoPadding");
+ testEncryptDecrypt("com.sun.crypto.provider.CounterMode", "implCrypt", "DESede", 168, "DESede/CTR/PKCS5Padding");
}
AlgorithmParameters algorithmParameters;
private byte[] encrypt(byte[] indata, SecretKey key, String algorithm) throws Exception {
-
byte[] result = indata;
Cipher c = Cipher.getInstance(algorithm);
@@ -157,7 +138,6 @@ public class HotSpotCryptoSubstitutionTest extends HotSpotGraalCompilerTest {
}
private byte[] decrypt(byte[] indata, SecretKey key, String algorithm) throws Exception {
-
byte[] result = indata;
Cipher c = Cipher.getInstance(algorithm);
@@ -182,11 +162,15 @@ public class HotSpotCryptoSubstitutionTest extends HotSpotGraalCompilerTest {
return classFile;
}
- public byte[] runEncryptDecrypt(SecretKey key, String algorithm) throws Exception {
- byte[] indata = input.clone();
- byte[] cipher = encrypt(indata, key, algorithm);
- byte[] plain = decrypt(cipher, key, algorithm);
- Assert.assertArrayEquals(indata, plain);
- return plain;
+ public Result runEncryptDecrypt(SecretKey key, String algorithm) throws Exception {
+ try {
+ byte[] indata = input.clone();
+ byte[] cipher = encrypt(indata, key, algorithm);
+ byte[] plain = decrypt(cipher, key, algorithm);
+ Assert.assertArrayEquals(indata, plain);
+ return new Result(plain, null);
+ } catch (NoSuchAlgorithmException e) {
+ return new Result(null, e);
+ }
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalCompilerTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalCompilerTest.java
index 5c7b1f5ca3c..a67e2dc2fc3 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalCompilerTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalCompilerTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, 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
@@ -31,6 +31,7 @@ import org.graalvm.compiler.hotspot.HotSpotBackend;
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.runtime.RuntimeProvider;
import org.junit.Assume;
@@ -73,7 +74,7 @@ public abstract class HotSpotGraalCompilerTest extends GraalCompilerTest {
HotSpotProviders providers = rt.getHostBackend().getProviders();
CompilationIdentifier compilationId = runtime().getHostBackend().getCompilationIdentifier(method);
OptionValues options = getInitialOptions();
- StructuredGraph graph = providers.getReplacements().getIntrinsicGraph(method, compilationId, getDebugContext(options), null);
+ StructuredGraph graph = providers.getReplacements().getIntrinsicGraph(method, compilationId, getDebugContext(options), AllowAssumptions.YES, null);
if (graph != null) {
return getCode(method, graph, true, true, graph.getOptions());
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotResolvedJavaFieldTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotResolvedJavaFieldTest.java
index 6e92711ca13..07ebda88604 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotResolvedJavaFieldTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotResolvedJavaFieldTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, 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
@@ -42,6 +42,7 @@ import org.junit.Assert;
import org.junit.Test;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaField;
+import jdk.vm.ci.hotspot.HotSpotVMConfigAccess;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaType;
@@ -80,8 +81,9 @@ public class HotSpotResolvedJavaFieldTest extends HotSpotGraalCompilerTest {
*/
private int jvmFieldModifiers() {
GraalHotSpotVMConfig config = runtime().getVMConfig();
- int accEnum = config.getConstant("JVM_ACC_ENUM", Integer.class, 0x4000);
- int accSynthetic = config.getConstant("JVM_ACC_SYNTHETIC", Integer.class, 0x1000);
+ HotSpotVMConfigAccess access = new HotSpotVMConfigAccess(config.getStore());
+ int accEnum = access.getConstant("JVM_ACC_ENUM", Integer.class, 0x4000);
+ int accSynthetic = access.getConstant("JVM_ACC_SYNTHETIC", Integer.class, 0x1000);
return PUBLIC | PRIVATE | PROTECTED | STATIC | FINAL | VOLATILE | TRANSIENT | accEnum | accSynthetic;
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/JVMCIInfopointErrorTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/JVMCIInfopointErrorTest.java
index e74d064eef9..70f13685ecd 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/JVMCIInfopointErrorTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/JVMCIInfopointErrorTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, 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
@@ -37,8 +37,8 @@ import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugContext.Builder;
import org.graalvm.compiler.debug.DebugContext.Scope;
-import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.hotspot.HotSpotCompiledCodeBuilder;
import org.graalvm.compiler.lir.FullInfopointOp;
@@ -282,7 +282,7 @@ public class JVMCIInfopointErrorTest extends GraalCompilerTest {
@SuppressWarnings("try")
@Test(expected = Error.class)
public void testUnknownJavaValue() {
- DebugContext debug = DebugContext.create(getInitialOptions(), DebugHandlersFactory.LOADER);
+ DebugContext debug = new Builder(getInitialOptions()).build();
try (Scope s = debug.disable()) {
/*
* Expected: either AssertionError or GraalError, depending on whether the unit test run
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/LambdaStableNameTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/LambdaStableNameTest.java
index daee8c99314..008b19ddac7 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/LambdaStableNameTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/LambdaStableNameTest.java
@@ -31,6 +31,7 @@ import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.runtime.JVMCI;
import org.graalvm.compiler.api.runtime.GraalJVMCICompiler;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugContext.Builder;
import org.graalvm.compiler.hotspot.meta.HotSpotJITClassInitializationPlugin;
import org.graalvm.compiler.java.LambdaUtils;
import org.graalvm.compiler.options.OptionValues;
@@ -45,7 +46,7 @@ import org.junit.Test;
public class LambdaStableNameTest {
private String findStableLambdaName(ResolvedJavaType type) {
OptionValues options = new OptionValues(OptionValues.newOptionMap());
- DebugContext debug = DebugContext.create(options, Collections.emptyList());
+ DebugContext debug = new Builder(options, Collections.emptyList()).build();
GraalJVMCICompiler compiler = (GraalJVMCICompiler) JVMCI.getRuntime().getCompiler();
Providers providers = compiler.getGraalRuntime().getCapability(RuntimeProvider.class).getHostBackend().getProviders();
final HotSpotJITClassInitializationPlugin initializationPlugin = new HotSpotJITClassInitializationPlugin();
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/MethodSubstitutionEffectTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/MethodSubstitutionEffectTest.java
index b8187c8125e..1efe0e86507 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/MethodSubstitutionEffectTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/MethodSubstitutionEffectTest.java
@@ -391,14 +391,14 @@ public class MethodSubstitutionEffectTest extends GraalCompilerTest {
intrinisicsErrors.add(getResolvedJavaMethod(Substitutee.class, "multiSplitEffectNoMergeInvalid"));
for (ResolvedJavaMethod method : intrinisicsWithoutErrors) {
- StructuredGraph graph = getProviders().getReplacements().getIntrinsicGraph(method, INVALID_COMPILATION_ID, getDebugContext(method), null);
+ StructuredGraph graph = getProviders().getReplacements().getIntrinsicGraph(method, INVALID_COMPILATION_ID, getDebugContext(method), AllowAssumptions.YES, null);
getCode(method, graph);
}
for (ResolvedJavaMethod method : intrinisicsErrors) {
try (AutoCloseable c = new TTY.Filter();
DebugContext debug = getDebugContext(method);
DebugCloseable s = debug.disableIntercept()) {
- StructuredGraph graph = getProviders().getReplacements().getIntrinsicGraph(method, INVALID_COMPILATION_ID, debug, null);
+ StructuredGraph graph = getProviders().getReplacements().getIntrinsicGraph(method, INVALID_COMPILATION_ID, debug, AllowAssumptions.YES, null);
getCode(method, graph);
Assert.fail("Compilation should not reach this point, must throw an exception before");
} catch (Throwable t) {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/MethodSubstitutionForeignCallTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/MethodSubstitutionForeignCallTest.java
index 4b61a521ee3..f39719cd645 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/MethodSubstitutionForeignCallTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/MethodSubstitutionForeignCallTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2020, 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
@@ -30,10 +30,7 @@ import org.graalvm.compiler.api.directives.GraalDirectives;
import org.graalvm.compiler.api.replacements.ClassSubstitution;
import org.graalvm.compiler.api.replacements.MethodSubstitution;
import org.graalvm.compiler.api.test.Graal;
-import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
-import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
-import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.debug.TTY;
@@ -60,7 +57,9 @@ import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaMethod;
public class MethodSubstitutionForeignCallTest extends GraalCompilerTest {
- public static final ForeignCallDescriptor TEST_CALL = new ForeignCallDescriptor("test", int.class, int.class);
+ public static final ForeignCallDescriptor TEST_CALL_DEOPT = new ForeignCallDescriptor("test", int.class, new Class>[]{int.class}, false, new LocationIdentity[0], true, true);
+ public static final ForeignCallDescriptor TEST_CALL_REEXECUTABLE = new ForeignCallDescriptor("test", int.class, new Class>[]{int.class}, true, new LocationIdentity[0], false, false);
+ public static final ForeignCallDescriptor TEST_CALL_NON_DEOPT = new ForeignCallDescriptor("test", int.class, new Class>[]{int.class}, false, new LocationIdentity[0], false, false);
public static class A {
static void invalidConsecutiveForeignCall1(@SuppressWarnings("unused") int phi) {
@@ -135,44 +134,8 @@ public class MethodSubstitutionForeignCallTest extends GraalCompilerTest {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
- ForeignCallsProvider foreignCalls = new ForeignCallsProvider() {
- @Override
- public LIRKind getValueKind(JavaKind javaKind) {
- return LIRKind.fromJavaKind(getTarget().arch, javaKind);
- }
-
- @Override
- public ForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor) {
- throw GraalError.shouldNotReachHere("Test code must not need this method");
- }
-
- @Override
- public boolean isReexecutable(ForeignCallDescriptor descriptor) {
- return false;
- }
-
- @Override
- public boolean isGuaranteedSafepoint(ForeignCallDescriptor descriptor) {
- return true;
- }
-
- @Override
- public boolean isAvailable(ForeignCallDescriptor descriptor) {
- return true;
- }
-
- @Override
- public LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor) {
- return new LocationIdentity[]{LocationIdentity.any()};
- }
-
- @Override
- public boolean canDeoptimize(ForeignCallDescriptor descriptor) {
- return true;
- }
- };
- ForeignCallNode node = new ForeignCallNode(foreignCalls, TEST_CALL, arg);
+ ForeignCallNode node = new ForeignCallNode(TEST_CALL_DEOPT, arg);
node.setBci(b.bci());
b.addPush(JavaKind.Int, node);
return true;
@@ -182,44 +145,7 @@ public class MethodSubstitutionForeignCallTest extends GraalCompilerTest {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
- ForeignCallsProvider foreignCalls = new ForeignCallsProvider() {
-
- @Override
- public LIRKind getValueKind(JavaKind javaKind) {
- return LIRKind.fromJavaKind(getTarget().arch, javaKind);
- }
-
- @Override
- public ForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor) {
- throw GraalError.shouldNotReachHere("Test code must not need this method");
- }
-
- @Override
- public boolean isReexecutable(ForeignCallDescriptor descriptor) {
- return false;
- }
-
- @Override
- public boolean isGuaranteedSafepoint(ForeignCallDescriptor descriptor) {
- return false;
- }
-
- @Override
- public boolean isAvailable(ForeignCallDescriptor descriptor) {
- return true;
- }
-
- @Override
- public LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor) {
- return new LocationIdentity[]{LocationIdentity.any()};
- }
-
- @Override
- public boolean canDeoptimize(ForeignCallDescriptor descriptor) {
- return false;
- }
- };
- ForeignCallNode node = new ForeignCallNode(foreignCalls, TEST_CALL, arg);
+ ForeignCallNode node = new ForeignCallNode(TEST_CALL_NON_DEOPT, arg);
node.setBci(b.bci());
b.addPush(JavaKind.Int, node);
return true;
@@ -229,44 +155,7 @@ public class MethodSubstitutionForeignCallTest extends GraalCompilerTest {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
- ForeignCallsProvider foreignCalls = new ForeignCallsProvider() {
-
- @Override
- public LIRKind getValueKind(JavaKind javaKind) {
- return LIRKind.fromJavaKind(getTarget().arch, javaKind);
- }
-
- @Override
- public ForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor) {
- throw GraalError.shouldNotReachHere("Test code must not need this method");
- }
-
- @Override
- public boolean isReexecutable(ForeignCallDescriptor descriptor) {
- return true;
- }
-
- @Override
- public boolean isGuaranteedSafepoint(ForeignCallDescriptor descriptor) {
- return false;
- }
-
- @Override
- public boolean isAvailable(ForeignCallDescriptor descriptor) {
- return true;
- }
-
- @Override
- public LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor) {
- return new LocationIdentity[]{LocationIdentity.any()};
- }
-
- @Override
- public boolean canDeoptimize(ForeignCallDescriptor descriptor) {
- return false;
- }
- };
- ForeignCallNode node = new ForeignCallNode(foreignCalls, TEST_CALL, arg);
+ ForeignCallNode node = new ForeignCallNode(TEST_CALL_REEXECUTABLE, arg);
node.setBci(b.bci());
b.addPush(JavaKind.Int, node);
return true;
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ReplaceConstantNodesPhaseTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ReplaceConstantNodesPhaseTest.java
index 4a329721d03..d720dd29c4b 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ReplaceConstantNodesPhaseTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ReplaceConstantNodesPhaseTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, 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
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ReservedStackAccessTest.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ReservedStackAccessTest.java
index 797f7f6cb77..44a2e204a32 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ReservedStackAccessTest.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ReservedStackAccessTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, 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
@@ -34,6 +34,10 @@ import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
+/**
+ * Tests the ReservedStackAccess annotation. This test is derived from
+ * https://github.com/openjdk/jdk/blob/master/test/hotspot/jtreg/runtime/ReservedStack/ReservedStackTest.java
+ */
public class ReservedStackAccessTest extends HotSpotGraalCompilerTest {
@Before
public void check() {
@@ -72,6 +76,8 @@ public class ReservedStackAccessTest extends HotSpotGraalCompilerTest {
List vmArgs = SubprocessUtil.withoutDebuggerArguments(SubprocessUtil.getVMCommandLine());
vmArgs.add("-XX:+UseJVMCICompiler");
vmArgs.add("-Dgraal.Inline=false");
+ vmArgs.add("-XX:MaxInlineLevel=2");
+ vmArgs.add("-XX:CompileCommand=exclude,java/util/concurrent/locks/ReentrantLock,lock");
vmArgs.add("-XX:CompileCommand=exclude,java/util/concurrent/locks/AbstractOwnableSynchronizer.setExclusiveOwnerThread");
vmArgs.add(SubprocessUtil.PACKAGE_OPENING_OPTIONS);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/TestIntrinsicCompiles.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/TestIntrinsicCompiles.java
index faca1bd3071..a9eaf0105ed 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/TestIntrinsicCompiles.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/TestIntrinsicCompiles.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2020, 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
@@ -35,6 +35,7 @@ import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
@@ -72,7 +73,7 @@ public class TestIntrinsicCompiles extends GraalCompilerTest {
if (plugin instanceof MethodSubstitutionPlugin) {
ResolvedJavaMethod method = CheckGraalIntrinsics.resolveIntrinsic(getMetaAccess(), intrinsic);
if (!method.isNative()) {
- StructuredGraph graph = providers.getReplacements().getIntrinsicGraph(method, INVALID_COMPILATION_ID, debug, null);
+ StructuredGraph graph = providers.getReplacements().getIntrinsicGraph(method, INVALID_COMPILATION_ID, debug, AllowAssumptions.YES, null);
getCode(method, graph);
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/AOTGraalHotSpotVMConfig.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/AOTGraalHotSpotVMConfig.java
index 694357a3db0..4b205068653 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/AOTGraalHotSpotVMConfig.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/AOTGraalHotSpotVMConfig.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,6 +44,7 @@ public class AOTGraalHotSpotVMConfig extends GraalHotSpotVMConfig {
CompressEncoding vmKlassEncoding = super.getKlassEncoding();
aotKlassEncoding = new CompressEncoding(vmKlassEncoding.getBase(), logKlassAlignment);
assert check();
+ reportErrors();
}
@Override
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java
index f93363e93cd..91e8fbdb01f 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,8 +32,6 @@ import static org.graalvm.compiler.core.phases.HighTier.Options.Inline;
import static org.graalvm.compiler.java.BytecodeParserOptions.InlineDuringParsing;
import java.io.PrintStream;
-import java.util.Collections;
-import java.util.List;
import jdk.internal.vm.compiler.collections.EconomicMap;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
@@ -44,6 +42,7 @@ import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.debug.CounterKey;
import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugContext.Builder;
import org.graalvm.compiler.debug.DebugContext.Description;
import org.graalvm.compiler.debug.DebugDumpScope;
import org.graalvm.compiler.debug.DebugHandlersFactory;
@@ -92,8 +91,8 @@ public class CompilationTask {
protected DebugContext createRetryDebugContext(DebugContext initialDebug, OptionValues retryOptions, PrintStream logStream) {
SnippetReflectionProvider snippetReflection = compiler.getGraalRuntime().getHostProviders().getSnippetReflection();
Description description = initialDebug.getDescription();
- List factories = Collections.singletonList(new GraalDebugHandlersFactory(snippetReflection));
- return DebugContext.create(retryOptions, description, initialDebug.getGlobalMetrics(), logStream, factories);
+ DebugHandlersFactory factory = new GraalDebugHandlersFactory(snippetReflection);
+ return new Builder(retryOptions, factory).globalMetrics(initialDebug.getGlobalMetrics()).description(description).logStream(logStream).build();
}
@Override
@@ -304,7 +303,7 @@ public class CompilationTask {
public HotSpotCompilationRequestResult runCompilation(OptionValues initialOptions) {
OptionValues options = filterOptions(initialOptions);
HotSpotGraalRuntimeProvider graalRuntime = compiler.getGraalRuntime();
- try (DebugContext debug = graalRuntime.openDebugContext(options, compilationId, getMethod(), compiler.getDebugHandlersFactories(), DebugContext.DEFAULT_LOG_STREAM)) {
+ try (DebugContext debug = graalRuntime.openDebugContext(options, compilationId, getMethod(), compiler.getDebugHandlersFactories(), DebugContext.getDefaultLogStream())) {
return runCompilation(debug);
}
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/EncodedSnippets.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/EncodedSnippets.java
new file mode 100644
index 00000000000..39cd7fde992
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/EncodedSnippets.java
@@ -0,0 +1,448 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.hotspot;
+
+import static jdk.vm.ci.runtime.JVMCI.getRuntime;
+import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE;
+import static org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.CompilationContext.INLINE_AFTER_PARSING;
+
+import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap;
+import org.graalvm.compiler.api.runtime.GraalJVMCICompiler;
+import org.graalvm.compiler.api.runtime.GraalRuntime;
+import org.graalvm.compiler.bytecode.BytecodeProvider;
+import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode;
+import org.graalvm.compiler.core.common.type.Stamp;
+import org.graalvm.compiler.core.common.type.StampPair;
+import org.graalvm.compiler.core.common.type.SymbolicJVMCIReference;
+import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.GraalError;
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodes.Cancellable;
+import org.graalvm.compiler.nodes.EncodedGraph;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin;
+import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext;
+import org.graalvm.compiler.nodes.graphbuilderconf.MethodSubstitutionPlugin;
+import org.graalvm.compiler.nodes.graphbuilderconf.ParameterPlugin;
+import org.graalvm.compiler.nodes.spi.SnippetParameterInfo;
+import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.phases.util.Providers;
+import org.graalvm.compiler.replacements.ConstantBindingParameterPlugin;
+import org.graalvm.compiler.replacements.PEGraphDecoder;
+import org.graalvm.compiler.replacements.ReplacementsImpl;
+
+import jdk.vm.ci.meta.ResolvedJavaField;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.UnresolvedJavaField;
+import jdk.vm.ci.meta.UnresolvedJavaMethod;
+import jdk.vm.ci.meta.UnresolvedJavaType;
+
+public class EncodedSnippets {
+ private final byte[] snippetEncoding;
+ private final Object[] snippetObjects;
+ private final NodeClass>[] snippetNodeClasses;
+ private final UnmodifiableEconomicMap snippetStartOffsets;
+ private final UnmodifiableEconomicMap originalMethods;
+ private UnmodifiableEconomicMap snippetParameterInfos;
+
+ EncodedSnippets(byte[] snippetEncoding, Object[] snippetObjects, NodeClass>[] snippetNodeClasses, UnmodifiableEconomicMap snippetStartOffsets,
+ UnmodifiableEconomicMap originalMethods, UnmodifiableEconomicMap snippetParameterInfos) {
+ this.snippetEncoding = snippetEncoding;
+ this.snippetObjects = snippetObjects;
+ this.snippetNodeClasses = snippetNodeClasses;
+ this.snippetStartOffsets = snippetStartOffsets;
+ this.originalMethods = originalMethods;
+ this.snippetParameterInfos = snippetParameterInfos;
+ }
+
+ public byte[] getSnippetEncoding() {
+ return snippetEncoding;
+ }
+
+ public NodeClass>[] getSnippetNodeClasses() {
+ return snippetNodeClasses;
+ }
+
+ public UnmodifiableEconomicMap getSnippetStartOffsets() {
+ return snippetStartOffsets;
+ }
+
+ public UnmodifiableEconomicMap getOriginalMethods() {
+ return originalMethods;
+ }
+
+ StructuredGraph getMethodSubstitutionGraph(MethodSubstitutionPlugin plugin, ResolvedJavaMethod original, ReplacementsImpl replacements, IntrinsicContext.CompilationContext context,
+ StructuredGraph.AllowAssumptions allowAssumptions, Cancellable cancellable, OptionValues options) {
+ IntrinsicContext.CompilationContext contextToUse = context;
+ if (context == IntrinsicContext.CompilationContext.ROOT_COMPILATION) {
+ contextToUse = IntrinsicContext.CompilationContext.ROOT_COMPILATION_ENCODING;
+ }
+ Integer startOffset = snippetStartOffsets.get(plugin.toString() + contextToUse);
+ if (startOffset == null) {
+ throw GraalError.shouldNotReachHere("plugin graph not found: " + plugin + " with " + contextToUse);
+ }
+
+ ResolvedJavaType accessingClass = replacements.getProviders().getMetaAccess().lookupJavaType(plugin.getDeclaringClass());
+ return decodeGraph(original, accessingClass, startOffset, replacements, contextToUse, allowAssumptions, cancellable, options);
+ }
+
+ /**
+ * Generate a String name for a method including all type information. Used as a symbolic key
+ * for lookup.
+ */
+ public static String methodKey(ResolvedJavaMethod method) {
+ return method.format("%H.%n(%P)");
+ }
+
+ @SuppressWarnings("try")
+ private StructuredGraph decodeGraph(ResolvedJavaMethod method,
+ ResolvedJavaType accessingClass,
+ int startOffset,
+ ReplacementsImpl replacements,
+ IntrinsicContext.CompilationContext context,
+ StructuredGraph.AllowAssumptions allowAssumptions,
+ Cancellable cancellable,
+ OptionValues options) {
+ Providers providers = replacements.getProviders();
+ EncodedGraph encodedGraph = new SymbolicEncodedGraph(snippetEncoding, startOffset, snippetObjects, snippetNodeClasses,
+ methodKey(method), accessingClass, method.getDeclaringClass());
+ try (DebugContext debug = replacements.openDebugContext("SVMSnippet_", method, options)) {
+ boolean isSubstitution = true;
+ StructuredGraph result = new StructuredGraph.Builder(options, debug, allowAssumptions).cancellable(cancellable).method(method).setIsSubstitution(isSubstitution).build();
+ PEGraphDecoder graphDecoder = new SubstitutionGraphDecoder(providers, result, replacements, null, method, context, encodedGraph);
+
+ graphDecoder.decode(method, isSubstitution, encodedGraph.trackNodeSourcePosition());
+
+ assert result.verify();
+ return result;
+ }
+ }
+
+ StructuredGraph getEncodedSnippet(ResolvedJavaMethod method, ReplacementsImpl replacements, Object[] args, StructuredGraph.AllowAssumptions allowAssumptions, OptionValues options) {
+ Integer startOffset = null;
+ if (snippetStartOffsets != null) {
+ startOffset = snippetStartOffsets.get(methodKey(method));
+ }
+ if (startOffset == null) {
+ if (IS_IN_NATIVE_IMAGE) {
+ throw GraalError.shouldNotReachHere("snippet not found: " + method.format("%H.%n(%p)"));
+ } else {
+ return null;
+ }
+ }
+
+ SymbolicEncodedGraph encodedGraph = new SymbolicEncodedGraph(snippetEncoding, startOffset, snippetObjects, snippetNodeClasses,
+ originalMethods.get(methodKey(method)), method.getDeclaringClass());
+ return decodeSnippetGraph(encodedGraph, method, replacements, args, allowAssumptions, options);
+ }
+
+ public SnippetParameterInfo getSnippetParameterInfo(ResolvedJavaMethod method) {
+ SnippetParameterInfo info = snippetParameterInfos.get(methodKey(method));
+ assert info != null;
+ return info;
+ }
+
+ public boolean isSnippet(ResolvedJavaMethod method) {
+ return snippetParameterInfos.get(methodKey(method)) != null;
+ }
+
+ @SuppressWarnings("try")
+ private static StructuredGraph decodeSnippetGraph(SymbolicEncodedGraph encodedGraph, ResolvedJavaMethod method, ReplacementsImpl replacements, Object[] args,
+ StructuredGraph.AllowAssumptions allowAssumptions, OptionValues options) {
+ Providers providers = replacements.getProviders();
+ ParameterPlugin parameterPlugin = null;
+ if (args != null) {
+ parameterPlugin = new ConstantBindingParameterPlugin(args, providers.getMetaAccess(), replacements.snippetReflection);
+ }
+
+ try (DebugContext debug = replacements.openDebugContext("SVMSnippet_", method, options)) {
+ // @formatter:off
+ boolean isSubstitution = true;
+ StructuredGraph result = new StructuredGraph.Builder(options, debug, allowAssumptions)
+ .method(method)
+ .trackNodeSourcePosition(encodedGraph.trackNodeSourcePosition())
+ .setIsSubstitution(isSubstitution)
+ .build();
+ // @formatter:on
+ try (DebugContext.Scope scope = debug.scope("DecodeSnippetGraph", result)) {
+ PEGraphDecoder graphDecoder = new SubstitutionGraphDecoder(providers, result, replacements, parameterPlugin, method, INLINE_AFTER_PARSING, encodedGraph);
+
+ graphDecoder.decode(method, isSubstitution, encodedGraph.trackNodeSourcePosition());
+ debug.dump(DebugContext.VERBOSE_LEVEL, result, "After decoding");
+
+ assert result.verify();
+ return result;
+ } catch (Throwable t) {
+ throw debug.handle(t);
+ }
+ }
+ }
+
+ public static class SubstitutionGraphDecoder extends PEGraphDecoder {
+ private final ResolvedJavaMethod method;
+ private final EncodedGraph encodedGraph;
+ private IntrinsicContext intrinsic;
+
+ SubstitutionGraphDecoder(Providers providers, StructuredGraph result, ReplacementsImpl replacements, ParameterPlugin parameterPlugin, ResolvedJavaMethod method,
+ IntrinsicContext.CompilationContext context, EncodedGraph encodedGraph) {
+ super(providers.getCodeCache().getTarget().arch, result, providers, null,
+ replacements.getGraphBuilderPlugins().getInvocationPlugins(), new InlineInvokePlugin[0], parameterPlugin,
+ null, null, null);
+ this.method = method;
+ this.encodedGraph = encodedGraph;
+ intrinsic = new IntrinsicContext(method, null, replacements.getDefaultReplacementBytecodeProvider(), context, false);
+ }
+
+ @Override
+ protected EncodedGraph lookupEncodedGraph(ResolvedJavaMethod lookupMethod,
+ MethodSubstitutionPlugin plugin,
+ BytecodeProvider intrinsicBytecodeProvider,
+ boolean isSubstitution,
+ boolean trackNodeSourcePosition) {
+ if (lookupMethod.equals(method)) {
+ return encodedGraph;
+ } else {
+ throw GraalError.shouldNotReachHere(method.format("%H.%n(%p)"));
+ }
+ }
+
+ @Override
+ protected IntrinsicContext getIntrinsic() {
+ return intrinsic;
+ }
+ }
+
+ static class SymbolicEncodedGraph extends EncodedGraph {
+
+ private final ResolvedJavaType[] accessingClasses;
+ private final String originalMethod;
+
+ SymbolicEncodedGraph(byte[] encoding, int startOffset, Object[] objects, NodeClass>[] types, String originalMethod, ResolvedJavaType... accessingClasses) {
+ super(encoding, startOffset, objects, types, null, null, null, false, false);
+ this.accessingClasses = accessingClasses;
+ this.originalMethod = originalMethod;
+ }
+
+ SymbolicEncodedGraph(EncodedGraph encodedGraph, ResolvedJavaType declaringClass, String originalMethod) {
+ this(encodedGraph.getEncoding(), encodedGraph.getStartOffset(), encodedGraph.getObjects(), encodedGraph.getNodeClasses(),
+ originalMethod, declaringClass);
+ }
+
+ @Override
+ public Object getObject(int i) {
+ Object o = objects[i];
+ Object replacement = null;
+ if (o instanceof SymbolicJVMCIReference) {
+ for (ResolvedJavaType type : accessingClasses) {
+ try {
+ replacement = ((SymbolicJVMCIReference>) o).resolve(type);
+ break;
+ } catch (NoClassDefFoundError e) {
+ }
+ }
+ } else if (o instanceof UnresolvedJavaType) {
+ for (ResolvedJavaType type : accessingClasses) {
+ try {
+ replacement = ((UnresolvedJavaType) o).resolve(type);
+ break;
+ } catch (NoClassDefFoundError e) {
+ }
+ }
+ } else if (o instanceof UnresolvedJavaMethod) {
+ throw new InternalError(o.toString());
+ } else if (o instanceof UnresolvedJavaField) {
+ for (ResolvedJavaType type : accessingClasses) {
+ try {
+ replacement = ((UnresolvedJavaField) o).resolve(type);
+ break;
+ } catch (NoClassDefFoundError e) {
+ }
+ }
+ } else if (o instanceof GraalCapability) {
+ replacement = ((GraalCapability) o).resolve(((GraalJVMCICompiler) getRuntime().getCompiler()).getGraalRuntime());
+ } else {
+ return o;
+ }
+ if (replacement != null) {
+ objects[i] = o = replacement;
+ } else {
+ throw new GraalError("Can't resolve " + o);
+ }
+ return o;
+ }
+
+ @Override
+ public boolean isCallToOriginal(ResolvedJavaMethod callTarget) {
+ if (originalMethod != null && originalMethod.equals(EncodedSnippets.methodKey(callTarget))) {
+ return true;
+ }
+ return super.isCallToOriginal(callTarget);
+ }
+ }
+
+ /**
+ * Symbolic reference to an object which can be retrieved from
+ * {@link GraalRuntime#getCapability(Class)}.
+ */
+ static class GraalCapability {
+ final Class> capabilityClass;
+
+ GraalCapability(Class> capabilityClass) {
+ this.capabilityClass = capabilityClass;
+ }
+
+ public Object resolve(GraalRuntime runtime) {
+ Object capability = runtime.getCapability(this.capabilityClass);
+ if (capability != null) {
+ assert capability.getClass() == capabilityClass;
+ return capability;
+ }
+ throw new InternalError(this.capabilityClass.getName());
+ }
+ }
+
+ static class SymbolicResolvedJavaMethod implements SymbolicJVMCIReference {
+ final UnresolvedJavaType type;
+ final String methodName;
+ final String signature;
+
+ SymbolicResolvedJavaMethod(ResolvedJavaMethod method) {
+ this.type = UnresolvedJavaType.create(method.getDeclaringClass().getName());
+ this.methodName = method.getName();
+ this.signature = method.getSignature().toMethodDescriptor();
+ }
+
+ @Override
+ public String toString() {
+ return "SymbolicResolvedJavaMethod{" +
+ "declaringType='" + type.getName() + '\'' +
+ ", methodName='" + methodName + '\'' +
+ ", signature='" + signature + '\'' +
+ '}';
+ }
+
+ @Override
+ public ResolvedJavaMethod resolve(ResolvedJavaType accessingClass) {
+ ResolvedJavaType resolvedType = type.resolve(accessingClass);
+ if (resolvedType == null) {
+ throw new InternalError("Could not resolve " + this + " in context of " + accessingClass.toJavaName());
+ }
+ for (ResolvedJavaMethod method : methodName.equals("") ? resolvedType.getDeclaredConstructors() : resolvedType.getDeclaredMethods()) {
+ if (method.getName().equals(methodName) && method.getSignature().toMethodDescriptor().equals(signature)) {
+ return method;
+ }
+ }
+ throw new InternalError("Could not resolve " + this + " in context of " + accessingClass.toJavaName());
+ }
+ }
+
+ static class SymbolicResolvedJavaField implements SymbolicJVMCIReference {
+ final UnresolvedJavaType declaringType;
+ final String name;
+ final UnresolvedJavaType signature;
+ private final boolean isStatic;
+
+ SymbolicResolvedJavaField(ResolvedJavaField field) {
+ this.declaringType = UnresolvedJavaType.create(field.getDeclaringClass().getName());
+ this.name = field.getName();
+ this.signature = UnresolvedJavaType.create(field.getType().getName());
+ this.isStatic = field.isStatic();
+ }
+
+ @Override
+ public ResolvedJavaField resolve(ResolvedJavaType accessingClass) {
+ ResolvedJavaType resolvedType = declaringType.resolve(accessingClass);
+ ResolvedJavaType resolvedFieldType = signature.resolve(accessingClass);
+ ResolvedJavaField[] fields = isStatic ? resolvedType.getStaticFields() : resolvedType.getInstanceFields(true);
+ for (ResolvedJavaField field : fields) {
+ if (field.getName().equals(name)) {
+ if (field.getType().equals(resolvedFieldType)) {
+ return field;
+ }
+ }
+ }
+ throw new InternalError("Could not resolve " + this + " in context of " + accessingClass.toJavaName());
+ }
+
+ @Override
+ public String toString() {
+ return "SymbolicResolvedJavaField{" +
+ signature.getName() + ' ' +
+ declaringType.getName() + '.' +
+ name +
+ '}';
+ }
+ }
+
+ static class SymbolicResolvedJavaMethodBytecode implements SymbolicJVMCIReference {
+ SymbolicResolvedJavaMethod method;
+
+ SymbolicResolvedJavaMethodBytecode(ResolvedJavaMethodBytecode bytecode) {
+ method = new SymbolicResolvedJavaMethod(bytecode.getMethod());
+ }
+
+ @Override
+ public ResolvedJavaMethodBytecode resolve(ResolvedJavaType accessingClass) {
+ return new ResolvedJavaMethodBytecode(method.resolve(accessingClass));
+ }
+ }
+
+ static class SymbolicStampPair implements SymbolicJVMCIReference {
+ Object trustedStamp;
+ Object uncheckdStamp;
+
+ SymbolicStampPair(StampPair stamp) {
+ this.trustedStamp = maybeMakeSymbolic(stamp.getTrustedStamp());
+ this.uncheckdStamp = maybeMakeSymbolic(stamp.getUncheckedStamp());
+ }
+
+ @Override
+ public StampPair resolve(ResolvedJavaType accessingClass) {
+ return StampPair.create(resolveStamp(accessingClass, trustedStamp), resolveStamp(accessingClass, uncheckdStamp));
+ }
+ }
+
+ private static Object maybeMakeSymbolic(Stamp trustedStamp) {
+ if (trustedStamp != null) {
+ SymbolicJVMCIReference> symbolicJVMCIReference = trustedStamp.makeSymbolic();
+ if (symbolicJVMCIReference != null) {
+ return symbolicJVMCIReference;
+ }
+ }
+ return trustedStamp;
+ }
+
+ private static Stamp resolveStamp(ResolvedJavaType accessingClass, Object stamp) {
+ if (stamp == null) {
+ return null;
+ }
+ if (stamp instanceof Stamp) {
+ return (Stamp) stamp;
+ }
+ return (Stamp) ((SymbolicJVMCIReference>) stamp).resolve(accessingClass);
+ }
+
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java
index 4f2c3a99cc0..e7a77962d37 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java
@@ -28,18 +28,31 @@ import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.List;
+import org.graalvm.compiler.api.replacements.Fold;
+import org.graalvm.compiler.api.replacements.Fold.InjectedParameter;
import org.graalvm.compiler.core.common.CompressEncoding;
-import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode;
+import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext;
+import org.graalvm.compiler.options.OptionValues;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
+import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
* Used to access native configuration details.
*/
-public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
+public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigAccess {
+
+ /**
+ * Sentinel value to use for an {@linkplain InjectedParameter injected}
+ * {@link GraalHotSpotVMConfig} parameter to a {@linkplain Fold foldable} method.
+ */
+ public static final GraalHotSpotVMConfig INJECTED_VMCONFIG = null;
+ public static final MetaAccessProvider INJECTED_METAACCESS = null;
+ public static final OptionValues INJECTED_OPTIONVALUES = null;
+ public static final IntrinsicContext INJECTED_INTRINSIC_CONTEXT = null;
GraalHotSpotVMConfig(HotSpotVMConfigStore store) {
super(store);
@@ -50,11 +63,12 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
klassEncoding = new CompressEncoding(narrowKlassBase, narrowKlassShift);
assert check();
+ reportErrors();
}
private final CompressEncoding oopEncoding;
private final CompressEncoding klassEncoding;
- private final String markWord = versioned.markWordFieldType;
+ private final String markWord = JDK < 14 ? "markOop" : "markWord"; // JDK-8229258
public CompressEncoding getOopEncoding() {
return oopEncoding;
@@ -64,14 +78,34 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
return klassEncoding;
}
+ private final boolean isJDK11Plus = JDK >= 11;
+ private final boolean isJDK8OrJDK11Plus = JDK == 8 || isJDK11Plus;
+
+ // Certain values were accidentally omitted in JDK 9+ only VM values
+ // in vmStructs_jvmci.cpp are exposed to JVMCI. In JDK 8, values in any
+ // vmStructs*.[cpp|hpp] file are exposed to JVMCI.
+ private final boolean gr21761 = JDK == 8 || (JVMCI ? jvmciGE(JVMCI_20_0_b03) : JDK >= 15);
+
+ private final boolean jdk13Backport = JVMCI ? jvmciGE(JVMCI_19_3_b03) : JDK >= 13;
+
public final boolean cAssertions = getConstant("ASSERT", Boolean.class);
public final int codeEntryAlignment = getFlag("CodeEntryAlignment", Integer.class);
public final boolean enableContended = getFlag("EnableContended", Boolean.class);
public final boolean restrictContended = getFlag("RestrictContended", Boolean.class);
public final int contendedPaddingWidth = getFlag("ContendedPaddingWidth", Integer.class);
- public final int fieldsAllocationStyle = versioned.fieldsAllocationStyle;
- public final boolean compactFields = versioned.compactFields;
+ public final int fieldsAllocationStyle;
+ public final boolean compactFields;
+ {
+ // JDK-8236224
+ if (JDK >= 15) {
+ fieldsAllocationStyle = 1;
+ compactFields = true;
+ } else {
+ fieldsAllocationStyle = getFlag("FieldsAllocationStyle", Integer.class);
+ compactFields = getFlag("CompactFields", Boolean.class);
+ }
+ }
public final boolean verifyOops = getFlag("VerifyOops", Boolean.class);
public final boolean ciTime = getFlag("CITime", Boolean.class);
public final boolean ciTimeEach = getFlag("CITimeEach", Boolean.class);
@@ -79,7 +113,7 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
public final int hugeMethodLimit = getFlag("HugeMethodLimit", Integer.class);
public final boolean printInlining = getFlag("PrintInlining", Boolean.class);
public final boolean inline = getFlag("Inline", Boolean.class);
- public final boolean inlineNotify = versioned.inlineNotify;
+ public final boolean inlineNotify = JDK > 8;
public final boolean useFastLocking = getFlag("JVMCIUseFastLocking", Boolean.class);
public final boolean forceUnreachable = getFlag("ForceUnreachable", Boolean.class);
public final int codeSegmentSize = getFlag("CodeCacheSegmentSize", Integer.class);
@@ -93,26 +127,35 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
public final boolean useBiasedLocking = getFlag("UseBiasedLocking", Boolean.class);
public final boolean usePopCountInstruction = getFlag("UsePopCountInstruction", Boolean.class);
public final boolean useAESIntrinsics = getFlag("UseAESIntrinsics", Boolean.class);
- public final boolean useAESCTRIntrinsics = getFlag("UseAESCTRIntrinsics", Boolean.class, false);
+ public final boolean useAESCTRIntrinsics = getFlag("UseAESCTRIntrinsics", Boolean.class, false, (JDK == 8 && !IS_OPENJDK) || JDK >= 9);
public final boolean useCRC32Intrinsics = getFlag("UseCRC32Intrinsics", Boolean.class);
- public final boolean useCRC32CIntrinsics = versioned.useCRC32CIntrinsics;
- public final boolean threadLocalHandshakes = versioned.threadLocalHandshakes;
-
+ public final boolean useCRC32CIntrinsics = getFlag("UseCRC32CIntrinsics", Boolean.class, false, JDK >= 9); // JDK-8073583
+ public final boolean useThreadLocalPolling;
+ {
+ if (JDK >= 14) {
+ // JDK-8220049, JDK-8220051
+ useThreadLocalPolling = true;
+ } else if (JDK >= 10) {
+ useThreadLocalPolling = getFlag("ThreadLocalHandshakes", Boolean.class);
+ } else {
+ useThreadLocalPolling = false;
+ }
+ }
private final boolean useMultiplyToLenIntrinsic = getFlag("UseMultiplyToLenIntrinsic", Boolean.class);
private final boolean useSHA1Intrinsics = getFlag("UseSHA1Intrinsics", Boolean.class);
private final boolean useSHA256Intrinsics = getFlag("UseSHA256Intrinsics", Boolean.class);
private final boolean useSHA512Intrinsics = getFlag("UseSHA512Intrinsics", Boolean.class);
- private final boolean useGHASHIntrinsics = getFlag("UseGHASHIntrinsics", Boolean.class, false);
- private final boolean useBase64Intrinsics = getFlag("UseBASE64Intrinsics", Boolean.class, false);
- private final boolean useMontgomeryMultiplyIntrinsic = getFlag("UseMontgomeryMultiplyIntrinsic", Boolean.class, false);
- private final boolean useMontgomerySquareIntrinsic = getFlag("UseMontgomerySquareIntrinsic", Boolean.class, false);
- private final boolean useMulAddIntrinsic = getFlag("UseMulAddIntrinsic", Boolean.class, false);
- private final boolean useSquareToLenIntrinsic = getFlag("UseSquareToLenIntrinsic", Boolean.class, false);
- public final boolean useVectorizedMismatchIntrinsic = getFlag("UseVectorizedMismatchIntrinsic", Boolean.class, false);
- public final boolean useFMAIntrinsics = getFlag("UseFMA", Boolean.class, false);
- public final int useAVX3Threshold = getFlag("AVX3Threshold", Integer.class, 4096);
+ private final boolean useGHASHIntrinsics = getFlag("UseGHASHIntrinsics", Boolean.class, false, isJDK8OrJDK11Plus);
+ private final boolean useBase64Intrinsics = getFlag("UseBASE64Intrinsics", Boolean.class, false, isJDK11Plus);
+ private final boolean useMontgomeryMultiplyIntrinsic = getFlag("UseMontgomeryMultiplyIntrinsic", Boolean.class, false, isJDK8OrJDK11Plus);
+ private final boolean useMontgomerySquareIntrinsic = getFlag("UseMontgomerySquareIntrinsic", Boolean.class, false, isJDK8OrJDK11Plus);
+ private final boolean useMulAddIntrinsic = getFlag("UseMulAddIntrinsic", Boolean.class, false, isJDK8OrJDK11Plus);
+ private final boolean useSquareToLenIntrinsic = getFlag("UseSquareToLenIntrinsic", Boolean.class, false, isJDK8OrJDK11Plus);
+ public final boolean useVectorizedMismatchIntrinsic = getFlag("UseVectorizedMismatchIntrinsic", Boolean.class, false, isJDK11Plus);
+ public final boolean useFMAIntrinsics = getFlag("UseFMA", Boolean.class, false, JDK >= 9);
+ public final int useAVX3Threshold = getFlag("AVX3Threshold", Integer.class, 4096, osArch.equals("amd64") && (JDK >= 14 || (JDK == 11 && JDK_UPDATE >= 6)));
- public final boolean preserveFramePointer = getFlag("PreserveFramePointer", Boolean.class, false);
+ public final boolean preserveFramePointer = getFlag("PreserveFramePointer", Boolean.class);
/*
* These are methods because in some JDKs the flags are visible but the stubs themselves haven't
@@ -167,7 +210,7 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
}
public final boolean useG1GC = getFlag("UseG1GC", Boolean.class);
- public final boolean useCMSGC = getFlag("UseConcMarkSweepGC", Boolean.class, false);
+ public final boolean useCMSGC = getFlag("UseConcMarkSweepGC", Boolean.class, false, JDK < 14); // JDK-8231559
public final int allocatePrefetchStyle = getFlag("AllocatePrefetchStyle", Integer.class);
public final int allocatePrefetchInstr = getFlag("AllocatePrefetchInstr", Integer.class);
@@ -207,9 +250,9 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
public final int logKlassAlignment = getConstant("LogKlassAlignmentInBytes", Integer.class);
public final int stackShadowPages = getFlag("StackShadowPages", Integer.class);
- public final int stackReservedPages = getFlag("StackReservedPages", Integer.class, 0);
+ public final int stackReservedPages = getFlag("StackReservedPages", Integer.class, 0, JDK >= 9);
public final boolean useStackBanging = getFlag("UseStackBanging", Boolean.class);
- public final int stackBias = getConstant("STACK_BIAS", Integer.class, 0);
+ public final int stackBias = getConstant("STACK_BIAS", Integer.class, 0, JDK < 15);
public final int vmPageSize = getFieldValue("CompilerToVM::Data::vm_page_size", Integer.class, "int");
public final int markOffset = getFieldOffset("oopDesc::_mark", Integer.class, markWord);
@@ -222,8 +265,18 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
public final int secondarySuperCacheOffset = getFieldOffset("Klass::_secondary_super_cache", Integer.class, "Klass*");
public final int secondarySupersOffset = getFieldOffset("Klass::_secondary_supers", Integer.class, "Array*");
- public final boolean classMirrorIsHandle = versioned.classMirrorIsHandle;
- public final int classMirrorOffset = versioned.classMirrorOffset;
+ public final boolean classMirrorIsHandle;
+ public final int classMirrorOffset;
+ {
+ // JDK-8186777
+ if (JDK <= 8) {
+ classMirrorIsHandle = false;
+ classMirrorOffset = getFieldOffset("Klass::_java_mirror", Integer.class, "oop");
+ } else {
+ classMirrorIsHandle = true;
+ classMirrorOffset = getFieldOffset("Klass::_java_mirror", Integer.class, "OopHandle");
+ }
+ }
public final int klassSuperKlassOffset = getFieldOffset("Klass::_super", Integer.class, "Klass*");
public final int klassModifierFlagsOffset = getFieldOffset("Klass::_modifier_flags", Integer.class, "jint");
@@ -252,14 +305,14 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
public final int vtableEntryMethodOffset = getFieldOffset("vtableEntry::_method", Integer.class, "Method*");
public final int instanceKlassInitStateOffset = getFieldOffset("InstanceKlass::_init_state", Integer.class, "u1");
- public final int instanceKlassInitThreadOffset = getFieldOffset("InstanceKlass::_init_thread", Integer.class, "Thread*", -1);
+ public final int instanceKlassInitThreadOffset = getFieldOffset("InstanceKlass::_init_thread", Integer.class, "Thread*", -1, JDK == 8 || JDK >= 15 || (JVMCI && jvmciGE(JVMCI_20_0_b03)));
public final int instanceKlassConstantsOffset = getFieldOffset("InstanceKlass::_constants", Integer.class, "ConstantPool*");
public final int instanceKlassFieldsOffset = getFieldOffset("InstanceKlass::_fields", Integer.class, "Array*");
public final int klassVtableStartOffset = getFieldValue("CompilerToVM::Data::Klass_vtable_start_offset", Integer.class, "int");
public final int klassVtableLengthOffset = getFieldValue("CompilerToVM::Data::Klass_vtable_length_offset", Integer.class, "int");
public final int instanceKlassStateLinked = getConstant("InstanceKlass::linked", Integer.class);
- public final int instanceKlassStateBeingInitialized = getConstant("InstanceKlass::being_initialized", Integer.class, -1);
+ public final int instanceKlassStateBeingInitialized = getConstant("InstanceKlass::being_initialized", Integer.class, -1, JDK == 8 || (JVMCI ? jvmciGE(JVMCI_20_0_b03) : JDK >= 14));
public final int instanceKlassStateFullyInitialized = getConstant("InstanceKlass::fully_initialized", Integer.class);
public final int arrayOopDescSize = getFieldValue("CompilerToVM::Data::sizeof_arrayOopDesc", Integer.class, "int");
@@ -299,7 +352,7 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
public final int jvmAccFieldHasGenericSignature = getConstant("JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE", Integer.class);
public final int jvmAccWrittenFlags = getConstant("JVM_ACC_WRITTEN_FLAGS", Integer.class);
public final int jvmAccSynthetic = getConstant("JVM_ACC_SYNTHETIC", Integer.class);
- public final int jvmAccIsHiddenClass = getConstant("JVM_ACC_IS_HIDDEN_CLASS", Integer.class);
+ public final int jvmAccIsHiddenClass = getConstant("JVM_ACC_IS_HIDDEN_CLASS", Integer.class, 0, JDK >= 15); // JDK-8219607
public final int jvmciCompileStateCanPostOnExceptionsOffset = getJvmciJvmtiCapabilityOffset("_jvmti_can_post_on_exceptions");
public final int jvmciCompileStateCanPopFrameOffset = getJvmciJvmtiCapabilityOffset("_jvmti_can_pop_frame");
@@ -307,25 +360,29 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
// Integer.MIN_VALUE if not available
private int getJvmciJvmtiCapabilityOffset(String name) {
- int offset = getFieldOffset("JVMCICompileState::" + name, Integer.class, "jbyte", Integer.MIN_VALUE);
- if (offset == Integer.MIN_VALUE) {
- // JDK 12
- offset = getFieldOffset("JVMCIEnv::" + name, Integer.class, "jbyte", Integer.MIN_VALUE);
+ if (JVMCI) {
+ return getFieldOffset("JVMCICompileState::" + name, Integer.class, "jbyte");
}
- return offset;
+ if (JDK >= 13) {
+ return getFieldOffset("JVMCICompileState::" + name, Integer.class, "jbyte");
+ }
+ if (JDK == 12) {
+ return getFieldOffset("JVMCIEnv::" + name, Integer.class, "jbyte");
+ }
+ return Integer.MIN_VALUE;
}
public final int threadTlabOffset = getFieldOffset("Thread::_tlab", Integer.class, "ThreadLocalAllocBuffer");
public final int javaThreadAnchorOffset = getFieldOffset("JavaThread::_anchor", Integer.class, "JavaFrameAnchor");
- public final int javaThreadShouldPostOnExceptionsFlagOffset = getFieldOffset("JavaThread::_should_post_on_exceptions_flag", Integer.class, "int", Integer.MIN_VALUE);
+ public final int javaThreadShouldPostOnExceptionsFlagOffset = getFieldOffset("JavaThread::_should_post_on_exceptions_flag", Integer.class, "int", Integer.MIN_VALUE, JVMCI || JDK >= 12);
public final int threadObjectOffset = getFieldOffset("JavaThread::_threadObj", Integer.class, "oop");
- public final int osThreadOffset = getFieldOffset("JavaThread::_osthread", Integer.class, "OSThread*", Integer.MAX_VALUE);
+ public final int osThreadOffset = getFieldOffset("JavaThread::_osthread", Integer.class, "OSThread*");
public final int threadIsMethodHandleReturnOffset = getFieldOffset("JavaThread::_is_method_handle_return", Integer.class, "int");
public final int threadObjectResultOffset = getFieldOffset("JavaThread::_vm_result", Integer.class, "oop");
public final int jvmciCountersThreadOffset = getFieldOffset("JavaThread::_jvmci_counters", Integer.class, "jlong*");
- public final int doingUnsafeAccessOffset = getFieldOffset("JavaThread::_doing_unsafe_access", Integer.class, "bool", Integer.MAX_VALUE);
- public final int javaThreadReservedStackActivationOffset = versioned.javaThreadReservedStackActivationOffset;
- public final int jniEnvironmentOffset = getFieldOffset("JavaThread::_jni_environment", Integer.class, "JNIEnv", Integer.MIN_VALUE);
+ public final int doingUnsafeAccessOffset = getFieldOffset("JavaThread::_doing_unsafe_access", Integer.class, "bool", Integer.MAX_VALUE, JVMCI || JDK >= 14);
+ public final int javaThreadReservedStackActivationOffset = JDK <= 8 ? 0 : getFieldOffset("JavaThread::_reserved_stack_activation", Integer.class, "address"); // JDK-8046936
+ public final int jniEnvironmentOffset = getFieldOffset("JavaThread::_jni_environment", Integer.class, "JNIEnv", Integer.MIN_VALUE, JVMCI || JDK >= 14);
public boolean requiresReservedStackCheck(List methods) {
if (enableStackReservedZoneAddress != 0 && methods != null) {
@@ -367,7 +424,7 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
* this field is {@value #INVALID_RTLD_DEFAULT_HANDLE}, then this capability is not supported on
* the current platform.
*/
- public final long rtldDefault = getAddress("RTLD_DEFAULT", osName.equals("bsd") || osName.equals("linux") ? null : INVALID_RTLD_DEFAULT_HANDLE);
+ public final long rtldDefault = getAddress("RTLD_DEFAULT", INVALID_RTLD_DEFAULT_HANDLE, osName.equals("darwin") || osName.equals("linux"));
/**
* This field is used to pass exception objects into and out of the runtime system during
@@ -414,11 +471,16 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
return javaThreadAnchorOffset + getFieldOffset("JavaFrameAnchor::_last_Java_fp", Integer.class, "intptr_t*");
}
- public final int runtimeCallStackSize = getConstant("frame::arg_reg_save_area_bytes", Integer.class, intRequiredOnAMD64);
- public final int frameInterpreterFrameSenderSpOffset = getConstant("frame::interpreter_frame_sender_sp_offset", Integer.class, intRequiredOnAMD64);
- public final int frameInterpreterFrameLastSpOffset = getConstant("frame::interpreter_frame_last_sp_offset", Integer.class, intRequiredOnAMD64);
+ public int threadJavaFrameAnchorFlagsOffset() {
+ assert osArch.equals("sparc");
+ return javaThreadAnchorOffset + getFieldOffset("JavaFrameAnchor::_flags", Integer.class, "int");
+ }
- public final int osThreadInterruptedOffset = getFieldOffset("OSThread::_interrupted", Integer.class, "jint", Integer.MAX_VALUE);
+ public final int runtimeCallStackSize = getConstant("frame::arg_reg_save_area_bytes", Integer.class, 0, osArch.equals("amd64"));
+ public final int frameInterpreterFrameSenderSpOffset = getConstant("frame::interpreter_frame_sender_sp_offset", Integer.class, 0, osArch.equals("amd64"));
+ public final int frameInterpreterFrameLastSpOffset = getConstant("frame::interpreter_frame_last_sp_offset", Integer.class, 0, osArch.equals("amd64"));
+
+ public final int osThreadInterruptedOffset = getFieldOffset("OSThread::_interrupted", Integer.class, "jint", Integer.MAX_VALUE, JDK < 14);
public final long markWordHashShift = getConstant(markWordField("hash_shift"), Long.class);
@@ -429,15 +491,15 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
public final long markWordHashMaskInPlace = getConstant(markWordField("hash_mask_in_place"), Long.class);
public final int unlockedMask = getConstant(markWordField("unlocked_value"), Integer.class);
- public final int monitorMask = getConstant(markWordField("monitor_value"), Integer.class, -1);
+ public final int monitorMask = getConstant(markWordField("monitor_value"), Integer.class, -1, gr21761);
public final int biasedLockPattern = getConstant(markWordField("biased_lock_pattern"), Integer.class);
// This field has no type in vmStructs.cpp
- public final int objectMonitorOwner = getFieldOffset("ObjectMonitor::_owner", Integer.class, null, -1);
- public final int objectMonitorRecursions = getFieldOffset("ObjectMonitor::_recursions", Integer.class, "intptr_t", -1);
- public final int objectMonitorCxq = getFieldOffset("ObjectMonitor::_cxq", Integer.class, "ObjectWaiter*", -1);
- public final int objectMonitorEntryList = getFieldOffset("ObjectMonitor::_EntryList", Integer.class, "ObjectWaiter*", -1);
- public final int objectMonitorSucc = getFieldOffset("ObjectMonitor::_succ", Integer.class, "Thread*", -1);
+ public final int objectMonitorOwner = getFieldOffset("ObjectMonitor::_owner", Integer.class, null, -1, gr21761);
+ public final int objectMonitorRecursions = getFieldOffset("ObjectMonitor::_recursions", Integer.class, "intptr_t", -1, gr21761);
+ public final int objectMonitorCxq = getFieldOffset("ObjectMonitor::_cxq", Integer.class, "ObjectWaiter*", -1, jdk13Backport);
+ public final int objectMonitorEntryList = getFieldOffset("ObjectMonitor::_EntryList", Integer.class, "ObjectWaiter*", -1, jdk13Backport);
+ public final int objectMonitorSucc = getFieldOffset("ObjectMonitor::_succ", Integer.class, "Thread*", -1, jdk13Backport);
public final int markWordNoHashInPlace = getConstant(markWordField("no_hash_in_place"), Integer.class);
public final int markWordNoLockInPlace = getConstant(markWordField("no_lock_in_place"), Integer.class);
@@ -458,8 +520,8 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
return tmp;
}
- private String markWordField(String simpleName) {
- return versioned.markWordClassName + "::" + simpleName;
+ private static String markWordField(String simpleName) {
+ return (JDK < 14 ? "markOopDesc::" : "markWord::") + simpleName;
}
/**
@@ -474,14 +536,14 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
public final int methodAccessFlagsOffset = getFieldOffset("Method::_access_flags", Integer.class, "AccessFlags");
public final int methodConstMethodOffset = getFieldOffset("Method::_constMethod", Integer.class, "ConstMethod*");
- public final int methodIntrinsicIdOffset = versioned.methodIntrinsicIdOffset;
- public final int methodFlagsOffset = versioned.methodFlagsOffset;
+ public final int methodIntrinsicIdOffset = getFieldOffset("Method::_intrinsic_id", Integer.class, JDK <= 8 ? "u1" : "u2");
+ public final int methodFlagsOffset = getFieldOffset("Method::_flags", Integer.class, JDK <= 8 ? "u1" : "u2");
public final int methodVtableIndexOffset = getFieldOffset("Method::_vtable_index", Integer.class, "int");
public final int methodCountersOffset = getFieldOffset("Method::_method_counters", Integer.class, "MethodCounters*");
public final int methodDataOffset = getFieldOffset("Method::_method_data", Integer.class, "MethodData*");
public final int methodCompiledEntryOffset = getFieldOffset("Method::_from_compiled_entry", Integer.class, "address");
- public final int methodCodeOffset = versioned.methodCodeOffset;
+ public final int methodCodeOffset = getFieldOffset("Method::_code", Integer.class, JDK <= 8 ? "nmethod*" : "CompiledMethod*");
public final int methodFlagsCallerSensitive = getConstant("Method::_caller_sensitive", Integer.class);
public final int methodFlagsForceInline = getConstant("Method::_force_inline", Integer.class);
@@ -492,17 +554,14 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
public final int invocationCounterOffset = getFieldOffset("MethodCounters::_invocation_counter", Integer.class, "InvocationCounter");
public final int backedgeCounterOffset = getFieldOffset("MethodCounters::_backedge_counter", Integer.class, "InvocationCounter");
- public final int invocationCounterIncrement = versioned.invocationCounterIncrement;
- public final int invocationCounterShift = versioned.invocationCounterShift;
+ public final int invocationCounterIncrement = JDK <= 8 ? 0 : getConstant("InvocationCounter::count_increment", Integer.class);
+ public final int invocationCounterShift = JDK <= 8 ? 0 : getConstant("InvocationCounter::count_shift", Integer.class);
- public final int nmethodEntryOffset = getFieldOffset("nmethod::_verified_entry_point",
- Integer.class, "address");
- public final int compilationLevelFullOptimization = getConstant("CompLevel_full_optimization",
- Integer.class);
+ public final int nmethodEntryOffset = getFieldOffset("nmethod::_verified_entry_point", Integer.class, "address");
+ public final int compilationLevelFullOptimization = getConstant("CompLevel_full_optimization", Integer.class);
public final int constantPoolSize = getFieldValue("CompilerToVM::Data::sizeof_ConstantPool", Integer.class, "int");
- public final int constantPoolLengthOffset = getFieldOffset("ConstantPool::_length",
- Integer.class, "int");
+ public final int constantPoolLengthOffset = getFieldOffset("ConstantPool::_length", Integer.class, "int");
public final int heapWordSize = getConstant("HeapWordSize", Integer.class);
@@ -518,8 +577,16 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
public final int logOfHRGrainBytes = getFieldValue("HeapRegion::LogOfHRGrainBytes", Integer.class, "int");
- public final long cardtableStartAddress = getFieldValue("CompilerToVM::Data::cardtable_start_address", Long.class, "CardTable::CardValue*");
public final int cardtableShift = getFieldValue("CompilerToVM::Data::cardtable_shift", Integer.class, "int");
+ public final long cardtableStartAddress;
+ {
+ // JDK-8237497
+ if (JDK < 15) {
+ cardtableStartAddress = getFieldValue("CompilerToVM::Data::cardtable_start_address", Long.class, "jbyte*");
+ } else {
+ cardtableStartAddress = getFieldValue("CompilerToVM::Data::cardtable_start_address", Long.class, "CardTable::CardValue*");
+ }
+ }
/**
* This is the largest stack offset encodeable in an OopMapValue. Offsets larger than this will
@@ -530,15 +597,40 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
public final long safepointPollingAddress = getFieldValue("os::_polling_page", Long.class, "address");
// G1 Collector Related Values.
+ public final byte dirtyCardValue;
+ public final byte g1YoungCardValue;
+ public final int g1SATBQueueMarkingOffset;
+ public final int g1SATBQueueIndexOffset;
+ public final int g1SATBQueueBufferOffset;
+ public final int g1CardQueueIndexOffset;
+ public final int g1CardQueueBufferOffset;
+ {
+ if (JDK <= 8) {
+ int dirtyCardQueueBufferOffset = getFieldOffset("PtrQueue::_buf", Integer.class, "void**");
+ int dirtyCardQueueIndexOffset = getFieldOffset("PtrQueue::_index", Integer.class, "size_t");
+ int satbMarkQueueBufferOffset = dirtyCardQueueBufferOffset;
+ int satbMarkQueueIndexOffset = dirtyCardQueueIndexOffset;
+ int satbMarkQueueActiveOffset = getFieldOffset("PtrQueue::_active", Integer.class, "bool");
+ int javaThreadSatbMarkQueueOffset = getFieldOffset("JavaThread::_satb_mark_queue", Integer.class);
+ int javaThreadDirtyCardQueueOffset = getFieldOffset("JavaThread::_dirty_card_queue", Integer.class, "DirtyCardQueue");
- public final byte dirtyCardValue = versioned.dirtyCardValue;
- public final byte g1YoungCardValue = versioned.g1YoungCardValue;
-
- public final int g1SATBQueueMarkingOffset = versioned.g1SATBQueueMarkingOffset;
- public final int g1SATBQueueIndexOffset = versioned.g1SATBQueueIndexOffset;
- public final int g1SATBQueueBufferOffset = versioned.g1SATBQueueBufferOffset;
- public final int g1CardQueueIndexOffset = versioned.g1CardQueueIndexOffset;
- public final int g1CardQueueBufferOffset = versioned.g1CardQueueBufferOffset;
+ dirtyCardValue = getFieldValue("CompilerToVM::Data::dirty_card", Byte.class, "int");
+ g1YoungCardValue = getFieldValue("CompilerToVM::Data::g1_young_card", Byte.class, "int");
+ g1CardQueueIndexOffset = javaThreadDirtyCardQueueOffset + dirtyCardQueueIndexOffset;
+ g1CardQueueBufferOffset = javaThreadDirtyCardQueueOffset + dirtyCardQueueBufferOffset;
+ g1SATBQueueMarkingOffset = javaThreadSatbMarkQueueOffset + satbMarkQueueActiveOffset;
+ g1SATBQueueIndexOffset = javaThreadSatbMarkQueueOffset + satbMarkQueueIndexOffset;
+ g1SATBQueueBufferOffset = javaThreadSatbMarkQueueOffset + satbMarkQueueBufferOffset;
+ } else {
+ dirtyCardValue = getConstant("CardTable::dirty_card", Byte.class);
+ g1YoungCardValue = getConstant("G1CardTable::g1_young_gen", Byte.class);
+ g1SATBQueueMarkingOffset = getConstant("G1ThreadLocalData::satb_mark_queue_active_offset", Integer.class);
+ g1SATBQueueIndexOffset = getConstant("G1ThreadLocalData::satb_mark_queue_index_offset", Integer.class);
+ g1SATBQueueBufferOffset = getConstant("G1ThreadLocalData::satb_mark_queue_buffer_offset", Integer.class);
+ g1CardQueueIndexOffset = getConstant("G1ThreadLocalData::dirty_card_queue_index_offset", Integer.class);
+ g1CardQueueBufferOffset = getConstant("G1ThreadLocalData::dirty_card_queue_buffer_offset", Integer.class);
+ }
+ }
public final int klassOffset = getFieldValue("java_lang_Class::_klass_offset", Integer.class, "int");
public final int arrayKlassOffset = getFieldValue("java_lang_Class::_array_klass_offset", Integer.class, "int");
@@ -546,8 +638,16 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
public final int basicLockSize = getFieldValue("CompilerToVM::Data::sizeof_BasicLock", Integer.class, "int");
public final int basicLockDisplacedHeaderOffset = getFieldOffset("BasicLock::_displaced_header", Integer.class, markWord);
- public final int threadPollingPageOffset = getFieldOffset("Thread::_polling_page", Integer.class, "volatile void*", -1);
public final int threadAllocatedBytesOffset = getFieldOffset("Thread::_allocated_bytes", Integer.class, "jlong");
+ public final int threadPollingPageOffset;
+ {
+ // JDK-8237497
+ if (JDK < 15) {
+ threadPollingPageOffset = getFieldOffset("Thread::_polling_page", Integer.class, "address", -1, JDK >= 10);
+ } else {
+ threadPollingPageOffset = getFieldOffset("Thread::_polling_page", Integer.class, "volatile void*");
+ }
+ }
public final int tlabRefillWasteIncrement = getFlag("TLABWasteIncrement", Integer.class);
@@ -605,24 +705,25 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
// ARMv8-A architecture reference manual D12.2.35 Data Cache Zero ID register says:
// * BS, bits [3:0] indicate log2 of the DC ZVA block size in (4-byte) words.
// * DZP, bit [4] of indicates whether use of DC ZVA instruction is prohibited.
- public final int psrInfoDczidValue = getFieldValue("VM_Version::_psr_info.dczid_el0", Integer.class, "uint32_t", 0x10);
+ public final int psrInfoDczidValue = getFieldValue("VM_Version::_psr_info.dczid_el0", Integer.class, "uint32_t", 0x10, (JVMCI ? jvmciGE(JVMCI_19_3_b04) : JDK >= 14) && osArch.equals("aarch64"));
// FIXME This is only temporary until the GC code is changed.
public final boolean inlineContiguousAllocationSupported = getFieldValue("CompilerToVM::Data::_supports_inline_contig_alloc", Boolean.class);
public final long heapEndAddress = getFieldValue("CompilerToVM::Data::_heap_end_addr", Long.class, "HeapWord**");
- public final long heapTopAddress = versioned.heapTopAddress;
+ public final long heapTopAddress = getFieldValue("CompilerToVM::Data::_heap_top_addr", Long.class, JDK <= 8 ? "HeapWord**" : "HeapWord* volatile*");
- public final boolean cmsIncrementalMode = getFlag("CMSIncrementalMode", Boolean.class, false);
+ public final boolean cmsIncrementalMode = getFlag("CMSIncrementalMode", Boolean.class, false, JDK <= 8);
public final long inlineCacheMissStub = getFieldValue("CompilerToVM::Data::SharedRuntime_ic_miss_stub", Long.class, "address");
public final long handleWrongMethodStub = getFieldValue("CompilerToVM::Data::SharedRuntime_handle_wrong_method_stub", Long.class, "address");
public final long deoptBlobUnpack = getFieldValue("CompilerToVM::Data::SharedRuntime_deopt_blob_unpack", Long.class, "address");
- public final long deoptBlobUnpackWithExceptionInTLS = getFieldValue("CompilerToVM::Data::SharedRuntime_deopt_blob_unpack_with_exception_in_tls", Long.class, "address", 0L);
+ public final long deoptBlobUnpackWithExceptionInTLS = getFieldValue("CompilerToVM::Data::SharedRuntime_deopt_blob_unpack_with_exception_in_tls", Long.class, "address", 0L,
+ JVMCI ? jvmciGE(JVMCI_19_3_b07) : JDK >= 14);
public final long deoptBlobUncommonTrap = getFieldValue("CompilerToVM::Data::SharedRuntime_deopt_blob_uncommon_trap", Long.class, "address");
- public final long codeCacheLowBound = versioned.codeCacheLowBound;
- public final long codeCacheHighBound = versioned.codeCacheHighBound;
+ public final long codeCacheLowBound = getFieldValue(JDK == 8 ? "CompilerToVM::Data::CodeCache_low_bound" : "CodeCache::_low_bound", Long.class, "address");
+ public final long codeCacheHighBound = getFieldValue(JDK == 8 ? "CompilerToVM::Data::CodeCache_high_bound" : "CodeCache::_high_bound", Long.class, "address");
public final long aescryptEncryptBlockStub = getFieldValue("StubRoutines::_aescrypt_encryptBlock", Long.class, "address");
public final long aescryptDecryptBlockStub = getFieldValue("StubRoutines::_aescrypt_decryptBlock", Long.class, "address");
@@ -631,27 +732,27 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
public final long updateBytesCRC32Stub = getFieldValue("StubRoutines::_updateBytesCRC32", Long.class, "address");
public final long crcTableAddress = getFieldValue("StubRoutines::_crc_table_adr", Long.class, "address");
- public final long sha1ImplCompress = getFieldValue("StubRoutines::_sha1_implCompress", Long.class, "address", 0L);
- public final long sha1ImplCompressMultiBlock = getFieldValue("StubRoutines::_sha1_implCompressMB", Long.class, "address", 0L);
- public final long sha256ImplCompress = getFieldValue("StubRoutines::_sha256_implCompress", Long.class, "address", 0L);
- public final long sha256ImplCompressMultiBlock = getFieldValue("StubRoutines::_sha256_implCompressMB", Long.class, "address", 0L);
- public final long sha512ImplCompress = getFieldValue("StubRoutines::_sha512_implCompress", Long.class, "address", 0L);
- public final long sha512ImplCompressMultiBlock = getFieldValue("StubRoutines::_sha512_implCompressMB", Long.class, "address", 0L);
- public final long multiplyToLen = getFieldValue("StubRoutines::_multiplyToLen", Long.class, "address", longRequiredOnAMD64);
+ public final long sha1ImplCompress = getFieldValue("StubRoutines::_sha1_implCompress", Long.class, "address");
+ public final long sha1ImplCompressMultiBlock = getFieldValue("StubRoutines::_sha1_implCompressMB", Long.class, "address");
+ public final long sha256ImplCompress = getFieldValue("StubRoutines::_sha256_implCompress", Long.class, "address");
+ public final long sha256ImplCompressMultiBlock = getFieldValue("StubRoutines::_sha256_implCompressMB", Long.class, "address");
+ public final long sha512ImplCompress = getFieldValue("StubRoutines::_sha512_implCompress", Long.class, "address");
+ public final long sha512ImplCompressMultiBlock = getFieldValue("StubRoutines::_sha512_implCompressMB", Long.class, "address");
+ public final long multiplyToLen = getFieldValue("StubRoutines::_multiplyToLen", Long.class, "address");
- public final long counterModeAESCrypt = getFieldValue("StubRoutines::_counterMode_AESCrypt", Long.class, "address", 0L);
- public final long ghashProcessBlocks = getFieldValue("StubRoutines::_ghash_processBlocks", Long.class, "address", 0L);
- public final long base64EncodeBlock = getFieldValue("StubRoutines::_base64_encodeBlock", Long.class, "address", 0L);
- public final long crc32cTableTddr = getFieldValue("StubRoutines::_crc32c_table_addr", Long.class, "address", 0L);
- public final long updateBytesCRC32C = getFieldValue("StubRoutines::_updateBytesCRC32C", Long.class, "address", 0L);
- public final long updateBytesAdler32 = getFieldValue("StubRoutines::_updateBytesAdler32", Long.class, "address", 0L);
- public final long squareToLen = getFieldValue("StubRoutines::_squareToLen", Long.class, "address", longRequiredOnAMD64);
- public final long mulAdd = getFieldValue("StubRoutines::_mulAdd", Long.class, "address", longRequiredOnAMD64);
- public final long montgomeryMultiply = getFieldValue("StubRoutines::_montgomeryMultiply", Long.class, "address", longRequiredOnAMD64);
- public final long montgomerySquare = getFieldValue("StubRoutines::_montgomerySquare", Long.class, "address", longRequiredOnAMD64);
- public final long vectorizedMismatch = getFieldValue("StubRoutines::_vectorizedMismatch", Long.class, "address", 0L);
+ public final long counterModeAESCrypt = getFieldValue("StubRoutines::_counterMode_AESCrypt", Long.class, "address", 0L, (JDK == 8 && !IS_OPENJDK) || JDK >= 9);
+ public final long ghashProcessBlocks = getFieldValue("StubRoutines::_ghash_processBlocks", Long.class, "address", 0L, isJDK8OrJDK11Plus);
+ public final long base64EncodeBlock = getFieldValue("StubRoutines::_base64_encodeBlock", Long.class, "address", 0L, isJDK11Plus);
+ public final long crc32cTableTddr = getFieldValue("StubRoutines::_crc32c_table_addr", Long.class, "address", 0L, isJDK11Plus);
+ public final long updateBytesCRC32C = getFieldValue("StubRoutines::_updateBytesCRC32C", Long.class, "address", 0L, isJDK11Plus);
+ public final long updateBytesAdler32 = getFieldValue("StubRoutines::_updateBytesAdler32", Long.class, "address", 0L, isJDK11Plus);
+ public final long squareToLen = getFieldValue("StubRoutines::_squareToLen", Long.class, "address");
+ public final long mulAdd = getFieldValue("StubRoutines::_mulAdd", Long.class, "address");
+ public final long montgomeryMultiply = getFieldValue("StubRoutines::_montgomeryMultiply", Long.class, "address");
+ public final long montgomerySquare = getFieldValue("StubRoutines::_montgomerySquare", Long.class, "address");
+ public final long vectorizedMismatch = getFieldValue("StubRoutines::_vectorizedMismatch", Long.class, "address", 0L, isJDK11Plus);
- public final long throwDelayedStackOverflowErrorEntry = versioned.throwDelayedStackOverflowErrorEntry;
+ public final long throwDelayedStackOverflowErrorEntry = JDK <= 8 ? 0 : getFieldValue("StubRoutines::_throw_delayed_StackOverflowError_entry", Long.class, "address");
public final long jbyteArraycopy = getFieldValue("StubRoutines::_jbyte_arraycopy", Long.class, "address");
public final long jshortArraycopy = getFieldValue("StubRoutines::_jshort_arraycopy", Long.class, "address");
@@ -689,10 +790,10 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
public final long dynamicNewInstanceAddress = getAddress("JVMCIRuntime::dynamic_new_instance");
// Allocation stubs that return null when allocation fails
- public final long newInstanceOrNullAddress = getAddress("JVMCIRuntime::new_instance_or_null", 0L);
- public final long newArrayOrNullAddress = getAddress("JVMCIRuntime::new_array_or_null", 0L);
- public final long newMultiArrayOrNullAddress = getAddress("JVMCIRuntime::new_multi_array_or_null", 0L);
- public final long dynamicNewInstanceOrNullAddress = getAddress("JVMCIRuntime::dynamic_new_instance_or_null", 0L);
+ public final long newInstanceOrNullAddress = getAddress("JVMCIRuntime::new_instance_or_null", 0L, JVMCI || JDK >= 12 || (!IS_OPENJDK && JDK == 11 && JDK_UPDATE >= 7));
+ public final long newArrayOrNullAddress = getAddress("JVMCIRuntime::new_array_or_null", 0L, JVMCI || JDK >= 12 || (!IS_OPENJDK && JDK == 11 && JDK_UPDATE >= 7));
+ public final long newMultiArrayOrNullAddress = getAddress("JVMCIRuntime::new_multi_array_or_null", 0L, JVMCI || JDK >= 12 || (!IS_OPENJDK && JDK == 11 && JDK_UPDATE >= 7));
+ public final long dynamicNewInstanceOrNullAddress = getAddress("JVMCIRuntime::dynamic_new_instance_or_null", 0L, JVMCI || JDK >= 12 || (!IS_OPENJDK && JDK == 11 && JDK_UPDATE >= 7));
public boolean areNullAllocationStubsAvailable() {
return newInstanceOrNullAddress != 0L;
@@ -719,8 +820,8 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
public final long exceptionHandlerForPcAddress = getAddress("JVMCIRuntime::exception_handler_for_pc");
public final long monitorenterAddress = getAddress("JVMCIRuntime::monitorenter");
public final long monitorexitAddress = getAddress("JVMCIRuntime::monitorexit");
- public final long notifyAddress = getAddress("JVMCIRuntime::object_notify", 0L);
- public final long notifyAllAddress = getAddress("JVMCIRuntime::object_notifyAll", 0L);
+ public final long notifyAddress = getAddress("JVMCIRuntime::object_notify", 0L, JDK >= 11);
+ public final long notifyAllAddress = getAddress("JVMCIRuntime::object_notifyAll", 0L, JDK >= 11);
public final long throwAndPostJvmtiExceptionAddress = getAddress("JVMCIRuntime::throw_and_post_jvmti_exception");
public final long throwKlassExternalNameExceptionAddress = getAddress("JVMCIRuntime::throw_klass_external_name_exception");
public final long throwClassCastExceptionAddress = getAddress("JVMCIRuntime::throw_class_cast_exception");
@@ -738,7 +839,7 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
public final long registerFinalizerAddress = getAddress("SharedRuntime::register_finalizer");
public final long exceptionHandlerForReturnAddressAddress = getAddress("SharedRuntime::exception_handler_for_return_address");
public final long osrMigrationEndAddress = getAddress("SharedRuntime::OSR_migration_end");
- public final long enableStackReservedZoneAddress = versioned.enableStackReservedZoneAddress;
+ public final long enableStackReservedZoneAddress = JDK <= 8 ? 0 : getAddress("SharedRuntime::enable_stack_reserved_zone");
public final long javaTimeMillisAddress = getAddress("os::javaTimeMillis");
public final long javaTimeNanosAddress = getAddress("os::javaTimeNanos");
@@ -773,39 +874,43 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
public final int deoptimizationUnrollBlockFramePcsOffset = getFieldOffset("Deoptimization::UnrollBlock::_frame_pcs", Integer.class, "address*");
public final int deoptimizationUnrollBlockInitialInfoOffset = getFieldOffset("Deoptimization::UnrollBlock::_initial_info", Integer.class, "intptr_t");
- public final boolean deoptimizationSupportLargeAccessByteArrayVirtualization = getConstant("Deoptimization::_support_large_access_byte_array_virtualization", Boolean.class, false);
+ // JDK-8231756, GR-16685
+ public final boolean deoptimizationSupportLargeAccessByteArrayVirtualization = //
+ getConstant("Deoptimization::_support_large_access_byte_array_virtualization", Boolean.class, false, JVMCI || JDK >= 15);
+
+ private static final boolean JDK_8245443 = ((JDK == 11 && JDK_UPDATE >= 8) || JDK >= 15);
// Checkstyle: stop
- public final int MARKID_VERIFIED_ENTRY = getConstant("CodeInstaller::VERIFIED_ENTRY", Integer.class);
- public final int MARKID_UNVERIFIED_ENTRY = getConstant("CodeInstaller::UNVERIFIED_ENTRY", Integer.class);
- public final int MARKID_OSR_ENTRY = getConstant("CodeInstaller::OSR_ENTRY", Integer.class);
- public final int MARKID_EXCEPTION_HANDLER_ENTRY = getConstant("CodeInstaller::EXCEPTION_HANDLER_ENTRY", Integer.class);
- public final int MARKID_DEOPT_HANDLER_ENTRY = getConstant("CodeInstaller::DEOPT_HANDLER_ENTRY", Integer.class);
- public final int MARKID_INVOKEINTERFACE = getConstant("CodeInstaller::INVOKEINTERFACE", Integer.class);
- public final int MARKID_INVOKEVIRTUAL = getConstant("CodeInstaller::INVOKEVIRTUAL", Integer.class);
- public final int MARKID_INVOKESTATIC = getConstant("CodeInstaller::INVOKESTATIC", Integer.class);
- public final int MARKID_INVOKESPECIAL = getConstant("CodeInstaller::INVOKESPECIAL", Integer.class);
- public final int MARKID_INLINE_INVOKE = getConstant("CodeInstaller::INLINE_INVOKE", Integer.class);
- public final int MARKID_POLL_NEAR = getConstant("CodeInstaller::POLL_NEAR", Integer.class);
- public final int MARKID_POLL_RETURN_NEAR = getConstant("CodeInstaller::POLL_RETURN_NEAR", Integer.class);
- public final int MARKID_POLL_FAR = getConstant("CodeInstaller::POLL_FAR", Integer.class);
- public final int MARKID_POLL_RETURN_FAR = getConstant("CodeInstaller::POLL_RETURN_FAR", Integer.class);
- public final int MARKID_CARD_TABLE_SHIFT = getConstant("CodeInstaller::CARD_TABLE_SHIFT", Integer.class);
- public final int MARKID_CARD_TABLE_ADDRESS = getConstant("CodeInstaller::CARD_TABLE_ADDRESS", Integer.class);
- public final int MARKID_INVOKE_INVALID = getConstant("CodeInstaller::INVOKE_INVALID", Integer.class);
+ public final int VERIFIED_ENTRY = getConstant("CodeInstaller::VERIFIED_ENTRY", Integer.class);
+ public final int UNVERIFIED_ENTRY = getConstant("CodeInstaller::UNVERIFIED_ENTRY", Integer.class);
+ public final int OSR_ENTRY = getConstant("CodeInstaller::OSR_ENTRY", Integer.class);
+ public final int EXCEPTION_HANDLER_ENTRY = getConstant("CodeInstaller::EXCEPTION_HANDLER_ENTRY", Integer.class);
+ public final int DEOPT_HANDLER_ENTRY = getConstant("CodeInstaller::DEOPT_HANDLER_ENTRY", Integer.class);
+ public final int FRAME_COMPLETE = getConstant("CodeInstaller::FRAME_COMPLETE", Integer.class, -1, (JVMCI ? jvmciGE(JVMCI_20_1_b01) : JDK_8245443));
+ public final int INVOKEINTERFACE = getConstant("CodeInstaller::INVOKEINTERFACE", Integer.class);
+ public final int INVOKEVIRTUAL = getConstant("CodeInstaller::INVOKEVIRTUAL", Integer.class);
+ public final int INVOKESTATIC = getConstant("CodeInstaller::INVOKESTATIC", Integer.class);
+ public final int INVOKESPECIAL = getConstant("CodeInstaller::INVOKESPECIAL", Integer.class);
+ public final int INLINE_INVOKE = getConstant("CodeInstaller::INLINE_INVOKE", Integer.class);
+ public final int POLL_NEAR = getConstant("CodeInstaller::POLL_NEAR", Integer.class);
+ public final int POLL_RETURN_NEAR = getConstant("CodeInstaller::POLL_RETURN_NEAR", Integer.class);
+ public final int POLL_FAR = getConstant("CodeInstaller::POLL_FAR", Integer.class);
+ public final int POLL_RETURN_FAR = getConstant("CodeInstaller::POLL_RETURN_FAR", Integer.class);
+ public final int CARD_TABLE_SHIFT = getConstant("CodeInstaller::CARD_TABLE_SHIFT", Integer.class);
+ public final int CARD_TABLE_ADDRESS = getConstant("CodeInstaller::CARD_TABLE_ADDRESS", Integer.class);
+ public final int INVOKE_INVALID = getConstant("CodeInstaller::INVOKE_INVALID", Integer.class);
+
+ public final boolean CPU_HAS_INTEL_JCC_ERRATUM = getFieldValue("VM_Version::_has_intel_jcc_erratum", Boolean.class, "bool",
+ true, "amd64".equals(osArch) && (JVMCI ? jvmciGE(JVMCI_20_1_b01) : JDK >= 15));
/**
* The following constants are given default values here since they are missing in the native
- * JVMCI-8 code but are still required for {@link GraalHotSpotVMConfigNode#canonical} to work in
- * a JDK8 environment.
+ * JVMCI-8 code but are still required for {@link HotSpotMarkId} to work in a JDK8 environment.
*/
- public final int MARKID_HEAP_TOP_ADDRESS = getConstant("CodeInstaller::HEAP_TOP_ADDRESS", Integer.class, 17);
- public final int MARKID_HEAP_END_ADDRESS = getConstant("CodeInstaller::HEAP_END_ADDRESS", Integer.class, 18);
- public final int MARKID_NARROW_KLASS_BASE_ADDRESS = getConstant("CodeInstaller::NARROW_KLASS_BASE_ADDRESS", Integer.class, 19);
- public final int MARKID_NARROW_OOP_BASE_ADDRESS = getConstant("CodeInstaller::NARROW_OOP_BASE_ADDRESS", Integer.class, 20);
- public final int MARKID_CRC_TABLE_ADDRESS = getConstant("CodeInstaller::CRC_TABLE_ADDRESS", Integer.class, 21);
- public final int MARKID_LOG_OF_HEAP_REGION_GRAIN_BYTES = getConstant("CodeInstaller::LOG_OF_HEAP_REGION_GRAIN_BYTES", Integer.class, 22);
- public final int MARKID_INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED = getConstant("CodeInstaller::INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED", Integer.class, 23);
+ public final int NARROW_KLASS_BASE_ADDRESS = getConstant("CodeInstaller::NARROW_KLASS_BASE_ADDRESS", Integer.class, 19, JDK > 9);
+ public final int NARROW_OOP_BASE_ADDRESS = getConstant("CodeInstaller::NARROW_OOP_BASE_ADDRESS", Integer.class, 20, JDK > 9);
+ public final int CRC_TABLE_ADDRESS = getConstant("CodeInstaller::CRC_TABLE_ADDRESS", Integer.class, 21, JDK > 9);
+ public final int LOG_OF_HEAP_REGION_GRAIN_BYTES = getConstant("CodeInstaller::LOG_OF_HEAP_REGION_GRAIN_BYTES", Integer.class, 22, JDK > 9);
// Checkstyle: resume
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigAccess.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigAccess.java
new file mode 100644
index 00000000000..a247d7c79eb
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigAccess.java
@@ -0,0 +1,406 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.hotspot;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.graalvm.compiler.debug.Assertions;
+import org.graalvm.compiler.hotspot.JVMCIVersionCheck.Version;
+import org.graalvm.compiler.hotspot.JVMCIVersionCheck.Version2;
+import org.graalvm.compiler.hotspot.JVMCIVersionCheck.Version3;
+import org.graalvm.compiler.serviceprovider.GraalServices;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
+
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.hotspot.HotSpotVMConfigAccess;
+import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
+import jdk.vm.ci.hotspot.VMField;
+import jdk.vm.ci.services.Services;
+
+/**
+ * Interposes on {@link HotSpotVMConfigAccess} to {@linkplain #isPresent check} when retrieving VM
+ * configuration values that they are only present in the VM iff expected to be.
+ */
+public class GraalHotSpotVMConfigAccess {
+
+ protected final HotSpotVMConfigAccess access;
+ private final Map vmAddresses;
+ private final Map vmConstants;
+ private final Map vmFields;
+
+ GraalHotSpotVMConfigAccess(HotSpotVMConfigStore store) {
+ this.access = new HotSpotVMConfigAccess(store);
+ this.vmAddresses = store.getAddresses();
+ this.vmConstants = store.getConstants();
+ this.vmFields = store.getFields();
+
+ String value = getProperty("os.name");
+ switch (value) {
+ case "Linux":
+ value = "linux";
+ break;
+ case "SunOS":
+ value = "solaris";
+ break;
+ case "Mac OS X":
+ value = "darwin";
+ break;
+ default:
+ // Of course Windows is different...
+ if (value.startsWith("Windows")) {
+ value = "windows";
+ } else {
+ throw new JVMCIError("Unexpected OS name: " + value);
+ }
+ }
+ assert KNOWN_OS_NAMES.contains(value);
+ this.osName = value;
+
+ String arch = getProperty("os.arch");
+ switch (arch) {
+ case "x86_64":
+ arch = "amd64";
+ break;
+ case "sparcv9":
+ arch = "sparc";
+ break;
+ }
+ osArch = arch;
+ assert KNOWN_ARCHITECTURES.contains(arch) : arch;
+ }
+
+ public HotSpotVMConfigStore getStore() {
+ return access.getStore();
+ }
+
+ protected static String getProperty(String name, String def) {
+ String value = Services.getSavedProperties().get(name);
+ if (value == null) {
+ return def;
+ }
+ return value;
+ }
+
+ protected static String getProperty(String name) {
+ return getProperty(name, null);
+ }
+
+ public static final Set KNOWN_ARCHITECTURES = new HashSet<>(Arrays.asList("amd64", "sparc", "aarch64"));
+ public static final Set KNOWN_OS_NAMES = new HashSet<>(Arrays.asList("windows", "linux", "darwin", "solaris"));
+
+ /**
+ * Name for current OS. Will be a value in {@value #KNOWN_OS_NAMES}.
+ */
+ public final String osName;
+
+ /**
+ * Name for current CPU architecture. Will be a value in {@value #KNOWN_ARCHITECTURES}.
+ */
+ public final String osArch;
+
+ protected static final Version JVMCI_0_55 = new Version2(0, 55);
+ protected static final Version JVMCI_20_1_b01 = new Version3(20, 1, 1);
+ protected static final Version JVMCI_20_0_b03 = new Version3(20, 0, 3);
+ protected static final Version JVMCI_19_3_b03 = new Version3(19, 3, 3);
+ protected static final Version JVMCI_19_3_b04 = new Version3(19, 3, 4);
+ protected static final Version JVMCI_19_3_b07 = new Version3(19, 3, 7);
+
+ public static boolean jvmciGE(Version v) {
+ return JVMCI_PRERELEASE || !JVMCI_VERSION.isLessThan(v);
+ }
+
+ public static final int JDK = JavaVersionUtil.JAVA_SPEC;
+ public static final int JDK_UPDATE = GraalServices.getJavaUpdateVersion();
+ public static final boolean IS_OPENJDK = getProperty("java.vm.name", "").startsWith("OpenJDK");
+ public static final Version JVMCI_VERSION;
+ public static final boolean JVMCI;
+ public static final boolean JVMCI_PRERELEASE;
+ static {
+ String vmVersion = getProperty("java.vm.version");
+ JVMCI_VERSION = Version.parse(vmVersion);
+ JVMCI_PRERELEASE = vmVersion.contains("SNAPSHOT") || vmVersion.contains("internal") || vmVersion.contains("-dev");
+ JVMCI = JVMCI_VERSION != null || JVMCI_PRERELEASE;
+ }
+
+ private final List missing = new ArrayList<>();
+ private final List unexpected = new ArrayList<>();
+
+ /**
+ * Records an error if {@code map.contains(name) != expectPresent}. That is, it's an error if
+ * {@code value} is unexpectedly present in the VM or is unexpectedly absent from the VM.
+ *
+ * @param expectPresent the expectation that the value is present in the VM
+ */
+ private boolean isPresent(String name, Map map, boolean expectPresent) {
+ if (map.containsKey(name)) {
+ if (!expectPresent) {
+ recordError(name, unexpected, String.valueOf(map.get(name)));
+ }
+ return true;
+ }
+ if (expectPresent) {
+ recordError(name, missing, null);
+ }
+
+ return false;
+ }
+
+ // Only defer errors while in the GraalHotSpotVMConfig
+ // constructor until reportErrors() is called.
+ private boolean deferErrors = this instanceof GraalHotSpotVMConfig;
+
+ private void recordError(String name, List list, String unexpectedValue) {
+ if (JVMCI_PRERELEASE) {
+ return;
+ }
+ String message = name;
+ if (deferErrors) {
+ StackTraceElement[] trace = new Exception().getStackTrace();
+ for (StackTraceElement e : trace) {
+ if (e.getClassName().equals(GraalHotSpotVMConfigAccess.class.getName())) {
+ // Skip methods in GraalHotSpotVMConfigAccess
+ continue;
+ }
+ // Looking for the field assignment in a constructor
+ if (e.getMethodName().equals("")) {
+ message += " at " + e;
+ break;
+ }
+ }
+ }
+ if (unexpectedValue != null) {
+ message += " [value: " + unexpectedValue + "]";
+ }
+ list.add(message);
+ if (!deferErrors) {
+ reportErrors();
+ }
+ }
+
+ protected void reportErrors() {
+ deferErrors = false;
+ if (!missing.isEmpty() || !unexpected.isEmpty()) {
+ String jvmci = JVMCI_VERSION == null ? "" : " jvmci-" + JVMCI_VERSION;
+ String runtime = String.format("JDK %d%s %s-%s (java.home=%s, java.vm.name=%s, java.vm.version=%s)",
+ JDK, jvmci, osName, osArch,
+ getProperty("java.home"),
+ getProperty("java.vm.name"),
+ getProperty("java.vm.version"));
+ List messages = new ArrayList<>();
+ if (!missing.isEmpty()) {
+ messages.add(String.format("VM config values missing that should be present in %s:%n %s", runtime,
+ missing.stream().sorted().collect(Collectors.joining(System.lineSeparator() + " "))));
+ }
+ if (!unexpected.isEmpty()) {
+ messages.add(String.format("VM config values not expected to be present in %s:%n %s", runtime,
+ unexpected.stream().sorted().collect(Collectors.joining(System.lineSeparator() + " "))));
+ }
+ throw new JVMCIError(String.join(System.lineSeparator(), messages));
+ }
+ }
+
+ /**
+ * @see HotSpotVMConfigAccess#getAddress(String, Long)
+ */
+ public long getAddress(String name, Long notPresent, boolean expectPresent) {
+ if (isPresent(name, vmAddresses, expectPresent)) {
+ return access.getAddress(name, notPresent);
+ }
+ return notPresent;
+ }
+
+ /**
+ * @see HotSpotVMConfigAccess#getAddress(String)
+ */
+ public long getAddress(String name) {
+ if (isPresent(name, vmAddresses, true)) {
+ return access.getAddress(name, 0L);
+ }
+ return 0L;
+ }
+
+ /**
+ * @see HotSpotVMConfigAccess#getConstant(String, Class, Object)
+ */
+ public T getConstant(String name, Class type, T notPresent, boolean expectPresent) {
+ if (isPresent(name, vmConstants, expectPresent)) {
+ return access.getConstant(name, type, notPresent);
+ }
+ return notPresent;
+ }
+
+ /**
+ * @see HotSpotVMConfigAccess#getConstant(String, Class)
+ */
+ public T getConstant(String name, Class type) {
+ if (isPresent(name, vmConstants, true)) {
+ return access.getConstant(name, type);
+ }
+ return getDefault(type);
+ }
+
+ /**
+ * @see HotSpotVMConfigAccess#getFieldOffset(String, Class, String, Object)
+ */
+ public T getFieldOffset(String name, Class type, String cppType, T notPresent, boolean expectPresent) {
+ if (isPresent(name, vmFields, expectPresent)) {
+ return access.getFieldOffset(name, type, cppType, notPresent);
+ }
+ return notPresent;
+ }
+
+ /**
+ * @see HotSpotVMConfigAccess#getFieldOffset(String, Class, String)
+ */
+ public T getFieldOffset(String name, Class type, String cppType) {
+ if (isPresent(name, vmFields, true)) {
+ return access.getFieldOffset(name, type, cppType);
+ }
+ return getDefault(type);
+ }
+
+ /**
+ * @see HotSpotVMConfigAccess#getFieldOffset(String, Class)
+ */
+ public T getFieldOffset(String name, Class type) {
+ if (isPresent(name, vmFields, true)) {
+ return access.getFieldOffset(name, type);
+ }
+ return getDefault(type);
+ }
+
+ /**
+ * @see HotSpotVMConfigAccess#getFieldAddress(String, String)
+ */
+ public long getFieldAddress(String name, String cppType) {
+ if (isPresent(name, vmFields, true)) {
+ return access.getFieldAddress(name, cppType);
+ }
+ return 0L;
+ }
+
+ /**
+ * @see HotSpotVMConfigAccess#getFieldValue(String, Class, String, Object)
+ */
+ public T getFieldValue(String name, Class type, String cppType, T notPresent, boolean expectPresent) {
+ if (isPresent(name, vmFields, expectPresent)) {
+ return access.getFieldValue(name, type, cppType, notPresent);
+ }
+ return notPresent;
+ }
+
+ /**
+ * @see HotSpotVMConfigAccess#getFieldValue(String, Class, String)
+ */
+ public T getFieldValue(String name, Class type, String cppType) {
+ if (isPresent(name, vmFields, true)) {
+ return access.getFieldValue(name, type, cppType);
+ }
+ return getDefault(type);
+ }
+
+ /**
+ * @see HotSpotVMConfigAccess#getFieldValue(String, Class)
+ */
+ public T getFieldValue(String name, Class type) {
+ if (isPresent(name, vmFields, true)) {
+ return access.getFieldValue(name, type);
+ }
+ return getDefault(type);
+ }
+
+ /**
+ * @see HotSpotVMConfigAccess#getFlag(String, Class)
+ */
+ public T getFlag(String name, Class type) {
+ try {
+ return access.getFlag(name, type);
+ } catch (JVMCIError e) {
+ recordError(name, missing, null);
+ return getDefault(type);
+ }
+ }
+
+ /**
+ * @see HotSpotVMConfigAccess#getFlag(String, Class, Object)
+ */
+ @SuppressWarnings("deprecation")
+ public T getFlag(String name, Class type, T notPresent, boolean expectPresent) {
+ if (expectPresent) {
+ return getFlag(name, type);
+ }
+ if (Assertions.assertionsEnabled()) {
+ // There's more overhead for checking unexpectedly
+ // present flag values due to the fact that a VM call
+ // not exposed by JVMCI is needed to determine whether
+ // a flag value is available. As such, only pay the
+ // overhead when running with assertions enabled.
+ T sentinel;
+ if (type == Boolean.class) {
+ sentinel = type.cast(new Boolean(false));
+ } else if (type == Byte.class) {
+ sentinel = type.cast(new Byte((byte) 123));
+ } else if (type == Integer.class) {
+ sentinel = type.cast(new Integer(1234567890));
+ } else if (type == Long.class) {
+ sentinel = type.cast(new Long(1234567890987654321L));
+ } else if (type == String.class) {
+ sentinel = type.cast(new String("1234567890987654321"));
+ } else {
+ throw new JVMCIError("Unsupported flag type: " + type.getName());
+ }
+ T value = access.getFlag(name, type, sentinel);
+ if (value != sentinel) {
+ recordError(name, unexpected, String.valueOf(value));
+ }
+ }
+ return access.getFlag(name, type, notPresent);
+ }
+
+ private static T getDefault(Class type) {
+ if (type == Boolean.class) {
+ return type.cast(Boolean.FALSE);
+ }
+ if (type == Byte.class) {
+ return type.cast(Byte.valueOf((byte) 0));
+ }
+ if (type == Integer.class) {
+ return type.cast(Integer.valueOf(0));
+ }
+ if (type == Long.class) {
+ return type.cast(Long.valueOf(0));
+ }
+ if (type == String.class) {
+ return type.cast(null);
+ }
+ throw new JVMCIError("Unsupported VM config value type: " + type.getName());
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigBase.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigBase.java
deleted file mode 100644
index 6ed2d6b5df0..00000000000
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigBase.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.hotspot;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-
-import org.graalvm.compiler.api.replacements.Fold;
-import org.graalvm.compiler.api.replacements.Fold.InjectedParameter;
-import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext;
-import org.graalvm.compiler.options.OptionValues;
-
-import jdk.vm.ci.common.JVMCIError;
-import jdk.vm.ci.hotspot.HotSpotVMConfigAccess;
-import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
-import jdk.vm.ci.meta.MetaAccessProvider;
-import jdk.vm.ci.services.Services;
-
-/**
- * Base class of class hierarchy for accessing HotSpot VM configuration.
- */
-public abstract class GraalHotSpotVMConfigBase extends HotSpotVMConfigAccess {
-
- GraalHotSpotVMConfigBase(HotSpotVMConfigStore store) {
- super(store);
- assert this instanceof GraalHotSpotVMConfig;
- versioned = new GraalHotSpotVMConfigVersioned(store);
- assert checkVersioned();
- }
-
- private boolean checkVersioned() {
- Class extends GraalHotSpotVMConfigVersioned> c = versioned.getClass();
- for (Field field : c.getDeclaredFields()) {
- int modifiers = field.getModifiers();
- if (!Modifier.isStatic(modifiers)) {
- // javac inlines non-static final fields which means
- // versioned values are ignored in non-flattened Graal
- assert !Modifier.isFinal(modifiers) : "Non-static field in " + c.getName() + " must not be final: " + field.getName();
- }
- }
- return true;
- }
-
- private static String getProperty(String name, String def) {
- String value = Services.getSavedProperties().get(name);
- if (value == null) {
- return def;
- }
- return value;
- }
-
- private static String getProperty(String name) {
- return getProperty(name, null);
- }
-
- /**
- * Contains values that are different between JDK versions.
- */
- protected final GraalHotSpotVMConfigVersioned versioned;
-
- /**
- * Sentinel value to use for an {@linkplain InjectedParameter injected}
- * {@link GraalHotSpotVMConfig} parameter to a {@linkplain Fold foldable} method.
- */
- public static final GraalHotSpotVMConfig INJECTED_VMCONFIG = null;
- public static final MetaAccessProvider INJECTED_METAACCESS = null;
- public static final OptionValues INJECTED_OPTIONVALUES = null;
- public static final IntrinsicContext INJECTED_INTRINSIC_CONTEXT = null;
-
- public final String osName = getHostOSName();
- public final String osArch = getHostArchitectureName();
- public final boolean windowsOs = getProperty("os.name", "").startsWith("Windows");
- public final boolean linuxOs = getProperty("os.name", "").startsWith("Linux");
-
- /**
- * Gets the host operating system name.
- */
- private static String getHostOSName() {
- String osName = getProperty("os.name");
- switch (osName) {
- case "Linux":
- osName = "linux";
- break;
- case "Mac OS X":
- osName = "bsd";
- break;
- default:
- // Of course Windows is different...
- if (osName.startsWith("Windows")) {
- osName = "windows";
- } else {
- throw new JVMCIError("Unexpected OS name: " + osName);
- }
- }
- return osName;
- }
-
- private static String getHostArchitectureName() {
- String arch = getProperty("os.arch");
- switch (arch) {
- case "x86_64":
- arch = "amd64";
- break;
- }
- return arch;
- }
-
- protected final Integer intRequiredOnAMD64 = osArch.equals("amd64") ? null : 0;
- protected final Long longRequiredOnAMD64 = osArch.equals("amd64") ? null : 0L;
-}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigVersioned.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigVersioned.java
deleted file mode 100644
index 08e05884553..00000000000
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfigVersioned.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.hotspot;
-
-import jdk.vm.ci.hotspot.HotSpotVMConfigAccess;
-import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
-
-/**
- * This is a source with different versions for various JDKs. When modifying/adding a field in this
- * class accessed from outside this class, be sure to update the field appropriately in all source
- * files named {@code GraalHotSpotVMConfigVersioned.java}.
- *
- * Fields are grouped according to the most recent JBS issue showing why they are versioned.
- *
- * JDK Version: 15+
- */
-final class GraalHotSpotVMConfigVersioned extends HotSpotVMConfigAccess {
-
- GraalHotSpotVMConfigVersioned(HotSpotVMConfigStore store) {
- super(store);
- }
-
- // JDK-8210848
- boolean inlineNotify = true;
-
- // JDK-8073583
- boolean useCRC32CIntrinsics = getFlag("UseCRC32CIntrinsics", Boolean.class);
-
- // JDK-8046936
- int javaThreadReservedStackActivationOffset = getFieldOffset("JavaThread::_reserved_stack_activation", Integer.class, "address");
- int methodFlagsOffset = getFieldOffset("Method::_flags", Integer.class, "u2");
- long throwDelayedStackOverflowErrorEntry = getFieldValue("StubRoutines::_throw_delayed_StackOverflowError_entry", Long.class, "address");
- long enableStackReservedZoneAddress = getAddress("SharedRuntime::enable_stack_reserved_zone");
-
- // JDK-8135085
- int methodIntrinsicIdOffset = getFieldOffset("Method::_intrinsic_id", Integer.class, "u2");
-
- // JDK-8151956
- int methodCodeOffset = getFieldOffset("Method::_code", Integer.class, "CompiledMethod*");
-
- // JDK-8059606
- int invocationCounterIncrement = getConstant("InvocationCounter::count_increment", Integer.class);
- int invocationCounterShift = getConstant("InvocationCounter::count_shift", Integer.class);
-
- // JDK-8195142
- byte dirtyCardValue = getConstant("CardTable::dirty_card", Byte.class);
- byte g1YoungCardValue = getConstant("G1CardTable::g1_young_gen", Byte.class);
-
- // JDK-8201318
- int g1SATBQueueMarkingOffset = getConstant("G1ThreadLocalData::satb_mark_queue_active_offset", Integer.class);
- int g1SATBQueueIndexOffset = getConstant("G1ThreadLocalData::satb_mark_queue_index_offset", Integer.class);
- int g1SATBQueueBufferOffset = getConstant("G1ThreadLocalData::satb_mark_queue_buffer_offset", Integer.class);
- int g1CardQueueIndexOffset = getConstant("G1ThreadLocalData::dirty_card_queue_index_offset", Integer.class);
- int g1CardQueueBufferOffset = getConstant("G1ThreadLocalData::dirty_card_queue_buffer_offset", Integer.class);
-
- // JDK-8033552
- long heapTopAddress = getFieldValue("CompilerToVM::Data::_heap_top_addr", Long.class, "HeapWord* volatile*");
-
- // JDK-8015774
- long codeCacheLowBound = getFieldValue("CodeCache::_low_bound", Long.class, "address");
- long codeCacheHighBound = getFieldValue("CodeCache::_high_bound", Long.class, "address");
-
- // JDK-8229258
- String markWordClassName = "markWord";
- String markWordFieldType = "markWord";
-
- // JDK-8186777
- int classMirrorOffset = getFieldOffset("Klass::_java_mirror", Integer.class, "OopHandle");
- boolean classMirrorIsHandle = true;
-
- // JDK-8220049
- boolean threadLocalHandshakes = true;
-
- // JDK-8236224
- boolean compactFields = true;
- int fieldsAllocationStyle = 1;
-}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java
index 584660e8949..9a994a1f8b3 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,16 @@
package org.graalvm.compiler.hotspot;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Reexecutability.NOT_REEXECUTABLE;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Reexecutability.REEXECUTABLE;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Transition.LEAF;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Transition.LEAF_NO_VZERO;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Transition.SAFEPOINT;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl.NO_LOCATIONS;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_END_LOCATION;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_TOP_LOCATION;
import static org.graalvm.compiler.replacements.arraycopy.ArrayCopyForeignCalls.UNSAFE_ARRAYCOPY;
+import static jdk.internal.vm.compiler.word.LocationIdentity.any;
import java.util.EnumSet;
@@ -37,9 +46,11 @@ import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
+import org.graalvm.compiler.core.common.spi.ForeignCallSignature;
import org.graalvm.compiler.core.target.Backend;
import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
import org.graalvm.compiler.graph.Node.NodeIntrinsic;
+import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.hotspot.nodes.VMErrorNode;
import org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantStubCall;
@@ -66,6 +77,7 @@ import org.graalvm.compiler.lir.StandardOp.SaveRegistersOp;
import org.graalvm.compiler.lir.ValueConsumer;
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
import org.graalvm.compiler.lir.framemap.FrameMap;
+import org.graalvm.compiler.nodes.NamedLocationIdentity;
import org.graalvm.compiler.nodes.UnwindNode;
import org.graalvm.compiler.nodes.extended.ForeignCallNode;
import org.graalvm.compiler.options.Option;
@@ -75,6 +87,7 @@ import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.tiers.SuitesProvider;
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
import org.graalvm.compiler.word.Word;
+import jdk.internal.vm.compiler.word.LocationIdentity;
import jdk.internal.vm.compiler.word.Pointer;
import jdk.vm.ci.code.CallingConvention;
@@ -87,6 +100,7 @@ import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.Value;
import jdk.vm.ci.runtime.JVMCICompiler;
@@ -108,70 +122,80 @@ public abstract class HotSpotBackend extends Backend implements FrameMap.Referen
/**
* Descriptor for {@link ExceptionHandlerStub}. This stub is called by the
- * {@linkplain GraalHotSpotVMConfig#MARKID_EXCEPTION_HANDLER_ENTRY exception handler} in a
- * compiled method.
+ * {@linkplain HotSpotMarkId#EXCEPTION_HANDLER_ENTRY exception handler} in a compiled method.
*/
- public static final ForeignCallDescriptor EXCEPTION_HANDLER = new ForeignCallDescriptor("exceptionHandler", void.class, Object.class, Word.class);
+ public static final HotSpotForeignCallDescriptor EXCEPTION_HANDLER = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, NOT_REEXECUTABLE, any(), "exceptionHandler", void.class, Object.class,
+ Word.class);
/**
* Descriptor for SharedRuntime::get_ic_miss_stub().
*/
- public static final ForeignCallDescriptor IC_MISS_HANDLER = new ForeignCallDescriptor("icMissHandler", void.class);
+ public static final HotSpotForeignCallDescriptor IC_MISS_HANDLER = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS, "icMissHandler", void.class);
/**
* Descriptor for SharedRuntime::get_handle_wrong_method_stub().
*/
- public static final ForeignCallDescriptor WRONG_METHOD_HANDLER = new ForeignCallDescriptor("wrongMethodHandler", void.class);
+ public static final HotSpotForeignCallDescriptor WRONG_METHOD_HANDLER = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS, "wrongMethodHandler", void.class);
/**
* Descriptor for {@link UnwindExceptionToCallerStub}. This stub is called by code generated
* from {@link UnwindNode}.
*/
- public static final ForeignCallDescriptor UNWIND_EXCEPTION_TO_CALLER = new ForeignCallDescriptor("unwindExceptionToCaller", void.class, Object.class, Word.class);
+ public static final HotSpotForeignCallDescriptor UNWIND_EXCEPTION_TO_CALLER = new HotSpotForeignCallDescriptor(SAFEPOINT, NOT_REEXECUTABLE, any(), "unwindExceptionToCaller", void.class,
+ Object.class, Word.class);
/**
* Descriptor for the arguments when unwinding to an exception handler in a caller.
*/
- public static final ForeignCallDescriptor EXCEPTION_HANDLER_IN_CALLER = new ForeignCallDescriptor("exceptionHandlerInCaller", void.class, Object.class, Word.class);
+ public static final HotSpotForeignCallDescriptor EXCEPTION_HANDLER_IN_CALLER = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, NOT_REEXECUTABLE, any(), "exceptionHandlerInCaller",
+ void.class, Object.class, Word.class);
private final HotSpotGraalRuntimeProvider runtime;
/**
* @see AESCryptSubstitutions#encryptBlockStub(ForeignCallDescriptor, Word, Word, Pointer)
*/
- public static final ForeignCallDescriptor ENCRYPT_BLOCK = new ForeignCallDescriptor("encrypt_block", void.class, Word.class, Word.class, Pointer.class);
+ public static final HotSpotForeignCallDescriptor ENCRYPT_BLOCK = new HotSpotForeignCallDescriptor(LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Byte), "encrypt_block",
+ void.class, Word.class, Word.class, Pointer.class);
/**
* @see AESCryptSubstitutions#decryptBlockStub(ForeignCallDescriptor, Word, Word, Pointer)
*/
- public static final ForeignCallDescriptor DECRYPT_BLOCK = new ForeignCallDescriptor("decrypt_block", void.class, Word.class, Word.class, Pointer.class);
+ public static final HotSpotForeignCallDescriptor DECRYPT_BLOCK = new HotSpotForeignCallDescriptor(LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Byte), "decrypt_block",
+ void.class, Word.class, Word.class, Pointer.class);
/**
* @see AESCryptSubstitutions#decryptBlockStub(ForeignCallDescriptor, Word, Word, Pointer)
*/
- public static final ForeignCallDescriptor DECRYPT_BLOCK_WITH_ORIGINAL_KEY = new ForeignCallDescriptor("decrypt_block_with_original_key", void.class, Word.class, Word.class, Pointer.class,
+ public static final HotSpotForeignCallDescriptor DECRYPT_BLOCK_WITH_ORIGINAL_KEY = new HotSpotForeignCallDescriptor(LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Byte),
+ "decrypt_block_with_original_key", void.class, Word.class, Word.class, Pointer.class,
Pointer.class);
/**
* @see CipherBlockChainingSubstitutions#crypt
*/
- public static final ForeignCallDescriptor ENCRYPT = new ForeignCallDescriptor("encrypt", void.class, Word.class, Word.class, Pointer.class, Pointer.class, int.class);
+ public static final HotSpotForeignCallDescriptor ENCRYPT = new HotSpotForeignCallDescriptor(LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Byte), "encrypt", void.class,
+ Word.class, Word.class, Pointer.class, Pointer.class, int.class);
/**
* @see CipherBlockChainingSubstitutions#crypt
*/
- public static final ForeignCallDescriptor DECRYPT = new ForeignCallDescriptor("decrypt", void.class, Word.class, Word.class, Pointer.class, Pointer.class, int.class);
+ public static final HotSpotForeignCallDescriptor DECRYPT = new HotSpotForeignCallDescriptor(LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Byte), "decrypt", void.class,
+ Word.class, Word.class, Pointer.class, Pointer.class, int.class);
/**
* @see CipherBlockChainingSubstitutions#crypt
*/
- public static final ForeignCallDescriptor DECRYPT_WITH_ORIGINAL_KEY = new ForeignCallDescriptor("decrypt_with_original_key", void.class, Word.class, Word.class, Pointer.class, Pointer.class,
+ public static final HotSpotForeignCallDescriptor DECRYPT_WITH_ORIGINAL_KEY = new HotSpotForeignCallDescriptor(LEAF, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Byte),
+ "decrypt_with_original_key", void.class, Word.class, Word.class, Pointer.class, Pointer.class,
int.class, Pointer.class);
/**
* @see BigIntegerSubstitutions#multiplyToLen
*/
- public static final ForeignCallDescriptor MULTIPLY_TO_LEN = new ForeignCallDescriptor("multiplyToLen", void.class, Word.class, int.class, Word.class, int.class, Word.class, int.class);
+ public static final HotSpotForeignCallDescriptor MULTIPLY_TO_LEN = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Int),
+ "multiplyToLen",
+ void.class, Word.class, int.class, Word.class, int.class, Word.class, int.class);
public static void multiplyToLenStub(Word xAddr, int xlen, Word yAddr, int ylen, Word zAddr, int zLen) {
multiplyToLenStub(HotSpotBackend.MULTIPLY_TO_LEN, xAddr, xlen, yAddr, ylen, zAddr, zLen);
@@ -183,7 +207,9 @@ public abstract class HotSpotBackend extends Backend implements FrameMap.Referen
/**
* @see BigIntegerSubstitutions#mulAdd
*/
- public static final ForeignCallDescriptor MUL_ADD = new ForeignCallDescriptor("mulAdd", int.class, Word.class, Word.class, int.class, int.class, int.class);
+ public static final HotSpotForeignCallDescriptor MUL_ADD = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Int), "mulAdd",
+ int.class,
+ Word.class, Word.class, int.class, int.class, int.class);
public static int mulAddStub(Word inAddr, Word outAddr, int newOffset, int len, int k) {
return mulAddStub(HotSpotBackend.MUL_ADD, inAddr, outAddr, newOffset, len, k);
@@ -195,7 +221,8 @@ public abstract class HotSpotBackend extends Backend implements FrameMap.Referen
/**
* @see BigIntegerSubstitutions#implMontgomeryMultiply
*/
- public static final ForeignCallDescriptor MONTGOMERY_MULTIPLY = new ForeignCallDescriptor("implMontgomeryMultiply", void.class, Word.class, Word.class, Word.class, int.class, long.class,
+ public static final HotSpotForeignCallDescriptor MONTGOMERY_MULTIPLY = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Int),
+ "implMontgomeryMultiply", void.class, Word.class, Word.class, Word.class, int.class, long.class,
Word.class);
public static void implMontgomeryMultiply(Word aAddr, Word bAddr, Word nAddr, int len, long inv, Word productAddr) {
@@ -208,7 +235,8 @@ public abstract class HotSpotBackend extends Backend implements FrameMap.Referen
/**
* @see BigIntegerSubstitutions#implMontgomerySquare
*/
- public static final ForeignCallDescriptor MONTGOMERY_SQUARE = new ForeignCallDescriptor("implMontgomerySquare", void.class, Word.class, Word.class, int.class, long.class, Word.class);
+ public static final HotSpotForeignCallDescriptor MONTGOMERY_SQUARE = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Int),
+ "implMontgomerySquare", void.class, Word.class, Word.class, int.class, long.class, Word.class);
public static void implMontgomerySquare(Word aAddr, Word nAddr, int len, long inv, Word productAddr) {
implMontgomerySquare(HotSpotBackend.MONTGOMERY_SQUARE, aAddr, nAddr, len, inv, productAddr);
@@ -220,7 +248,9 @@ public abstract class HotSpotBackend extends Backend implements FrameMap.Referen
/**
* @see BigIntegerSubstitutions#implSquareToLen
*/
- public static final ForeignCallDescriptor SQUARE_TO_LEN = new ForeignCallDescriptor("implSquareToLen", void.class, Word.class, int.class, Word.class, int.class);
+ public static final HotSpotForeignCallDescriptor SQUARE_TO_LEN = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, NOT_REEXECUTABLE, NamedLocationIdentity.getArrayLocation(JavaKind.Int),
+ "implSquareToLen",
+ void.class, Word.class, int.class, Word.class, int.class);
public static void implSquareToLen(Word xAddr, int len, Word zAddr, int zLen) {
implSquareToLen(SQUARE_TO_LEN, xAddr, len, zAddr, zLen);
@@ -232,7 +262,8 @@ public abstract class HotSpotBackend extends Backend implements FrameMap.Referen
/**
* @see SHASubstitutions#implCompress0
*/
- public static final ForeignCallDescriptor SHA_IMPL_COMPRESS = new ForeignCallDescriptor("shaImplCompress", void.class, Word.class, Object.class);
+ public static final HotSpotForeignCallDescriptor SHA_IMPL_COMPRESS = new HotSpotForeignCallDescriptor(LEAF, NOT_REEXECUTABLE, any(), "shaImplCompress", void.class, Word.class,
+ Object.class);
public static void shaImplCompressStub(Word bufAddr, Object state) {
shaImplCompressStub(HotSpotBackend.SHA_IMPL_COMPRESS, bufAddr, state);
@@ -244,7 +275,8 @@ public abstract class HotSpotBackend extends Backend implements FrameMap.Referen
/**
* @see SHA2Substitutions#implCompress0
*/
- public static final ForeignCallDescriptor SHA2_IMPL_COMPRESS = new ForeignCallDescriptor("sha2ImplCompress", void.class, Word.class, Object.class);
+ public static final HotSpotForeignCallDescriptor SHA2_IMPL_COMPRESS = new HotSpotForeignCallDescriptor(LEAF, NOT_REEXECUTABLE, any(), "sha2ImplCompress", void.class, Word.class,
+ Object.class);
public static void sha2ImplCompressStub(Word bufAddr, Object state) {
sha2ImplCompressStub(HotSpotBackend.SHA2_IMPL_COMPRESS, bufAddr, state);
@@ -256,7 +288,8 @@ public abstract class HotSpotBackend extends Backend implements FrameMap.Referen
/**
* @see SHA5Substitutions#implCompress0
*/
- public static final ForeignCallDescriptor SHA5_IMPL_COMPRESS = new ForeignCallDescriptor("sha5ImplCompress", void.class, Word.class, Object.class);
+ public static final HotSpotForeignCallDescriptor SHA5_IMPL_COMPRESS = new HotSpotForeignCallDescriptor(LEAF, NOT_REEXECUTABLE, any(), "sha5ImplCompress", void.class, Word.class,
+ Object.class);
public static void sha5ImplCompressStub(Word bufAddr, Object state) {
sha5ImplCompressStub(HotSpotBackend.SHA5_IMPL_COMPRESS, bufAddr, state);
@@ -268,7 +301,8 @@ public abstract class HotSpotBackend extends Backend implements FrameMap.Referen
/**
* @see DigestBaseSubstitutions#implCompressMultiBlock0
*/
- public static final ForeignCallDescriptor SHA_IMPL_COMPRESS_MB = new ForeignCallDescriptor("shaImplCompressMB", int.class, Word.class, Object.class, int.class, int.class);
+ public static final HotSpotForeignCallDescriptor SHA_IMPL_COMPRESS_MB = new HotSpotForeignCallDescriptor(LEAF, NOT_REEXECUTABLE, any(), "shaImplCompressMB", int.class, Word.class,
+ Object.class, int.class, int.class);
public static int shaImplCompressMBStub(Word bufAddr, Object stateAddr, int ofs, int limit) {
return shaImplCompressMBStub(HotSpotBackend.SHA_IMPL_COMPRESS_MB, bufAddr, stateAddr, ofs, limit);
@@ -277,7 +311,8 @@ public abstract class HotSpotBackend extends Backend implements FrameMap.Referen
@NodeIntrinsic(ForeignCallNode.class)
private static native int shaImplCompressMBStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word bufAddr, Object state, int ofs, int limit);
- public static final ForeignCallDescriptor SHA2_IMPL_COMPRESS_MB = new ForeignCallDescriptor("sha2ImplCompressMB", int.class, Word.class, Object.class, int.class, int.class);
+ public static final HotSpotForeignCallDescriptor SHA2_IMPL_COMPRESS_MB = new HotSpotForeignCallDescriptor(LEAF, NOT_REEXECUTABLE, any(), "sha2ImplCompressMB", int.class, Word.class,
+ Object.class, int.class, int.class);
public static int sha2ImplCompressMBStub(Word bufAddr, Object stateAddr, int ofs, int limit) {
return sha2ImplCompressMBStub(HotSpotBackend.SHA2_IMPL_COMPRESS_MB, bufAddr, stateAddr, ofs, limit);
@@ -286,7 +321,8 @@ public abstract class HotSpotBackend extends Backend implements FrameMap.Referen
@NodeIntrinsic(ForeignCallNode.class)
private static native int sha2ImplCompressMBStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word bufAddr, Object state, int ofs, int limit);
- public static final ForeignCallDescriptor SHA5_IMPL_COMPRESS_MB = new ForeignCallDescriptor("sha5ImplCompressMB", int.class, Word.class, Object.class, int.class, int.class);
+ public static final HotSpotForeignCallDescriptor SHA5_IMPL_COMPRESS_MB = new HotSpotForeignCallDescriptor(LEAF, NOT_REEXECUTABLE, any(), "sha5ImplCompressMB", int.class, Word.class,
+ Object.class, int.class, int.class);
public static int sha5ImplCompressMBStub(Word bufAddr, Object stateAddr, int ofs, int limit) {
return sha5ImplCompressMBStub(HotSpotBackend.SHA5_IMPL_COMPRESS_MB, bufAddr, stateAddr, ofs, limit);
@@ -300,22 +336,25 @@ public abstract class HotSpotBackend extends Backend implements FrameMap.Referen
}
@NodeIntrinsic(ForeignCallNode.class)
- private static native void unsafeArraycopyStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word srcAddr, Word dstAddr, Word size);
+ private static native void unsafeArraycopyStub(@ConstantNodeParameter ForeignCallSignature descriptor, Word srcAddr, Word dstAddr, Word size);
/**
* Descriptor for {@code StubRoutines::_ghash_processBlocks}.
*/
- public static final ForeignCallDescriptor GHASH_PROCESS_BLOCKS = new ForeignCallDescriptor("ghashProcessBlocks", void.class, Word.class, Word.class, Word.class, int.class);
+ public static final HotSpotForeignCallDescriptor GHASH_PROCESS_BLOCKS = new HotSpotForeignCallDescriptor(LEAF, NOT_REEXECUTABLE, any(), "ghashProcessBlocks", void.class, Word.class,
+ Word.class, Word.class, int.class);
/**
* Descriptor for {@code StubRoutines::_base64_encodeBlock}.
*/
- public static final ForeignCallDescriptor BASE64_ENCODE_BLOCK = new ForeignCallDescriptor("base64EncodeBlock", void.class, Word.class, int.class, int.class, Word.class, int.class, boolean.class);
+ public static final HotSpotForeignCallDescriptor BASE64_ENCODE_BLOCK = new HotSpotForeignCallDescriptor(LEAF, NOT_REEXECUTABLE, any(), "base64EncodeBlock", void.class, Word.class,
+ int.class, int.class, Word.class, int.class, boolean.class);
/**
* Descriptor for {@code StubRoutines::_counterMode_AESCrypt}.
*/
- public static final ForeignCallDescriptor COUNTERMODE_IMPL_CRYPT = new ForeignCallDescriptor("counterModeAESCrypt", int.class, Word.class, Word.class, Word.class, Word.class, int.class,
+ public static final HotSpotForeignCallDescriptor COUNTERMODE_IMPL_CRYPT = new HotSpotForeignCallDescriptor(LEAF, NOT_REEXECUTABLE, any(), "counterModeAESCrypt", int.class,
+ Word.class, Word.class, Word.class, Word.class, int.class,
Word.class, Word.class);
public static int counterModeAESCrypt(Word srcAddr, Word dstAddr, Word kPtr, Word cntPtr, int len, Word encCntPtr, Word used) {
@@ -329,7 +368,8 @@ public abstract class HotSpotBackend extends Backend implements FrameMap.Referen
/**
* Descriptor for {@code StubRoutines::_vectorizedMismatch}.
*/
- public static final ForeignCallDescriptor VECTORIZED_MISMATCHED = new ForeignCallDescriptor("vectorizedMismatch", int.class, Word.class, Word.class, int.class, int.class);
+ public static final HotSpotForeignCallDescriptor VECTORIZED_MISMATCHED = new HotSpotForeignCallDescriptor(LEAF, NOT_REEXECUTABLE, any(), "vectorizedMismatch", int.class, Word.class,
+ Word.class, int.class, int.class);
public static int vectorizedMismatch(Word aAddr, Word bAddr, int length, int log2ArrayIndexScale) {
return vectorizedMismatchStub(VECTORIZED_MISMATCHED, aAddr, bAddr, length, log2ArrayIndexScale);
@@ -341,69 +381,84 @@ public abstract class HotSpotBackend extends Backend implements FrameMap.Referen
/**
* @see VMErrorNode
*/
- public static final ForeignCallDescriptor VM_ERROR = new ForeignCallDescriptor("vm_error", void.class, Object.class, Object.class, long.class);
+ public static final HotSpotForeignCallDescriptor VM_ERROR = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS, "vm_error", void.class, Object.class, Object.class,
+ long.class);
+
+ private static final LocationIdentity[] TLAB_LOCATIONS = new LocationIdentity[]{TLAB_TOP_LOCATION, TLAB_END_LOCATION};
/**
* New multi array stub that throws an {@link OutOfMemoryError} on allocation failure.
*/
- public static final ForeignCallDescriptor NEW_MULTI_ARRAY = new ForeignCallDescriptor("new_multi_array", Object.class, KlassPointer.class, int.class, Word.class);
+ public static final HotSpotForeignCallDescriptor NEW_MULTI_ARRAY = new HotSpotForeignCallDescriptor(SAFEPOINT, REEXECUTABLE, TLAB_LOCATIONS, "new_multi_array", Object.class, KlassPointer.class,
+ int.class, Word.class);
/**
* New multi array stub that will return null on allocation failure.
*/
- public static final ForeignCallDescriptor NEW_MULTI_ARRAY_OR_NULL = new ForeignCallDescriptor("new_multi_array_or_null", Object.class, KlassPointer.class, int.class, Word.class);
+ public static final HotSpotForeignCallDescriptor NEW_MULTI_ARRAY_OR_NULL = new HotSpotForeignCallDescriptor(SAFEPOINT, REEXECUTABLE, TLAB_LOCATIONS, "new_multi_array_or_null", Object.class,
+ KlassPointer.class, int.class, Word.class);
/**
* New array stub that throws an {@link OutOfMemoryError} on allocation failure.
*/
- public static final ForeignCallDescriptor NEW_ARRAY = new ForeignCallDescriptor("new_array", Object.class, KlassPointer.class, int.class);
+ public static final HotSpotForeignCallDescriptor NEW_ARRAY = new HotSpotForeignCallDescriptor(SAFEPOINT, REEXECUTABLE, TLAB_LOCATIONS, "new_array", Object.class, KlassPointer.class, int.class);
/**
* New array stub that will return null on allocation failure.
*/
- public static final ForeignCallDescriptor NEW_ARRAY_OR_NULL = new ForeignCallDescriptor("new_array_or_null", Object.class, KlassPointer.class, int.class);
+ public static final HotSpotForeignCallDescriptor NEW_ARRAY_OR_NULL = new HotSpotForeignCallDescriptor(SAFEPOINT, REEXECUTABLE, TLAB_LOCATIONS, "new_array_or_null", Object.class,
+ KlassPointer.class,
+ int.class);
/**
* New instance stub that throws an {@link OutOfMemoryError} on allocation failure.
*/
- public static final ForeignCallDescriptor NEW_INSTANCE = new ForeignCallDescriptor("new_instance", Object.class, KlassPointer.class);
+ public static final HotSpotForeignCallDescriptor NEW_INSTANCE = new HotSpotForeignCallDescriptor(SAFEPOINT, REEXECUTABLE, TLAB_LOCATIONS, "new_instance", Object.class, KlassPointer.class);
/**
* New instance stub that will return null on allocation failure.
*/
- public static final ForeignCallDescriptor NEW_INSTANCE_OR_NULL = new ForeignCallDescriptor("new_instance_or_null", Object.class, KlassPointer.class);
+ public static final HotSpotForeignCallDescriptor NEW_INSTANCE_OR_NULL = new HotSpotForeignCallDescriptor(SAFEPOINT, REEXECUTABLE, TLAB_LOCATIONS, "new_instance_or_null", Object.class,
+ KlassPointer.class);
/**
* @see ResolveConstantStubCall
*/
- public static final ForeignCallDescriptor RESOLVE_STRING_BY_SYMBOL = new ForeignCallDescriptor("resolve_string_by_symbol", Object.class, Word.class, Word.class);
+ public static final HotSpotForeignCallDescriptor RESOLVE_STRING_BY_SYMBOL = new HotSpotForeignCallDescriptor(SAFEPOINT, REEXECUTABLE, TLAB_LOCATIONS, "resolve_string_by_symbol", Object.class,
+ Word.class, Word.class);
/**
* @see ResolveConstantStubCall
*/
- public static final ForeignCallDescriptor RESOLVE_DYNAMIC_INVOKE = new ForeignCallDescriptor("resolve_dynamic_invoke", Object.class, Word.class);
+ public static final HotSpotForeignCallDescriptor RESOLVE_DYNAMIC_INVOKE = new HotSpotForeignCallDescriptor(SAFEPOINT, REEXECUTABLE, any(), "resolve_dynamic_invoke", Object.class, Word.class);
/**
* @see ResolveConstantStubCall
*/
- public static final ForeignCallDescriptor RESOLVE_KLASS_BY_SYMBOL = new ForeignCallDescriptor("resolve_klass_by_symbol", Word.class, Word.class, Word.class);
+ public static final HotSpotForeignCallDescriptor RESOLVE_KLASS_BY_SYMBOL = new HotSpotForeignCallDescriptor(SAFEPOINT, REEXECUTABLE, any(), "resolve_klass_by_symbol", Word.class, Word.class,
+ Word.class);
/**
* @see ResolveConstantStubCall
*/
- public static final ForeignCallDescriptor INITIALIZE_KLASS_BY_SYMBOL = new ForeignCallDescriptor("initialize_klass_by_symbol", Word.class, Word.class, Word.class);
+ public static final HotSpotForeignCallDescriptor INITIALIZE_KLASS_BY_SYMBOL = new HotSpotForeignCallDescriptor(SAFEPOINT, NOT_REEXECUTABLE, any(), "initialize_klass_by_symbol", Word.class,
+ Word.class,
+ Word.class);
/**
* @see ResolveConstantStubCall
*/
- public static final ForeignCallDescriptor RESOLVE_METHOD_BY_SYMBOL_AND_LOAD_COUNTERS = new ForeignCallDescriptor("resolve_method_by_symbol_and_load_counters", Word.class, Word.class, Word.class,
+ public static final HotSpotForeignCallDescriptor RESOLVE_METHOD_BY_SYMBOL_AND_LOAD_COUNTERS = new HotSpotForeignCallDescriptor(SAFEPOINT, REEXECUTABLE, NO_LOCATIONS,
+ "resolve_method_by_symbol_and_load_counters", Word.class, Word.class, Word.class,
Word.class);
/**
* Tiered support.
*/
- public static final ForeignCallDescriptor INVOCATION_EVENT = new ForeignCallDescriptor("invocation_event", void.class, MethodCountersPointer.class);
- public static final ForeignCallDescriptor BACKEDGE_EVENT = new ForeignCallDescriptor("backedge_event", void.class, MethodCountersPointer.class, int.class, int.class);
+ public static final HotSpotForeignCallDescriptor INVOCATION_EVENT = new HotSpotForeignCallDescriptor(SAFEPOINT, REEXECUTABLE, NO_LOCATIONS, "invocation_event", void.class,
+ MethodCountersPointer.class);
+ public static final HotSpotForeignCallDescriptor BACKEDGE_EVENT = new HotSpotForeignCallDescriptor(SAFEPOINT, REEXECUTABLE, NO_LOCATIONS, "backedge_event", void.class, MethodCountersPointer.class,
+ int.class, int.class);
public HotSpotBackend(HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) {
super(providers);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackendFactory.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackendFactory.java
index 10407b40951..251240e6569 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackendFactory.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackendFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,9 @@
package org.graalvm.compiler.hotspot;
import org.graalvm.compiler.bytecode.BytecodeProvider;
-import org.graalvm.compiler.hotspot.meta.HotSpotPlatformConfigurationProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotGraalConstantFieldProvider;
+import org.graalvm.compiler.hotspot.meta.HotSpotMetaAccessExtensionProvider;
+import org.graalvm.compiler.hotspot.meta.HotSpotPlatformConfigurationProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotSnippetReflectionProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotStampProvider;
import org.graalvm.compiler.hotspot.word.HotSpotWordTypes;
@@ -59,6 +60,10 @@ public abstract class HotSpotBackendFactory {
return new HotSpotPlatformConfigurationProvider(config, metaAccess);
}
+ protected HotSpotMetaAccessExtensionProvider createMetaAccessExtensionProvider() {
+ return new HotSpotMetaAccessExtensionProvider();
+ }
+
protected HotSpotReplacementsImpl createReplacements(TargetDescription target, Providers p, HotSpotSnippetReflectionProvider snippetReflection, BytecodeProvider bytecodeProvider) {
return new HotSpotReplacementsImpl(p, snippetReflection, bytecodeProvider, target);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCompiledCodeBuilder.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCompiledCodeBuilder.java
index d61089db9e8..fc516a2314c 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCompiledCodeBuilder.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotCompiledCodeBuilder.java
@@ -24,6 +24,8 @@
package org.graalvm.compiler.hotspot;
+import static java.util.Collections.emptyList;
+import static java.util.Collections.unmodifiableList;
import static org.graalvm.compiler.hotspot.HotSpotCompiledCodeBuilder.Options.ShowSubstitutionSourceInfo;
import static org.graalvm.util.CollectionsUtil.anyMatch;
@@ -37,11 +39,10 @@ import java.util.List;
import java.util.ListIterator;
import java.util.Map;
-import org.graalvm.compiler.api.replacements.MethodSubstitution;
-import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.code.CompilationResult;
import org.graalvm.compiler.code.CompilationResult.CodeAnnotation;
import org.graalvm.compiler.code.CompilationResult.CodeComment;
+import org.graalvm.compiler.code.CompilationResult.CodeMark;
import org.graalvm.compiler.code.CompilationResult.JumpTable;
import org.graalvm.compiler.code.DataSection;
import org.graalvm.compiler.code.SourceMapping;
@@ -138,10 +139,10 @@ public class HotSpotCompiledCodeBuilder {
jvmciCompileState = 0L;
}
return new HotSpotCompiledNmethod(name, targetCode, targetCodeSize, sites, assumptions, methods, comments, dataSection, dataSectionAlignment, dataSectionPatches, isImmutablePIC,
- totalFrameSize, customStackArea, hsMethod, entryBCI, id, jvmciCompileState, hasUnsafeAccess);
+ totalFrameSize, customStackArea, hsMethod, entryBCI, id, jvmciCompileState, hasUnsafeAccess);
} else {
return new HotSpotCompiledCode(name, targetCode, targetCodeSize, sites, assumptions, methods, comments, dataSection, dataSectionAlignment, dataSectionPatches, isImmutablePIC,
- totalFrameSize, customStackArea);
+ totalFrameSize, customStackArea);
}
}
@@ -211,6 +212,23 @@ public class HotSpotCompiledCodeBuilder {
}
}
+
+ /**
+ * @return the list of {@link Mark marks} converted from the {@link CodeMark CodeMarks}.
+ */
+ private static List getTranslatedMarks(List codeMarks) {
+ if (codeMarks.isEmpty()) {
+ return emptyList();
+ }
+ // The HotSpot backend needs these in the exact form of a Mark so convert all the marks
+ // to that form.
+ List translated = new ArrayList<>(codeMarks.size());
+ for (CodeMark m : codeMarks) {
+ translated.add(new Mark(m.pcOffset, m.id.getId()));
+ }
+ return unmodifiableList(translated);
+ }
+
/**
* HotSpot expects sites to be presented in ascending order of PC (see
* {@code DebugInformationRecorder::add_new_pc_offset}). In addition, it expects
@@ -218,11 +236,11 @@ public class HotSpotCompiledCodeBuilder {
*/
private static Site[] getSortedSites(CompilationResult target, OptionValues options, boolean includeSourceInfo) {
List sites = new ArrayList<>(
- target.getExceptionHandlers().size() + target.getInfopoints().size() + target.getDataPatches().size() + target.getMarks().size() + target.getSourceMappings().size());
+ target.getExceptionHandlers().size() + target.getInfopoints().size() + target.getDataPatches().size() + target.getMarks().size() + target.getSourceMappings().size());
sites.addAll(target.getExceptionHandlers());
sites.addAll(target.getInfopoints());
sites.addAll(target.getDataPatches());
- sites.addAll(target.getMarks());
+ sites.addAll(getTranslatedMarks(target.getMarks()));
if (includeSourceInfo) {
/*
@@ -332,7 +350,7 @@ public class HotSpotCompiledCodeBuilder {
private static boolean verifyTrim(NodeSourcePosition sourcePosition) {
for (NodeSourcePosition sp = sourcePosition; sp != null; sp = sp.getCaller()) {
- assert (sp.getMethod().getAnnotation(Snippet.class) == null && sp.getMethod().getAnnotation(MethodSubstitution.class) == null);
+ assert !sp.isSubstitution();
}
return true;
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotDebugInfoBuilder.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotDebugInfoBuilder.java
index 35c82be9826..dcecfc75f14 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotDebugInfoBuilder.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotDebugInfoBuilder.java
@@ -29,8 +29,6 @@ import static jdk.vm.ci.code.BytecodeFrame.isPlaceholderBci;
import java.util.ArrayList;
import java.util.List;
-import org.graalvm.compiler.api.replacements.MethodSubstitution;
-import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.bytecode.Bytecodes;
import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
import org.graalvm.compiler.core.gen.DebugInfoBuilder;
@@ -38,6 +36,8 @@ import org.graalvm.compiler.graph.GraalGraphError;
import org.graalvm.compiler.graph.NodeSourcePosition;
import org.graalvm.compiler.hotspot.meta.DefaultHotSpotLoweringProvider;
import org.graalvm.compiler.lir.VirtualStackSlot;
+import org.graalvm.compiler.nodeinfo.Verbosity;
+import org.graalvm.compiler.nodes.DeoptimizeNode;
import org.graalvm.compiler.nodes.FrameState;
import org.graalvm.compiler.nodes.FullInfopointNode;
import org.graalvm.compiler.nodes.ValueNode;
@@ -65,7 +65,7 @@ public class HotSpotDebugInfoBuilder extends DebugInfoBuilder {
private HotSpotCodeCacheProvider codeCacheProvider;
public HotSpotDebugInfoBuilder(NodeValueMap nodeValueMap, HotSpotLockStack lockStack, HotSpotLIRGenerator gen) {
- super(nodeValueMap, gen.getResult().getLIR().getDebug());
+ super(nodeValueMap, gen.getProviders().getMetaAccessExtensionProvider(), gen.getResult().getLIR().getDebug());
this.lockStack = lockStack;
this.codeCacheProvider = gen.getProviders().getCodeCache();
}
@@ -100,7 +100,7 @@ public class HotSpotDebugInfoBuilder extends DebugInfoBuilder {
if (node instanceof ForeignCallNode) {
ForeignCallNode call = (ForeignCallNode) node;
ForeignCallDescriptor descriptor = call.getDescriptor();
- if (DefaultHotSpotLoweringProvider.RuntimeCalls.runtimeCalls.containsValue(descriptor)) {
+ if (DefaultHotSpotLoweringProvider.RuntimeCalls.runtimeCalls.containsValue(descriptor.getSignature())) {
return true;
}
}
@@ -120,6 +120,9 @@ public class HotSpotDebugInfoBuilder extends DebugInfoBuilder {
}
}
}
+ if (node instanceof DeoptimizeNode) {
+ assert !topState.duringCall() : topState.toString(Verbosity.Debugger);
+ }
return true;
}
@@ -144,8 +147,7 @@ public class HotSpotDebugInfoBuilder extends DebugInfoBuilder {
StringBuilder sb = new StringBuilder("parsing ");
ResolvedJavaMethod method = pos.getMethod();
MetaUtil.appendLocation(sb, method, pos.getBCI());
- if (method.getAnnotation(MethodSubstitution.class) != null ||
- method.getAnnotation(Snippet.class) != null) {
+ if (pos.isSubstitution()) {
replacementMethodWithProblematicSideEffect = method;
}
context.add(sb.toString());
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkage.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkage.java
index 19768c734c3..9c8c8769ceb 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkage.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkage.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020, 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
@@ -26,8 +26,8 @@ package org.graalvm.compiler.hotspot;
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
import org.graalvm.compiler.core.target.Backend;
+import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor;
import org.graalvm.compiler.hotspot.stubs.Stub;
-import jdk.internal.vm.compiler.word.LocationIdentity;
import jdk.vm.ci.meta.InvokeTarget;
@@ -46,76 +46,14 @@ public interface HotSpotForeignCallLinkage extends ForeignCallLinkage, InvokeTar
COMPUTES_REGISTERS_KILLED
}
- /**
- * Constants for specifying whether a call is a leaf or not and whether a
- * {@code JavaFrameAnchor} prologue and epilogue is required around the call. A leaf function
- * does not lock, GC or throw exceptions.
- */
- enum Transition {
- /**
- * A call to a leaf function that is guaranteed to not use floating point registers.
- * Consequently, floating point registers cleanup will be waived. On AMD64, this means the
- * compiler will no longer emit vzeroupper instruction around the foreign call, which it
- * normally does for unknown foreign calls to avoid potential SSE-AVX transition penalty.
- * Besides, this foreign call will never have its caller stack inspected by the VM. That is,
- * {@code JavaFrameAnchor} management around the call can be omitted.
- */
- LEAF_NO_VZERO,
-
- /**
- * A call to a leaf function that might use floating point registers but will never have its
- * caller stack inspected. That is, {@code JavaFrameAnchor} management around the call can
- * be omitted.
- */
- LEAF,
-
- /**
- * A call to a leaf function that might use floating point registers and may have its caller
- * stack inspected. That is, {@code JavaFrameAnchor} management code around the call is
- * required.
- */
- STACK_INSPECTABLE_LEAF,
-
- /**
- * A function that may lock, GC or raise an exception and thus requires debug info to be
- * associated with a call site to the function. The execution stack may be inspected while
- * in the called function. That is, {@code JavaFrameAnchor} management code around the call
- * is required.
- */
- SAFEPOINT,
- }
-
- /**
- * Constants specifying when a foreign call or stub call is re-executable.
- */
- enum Reexecutability {
- /**
- * Denotes a call that cannot be re-executed. If an exception is raised, the call is
- * deoptimized and the exception is passed on to be dispatched. If the call can throw an
- * exception it needs to have a precise frame state.
- */
- NOT_REEXECUTABLE,
-
- /**
- * Denotes a call that can always be re-executed. If an exception is raised by the call it
- * may be cleared, compiled code deoptimized and reexecuted. Since the call has no side
- * effects it is assumed that the same exception will be thrown.
- */
- REEXECUTABLE
- }
+ @Override
+ HotSpotForeignCallDescriptor getDescriptor();
/**
* Sentinel marker for a computed jump address.
*/
long JUMP_ADDRESS = 0xDEADDEADBEEFBEEFL;
- /**
- * Determines if the call has side effects.
- */
- boolean isReexecutable();
-
- LocationIdentity[] getKilledLocations();
-
void setCompiledStub(Stub stub);
RegisterEffect getEffect();
@@ -149,9 +87,4 @@ public interface HotSpotForeignCallLinkage extends ForeignCallLinkage, InvokeTar
* Gets the VM symbol associated with the target {@linkplain #getAddress() address} of the call.
*/
String getSymbol();
-
- /**
- * Identifies foreign calls which are guaranteed to include a safepoint check.
- */
- boolean isGuaranteedSafepoint();
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkageImpl.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkageImpl.java
index 3bfdc169169..aeab84b84db 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkageImpl.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotForeignCallLinkageImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020, 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
@@ -30,10 +30,10 @@ import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEff
import jdk.internal.vm.compiler.collections.EconomicSet;
import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
import org.graalvm.compiler.core.target.Backend;
+import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor;
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
import org.graalvm.compiler.hotspot.stubs.Stub;
import org.graalvm.compiler.word.WordTypes;
-import jdk.internal.vm.compiler.word.LocationIdentity;
import jdk.vm.ci.code.CallingConvention;
import jdk.vm.ci.code.CallingConvention.Type;
@@ -58,7 +58,7 @@ public class HotSpotForeignCallLinkageImpl extends HotSpotForeignCallTarget impl
/**
* The descriptor of the call.
*/
- protected final ForeignCallDescriptor descriptor;
+ protected final HotSpotForeignCallDescriptor descriptor;
/**
* Non-null (eventually) iff this is a call to a compiled {@linkplain Stub stub}.
@@ -78,20 +78,11 @@ public class HotSpotForeignCallLinkageImpl extends HotSpotForeignCallTarget impl
private final RegisterEffect effect;
- private final Transition transition;
-
/**
* The registers and stack slots defined/killed by the call.
*/
private Value[] temporaries = AllocatableValue.NONE;
- /**
- * The memory locations killed by the call.
- */
- private final LocationIdentity[] killedLocations;
-
- private final Reexecutability reexecutability;
-
/**
* Creates a {@link HotSpotForeignCallLinkage}.
*
@@ -101,19 +92,12 @@ public class HotSpotForeignCallLinkageImpl extends HotSpotForeignCallTarget impl
* temporaries which are always destroyed)
* @param outgoingCcType outgoing (caller) calling convention type
* @param incomingCcType incoming (callee) calling convention type (can be null)
- * @param transition specifies if this is a {@linkplain #needsDebugInfo() leaf} call
- * @param reexecutability specifies if the call can be re-executed without (meaningful) side
- * effects. Deoptimization will not return to a point before a call that cannot be
- * re-executed.
- * @param killedLocations the memory locations killed by the call
*/
public static HotSpotForeignCallLinkage create(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, WordTypes wordTypes, HotSpotForeignCallsProvider foreignCalls,
- ForeignCallDescriptor descriptor, long address, RegisterEffect effect, Type outgoingCcType, Type incomingCcType, Transition transition, Reexecutability reexecutability,
- LocationIdentity... killedLocations) {
+ HotSpotForeignCallDescriptor descriptor, long address, RegisterEffect effect, Type outgoingCcType, Type incomingCcType) {
CallingConvention outgoingCc = createCallingConvention(metaAccess, codeCache, wordTypes, foreignCalls, descriptor, outgoingCcType);
CallingConvention incomingCc = incomingCcType == null ? null : createCallingConvention(metaAccess, codeCache, wordTypes, foreignCalls, descriptor, incomingCcType);
- HotSpotForeignCallLinkageImpl linkage = new HotSpotForeignCallLinkageImpl(descriptor, address, effect, transition, reexecutability, outgoingCc, incomingCc,
- killedLocations);
+ HotSpotForeignCallLinkageImpl linkage = new HotSpotForeignCallLinkageImpl(descriptor, address, effect, outgoingCc, incomingCc);
if (outgoingCcType == HotSpotCallingConventionType.NativeCall) {
linkage.temporaries = foreignCalls.getNativeABICallerSaveRegisters();
}
@@ -144,18 +128,15 @@ public class HotSpotForeignCallLinkageImpl extends HotSpotForeignCallTarget impl
return javaType;
}
- public HotSpotForeignCallLinkageImpl(ForeignCallDescriptor descriptor, long address, RegisterEffect effect, Transition transition, Reexecutability reexecutability,
- CallingConvention outgoingCallingConvention, CallingConvention incomingCallingConvention, LocationIdentity... killedLocations) {
+ public HotSpotForeignCallLinkageImpl(HotSpotForeignCallDescriptor descriptor, long address, RegisterEffect effect,
+ CallingConvention outgoingCallingConvention, CallingConvention incomingCallingConvention) {
super(address);
this.descriptor = descriptor;
this.address = address;
this.effect = effect;
- this.transition = transition;
- this.reexecutability = reexecutability;
assert outgoingCallingConvention != null : "only incomingCallingConvention can be null";
this.outgoingCallingConvention = outgoingCallingConvention;
this.incomingCallingConvention = incomingCallingConvention != null ? incomingCallingConvention : outgoingCallingConvention;
- this.killedLocations = killedLocations;
}
@Override
@@ -173,26 +154,11 @@ public class HotSpotForeignCallLinkageImpl extends HotSpotForeignCallTarget impl
return sb.toString();
}
- @Override
- public boolean isReexecutable() {
- return reexecutability == Reexecutability.REEXECUTABLE;
- }
-
- @Override
- public boolean isGuaranteedSafepoint() {
- return transition == Transition.SAFEPOINT;
- }
-
@Override
public RegisterEffect getEffect() {
return effect;
}
- @Override
- public LocationIdentity[] getKilledLocations() {
- return killedLocations;
- }
-
@Override
public CallingConvention getOutgoingCallingConvention() {
return outgoingCallingConvention;
@@ -217,7 +183,7 @@ public class HotSpotForeignCallLinkageImpl extends HotSpotForeignCallTarget impl
}
@Override
- public ForeignCallDescriptor getDescriptor() {
+ public HotSpotForeignCallDescriptor getDescriptor() {
return descriptor;
}
@@ -278,17 +244,17 @@ public class HotSpotForeignCallLinkageImpl extends HotSpotForeignCallTarget impl
@Override
public boolean needsDebugInfo() {
- return transition == Transition.SAFEPOINT;
+ return descriptor.canDeoptimize();
}
@Override
public boolean mayContainFP() {
- return transition != Transition.LEAF_NO_VZERO;
+ return descriptor.getTransition() != HotSpotForeignCallDescriptor.Transition.LEAF_NO_VZERO;
}
@Override
public boolean needsJavaFrameAnchor() {
- if (transition == Transition.SAFEPOINT || transition == Transition.STACK_INSPECTABLE_LEAF) {
+ if (descriptor.getTransition() == HotSpotForeignCallDescriptor.Transition.SAFEPOINT || descriptor.getTransition() == HotSpotForeignCallDescriptor.Transition.STACK_INSPECTABLE_LEAF) {
if (stub != null) {
// The stub will do the JavaFrameAnchor management
// around the runtime call(s) it makes
@@ -309,4 +275,5 @@ public class HotSpotForeignCallLinkageImpl extends HotSpotForeignCallTarget impl
public boolean needsClearUpperVectorRegisters() {
return isCompiledStub() && mayContainFP();
}
+
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java
index cf03cfb7308..58b84fedede 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, 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
@@ -139,7 +139,7 @@ public class HotSpotGraalCompiler implements GraalJVMCICompiler, Cancellable {
compilationCounters.countCompilation(method);
}
CompilationRequestResult r = null;
- try (DebugContext debug = graalRuntime.openDebugContext(options, task.getCompilationIdentifier(), method, getDebugHandlersFactories(), DebugContext.DEFAULT_LOG_STREAM);
+ try (DebugContext debug = graalRuntime.openDebugContext(options, task.getCompilationIdentifier(), method, getDebugHandlersFactories(), DebugContext.getDefaultLogStream());
Activation a = debug.activate()) {
r = task.runCompilation(debug);
}
@@ -176,7 +176,8 @@ public class HotSpotGraalCompiler implements GraalJVMCICompiler, Cancellable {
HotSpotBackend backend = graalRuntime.getHostBackend();
HotSpotProviders providers = backend.getProviders();
final boolean isOSR = entryBCI != JVMCICompiler.INVOCATION_ENTRY_BCI;
- StructuredGraph graph = method.isNative() || isOSR ? null : providers.getReplacements().getIntrinsicGraph(method, compilationId, debug, this);
+ AllowAssumptions allowAssumptions = AllowAssumptions.ifTrue(OptAssumptions.getValue(options));
+ StructuredGraph graph = method.isNative() || isOSR ? null : providers.getReplacements().getIntrinsicGraph(method, compilationId, debug, allowAssumptions, this);
if (graph == null) {
SpeculationLog speculationLog = method.getSpeculationLog();
@@ -184,7 +185,7 @@ public class HotSpotGraalCompiler implements GraalJVMCICompiler, Cancellable {
speculationLog.collectFailedSpeculations();
}
// @formatter:off
- graph = new StructuredGraph.Builder(options, debug, AllowAssumptions.ifTrue(OptAssumptions.getValue(options))).
+ graph = new StructuredGraph.Builder(options, debug, allowAssumptions).
method(method).
cancellable(this).
entryBCI(entryBCI).
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java
index fab3642f58e..9a363196fc3 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@ import static jdk.vm.ci.common.InitTimer.timer;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
import static org.graalvm.compiler.core.common.GraalOptions.HotSpotPrintInlining;
+import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigAccess.JDK;
import java.io.PrintStream;
import java.util.ArrayList;
@@ -45,10 +46,14 @@ import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
import org.graalvm.compiler.api.runtime.GraalRuntime;
import org.graalvm.compiler.core.CompilationWrapper.ExceptionAction;
import org.graalvm.compiler.core.common.CompilationIdentifier;
+import org.graalvm.compiler.core.common.CompilationListenerProfiler;
+import org.graalvm.compiler.core.common.CompilerProfiler;
import org.graalvm.compiler.core.common.GraalOptions;
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
import org.graalvm.compiler.core.target.Backend;
+import org.graalvm.compiler.debug.Assertions;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugContext.Builder;
import org.graalvm.compiler.debug.DebugContext.Description;
import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.DebugOptions;
@@ -98,8 +103,10 @@ import jdk.vm.ci.services.Services;
public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider {
private static final boolean IS_AOT = Boolean.parseBoolean(Services.getSavedProperties().get("com.oracle.graalvm.isaot"));
+
/**
- * A factory for {@link HotSpotGraalManagementRegistration} injected by {@code LibGraalFeature}.
+ * A factory for a {@link HotSpotGraalManagementRegistration} injected by
+ * {@code Target_org_graalvm_compiler_hotspot_HotSpotGraalRuntime}.
*/
private static final Supplier AOT_INJECTED_MANAGEMENT = null;
@@ -142,6 +149,8 @@ public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider {
private final DiagnosticsOutputDirectory outputDirectory;
private final Map compilationProblemsPerAction;
+ private final CompilerProfiler compilerProfiler;
+
/**
* @param nameQualifier a qualifier to be added to this runtime's {@linkplain #getName() name}
* @param compilerConfigurationFactory factory for the compiler configuration
@@ -175,7 +184,14 @@ public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider {
management = GraalServices.loadSingle(HotSpotGraalManagementRegistration.class, false);
}
if (management != null) {
- management.initialize(this, config);
+ try {
+ management.initialize(this, config);
+ } catch (ThreadDeath td) {
+ throw td;
+ } catch (Throwable error) {
+ TTY.println("Cannot install GraalVM MBean due to " + error.getMessage());
+ management = null;
+ }
}
BackendMap backendMap = compilerConfigurationFactory.createBackendMap();
@@ -223,6 +239,8 @@ public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider {
runtimeStartTime = System.nanoTime();
bootstrapJVMCI = config.getFlag("BootstrapJVMCI", Boolean.class);
+
+ this.compilerProfiler = GraalServices.loadSingle(CompilerProfiler.class, false);
}
/**
@@ -230,47 +248,70 @@ public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider {
*/
public enum HotSpotGC {
// Supported GCs
- Serial(true, "UseSerialGC"),
- Parallel(true, "UseParallelGC", "UseParallelOldGC", "UseParNewGC"),
- CMS(true, "UseConcMarkSweepGC"),
- G1(true, "UseG1GC"),
+ Serial(true, "UseSerialGC", true),
+ Parallel(true, "UseParallelGC", true, "UseParallelOldGC", JDK < 15, "UseParNewGC", JDK < 10),
+ CMS(true, "UseConcMarkSweepGC", JDK < 14),
+ G1(true, "UseG1GC", true),
// Unsupported GCs
- Epsilon(false, "UseEpsilonGC"),
- Z(false, "UseZGC");
+ Epsilon(false, "UseEpsilonGC", JDK >= 11),
+ Z(false, "UseZGC", JDK >= 11);
- HotSpotGC(boolean supported, String... flags) {
+ HotSpotGC(boolean supported,
+ String flag1, boolean expectFlagPresent1,
+ String flag2, boolean expectFlagPresent2,
+ String flag3, boolean expectFlagPresent3) {
this.supported = supported;
- this.flags = flags;
+ this.expectFlagsPresent = new boolean[]{expectFlagPresent1, expectFlagPresent2, expectFlagPresent3};
+ this.flags = new String[]{flag1, flag2, flag3};
+ }
+
+ HotSpotGC(boolean supported, String flag, boolean expectFlagPresent) {
+ this.supported = supported;
+ this.expectFlagsPresent = new boolean[]{expectFlagPresent};
+ this.flags = new String[]{flag};
}
final boolean supported;
+ final boolean[] expectFlagsPresent;
private final String[] flags;
public boolean isSelected(GraalHotSpotVMConfig config) {
- for (String flag : flags) {
+ boolean selected = false;
+ for (int i = 0; i < flags.length; i++) {
final boolean notPresent = false;
- if (config.getFlag(flag, Boolean.class, notPresent)) {
- return true;
+ if (config.getFlag(flags[i], Boolean.class, notPresent, expectFlagsPresent[i])) {
+ selected = true;
+ if (!Assertions.assertionsEnabled()) {
+ // When asserting, check that isSelected works for all flag names
+ break;
+ }
}
}
- return false;
+ return selected;
}
-
}
private HotSpotGC getSelectedGC() throws GraalError {
+ HotSpotGC selected = null;
for (HotSpotGC gc : HotSpotGC.values()) {
if (gc.isSelected(config)) {
if (!gc.supported) {
throw new GraalError(gc.name() + " garbage collector is not supported by Graal");
}
- return gc;
+ selected = gc;
+ if (!Assertions.assertionsEnabled()) {
+ // When asserting, check that isSelected works for all HotSpotGC values
+ break;
+ }
}
}
- // As of JDK 9, exactly one GC flag is guaranteed to be selected.
- // On JDK 8, the default GC is Serial when no GC flag is true.
- return HotSpotGC.Serial;
+ if (selected == null) {
+ // As of JDK 9, exactly one GC flag is guaranteed to be selected.
+ // On JDK 8, the default GC is Serial when no GC flag is true.
+ selected = HotSpotGC.Serial;
+ }
+ return selected;
}
private HotSpotBackend registerBackend(HotSpotBackend backend) {
@@ -310,8 +351,18 @@ public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider {
}
}
}
+
Description description = new Description(compilable, compilationId.toString(CompilationIdentifier.Verbosity.ID));
- return DebugContext.create(compilationOptions, description, metricValues, logStream, factories);
+ Builder builder = new Builder(compilationOptions, factories).//
+ globalMetrics(metricValues).//
+ description(description).//
+ logStream(logStream);
+ if (compilerProfiler != null) {
+ int compileId = ((HotSpotCompilationIdentifier) compilationId).getRequest().getId();
+ builder.compilationListener(new CompilationListenerProfiler(compilerProfiler, compileId));
+ }
+ return builder.build();
+
}
@Override
@@ -383,6 +434,11 @@ public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider {
*/
private volatile boolean shutdown;
+ /**
+ * Shutdown hooks that should be run on the same thread doing the shutdown.
+ */
+ private List shutdownHooks = new ArrayList<>();
+
/**
* Take action related to entering a new execution phase.
*
@@ -394,8 +450,29 @@ public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider {
}
}
- void shutdown() {
+ /**
+ * Adds a {@link Runnable} that will be run when this runtime is {@link #shutdown()}. The
+ * runnable will be run on the same thread doing the shutdown. All the advice for regular
+ * {@linkplain Runtime#addShutdownHook(Thread) shutdown hooks} also applies here but even more
+ * so since the hook runs on the shutdown thread.
+ */
+ public synchronized void addShutdownHook(Runnable hook) {
+ if (!shutdown) {
+ shutdownHooks.add(hook);
+ }
+ }
+
+ synchronized void shutdown() {
shutdown = true;
+
+ for (Runnable r : shutdownHooks) {
+ try {
+ r.run();
+ } catch (Throwable e) {
+ e.printStackTrace(TTY.out);
+ }
+ }
+
metricValues.print(optionsRef.get());
phaseTransition("final");
@@ -453,7 +530,7 @@ public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider {
// ------- Management interface ---------
- private final HotSpotGraalManagementRegistration management;
+ private HotSpotGraalManagementRegistration management;
/**
* @returns the management object for this runtime or {@code null}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotHostBackend.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotHostBackend.java
index 0f297ce8189..4140c912a9a 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotHostBackend.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotHostBackend.java
@@ -27,15 +27,18 @@ package org.graalvm.compiler.hotspot;
import static jdk.vm.ci.code.CodeUtil.K;
import static jdk.vm.ci.code.CodeUtil.getCallingConvention;
import static jdk.vm.ci.common.InitTimer.timer;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Reexecutability.REEXECUTABLE;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Transition.LEAF_NO_VZERO;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl.NO_LOCATIONS;
import java.util.Collections;
import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
-import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
import org.graalvm.compiler.core.gen.LIRGenerationProvider;
import org.graalvm.compiler.debug.DebugHandlersFactory;
+import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor;
import org.graalvm.compiler.hotspot.meta.HotSpotHostForeignCallsProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotLoweringProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
@@ -67,21 +70,25 @@ public abstract class HotSpotHostBackend extends HotSpotBackend implements LIRGe
/**
* Descriptor for {@code SharedRuntime::deopt_blob()->unpack()}.
*/
- public static final ForeignCallDescriptor DEOPT_BLOB_UNPACK = new ForeignCallDescriptor("deopt_blob()->unpack()", void.class);
+ public static final HotSpotForeignCallDescriptor DEOPT_BLOB_UNPACK = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS, "deopt_blob()->unpack()", void.class);
/**
* Descriptor for {@code SharedRuntime::deopt_blob()->unpack_with_exception_in_tls()}.
*/
- public static final ForeignCallDescriptor DEOPT_BLOB_UNPACK_WITH_EXCEPTION_IN_TLS = new ForeignCallDescriptor("deopt_blob()->unpack_with_exception_in_tls()", void.class);
+ public static final HotSpotForeignCallDescriptor DEOPT_BLOB_UNPACK_WITH_EXCEPTION_IN_TLS = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS,
+ "deopt_blob()->unpack_with_exception_in_tls()", void.class);
/**
* Descriptor for {@code SharedRuntime::deopt_blob()->uncommon_trap()}.
*/
- public static final ForeignCallDescriptor DEOPT_BLOB_UNCOMMON_TRAP = new ForeignCallDescriptor("deopt_blob()->uncommon_trap()", void.class);
+ public static final HotSpotForeignCallDescriptor DEOPT_BLOB_UNCOMMON_TRAP = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS, "deopt_blob()->uncommon_trap()",
+ void.class);
- public static final ForeignCallDescriptor ENABLE_STACK_RESERVED_ZONE = new ForeignCallDescriptor("enableStackReservedZoneEntry", void.class, Word.class);
+ public static final HotSpotForeignCallDescriptor ENABLE_STACK_RESERVED_ZONE = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS, "enableStackReservedZoneEntry",
+ void.class, Word.class);
- public static final ForeignCallDescriptor THROW_DELAYED_STACKOVERFLOW_ERROR = new ForeignCallDescriptor("throwDelayedStackoverflowError", void.class);
+ public static final HotSpotForeignCallDescriptor THROW_DELAYED_STACKOVERFLOW_ERROR = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS, "throwDelayedStackoverflowError",
+ void.class);
protected final GraalHotSpotVMConfig config;
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotLIRGenerator.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotLIRGenerator.java
index b20e7623b40..d2543724ec3 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotLIRGenerator.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotLIRGenerator.java
@@ -103,7 +103,7 @@ public interface HotSpotLIRGenerator extends LIRGeneratorTool {
* @param kind type of the value to load
* @return value of loaded global in register
*/
- default Value emitLoadConfigValue(int markId, LIRKind kind) {
+ default Value emitLoadConfigValue(HotSpotMarkId markId, LIRKind kind) {
throw new GraalError("Emitting code to load a config value is not currently supported on %s", target().arch);
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotMarkId.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotMarkId.java
new file mode 100644
index 00000000000..bfb9e0f9c42
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotMarkId.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+
+package org.graalvm.compiler.hotspot;
+
+import static org.graalvm.compiler.debug.GraalError.shouldNotReachHere;
+
+import org.graalvm.compiler.code.CompilationResult;
+
+import jdk.vm.ci.common.NativeImageReinitialize;
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
+
+/**
+ * Constants used to mark special positions in code being installed into the code cache by Graal C++
+ * code.
+ */
+public enum HotSpotMarkId implements CompilationResult.MarkId {
+ VERIFIED_ENTRY(false),
+ UNVERIFIED_ENTRY(false),
+ OSR_ENTRY(false),
+ EXCEPTION_HANDLER_ENTRY(false),
+ DEOPT_HANDLER_ENTRY(false),
+ FRAME_COMPLETE(true, true),
+ INVOKEINTERFACE(false),
+ INVOKEVIRTUAL(false),
+ INVOKESTATIC(false),
+ INVOKESPECIAL(false),
+ INLINE_INVOKE(false),
+ POLL_NEAR(false),
+ POLL_RETURN_NEAR(false),
+ POLL_FAR(false),
+ POLL_RETURN_FAR(false),
+ CARD_TABLE_ADDRESS(true),
+ NARROW_KLASS_BASE_ADDRESS(true),
+ NARROW_OOP_BASE_ADDRESS(true),
+ CRC_TABLE_ADDRESS(true),
+ LOG_OF_HEAP_REGION_GRAIN_BYTES(true);
+
+ private final boolean isMarkAfter;
+ @NativeImageReinitialize private Integer value;
+ private final boolean optional;
+
+ HotSpotMarkId(boolean isMarkAfter) {
+ this(isMarkAfter, false);
+ }
+
+ HotSpotMarkId(boolean isMarkAfter, boolean optional) {
+ this.isMarkAfter = isMarkAfter;
+ this.optional = optional;
+ }
+
+ private Integer getValue() {
+ if (value == null) {
+ Long result = HotSpotJVMCIRuntime.runtime().getConfigStore().getConstants().get("CodeInstaller::" + name());
+ if (result != null) {
+ this.value = result.intValue();
+ } else if (!optional) {
+ throw shouldNotReachHere("Unsupported Mark " + name());
+ }
+ }
+ return value;
+ }
+
+ @Override
+ public String getName() {
+ return name();
+ }
+
+ @Override
+ public Object getId() {
+ assert isAvailable() : this;
+ return getValue();
+ }
+
+ @Override
+ public boolean isMarkAfter() {
+ return isMarkAfter;
+ }
+
+ public boolean isAvailable() {
+ return getValue() != null;
+ }
+
+ @Override
+ public String toString() {
+ return "HotSpotCodeMark{" + name() +
+ ", value=" + getValue() +
+ ", optional=" + optional +
+ '}';
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotReplacementsImpl.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotReplacementsImpl.java
index 8c64da2c57e..775337d4289 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotReplacementsImpl.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotReplacementsImpl.java
@@ -30,8 +30,6 @@ import static org.graalvm.compiler.core.common.GraalOptions.UseEncodedGraphs;
import static org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.CompilationContext.INLINE_AFTER_PARSING;
import static org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.CompilationContext.ROOT_COMPILATION;
-import java.util.Set;
-
import jdk.internal.vm.compiler.collections.EconomicSet;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
import org.graalvm.compiler.bytecode.BytecodeProvider;
@@ -44,11 +42,13 @@ import org.graalvm.compiler.hotspot.word.HotSpotOperation;
import org.graalvm.compiler.nodes.Cancellable;
import org.graalvm.compiler.nodes.Invoke;
import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderPlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.MethodSubstitutionPlugin;
+import org.graalvm.compiler.nodes.spi.SnippetParameterInfo;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.util.Providers;
import org.graalvm.compiler.printer.GraalDebugHandlersFactory;
@@ -73,6 +73,9 @@ public class HotSpotReplacementsImpl extends ReplacementsImpl {
}
public void maybeInitializeEncoder(OptionValues options) {
+ if (IS_IN_NATIVE_IMAGE) {
+ return;
+ }
if (IS_BUILDING_NATIVE_IMAGE || UseEncodedGraphs.getValue(options)) {
synchronized (HotSpotReplacementsImpl.class) {
if (snippetEncoder == null) {
@@ -82,22 +85,39 @@ public class HotSpotReplacementsImpl extends ReplacementsImpl {
}
}
+ /**
+ * Returns true if this Replacements is being used for preparation of snippets and substitutions
+ * for libgraal.
+ */
+ public boolean isEncodingSnippets() {
+ return false;
+ }
+
@Override
public Class extends GraphBuilderPlugin> getIntrinsifyingPlugin(ResolvedJavaMethod method) {
- return method.getAnnotation(HotSpotOperation.class) != null ? HotSpotWordOperationPlugin.class : super.getIntrinsifyingPlugin(method);
+ if (!IS_IN_NATIVE_IMAGE) {
+ if (method.getAnnotation(HotSpotOperation.class) != null) {
+ return HotSpotWordOperationPlugin.class;
+ }
+ }
+ return super.getIntrinsifyingPlugin(method);
}
@Override
public void registerMethodSubstitution(MethodSubstitutionPlugin plugin) {
- if (snippetEncoder != null) {
- snippetEncoder.registerMethodSubstitution(plugin);
+ if (!IS_IN_NATIVE_IMAGE) {
+ if (snippetEncoder != null) {
+ snippetEncoder.registerMethodSubstitution(plugin);
+ }
}
}
@Override
public void registerConditionalPlugin(InvocationPlugin plugin) {
- if (snippetEncoder != null) {
- snippetEncoder.registerConditionalPlugin(plugin);
+ if (!IS_IN_NATIVE_IMAGE) {
+ if (snippetEncoder != null) {
+ snippetEncoder.registerConditionalPlugin(plugin);
+ }
}
}
@@ -106,7 +126,7 @@ public class HotSpotReplacementsImpl extends ReplacementsImpl {
}
@Override
- public StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationIdentifier compilationId, DebugContext debug, Cancellable cancellable) {
+ public StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationIdentifier compilationId, DebugContext debug, AllowAssumptions allowAssumptions, Cancellable cancellable) {
boolean useEncodedGraphs = UseEncodedGraphs.getValue(debug.getOptions());
if (IS_IN_NATIVE_IMAGE || useEncodedGraphs) {
HotSpotReplacementsImpl replacements = (HotSpotReplacementsImpl) providers.getReplacements();
@@ -117,17 +137,18 @@ public class HotSpotReplacementsImpl extends ReplacementsImpl {
replacements.maybeInitializeEncoder(debug.getOptions());
replacements.registerMethodSubstitution(msp);
}
- StructuredGraph methodSubstitution = replacements.getMethodSubstitution(msp, method, ROOT_COMPILATION, StructuredGraph.AllowAssumptions.YES, cancellable, debug.getOptions());
+ StructuredGraph methodSubstitution = replacements.getMethodSubstitution(msp, method, ROOT_COMPILATION, allowAssumptions, cancellable, debug.getOptions());
methodSubstitution.resetDebug(debug);
return methodSubstitution;
}
return null;
}
- return super.getIntrinsicGraph(method, compilationId, debug, cancellable);
+ return super.getIntrinsicGraph(method, compilationId, debug, allowAssumptions, cancellable);
}
@Override
- public StructuredGraph getSubstitution(ResolvedJavaMethod targetMethod, int invokeBci, boolean trackNodeSourcePosition, NodeSourcePosition replaceePosition, OptionValues options) {
+ public StructuredGraph getSubstitution(ResolvedJavaMethod targetMethod, int invokeBci, boolean trackNodeSourcePosition, NodeSourcePosition replaceePosition,
+ AllowAssumptions allowAssumptions, OptionValues options) {
boolean useEncodedGraphs = UseEncodedGraphs.getValue(options);
if (IS_IN_NATIVE_IMAGE || useEncodedGraphs) {
InvocationPlugin plugin = getGraphBuilderPlugins().getInvocationPlugins().lookupInvocation(targetMethod);
@@ -139,20 +160,22 @@ public class HotSpotReplacementsImpl extends ReplacementsImpl {
}
// This assumes the normal path creates the graph using
// GraphBuilderConfiguration.getSnippetDefault with omits exception edges
- StructuredGraph subst = getMethodSubstitution(msPlugin, targetMethod, INLINE_AFTER_PARSING, StructuredGraph.AllowAssumptions.NO, null, options);
+ StructuredGraph subst = getMethodSubstitution(msPlugin, targetMethod, INLINE_AFTER_PARSING, allowAssumptions, null, options);
return subst;
}
}
- return super.getSubstitution(targetMethod, invokeBci, trackNodeSourcePosition, replaceePosition, options);
+ return super.getSubstitution(targetMethod, invokeBci, trackNodeSourcePosition, replaceePosition, allowAssumptions, options);
}
@Override
public void notifyNotInlined(GraphBuilderContext b, ResolvedJavaMethod method, Invoke invoke) {
- if (b.parsingIntrinsic() && snippetEncoder != null) {
- if (getIntrinsifyingPlugin(method) != null) {
- snippetEncoder.addDelayedInvocationPluginMethod(method);
- return;
+ if (!IS_IN_NATIVE_IMAGE) {
+ if (b.parsingIntrinsic() && snippetEncoder != null) {
+ if (getIntrinsifyingPlugin(method) != null) {
+ snippetEncoder.addDelayedInvocationPluginMethod(method);
+ return;
+ }
}
}
super.notifyNotInlined(b, method, invoke);
@@ -177,38 +200,59 @@ public class HotSpotReplacementsImpl extends ReplacementsImpl {
}
}
+ @Override
+ public SnippetParameterInfo getSnippetParameterInfo(ResolvedJavaMethod method) {
+ if (IS_IN_NATIVE_IMAGE) {
+ OptionValues options = null;
+ if (getEncodedSnippets(options) == null) {
+ throw GraalError.shouldNotReachHere("encoded snippets not found");
+ }
+ return getEncodedSnippets(options).getSnippetParameterInfo(method);
+ }
+ return super.getSnippetParameterInfo(method);
+ }
+
+ @Override
+ public boolean isSnippet(ResolvedJavaMethod method) {
+ if (IS_IN_NATIVE_IMAGE) {
+ if (encodedSnippets == null) {
+ throw GraalError.shouldNotReachHere("encoded snippets not found");
+ }
+ return encodedSnippets.isSnippet(method);
+ }
+ return super.isSnippet(method);
+ }
+
@Override
public void closeSnippetRegistration() {
snippetRegistrationClosed = true;
}
- public static SymbolicSnippetEncoder.EncodedSnippets getEncodedSnippets(OptionValues options) {
+ public static EncodedSnippets getEncodedSnippets(OptionValues options) {
if (!IS_IN_NATIVE_IMAGE && snippetEncoder != null) {
snippetEncoder.encode(options);
}
return encodedSnippets;
}
- public Set getSnippetMethods() {
- if (snippetEncoder != null) {
- return snippetEncoder.getSnippetMethods();
- }
- return null;
+ public void clearSnippetParameterNames() {
+ assert snippetEncoder != null;
+ snippetEncoder.clearSnippetParameterNames();
}
- static void setEncodedSnippets(SymbolicSnippetEncoder.EncodedSnippets encodedSnippets) {
+ static void setEncodedSnippets(EncodedSnippets encodedSnippets) {
HotSpotReplacementsImpl.encodedSnippets = encodedSnippets;
}
public boolean encode(OptionValues options) {
- SymbolicSnippetEncoder encoder = HotSpotReplacementsImpl.snippetEncoder;
+ SymbolicSnippetEncoder encoder = snippetEncoder;
if (encoder != null) {
return encoder.encode(options);
}
return false;
}
- private static volatile SymbolicSnippetEncoder.EncodedSnippets encodedSnippets;
+ private static volatile EncodedSnippets encodedSnippets;
@NativeImageReinitialize private static SymbolicSnippetEncoder snippetEncoder;
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotTTYStreamProvider.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotTTYStreamProvider.java
index ed90b7dcfe1..60d9abf4b2f 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotTTYStreamProvider.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotTTYStreamProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, 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
@@ -26,7 +26,9 @@ package org.graalvm.compiler.hotspot;
import static org.graalvm.compiler.hotspot.HotSpotGraalOptionValues.GRAAL_OPTION_PROPERTY_PREFIX;
import static org.graalvm.compiler.hotspot.HotSpotGraalOptionValues.defaultOptions;
+import static jdk.internal.vm.compiler.word.LocationIdentity.ANY_LOCATION;
+import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -40,7 +42,11 @@ import org.graalvm.compiler.options.Option;
import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionType;
import org.graalvm.compiler.serviceprovider.GraalServices;
+import org.graalvm.compiler.serviceprovider.IsolateUtil;
import org.graalvm.compiler.serviceprovider.ServiceProvider;
+import org.graalvm.compiler.word.Word;
+import jdk.internal.vm.compiler.word.Pointer;
+import jdk.internal.vm.compiler.word.WordFactory;
import jdk.vm.ci.common.NativeImageReinitialize;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
@@ -53,7 +59,10 @@ public class HotSpotTTYStreamProvider implements TTYStreamProvider {
// @formatter:off
@Option(help = "File to which logging is sent. A %p in the name will be replaced with a string identifying " +
- "the process, usually the process id and %t will be replaced by System.currentTimeMillis(). " +
+ "the process, usually the process id and %t will be replaced by System.currentTimeMillis(). " +
+ "If the current runtime is in an isolate, then %i will be replaced by '' " +
+ "otherwise %i is removed. An %I is the same as %i except that the replacement is " +
+ "'@'. " +
"Using %o as filename sends logging to System.out whereas %e sends logging to System.err.", type = OptionType.Expert)
public static final LogStreamOptionKey LogFile = new LogStreamOptionKey();
// @formatter:on
@@ -64,6 +73,55 @@ public class HotSpotTTYStreamProvider implements TTYStreamProvider {
return Options.LogFile.getStream();
}
+ static {
+ Word.ensureInitialized();
+ }
+
+ /**
+ * Gets a pointer to a global word initialized to 0.
+ */
+ private static Pointer getBarrierPointer() {
+ // Substituted by Target_org_graalvm_compiler_hotspot_HotSpotTTYStreamProvider
+ return WordFactory.nullPointer();
+ }
+
+ /**
+ * Executes {@code action}. If {@code barrier.isNonNull()}, then {@code barrier} is used to
+ * ensure the action is executed exactly once in the process (i.e. synchronized across all
+ * threads and isolates) and that threads will block here until the action is guaranteed to have
+ * been executed. Note that each {@code barrier} is specific to a specific {@code action} and
+ * cannot be used for any other action.
+ */
+ private static boolean execute(Runnable action, Pointer barrier) {
+ if (barrier.isNull()) {
+ action.run();
+ return true;
+ }
+ final long initial = 0L;
+ final long executing = 1L;
+ final long executed = 2L;
+
+ while (true) {
+ long value = barrier.readLong(0);
+ if (value == initial) {
+ if (barrier.compareAndSwapLong(0, value, executing, ANY_LOCATION) == value) {
+ action.run();
+ barrier.writeLong(0, executed);
+ return true;
+ }
+ } else {
+ if (value == executed) {
+ return false;
+ }
+ try {
+ Thread.sleep(5);
+ } catch (InterruptedException e) {
+ }
+ value = barrier.readLong(0);
+ }
+ }
+ }
+
/**
* An option for a configurable file name that can also open a {@link PrintStream} on the file.
* If no value is given for the option, the stream will output to HotSpot's
@@ -84,10 +142,16 @@ public class HotSpotTTYStreamProvider implements TTYStreamProvider {
private static String makeFilename(String nameTemplate) {
String name = nameTemplate;
if (name.contains("%p")) {
- name = name.replaceAll("%p", GraalServices.getExecutionID());
+ name = name.replace("%p", GraalServices.getExecutionID());
+ }
+ if (name.contains("%i")) {
+ name = name.replace("%i", IsolateUtil.getIsolateID(false));
+ }
+ if (name.contains("%I")) {
+ name = name.replace("%I", IsolateUtil.getIsolateID(true));
}
if (name.contains("%t")) {
- name = name.replaceAll("%t", String.valueOf(System.currentTimeMillis()));
+ name = name.replace("%t", String.valueOf(System.currentTimeMillis()));
}
for (String subst : new String[]{"%o", "%e"}) {
@@ -108,7 +172,7 @@ public class HotSpotTTYStreamProvider implements TTYStreamProvider {
class DelayedOutputStream extends OutputStream {
@NativeImageReinitialize private volatile OutputStream lazy;
- private OutputStream lazy() {
+ private OutputStream lazy() throws FileNotFoundException {
if (lazy == null) {
synchronized (this) {
if (lazy == null) {
@@ -123,27 +187,29 @@ public class HotSpotTTYStreamProvider implements TTYStreamProvider {
lazy = System.err;
break;
default:
- try {
- final boolean enableAutoflush = true;
- FileOutputStream result = new FileOutputStream(name);
- if (!Services.IS_IN_NATIVE_IMAGE) {
- printVMConfig(enableAutoflush, result);
- } else {
- // There are no VM arguments for the libgraal
- // library.
+ boolean executed = execute(() -> {
+ File file = new File(name);
+ if (file.exists()) {
+ file.delete();
}
- lazy = result;
- } catch (FileNotFoundException e) {
- throw new RuntimeException("couldn't open file: " + name, e);
+ }, getBarrierPointer());
+ final boolean enableAutoflush = true;
+ FileOutputStream result = new FileOutputStream(name, true);
+ if (executed) {
+ printVMConfig(enableAutoflush, result);
}
+ lazy = result;
}
return lazy;
}
lazy = HotSpotJVMCIRuntime.runtime().getLogStream();
- PrintStream ps = new PrintStream(lazy);
- ps.printf("[Use -D%sLogFile= to redirect Graal log output to a file.]%n", GRAAL_OPTION_PROPERTY_PREFIX);
- ps.flush();
+ execute(() -> {
+ PrintStream ps = new PrintStream(lazy);
+ ps.printf("[Use -D%sLogFile= to redirect Graal log output to a file.]%n", GRAAL_OPTION_PROPERTY_PREFIX);
+ ps.flush();
+
+ }, getBarrierPointer());
}
}
}
@@ -195,5 +261,4 @@ public class HotSpotTTYStreamProvider implements TTYStreamProvider {
return new PrintStream(new DelayedOutputStream());
}
}
-
}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JFRCompilerProfiler.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JFRCompilerProfiler.java
new file mode 100644
index 00000000000..626c5c908ce
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JFRCompilerProfiler.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.hotspot;
+
+import org.graalvm.compiler.core.common.CompilerProfiler;
+import org.graalvm.compiler.serviceprovider.ServiceProvider;
+
+import jdk.vm.ci.hotspot.JFR;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+/**
+ * A HotSpot JFR implementation of {@link CompilerProfiler}.
+ */
+@ServiceProvider(CompilerProfiler.class)
+public final class JFRCompilerProfiler implements CompilerProfiler {
+
+ @Override
+ public long getTicks() {
+ return JFR.Ticks.now();
+ }
+
+ @Override
+ public void notifyCompilerPhaseEvent(int compileId, long startTime, String name, int nestingLevel) {
+ JFR.CompilerPhaseEvent.write(startTime, name, compileId, nestingLevel);
+ }
+
+ @Override
+ public void notifyCompilerInlingEvent(int compileId, ResolvedJavaMethod caller, ResolvedJavaMethod callee,
+ boolean succeeded, String message, int bci) {
+ JFR.CompilerInliningEvent.write(compileId, caller, callee, succeeded, message, bci);
+ }
+
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java
index 270bde1fb91..c25b74b3f16 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2020, 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
@@ -43,11 +43,18 @@ import java.util.regex.Pattern;
*/
public final class JVMCIVersionCheck {
- private static final Version JVMCI_MIN_VERSION = new Version3(19, 3, 4);
+ private static final Version JVMCI_MIN_VERSION = new Version3(20, 1, 2);
public interface Version {
boolean isLessThan(Version other);
+ default boolean isGreaterThan(Version other) {
+ if (!isLessThan(other)) {
+ return !equals(other);
+ }
+ return false;
+ }
+
static Version parse(String vmVersion) {
Matcher m = Pattern.compile(".*-jvmci-(\\d+)\\.(\\d+)-b(\\d+).*").matcher(vmVersion);
if (m.matches()) {
@@ -98,6 +105,20 @@ public final class JVMCIVersionCheck {
return false;
}
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof Version2) {
+ Version2 that = (Version2) obj;
+ return this.major == that.major && this.minor == that.minor;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return this.major ^ this.minor;
+ }
+
@Override
public String toString() {
if (major >= 19) {
@@ -139,6 +160,20 @@ public final class JVMCIVersionCheck {
return false;
}
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof Version3) {
+ Version3 that = (Version3) obj;
+ return this.major == that.major && this.minor == that.minor && this.build == that.build;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return this.major ^ this.minor ^ this.build;
+ }
+
@Override
public String toString() {
return String.format("%d.%d-b%02d", major, minor, build);
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/SymbolicSnippetEncoder.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/SymbolicSnippetEncoder.java
index 5c6ff405f32..a210a721e3b 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/SymbolicSnippetEncoder.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/SymbolicSnippetEncoder.java
@@ -24,10 +24,10 @@
package org.graalvm.compiler.hotspot;
-import static jdk.vm.ci.runtime.JVMCI.getRuntime;
import static jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE;
import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE;
import static org.graalvm.compiler.core.common.GraalOptions.UseEncodedGraphs;
+import static org.graalvm.compiler.hotspot.EncodedSnippets.methodKey;
import static org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo.createIntrinsicInlineInfo;
import static org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.CompilationContext.INLINE_AFTER_PARSING;
import static org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.CompilationContext.ROOT_COMPILATION_ENCODING;
@@ -43,13 +43,10 @@ import java.util.Set;
import jdk.internal.vm.compiler.collections.EconomicMap;
import jdk.internal.vm.compiler.collections.EconomicSet;
import jdk.internal.vm.compiler.collections.MapCursor;
-import jdk.internal.vm.compiler.collections.UnmodifiableEconomicMap;
import org.graalvm.compiler.api.replacements.Fold;
import org.graalvm.compiler.api.replacements.MethodSubstitution;
import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
-import org.graalvm.compiler.api.runtime.GraalJVMCICompiler;
-import org.graalvm.compiler.api.runtime.GraalRuntime;
import org.graalvm.compiler.bytecode.BytecodeProvider;
import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode;
import org.graalvm.compiler.core.common.type.AbstractObjectStamp;
@@ -62,13 +59,18 @@ import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.NodeMap;
import org.graalvm.compiler.graph.NodeSourcePosition;
+import org.graalvm.compiler.hotspot.EncodedSnippets.GraalCapability;
+import org.graalvm.compiler.hotspot.EncodedSnippets.SymbolicEncodedGraph;
+import org.graalvm.compiler.hotspot.EncodedSnippets.SymbolicResolvedJavaField;
+import org.graalvm.compiler.hotspot.EncodedSnippets.SymbolicResolvedJavaMethod;
+import org.graalvm.compiler.hotspot.EncodedSnippets.SymbolicResolvedJavaMethodBytecode;
+import org.graalvm.compiler.hotspot.EncodedSnippets.SymbolicStampPair;
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.java.BytecodeParser;
import org.graalvm.compiler.java.GraphBuilderPhase;
import org.graalvm.compiler.nodeinfo.Verbosity;
import org.graalvm.compiler.nodes.CallTargetNode;
-import org.graalvm.compiler.nodes.Cancellable;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.EncodedGraph;
import org.graalvm.compiler.nodes.FrameState;
@@ -91,6 +93,7 @@ import org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.ParameterPlugin;
import org.graalvm.compiler.nodes.java.AccessFieldNode;
import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+import org.graalvm.compiler.nodes.spi.SnippetParameterInfo;
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.OptimisticOptimizations;
@@ -117,8 +120,6 @@ import jdk.vm.ci.meta.MethodHandleAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
-import jdk.vm.ci.meta.UnresolvedJavaField;
-import jdk.vm.ci.meta.UnresolvedJavaMethod;
import jdk.vm.ci.meta.UnresolvedJavaType;
/**
@@ -134,14 +135,9 @@ public class SymbolicSnippetEncoder {
*/
private final HotSpotSnippetReplacementsImpl snippetReplacements;
- /**
- * The set of all snippet methods that have been encoded.
- */
- private final Set snippetMethods = Collections.synchronizedSet(new HashSet<>());
-
/**
* A mapping from the method substitution method to the original method name. The string key and
- * values are produced using {@link #methodKey(ResolvedJavaMethod)}.
+ * values are produced using {@link EncodedSnippets#methodKey(ResolvedJavaMethod)}.
*/
private final EconomicMap originalMethods = EconomicMap.create();
@@ -158,6 +154,8 @@ public class SymbolicSnippetEncoder {
*/
private EconomicMap preparedSnippetGraphs = EconomicMap.create();
+ private EconomicMap snippetParameterInfos = EconomicMap.create();
+
private EconomicSet knownPlugins = EconomicSet.create();
private EconomicSet conditionalPlugins = EconomicSet.create();
@@ -173,8 +171,11 @@ public class SymbolicSnippetEncoder {
delayedInvocationPluginMethods.add(method);
}
- Set getSnippetMethods() {
- return snippetMethods;
+ public void clearSnippetParameterNames() {
+ MapCursor cursor = snippetParameterInfos.getEntries();
+ while (cursor.advance()) {
+ cursor.getValue().clearNames();
+ }
}
protected class SnippetInlineInvokePlugin implements InlineInvokePlugin {
@@ -242,14 +243,6 @@ public class SymbolicSnippetEncoder {
}
}
- /**
- * Generate a String name for a method including all type information. Used as a symbolic key
- * for lookup.
- */
- private static String methodKey(ResolvedJavaMethod method) {
- return method.format("%H.%n(%P)");
- }
-
SymbolicSnippetEncoder(HotSpotReplacementsImpl replacements) {
this.originalReplacements = replacements;
GraphBuilderConfiguration.Plugins plugins = replacements.getGraphBuilderPlugins();
@@ -285,135 +278,10 @@ public class SymbolicSnippetEncoder {
assert method.getAnnotation(MethodSubstitution.class) != null : "MethodSubstitution must be annotated with @" + MethodSubstitution.class.getSimpleName();
String originalMethodString = plugin.originalMethodAsString();
StructuredGraph subst = buildGraph(method, original, originalMethodString, null, true, false, context, options);
- snippetMethods.add(method);
originalMethods.put(methodKey(method), originalMethodString);
preparedSnippetGraphs.put(plugin.toString() + context, subst);
}
- public static class EncodedSnippets {
- private final byte[] snippetEncoding;
- private final Object[] snippetObjects;
- private final NodeClass>[] snippetNodeClasses;
- private final UnmodifiableEconomicMap snippetStartOffsets;
- private final UnmodifiableEconomicMap originalMethods;
-
- EncodedSnippets(byte[] snippetEncoding, Object[] snippetObjects, NodeClass>[] snippetNodeClasses, UnmodifiableEconomicMap snippetStartOffsets,
- UnmodifiableEconomicMap originalMethods) {
- this.snippetEncoding = snippetEncoding;
- this.snippetObjects = snippetObjects;
- this.snippetNodeClasses = snippetNodeClasses;
- this.snippetStartOffsets = snippetStartOffsets;
- this.originalMethods = originalMethods;
- }
-
- public byte[] getSnippetEncoding() {
- return snippetEncoding;
- }
-
- public NodeClass>[] getSnippetNodeClasses() {
- return snippetNodeClasses;
- }
-
- public UnmodifiableEconomicMap getSnippetStartOffsets() {
- return snippetStartOffsets;
- }
-
- public UnmodifiableEconomicMap getOriginalMethods() {
- return originalMethods;
- }
-
- StructuredGraph getMethodSubstitutionGraph(MethodSubstitutionPlugin plugin, ResolvedJavaMethod original, ReplacementsImpl replacements, IntrinsicContext.CompilationContext context,
- StructuredGraph.AllowAssumptions allowAssumptions, Cancellable cancellable, OptionValues options) {
- IntrinsicContext.CompilationContext contextToUse = context;
- if (context == IntrinsicContext.CompilationContext.ROOT_COMPILATION) {
- contextToUse = IntrinsicContext.CompilationContext.ROOT_COMPILATION_ENCODING;
- }
- Integer startOffset = snippetStartOffsets.get(plugin.toString() + contextToUse);
- if (startOffset == null) {
- throw GraalError.shouldNotReachHere("plugin graph not found: " + plugin + " with " + contextToUse);
- }
-
- ResolvedJavaType accessingClass = replacements.getProviders().getMetaAccess().lookupJavaType(plugin.getDeclaringClass());
- return decodeGraph(original, accessingClass, startOffset, replacements, contextToUse, allowAssumptions, cancellable, options);
- }
-
- @SuppressWarnings("try")
- private StructuredGraph decodeGraph(ResolvedJavaMethod method,
- ResolvedJavaType accessingClass,
- int startOffset,
- ReplacementsImpl replacements,
- IntrinsicContext.CompilationContext context,
- StructuredGraph.AllowAssumptions allowAssumptions,
- Cancellable cancellable,
- OptionValues options) {
- Providers providers = replacements.getProviders();
- EncodedGraph encodedGraph = new SymbolicEncodedGraph(snippetEncoding, startOffset, snippetObjects, snippetNodeClasses,
- methodKey(method), accessingClass, method.getDeclaringClass());
- try (DebugContext debug = replacements.openDebugContext("SVMSnippet_", method, options)) {
- StructuredGraph result = new StructuredGraph.Builder(options, debug, allowAssumptions).cancellable(cancellable).method(method).setIsSubstitution(true).build();
- PEGraphDecoder graphDecoder = new SubstitutionGraphDecoder(providers, result, replacements, null, method, context, encodedGraph);
-
- graphDecoder.decode(method, result.isSubstitution(), encodedGraph.trackNodeSourcePosition());
-
- assert result.verify();
- return result;
- }
- }
-
- StructuredGraph getEncodedSnippet(ResolvedJavaMethod method, ReplacementsImpl replacements, Object[] args, StructuredGraph.AllowAssumptions allowAssumptions, OptionValues options) {
- Integer startOffset = null;
- if (snippetStartOffsets != null) {
- startOffset = snippetStartOffsets.get(methodKey(method));
- }
- if (startOffset == null) {
- if (IS_IN_NATIVE_IMAGE) {
- throw GraalError.shouldNotReachHere("snippet not found: " + method.format("%H.%n(%p)"));
- } else {
- return null;
- }
- }
-
- SymbolicEncodedGraph encodedGraph = new SymbolicEncodedGraph(snippetEncoding, startOffset, snippetObjects, snippetNodeClasses,
- originalMethods.get(methodKey(method)), method.getDeclaringClass());
- return decodeSnippetGraph(encodedGraph, method, replacements, args, allowAssumptions, options);
- }
-
- }
-
- private static class SubstitutionGraphDecoder extends PEGraphDecoder {
- private final ResolvedJavaMethod method;
- private final EncodedGraph encodedGraph;
- private IntrinsicContext intrinsic;
-
- SubstitutionGraphDecoder(Providers providers, StructuredGraph result, ReplacementsImpl replacements, ParameterPlugin parameterPlugin, ResolvedJavaMethod method,
- IntrinsicContext.CompilationContext context, EncodedGraph encodedGraph) {
- super(providers.getCodeCache().getTarget().arch, result, providers, null,
- replacements.getGraphBuilderPlugins().getInvocationPlugins(), new InlineInvokePlugin[0], parameterPlugin,
- null, null, null, null);
- this.method = method;
- this.encodedGraph = encodedGraph;
- intrinsic = new IntrinsicContext(method, null, replacements.getDefaultReplacementBytecodeProvider(), context, false);
- }
-
- @Override
- protected EncodedGraph lookupEncodedGraph(ResolvedJavaMethod lookupMethod,
- MethodSubstitutionPlugin plugin,
- BytecodeProvider intrinsicBytecodeProvider,
- boolean isSubstitution,
- boolean trackNodeSourcePosition) {
- if (lookupMethod.equals(method)) {
- return encodedGraph;
- } else {
- throw GraalError.shouldNotReachHere(method.format("%H.%n(%p)"));
- }
- }
-
- @Override
- protected IntrinsicContext getIntrinsic() {
- return intrinsic;
- }
- }
-
private StructuredGraph buildGraph(ResolvedJavaMethod method, ResolvedJavaMethod original, String originalMethodString, Object receiver, boolean requireInlining, boolean trackNodeSourcePosition,
IntrinsicContext.CompilationContext context, OptionValues options) {
assert method.hasBytecodes() : "Snippet must not be abstract or native";
@@ -460,16 +328,17 @@ public class SymbolicSnippetEncoder {
try (DebugContext debug = replacements.openDebugContext("SVMSnippet_", method, options)) {
// @formatter:off
+ boolean isSubstitution = true;
StructuredGraph result = new StructuredGraph.Builder(options, debug, allowAssumptions)
.method(method)
.trackNodeSourcePosition(encodedGraph.trackNodeSourcePosition())
- .setIsSubstitution(true)
+ .setIsSubstitution(isSubstitution)
.build();
// @formatter:on
try (DebugContext.Scope scope = debug.scope("DecodeSnippetGraph", result)) {
- PEGraphDecoder graphDecoder = new SubstitutionGraphDecoder(providers, result, replacements, parameterPlugin, method, INLINE_AFTER_PARSING, encodedGraph);
+ PEGraphDecoder graphDecoder = new EncodedSnippets.SubstitutionGraphDecoder(providers, result, replacements, parameterPlugin, method, INLINE_AFTER_PARSING, encodedGraph);
- graphDecoder.decode(method, result.isSubstitution(), encodedGraph.trackNodeSourcePosition());
+ graphDecoder.decode(method, isSubstitution, encodedGraph.trackNodeSourcePosition());
debug.dump(DebugContext.VERBOSE_LEVEL, result, "After decoding");
assert result.verify();
@@ -494,7 +363,7 @@ public class SymbolicSnippetEncoder {
HotSpotProviders newProviders = new HotSpotProviders(originalProvider.getMetaAccess(), originalProvider.getCodeCache(), constantReflection,
originalProvider.getConstantFieldProvider(), originalProvider.getForeignCalls(), originalProvider.getLowerer(), null, originalProvider.getSuites(),
originalProvider.getRegisters(), snippetReflection, originalProvider.getWordTypes(), originalProvider.getGraphBuilderPlugins(),
- originalProvider.getPlatformConfigurationProvider());
+ originalProvider.getPlatformConfigurationProvider(), originalProvider.getMetaAccessExtensionProvider());
HotSpotSnippetReplacementsImpl filteringReplacements = new HotSpotSnippetReplacementsImpl(newProviders, snippetReflection,
originalProvider.getReplacements().getDefaultReplacementBytecodeProvider(), originalProvider.getCodeCache().getTarget());
filteringReplacements.setGraphBuilderPlugins(originalProvider.getReplacements().getGraphBuilderPlugins());
@@ -567,8 +436,8 @@ public class SymbolicSnippetEncoder {
originalMethods.put(key, methodKey(original));
}
StructuredGraph snippet = buildGraph(method, original, null, receiver, true, trackNodeSourcePosition, INLINE_AFTER_PARSING, options);
- snippetMethods.add(method);
preparedSnippetGraphs.put(key, snippet);
+ snippetParameterInfos.put(key, new SnippetParameterInfo(method));
}
}
@@ -600,7 +469,7 @@ public class SymbolicSnippetEncoder {
snippetObjects[i] = o;
}
debug.log("Encoded %d snippet preparedSnippetGraphs using %d bytes with %d objects", snippetStartOffsets.size(), snippetEncoding.length, snippetObjects.length);
- return new EncodedSnippets(snippetEncoding, snippetObjects, snippetNodeClasses, snippetStartOffsets, originalMethods);
+ return new EncodedSnippets(snippetEncoding, snippetObjects, snippetNodeClasses, snippetStartOffsets, originalMethods, snippetParameterInfos);
}
/**
@@ -608,10 +477,12 @@ public class SymbolicSnippetEncoder {
*/
@SuppressWarnings("try")
public boolean encode(OptionValues options) {
- EncodedSnippets encodedSnippets = maybeEncodeSnippets(options);
- if (encodedSnippets != null) {
- HotSpotReplacementsImpl.setEncodedSnippets(encodedSnippets);
- return true;
+ if (!IS_IN_NATIVE_IMAGE) {
+ EncodedSnippets encodedSnippets = maybeEncodeSnippets(options);
+ if (encodedSnippets != null) {
+ HotSpotReplacementsImpl.setEncodedSnippets(encodedSnippets);
+ return true;
+ }
}
return false;
}
@@ -620,216 +491,6 @@ public class SymbolicSnippetEncoder {
return snippetReplacements.openDebugContext(idPrefix, method, options);
}
- static class SymbolicEncodedGraph extends EncodedGraph {
-
- private final ResolvedJavaType[] accessingClasses;
- private final String originalMethod;
-
- SymbolicEncodedGraph(byte[] encoding, int startOffset, Object[] objects, NodeClass>[] types, String originalMethod, ResolvedJavaType... accessingClasses) {
- super(encoding, startOffset, objects, types, null, null, null, false, false);
- this.accessingClasses = accessingClasses;
- this.originalMethod = originalMethod;
- }
-
- SymbolicEncodedGraph(EncodedGraph encodedGraph, ResolvedJavaType declaringClass, String originalMethod) {
- this(encodedGraph.getEncoding(), encodedGraph.getStartOffset(), encodedGraph.getObjects(), encodedGraph.getNodeClasses(),
- originalMethod, declaringClass);
- }
-
- @Override
- public Object getObject(int i) {
- Object o = objects[i];
- Object replacement = null;
- if (o instanceof SymbolicJVMCIReference) {
- for (ResolvedJavaType type : accessingClasses) {
- try {
- replacement = ((SymbolicJVMCIReference>) o).resolve(type);
- break;
- } catch (NoClassDefFoundError e) {
- }
- }
- } else if (o instanceof UnresolvedJavaType) {
- for (ResolvedJavaType type : accessingClasses) {
- try {
- replacement = ((UnresolvedJavaType) o).resolve(type);
- break;
- } catch (NoClassDefFoundError e) {
- }
- }
- } else if (o instanceof UnresolvedJavaMethod) {
- throw new InternalError(o.toString());
- } else if (o instanceof UnresolvedJavaField) {
- for (ResolvedJavaType type : accessingClasses) {
- try {
- replacement = ((UnresolvedJavaField) o).resolve(type);
- break;
- } catch (NoClassDefFoundError e) {
- }
- }
- } else if (o instanceof GraalCapability) {
- replacement = ((GraalCapability) o).resolve(((GraalJVMCICompiler) getRuntime().getCompiler()).getGraalRuntime());
- } else {
- return o;
- }
- if (replacement != null) {
- objects[i] = o = replacement;
- } else {
- throw new GraalError("Can't resolve " + o);
- }
- return o;
- }
-
- @Override
- public boolean isCallToOriginal(ResolvedJavaMethod callTarget) {
- if (originalMethod != null && originalMethod.equals(methodKey(callTarget))) {
- return true;
- }
- return super.isCallToOriginal(callTarget);
- }
- }
-
- /**
- * Symbolic reference to an object which can be retrieved from
- * {@link GraalRuntime#getCapability(Class)}.
- */
- static class GraalCapability {
- final Class> capabilityClass;
-
- GraalCapability(Class> capabilityClass) {
- this.capabilityClass = capabilityClass;
- }
-
- public Object resolve(GraalRuntime runtime) {
- Object capability = runtime.getCapability(this.capabilityClass);
- if (capability != null) {
- assert capability.getClass() == capabilityClass;
- return capability;
- }
- throw new InternalError(this.capabilityClass.getName());
- }
- }
-
- static class SymbolicResolvedJavaMethod implements SymbolicJVMCIReference {
- final UnresolvedJavaType type;
- final String methodName;
- final String signature;
-
- SymbolicResolvedJavaMethod(ResolvedJavaMethod method) {
- this.type = UnresolvedJavaType.create(method.getDeclaringClass().getName());
- this.methodName = method.getName();
- this.signature = method.getSignature().toMethodDescriptor();
- }
-
- @Override
- public String toString() {
- return "SymbolicResolvedJavaMethod{" +
- "declaringType='" + type.getName() + '\'' +
- ", methodName='" + methodName + '\'' +
- ", signature='" + signature + '\'' +
- '}';
- }
-
- @Override
- public ResolvedJavaMethod resolve(ResolvedJavaType accessingClass) {
- ResolvedJavaType resolvedType = type.resolve(accessingClass);
- if (resolvedType == null) {
- throw new InternalError("Could not resolve " + this + " in context of " + accessingClass.toJavaName());
- }
- for (ResolvedJavaMethod method : methodName.equals("") ? resolvedType.getDeclaredConstructors() : resolvedType.getDeclaredMethods()) {
- if (method.getName().equals(methodName) && method.getSignature().toMethodDescriptor().equals(signature)) {
- return method;
- }
- }
- throw new InternalError("Could not resolve " + this + " in context of " + accessingClass.toJavaName());
- }
- }
-
- static class SymbolicResolvedJavaField implements SymbolicJVMCIReference {
- final UnresolvedJavaType declaringType;
- final String name;
- final UnresolvedJavaType signature;
- private final boolean isStatic;
-
- SymbolicResolvedJavaField(ResolvedJavaField field) {
- this.declaringType = UnresolvedJavaType.create(field.getDeclaringClass().getName());
- this.name = field.getName();
- this.signature = UnresolvedJavaType.create(field.getType().getName());
- this.isStatic = field.isStatic();
- }
-
- @Override
- public ResolvedJavaField resolve(ResolvedJavaType accessingClass) {
- ResolvedJavaType resolvedType = declaringType.resolve(accessingClass);
- ResolvedJavaType resolvedFieldType = signature.resolve(accessingClass);
- ResolvedJavaField[] fields = isStatic ? resolvedType.getStaticFields() : resolvedType.getInstanceFields(true);
- for (ResolvedJavaField field : fields) {
- if (field.getName().equals(name)) {
- if (field.getType().equals(resolvedFieldType)) {
- return field;
- }
- }
- }
- throw new InternalError("Could not resolve " + this + " in context of " + accessingClass.toJavaName());
- }
-
- @Override
- public String toString() {
- return "SymbolicResolvedJavaField{" +
- signature.getName() + ' ' +
- declaringType.getName() + '.' +
- name +
- '}';
- }
- }
-
- static class SymbolicResolvedJavaMethodBytecode implements SymbolicJVMCIReference {
- SymbolicResolvedJavaMethod method;
-
- SymbolicResolvedJavaMethodBytecode(ResolvedJavaMethodBytecode bytecode) {
- method = new SymbolicResolvedJavaMethod(bytecode.getMethod());
- }
-
- @Override
- public ResolvedJavaMethodBytecode resolve(ResolvedJavaType accessingClass) {
- return new ResolvedJavaMethodBytecode(method.resolve(accessingClass));
- }
- }
-
- static class SymbolicStampPair implements SymbolicJVMCIReference {
- Object trustedStamp;
- Object uncheckdStamp;
-
- SymbolicStampPair(StampPair stamp) {
- this.trustedStamp = maybeMakeSymbolic(stamp.getTrustedStamp());
- this.uncheckdStamp = maybeMakeSymbolic(stamp.getUncheckedStamp());
- }
-
- @Override
- public StampPair resolve(ResolvedJavaType accessingClass) {
- return StampPair.create(resolveStamp(accessingClass, trustedStamp), resolveStamp(accessingClass, uncheckdStamp));
- }
- }
-
- private static Object maybeMakeSymbolic(Stamp trustedStamp) {
- if (trustedStamp != null) {
- SymbolicJVMCIReference> symbolicJVMCIReference = trustedStamp.makeSymbolic();
- if (symbolicJVMCIReference != null) {
- return symbolicJVMCIReference;
- }
- }
- return trustedStamp;
- }
-
- private static Stamp resolveStamp(ResolvedJavaType accessingClass, Object stamp) {
- if (stamp == null) {
- return null;
- }
- if (stamp instanceof Stamp) {
- return (Stamp) stamp;
- }
- return (Stamp) ((SymbolicJVMCIReference>) stamp).resolve(accessingClass);
- }
-
public static class HotSpotSubstrateConstantReflectionProvider implements ConstantReflectionProvider {
private final ConstantReflectionProvider constantReflection;
@@ -1082,6 +743,12 @@ public class SymbolicSnippetEncoder {
protected GraphMaker createGraphMaker(ResolvedJavaMethod substitute, ResolvedJavaMethod original) {
return new SnippetGraphMaker(this, substitute, original);
}
+
+ @Override
+ public boolean isEncodingSnippets() {
+ return true;
+ }
+
}
class SnippetGraphMaker extends ReplacementsImpl.GraphMaker {
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java
index b47fd242732..bb7cd9713d3 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java
@@ -46,7 +46,9 @@ import org.graalvm.compiler.api.directives.GraalDirectives;
import org.graalvm.compiler.core.common.CompressEncoding;
import org.graalvm.compiler.core.common.GraalOptions;
import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
+import org.graalvm.compiler.core.common.spi.ForeignCallSignature;
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
+import org.graalvm.compiler.core.common.spi.MetaAccessExtensionProvider;
import org.graalvm.compiler.core.common.type.ObjectStamp;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.core.common.type.StampFactory;
@@ -144,12 +146,12 @@ import org.graalvm.compiler.nodes.java.InstanceOfDynamicNode;
import org.graalvm.compiler.nodes.java.InstanceOfNode;
import org.graalvm.compiler.nodes.java.LoadExceptionObjectNode;
import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+import org.graalvm.compiler.nodes.java.MonitorEnterNode;
import org.graalvm.compiler.nodes.java.MonitorExitNode;
import org.graalvm.compiler.nodes.java.MonitorIdNode;
import org.graalvm.compiler.nodes.java.NewArrayNode;
import org.graalvm.compiler.nodes.java.NewInstanceNode;
import org.graalvm.compiler.nodes.java.NewMultiArrayNode;
-import org.graalvm.compiler.nodes.java.RawMonitorEnterNode;
import org.graalvm.compiler.nodes.memory.FloatingReadNode;
import org.graalvm.compiler.nodes.memory.OnHeapMemoryAccess.BarrierType;
import org.graalvm.compiler.nodes.memory.ReadNode;
@@ -209,8 +211,9 @@ public abstract class DefaultHotSpotLoweringProvider extends DefaultJavaLowering
protected ForeignCallSnippets.Templates foreignCallSnippets;
public DefaultHotSpotLoweringProvider(HotSpotGraalRuntimeProvider runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers,
- HotSpotConstantReflectionProvider constantReflection, PlatformConfigurationProvider platformConfig, TargetDescription target) {
- super(metaAccess, foreignCalls, platformConfig, target, runtime.getVMConfig().useCompressedOops);
+ HotSpotConstantReflectionProvider constantReflection, PlatformConfigurationProvider platformConfig, MetaAccessExtensionProvider metaAccessExtensionProvider,
+ TargetDescription target) {
+ super(metaAccess, foreignCalls, platformConfig, metaAccessExtensionProvider, target, runtime.getVMConfig().useCompressedOops);
this.runtime = runtime;
this.registers = registers;
this.constantReflection = constantReflection;
@@ -296,7 +299,8 @@ public abstract class DefaultHotSpotLoweringProvider extends DefaultJavaLowering
if (instanceOfDynamicNode.allowsNull()) {
ValueNode object = instanceOfDynamicNode.getObject();
LogicNode newTypeCheck = graph.addOrUniqueWithInputs(
- InstanceOfDynamicNode.create(graph.getAssumptions(), tool.getConstantReflection(), instanceOfDynamicNode.getMirrorOrHub(), object, false));
+ InstanceOfDynamicNode.create(graph.getAssumptions(), tool.getConstantReflection(), instanceOfDynamicNode.getMirrorOrHub(), object,
+ false/* null checked below */, instanceOfDynamicNode.isExact()));
LogicNode newNode = LogicNode.or(graph.unique(IsNullNode.create(object)), newTypeCheck, GraalDirectives.UNLIKELY_PROBABILITY);
instanceOfDynamicNode.replaceAndDelete(newNode);
}
@@ -337,9 +341,11 @@ public abstract class DefaultHotSpotLoweringProvider extends DefaultJavaLowering
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
allocationSnippets.lower((VerifyHeapNode) n, tool);
}
- } else if (n instanceof RawMonitorEnterNode) {
+ } else if (n instanceof MonitorEnterNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
- monitorSnippets.lower((RawMonitorEnterNode) n, registers, tool);
+ monitorSnippets.lower((MonitorEnterNode) n, registers, tool);
+ } else {
+ loadHubForMonitorEnterNode((MonitorEnterNode) n, tool, graph);
}
} else if (n instanceof MonitorExitNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
@@ -427,6 +433,14 @@ public abstract class DefaultHotSpotLoweringProvider extends DefaultJavaLowering
}
+ protected void loadHubForMonitorEnterNode(MonitorEnterNode monitor, LoweringTool tool, StructuredGraph graph) {
+ if (monitor.getObjectData() == null) {
+ ValueNode objectNonNull = createNullCheckedValue(monitor.object(), monitor, tool);
+ monitor.setObject(objectNonNull);
+ monitor.setObjectData(graph.addOrUnique(LoadHubNode.create(objectNonNull, tool.getStampProvider(), tool.getMetaAccess(), tool.getConstantReflection())));
+ }
+ }
+
private static void lowerComputeObjectAddressNode(ComputeObjectAddressNode n) {
/*
* Lower the node into a ComputeObjectAddress node and an Add but ensure that it's below any
@@ -591,6 +605,7 @@ public abstract class DefaultHotSpotLoweringProvider extends DefaultJavaLowering
private void lowerStoreHubNode(StoreHubNode storeHub, StructuredGraph graph) {
WriteNode hub = createWriteHub(graph, storeHub.getObject(), storeHub.getValue());
+ hub.setStateAfter(storeHub.stateAfter());
graph.replaceFixed(storeHub, hub);
}
@@ -599,7 +614,7 @@ public abstract class DefaultHotSpotLoweringProvider extends DefaultJavaLowering
if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
StartNode newStart = graph.add(new StartNode());
ParameterNode buffer = graph.addWithoutUnique(new ParameterNode(0, StampPair.createSingle(StampFactory.forKind(runtime.getTarget().wordJavaKind))));
- ForeignCallNode migrationEnd = graph.add(new ForeignCallNode(foreignCalls, OSR_MIGRATION_END, buffer));
+ ForeignCallNode migrationEnd = graph.add(new ForeignCallNode(OSR_MIGRATION_END, buffer));
migrationEnd.setStateAfter(osrStart.stateAfter());
newStart.setNext(migrationEnd);
FixedNode next = osrStart.next();
@@ -649,7 +664,7 @@ public abstract class DefaultHotSpotLoweringProvider extends DefaultJavaLowering
// write the displaced mark to the correct stack slot
AddressNode addressDisplacedMark = createOffsetAddress(graph, beginLockScope, runtime.getVMConfig().basicLockDisplacedHeaderOffset);
- WriteNode writeStackSlot = graph.add(new WriteNode(addressDisplacedMark, DISPLACED_MARK_WORD_LOCATION, loadDisplacedHeader, BarrierType.NONE, false));
+ WriteNode writeStackSlot = graph.add(new WriteNode(addressDisplacedMark, DISPLACED_MARK_WORD_LOCATION, loadDisplacedHeader, BarrierType.NONE));
graph.addBeforeFixed(migrationEnd, writeStackSlot);
// load the lock object from the osr buffer
@@ -682,17 +697,17 @@ public abstract class DefaultHotSpotLoweringProvider extends DefaultJavaLowering
}
public static final class RuntimeCalls {
- public static final EnumMap runtimeCalls;
+ public static final EnumMap runtimeCalls;
static {
runtimeCalls = new EnumMap<>(BytecodeExceptionKind.class);
- runtimeCalls.put(BytecodeExceptionKind.ARRAY_STORE, new ForeignCallDescriptor("createArrayStoreException", ArrayStoreException.class, Object.class));
- runtimeCalls.put(BytecodeExceptionKind.CLASS_CAST, new ForeignCallDescriptor("createClassCastException", ClassCastException.class, Object.class, KlassPointer.class));
- runtimeCalls.put(BytecodeExceptionKind.NULL_POINTER, new ForeignCallDescriptor("createNullPointerException", NullPointerException.class));
- runtimeCalls.put(BytecodeExceptionKind.OUT_OF_BOUNDS, new ForeignCallDescriptor("createOutOfBoundsException", ArrayIndexOutOfBoundsException.class, int.class, int.class));
- runtimeCalls.put(BytecodeExceptionKind.DIVISION_BY_ZERO, new ForeignCallDescriptor("createDivisionByZeroException", ArithmeticException.class));
- runtimeCalls.put(BytecodeExceptionKind.INTEGER_EXACT_OVERFLOW, new ForeignCallDescriptor("createIntegerExactOverflowException", ArithmeticException.class));
- runtimeCalls.put(BytecodeExceptionKind.LONG_EXACT_OVERFLOW, new ForeignCallDescriptor("createLongExactOverflowException", ArithmeticException.class));
+ runtimeCalls.put(BytecodeExceptionKind.ARRAY_STORE, new ForeignCallSignature("createArrayStoreException", ArrayStoreException.class, Object.class));
+ runtimeCalls.put(BytecodeExceptionKind.CLASS_CAST, new ForeignCallSignature("createClassCastException", ClassCastException.class, Object.class, KlassPointer.class));
+ runtimeCalls.put(BytecodeExceptionKind.NULL_POINTER, new ForeignCallSignature("createNullPointerException", NullPointerException.class));
+ runtimeCalls.put(BytecodeExceptionKind.OUT_OF_BOUNDS, new ForeignCallSignature("createOutOfBoundsException", ArrayIndexOutOfBoundsException.class, int.class, int.class));
+ runtimeCalls.put(BytecodeExceptionKind.DIVISION_BY_ZERO, new ForeignCallSignature("createDivisionByZeroException", ArithmeticException.class));
+ runtimeCalls.put(BytecodeExceptionKind.INTEGER_EXACT_OVERFLOW, new ForeignCallSignature("createIntegerExactOverflowException", ArithmeticException.class));
+ runtimeCalls.put(BytecodeExceptionKind.LONG_EXACT_OVERFLOW, new ForeignCallSignature("createLongExactOverflowException", ArithmeticException.class));
}
}
@@ -714,18 +729,20 @@ public abstract class DefaultHotSpotLoweringProvider extends DefaultJavaLowering
return;
}
- ForeignCallDescriptor descriptor = RuntimeCalls.runtimeCalls.get(node.getExceptionKind());
+ ForeignCallDescriptor descriptor = foreignCalls.getDescriptor(RuntimeCalls.runtimeCalls.get(node.getExceptionKind()));
assert descriptor != null;
StructuredGraph graph = node.graph();
- ForeignCallNode foreignCallNode = graph.add(new ForeignCallNode(foreignCalls, descriptor, node.stamp(NodeView.DEFAULT), node.getArguments()));
+ ForeignCallNode foreignCallNode = graph.add(new ForeignCallNode(descriptor, node.stamp(NodeView.DEFAULT), node.getArguments()));
/*
* The original BytecodeExceptionNode has a rethrowException FrameState which isn't suitable
* for deopt because the exception to be thrown come from this call so it's not available in
* the debug info. The foreign call needs a stateDuring instead so it can deopt with a
* pending exception.
*/
- foreignCallNode.setStateAfter(node.createStateDuring());
+ foreignCallNode.setStateDuring(node.createStateDuring());
+ // Keep a proper stateAfter for use by FSA
+ foreignCallNode.setStateAfter(node.stateAfter());
graph.replaceFixedWithFixed(node, foreignCallNode);
}
@@ -774,7 +791,7 @@ public abstract class DefaultHotSpotLoweringProvider extends DefaultJavaLowering
}
AddressNode address = createOffsetAddress(graph, object, runtime.getVMConfig().hubOffset);
- return graph.add(new WriteNode(address, HUB_WRITE_LOCATION, writeValue, BarrierType.NONE, false));
+ return graph.add(new WriteNode(address, HUB_WRITE_LOCATION, writeValue, BarrierType.NONE));
}
@Override
@@ -787,11 +804,6 @@ public abstract class DefaultHotSpotLoweringProvider extends DefaultJavaLowering
return runtime.getVMConfig().arrayOopDescLengthOffset();
}
- @Override
- public final JavaKind getStorageKind(ResolvedJavaField field) {
- return field.getJavaKind();
- }
-
@Override
public ObjectCloneSnippets.Templates getObjectCloneSnippets() {
return objectCloneSnippets;
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotForeignCallDescriptor.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotForeignCallDescriptor.java
new file mode 100644
index 00000000000..66950383ebc
--- /dev/null
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotForeignCallDescriptor.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.hotspot.meta;
+
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Transition.SAFEPOINT;
+
+import java.util.Arrays;
+
+import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
+import org.graalvm.compiler.core.common.spi.ForeignCallSignature;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+
+public class HotSpotForeignCallDescriptor extends ForeignCallDescriptor {
+
+ /**
+ * Constants for specifying whether a call is a leaf or not and whether a
+ * {@code JavaFrameAnchor} prologue and epilogue is required around the call. A leaf function
+ * does not lock, GC or throw exceptions.
+ */
+ public enum Transition {
+ /**
+ * A call to a leaf function that is guaranteed to not use floating point registers.
+ * Consequently, floating point registers cleanup will be waived. On AMD64, this means the
+ * compiler will no longer emit vzeroupper instruction around the foreign call, which it
+ * normally does for unknown foreign calls to avoid potential SSE-AVX transition penalty.
+ * Besides, this foreign call will never have its caller stack inspected by the VM. That is,
+ * {@code JavaFrameAnchor} management around the call can be omitted.
+ */
+ LEAF_NO_VZERO,
+
+ /**
+ * A call to a leaf function that might use floating point registers but will never have its
+ * caller stack inspected. That is, {@code JavaFrameAnchor} management around the call can
+ * be omitted.
+ */
+ LEAF,
+
+ /**
+ * A call to a leaf function that might use floating point registers and may have its caller
+ * stack inspected. That is, {@code JavaFrameAnchor} management code around the call is
+ * required.
+ */
+ STACK_INSPECTABLE_LEAF,
+
+ /**
+ * A function that may lock, GC or raise an exception and thus requires debug info to be
+ * associated with a call site to the function. The execution stack may be inspected while
+ * in the called function. That is, {@code JavaFrameAnchor} management code around the call
+ * is required.
+ */
+ SAFEPOINT,
+ }
+
+ /**
+ * Constants specifying when a foreign call or stub call is re-executable.
+ */
+ public enum Reexecutability {
+ /**
+ * Denotes a call that cannot be re-executed. If an exception is raised, the call is
+ * deoptimized and the exception is passed on to be dispatched. If the call can throw an
+ * exception it needs to have a precise frame state.
+ */
+ NOT_REEXECUTABLE,
+
+ /**
+ * Denotes a call that can always be re-executed. If an exception is raised by the call it
+ * may be cleared, compiled code deoptimized and reexecuted. Since the call has no side
+ * effects it is assumed that the same exception will be thrown.
+ */
+ REEXECUTABLE
+ }
+
+ private final Transition transition;
+ private final Reexecutability reexecutability;
+
+ public HotSpotForeignCallDescriptor(Transition transition, Reexecutability reexecutability, LocationIdentity[] killedLocations, String name, Class> resultType, Class>... argumentTypes) {
+ super(name, resultType, argumentTypes, reexecutability == Reexecutability.REEXECUTABLE, killedLocations, transition == SAFEPOINT, transition == SAFEPOINT);
+ this.transition = transition;
+ this.reexecutability = reexecutability;
+ }
+
+ public HotSpotForeignCallDescriptor(Transition transition, Reexecutability reexecutability, LocationIdentity killedLocation, String name, Class> resultType, Class>... argumentTypes) {
+ this(transition, reexecutability, killedLocation == null ? HotSpotForeignCallsProviderImpl.NO_LOCATIONS : new LocationIdentity[]{killedLocation}, name, resultType, argumentTypes);
+ }
+
+ public HotSpotForeignCallDescriptor(ForeignCallSignature signature, Transition transition, Reexecutability reexecutability, LocationIdentity[] killedLocations) {
+ this(transition, reexecutability, killedLocations, signature.getName(), signature.getResultType(), signature.getArgumentTypes());
+ }
+
+ public Transition getTransition() {
+ return transition;
+ }
+
+ public Reexecutability getReexecutability() {
+ return reexecutability;
+ }
+
+ @Override
+ public String toString() {
+ return "HotSpotForeignCallDescriptor{" + signature +
+ ", isReexecutable=" + isReexecutable +
+ ", canDeoptimize=" + canDeoptimize +
+ ", isGuaranteedSafepoint=" + isGuaranteedSafepoint +
+ ", killedLocations=" + Arrays.toString(killedLocations) +
+ ", transition=" + transition +
+ ", reexecutability=" + reexecutability +
+ '}';
+ }
+}
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotForeignCallsProviderImpl.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotForeignCallsProviderImpl.java
index bcb595eab41..50ff33faf47 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotForeignCallsProviderImpl.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotForeignCallsProviderImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, 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
@@ -27,7 +27,12 @@ package org.graalvm.compiler.hotspot.meta;
import static jdk.vm.ci.hotspot.HotSpotCallingConventionType.JavaCall;
import static jdk.vm.ci.hotspot.HotSpotCallingConventionType.JavaCallee;
import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.DESTROYS_ALL_CALLER_SAVE_REGISTERS;
-import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.SAFEPOINT;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Reexecutability.NOT_REEXECUTABLE;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Reexecutability.REEXECUTABLE;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Transition.LEAF_NO_VZERO;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Transition.SAFEPOINT;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.MARK_WORD_LOCATION;
+import static jdk.internal.vm.compiler.word.LocationIdentity.any;
import java.util.ArrayList;
import java.util.List;
@@ -35,13 +40,14 @@ import java.util.List;
import jdk.internal.vm.compiler.collections.EconomicMap;
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
+import org.graalvm.compiler.core.common.spi.ForeignCallSignature;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
-import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability;
import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect;
-import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition;
import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkageImpl;
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
+import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Reexecutability;
+import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Transition;
import org.graalvm.compiler.hotspot.stubs.ForeignCallStub;
import org.graalvm.compiler.hotspot.stubs.Stub;
import org.graalvm.compiler.options.OptionValues;
@@ -60,17 +66,23 @@ import jdk.vm.ci.meta.MetaAccessProvider;
*/
public abstract class HotSpotForeignCallsProviderImpl implements HotSpotForeignCallsProvider {
- public static final ForeignCallDescriptor OSR_MIGRATION_END = new ForeignCallDescriptor("OSR_migration_end", void.class, long.class);
- public static final ForeignCallDescriptor IDENTITY_HASHCODE = new ForeignCallDescriptor("identity_hashcode", int.class, Object.class);
- public static final ForeignCallDescriptor VERIFY_OOP = new ForeignCallDescriptor("verify_oop", Object.class, Object.class);
- public static final ForeignCallDescriptor LOAD_AND_CLEAR_EXCEPTION = new ForeignCallDescriptor("load_and_clear_exception", Object.class, Word.class);
+ public static final LocationIdentity[] NO_LOCATIONS = {};
- public static final ForeignCallDescriptor TEST_DEOPTIMIZE_CALL_INT = new ForeignCallDescriptor("test_deoptimize_call_int", int.class, int.class);
+ public static final HotSpotForeignCallDescriptor OSR_MIGRATION_END = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, NOT_REEXECUTABLE, NO_LOCATIONS, "OSR_migration_end", void.class, long.class);
+ public static final HotSpotForeignCallDescriptor IDENTITY_HASHCODE = new HotSpotForeignCallDescriptor(SAFEPOINT, NOT_REEXECUTABLE, MARK_WORD_LOCATION, "identity_hashcode", int.class,
+ Object.class);
+ public static final HotSpotForeignCallDescriptor VERIFY_OOP = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS, "verify_oop", Object.class,
+ Object.class);
+ public static final HotSpotForeignCallDescriptor LOAD_AND_CLEAR_EXCEPTION = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, NOT_REEXECUTABLE, any(), "load_and_clear_exception", Object.class,
+ Word.class);
+
+ public static final HotSpotForeignCallDescriptor TEST_DEOPTIMIZE_CALL_INT = new HotSpotForeignCallDescriptor(SAFEPOINT, REEXECUTABLE, any(), "test_deoptimize_call_int", int.class, int.class);
protected final HotSpotJVMCIRuntime jvmciRuntime;
protected final HotSpotGraalRuntimeProvider runtime;
- protected final EconomicMap foreignCalls = EconomicMap.create();
+ protected final EconomicMap foreignCalls = EconomicMap.create();
+ protected final EconomicMap signatureMap = EconomicMap.create();
protected final MetaAccessProvider metaAccess;
protected final CodeCacheProvider codeCache;
protected final WordTypes wordTypes;
@@ -88,34 +100,19 @@ public abstract class HotSpotForeignCallsProviderImpl implements HotSpotForeignC
* Registers the linkage for a foreign call.
*/
public HotSpotForeignCallLinkage register(HotSpotForeignCallLinkage linkage) {
- assert !foreignCalls.containsKey(linkage.getDescriptor()) : "already registered linkage for " + linkage.getDescriptor();
- foreignCalls.put(linkage.getDescriptor(), linkage);
+ assert !foreignCalls.containsKey(linkage.getDescriptor().getSignature()) : "already registered linkage for " + linkage.getDescriptor();
+ foreignCalls.put(linkage.getDescriptor().getSignature(), linkage);
return linkage;
}
- /**
- * Return true if the descriptor has already been registered.
- */
- public boolean isRegistered(ForeignCallDescriptor descriptor) {
- return foreignCalls.containsKey(descriptor);
- }
-
/**
* Creates and registers the details for linking a foreign call to a {@link Stub}.
*
* @param descriptor the signature of the call to the stub
- * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call
- * @param reexecutability specifies if the stub call can be re-executed without (meaningful)
- * side effects. Deoptimization will not return to a point before a stub call that
- * cannot be re-executed.
- * @param killedLocations the memory locations killed by the stub call
*/
public HotSpotForeignCallLinkage registerStubCall(
- ForeignCallDescriptor descriptor,
- Transition transition,
- Reexecutability reexecutability,
- RegisterEffect effect,
- LocationIdentity... killedLocations) {
+ HotSpotForeignCallDescriptor descriptor,
+ RegisterEffect effect) {
return register(HotSpotForeignCallLinkageImpl.create(metaAccess,
codeCache,
wordTypes,
@@ -123,10 +120,18 @@ public abstract class HotSpotForeignCallsProviderImpl implements HotSpotForeignC
descriptor,
0L, effect,
JavaCall,
- JavaCallee,
- transition,
- reexecutability,
- killedLocations));
+ JavaCallee));
+ }
+
+ public HotSpotForeignCallLinkage registerStubCall(
+ ForeignCallSignature signature,
+ Transition transition,
+ Reexecutability reexecutability,
+ RegisterEffect effect,
+ LocationIdentity... killedLocations) {
+ HotSpotForeignCallDescriptor descriptor = new HotSpotForeignCallDescriptor(signature, transition, reexecutability, killedLocations);
+ signatureMap.put(signature, descriptor);
+ return registerStubCall(descriptor, effect);
}
/**
@@ -137,22 +142,17 @@ public abstract class HotSpotForeignCallsProviderImpl implements HotSpotForeignC
* @param descriptor the signature of the foreign call
* @param address the address of the code to call (must be non-zero)
* @param outgoingCcType outgoing (caller) calling convention type
- * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call
- * @param reexecutability specifies if the foreign call can be re-executed without (meaningful)
- * side effects. Deoptimization will not return to a point before a foreign call that
- * cannot be re-executed.
- * @param killedLocations the memory locations killed by the foreign call
*/
public HotSpotForeignCallLinkage registerForeignCall(
- ForeignCallDescriptor descriptor,
+ HotSpotForeignCallDescriptor descriptor,
long address,
- CallingConvention.Type outgoingCcType,
- Transition transition,
- Reexecutability reexecutability,
- LocationIdentity... killedLocations) {
+ CallingConvention.Type outgoingCcType) {
+ if (address == 0) {
+ throw new IllegalArgumentException("address must be non-zero");
+ }
Class> resultType = descriptor.getResultType();
- assert address != 0 : descriptor;
- assert transition != SAFEPOINT || resultType.isPrimitive() || Word.class.isAssignableFrom(resultType) : "non-leaf foreign calls must return objects in thread local storage: " + descriptor;
+ assert descriptor.getTransition() != SAFEPOINT || resultType.isPrimitive() || Word.class.isAssignableFrom(resultType) : "non-leaf foreign calls must return objects in thread local storage: " +
+ descriptor;
return register(HotSpotForeignCallLinkageImpl.create(metaAccess,
codeCache,
wordTypes,
@@ -161,10 +161,8 @@ public abstract class HotSpotForeignCallsProviderImpl implements HotSpotForeignC
address,
DESTROYS_ALL_CALLER_SAVE_REGISTERS,
outgoingCcType,
- null, // incomingCcType
- transition,
- reexecutability,
- killedLocations));
+ null // incomingCcType
+ ));
}
/**
@@ -175,22 +173,14 @@ public abstract class HotSpotForeignCallsProviderImpl implements HotSpotForeignC
* @param address the address of the foreign code to call
* @param prependThread true if the JavaThread value for the current thread is to be prepended
* to the arguments for the call to {@code address}
- * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call
- * @param reexecutability specifies if the foreign call can be re-executed without (meaningful)
- * side effects. Deoptimization will not return to a point before a foreign call that
- * cannot be re-executed.
- * @param killedLocations the memory locations killed by the foreign call
*/
public void linkForeignCall(OptionValues options,
HotSpotProviders providers,
- ForeignCallDescriptor descriptor,
+ HotSpotForeignCallDescriptor descriptor,
long address,
- boolean prependThread,
- Transition transition,
- Reexecutability reexecutability,
- LocationIdentity... killedLocations) {
+ boolean prependThread) {
if (address != 0) {
- ForeignCallStub stub = new ForeignCallStub(options, jvmciRuntime, providers, address, descriptor, prependThread, transition, reexecutability, killedLocations);
+ ForeignCallStub stub = new ForeignCallStub(options, jvmciRuntime, providers, address, descriptor, prependThread);
HotSpotForeignCallLinkage linkage = stub.getLinkage();
HotSpotForeignCallLinkage targetLinkage = stub.getTargetLinkage();
linkage.setCompiledStub(stub);
@@ -202,12 +192,10 @@ public abstract class HotSpotForeignCallsProviderImpl implements HotSpotForeignC
public static final boolean PREPEND_THREAD = true;
public static final boolean DONT_PREPEND_THREAD = !PREPEND_THREAD;
- public static final LocationIdentity[] NO_LOCATIONS = {};
-
@Override
public HotSpotForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor) {
assert foreignCalls != null : descriptor;
- HotSpotForeignCallLinkage callTarget = foreignCalls.get(descriptor);
+ HotSpotForeignCallLinkage callTarget = foreignCalls.get(descriptor.getSignature());
if (callTarget == null) {
throw GraalError.shouldNotReachHere("missing implementation for runtime call: " + descriptor);
}
@@ -216,32 +204,17 @@ public abstract class HotSpotForeignCallsProviderImpl implements HotSpotForeignC
}
@Override
- public boolean isAvailable(ForeignCallDescriptor descriptor) {
- return foreignCalls.containsKey(descriptor);
+ public HotSpotForeignCallDescriptor getDescriptor(ForeignCallSignature signature) {
+ HotSpotForeignCallDescriptor descriptor = signatureMap.get(signature);
+ assert descriptor != null : signature;
+ return descriptor;
}
- @Override
- public boolean isReexecutable(ForeignCallDescriptor descriptor) {
- assert foreignCalls.containsKey(descriptor) : "unknown foreign call: " + descriptor;
- return foreignCalls.get(descriptor).isReexecutable();
- }
-
- @Override
- public boolean canDeoptimize(ForeignCallDescriptor descriptor) {
- assert foreignCalls.containsKey(descriptor) : "unknown foreign call: " + descriptor;
- return foreignCalls.get(descriptor).needsDebugInfo();
- }
-
- @Override
- public boolean isGuaranteedSafepoint(ForeignCallDescriptor descriptor) {
- assert foreignCalls.containsKey(descriptor) : "unknown foreign call: " + descriptor;
- return foreignCalls.get(descriptor).isGuaranteedSafepoint();
- }
-
- @Override
- public LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor) {
- assert foreignCalls.containsKey(descriptor) : "unknown foreign call: " + descriptor;
- return foreignCalls.get(descriptor).getKilledLocations();
+ HotSpotForeignCallDescriptor createDescriptor(ForeignCallSignature signature, Transition transition, Reexecutability reexecutability, LocationIdentity... killLocations) {
+ assert signatureMap.get(signature) == null;
+ HotSpotForeignCallDescriptor descriptor = new HotSpotForeignCallDescriptor(signature, transition, reexecutability, killLocations);
+ signatureMap.put(signature, descriptor);
+ return descriptor;
}
@Override
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java
index cea5a0c9713..02bca74d8db 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java
@@ -24,7 +24,9 @@
package org.graalvm.compiler.hotspot.meta;
+import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE;
import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
+import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigAccess.JDK;
import static org.graalvm.compiler.hotspot.HotSpotBackend.BASE64_ENCODE_BLOCK;
import static org.graalvm.compiler.hotspot.HotSpotBackend.GHASH_PROCESS_BLOCKS;
import static org.graalvm.compiler.hotspot.meta.HotSpotAOTProfilingPlugin.Options.TieredAOT;
@@ -62,9 +64,9 @@ import org.graalvm.compiler.hotspot.replacements.DigestBaseSubstitutions;
import org.graalvm.compiler.hotspot.replacements.FastNotifyNode;
import org.graalvm.compiler.hotspot.replacements.HotSpotArraySubstitutions;
import org.graalvm.compiler.hotspot.replacements.HotSpotClassSubstitutions;
+import org.graalvm.compiler.hotspot.replacements.HotSpotReflectionGetCallerClassNode;
import org.graalvm.compiler.hotspot.replacements.IdentityHashCodeNode;
import org.graalvm.compiler.hotspot.replacements.ObjectCloneNode;
-import org.graalvm.compiler.hotspot.replacements.ReflectionGetCallerClassNode;
import org.graalvm.compiler.hotspot.replacements.ReflectionSubstitutions;
import org.graalvm.compiler.hotspot.replacements.SHA2Substitutions;
import org.graalvm.compiler.hotspot.replacements.SHA5Substitutions;
@@ -89,6 +91,7 @@ import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration;
import org.graalvm.compiler.nodes.graphbuilderconf.NodeIntrinsicPluginFactory;
+import org.graalvm.compiler.nodes.java.DynamicNewInstanceNode;
import org.graalvm.compiler.nodes.memory.OnHeapMemoryAccess.BarrierType;
import org.graalvm.compiler.nodes.memory.ReadNode;
import org.graalvm.compiler.nodes.memory.address.AddressNode;
@@ -103,6 +106,7 @@ import org.graalvm.compiler.replacements.NodeIntrinsificationProvider;
import org.graalvm.compiler.replacements.ReplacementsImpl;
import org.graalvm.compiler.replacements.StandardGraphBuilderPlugins;
import org.graalvm.compiler.replacements.arraycopy.ArrayCopyNode;
+import org.graalvm.compiler.replacements.nodes.MacroNode.MacroParams;
import org.graalvm.compiler.serviceprovider.GraalServices;
import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
import org.graalvm.compiler.word.WordOperationPlugin;
@@ -149,11 +153,13 @@ public class HotSpotGraphBuilderPlugins {
Plugins plugins = new Plugins(invocationPlugins);
NodeIntrinsificationProvider nodeIntrinsificationProvider = new NodeIntrinsificationProvider(metaAccess, snippetReflection, foreignCalls, wordTypes, target);
- HotSpotWordOperationPlugin wordOperationPlugin = new HotSpotWordOperationPlugin(snippetReflection, wordTypes);
- HotSpotNodePlugin nodePlugin = new HotSpotNodePlugin(wordOperationPlugin, config, wordTypes);
+ if (!IS_IN_NATIVE_IMAGE) {
+ HotSpotWordOperationPlugin wordOperationPlugin = new HotSpotWordOperationPlugin(snippetReflection, wordTypes);
+ HotSpotNodePlugin nodePlugin = new HotSpotNodePlugin(wordOperationPlugin, config, wordTypes);
- plugins.appendTypePlugin(nodePlugin);
- plugins.appendNodePlugin(nodePlugin);
+ plugins.appendTypePlugin(nodePlugin);
+ plugins.appendNodePlugin(nodePlugin);
+ }
if (!GeneratePIC.getValue(options)) {
plugins.appendNodePlugin(new MethodHandlePlugin(constantReflection.getMethodHandleAccess(), true));
}
@@ -179,7 +185,7 @@ public class HotSpotGraphBuilderPlugins {
public void run() {
registerObjectPlugins(invocationPlugins, options, config, replacements);
registerClassPlugins(plugins, config, replacements);
- registerSystemPlugins(invocationPlugins, foreignCalls);
+ registerSystemPlugins(invocationPlugins);
registerThreadPlugins(invocationPlugins, metaAccess, wordTypes, config, replacements);
if (!GeneratePIC.getValue(options)) {
registerCallSitePlugins(invocationPlugins);
@@ -191,9 +197,9 @@ public class HotSpotGraphBuilderPlugins {
registerCRC32CPlugins(invocationPlugins, config, replacements);
registerBigIntegerPlugins(invocationPlugins, config, replacements);
registerSHAPlugins(invocationPlugins, config, replacements);
- registerGHASHPlugins(invocationPlugins, config, metaAccess, foreignCalls);
+ registerGHASHPlugins(invocationPlugins, config, metaAccess);
registerCounterModePlugins(invocationPlugins, config, replacements);
- registerBase64Plugins(invocationPlugins, config, metaAccess, foreignCalls);
+ registerBase64Plugins(invocationPlugins, config, metaAccess);
registerUnsafePlugins(invocationPlugins, config, replacements);
StandardGraphBuilderPlugins.registerInvocationPlugins(metaAccess, snippetReflection, invocationPlugins, replacements, true, false, true);
registerArrayPlugins(invocationPlugins, replacements);
@@ -221,7 +227,7 @@ public class HotSpotGraphBuilderPlugins {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
ValueNode object = receiver.get();
- b.addPush(JavaKind.Object, new ObjectCloneNode(b.getInvokeKind(), targetMethod, b.bci(), b.getInvokeReturnStamp(b.getAssumptions()), object));
+ b.addPush(JavaKind.Object, new ObjectCloneNode(MacroParams.of(b, targetMethod, object)));
return true;
}
@@ -235,7 +241,7 @@ public class HotSpotGraphBuilderPlugins {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
ValueNode object = receiver.get();
- b.addPush(JavaKind.Int, new IdentityHashCodeNode(object));
+ b.addPush(JavaKind.Int, new IdentityHashCodeNode(object, b.bci()));
return true;
}
@@ -289,7 +295,7 @@ public class HotSpotGraphBuilderPlugins {
r.registerMethodSubstitution(HotSpotClassSubstitutions.class, "isHidden", Receiver.class);
}
- if (config.getFieldOffset("ArrayKlass::_component_mirror", Integer.class, "oop", Integer.MAX_VALUE) != Integer.MAX_VALUE) {
+ if (config.getFieldOffset("ArrayKlass::_component_mirror", Integer.class, "oop", Integer.MAX_VALUE, JDK <= 8) != Integer.MAX_VALUE) {
r.registerMethodSubstitution(HotSpotClassSubstitutions.class, "getComponentType", Receiver.class);
}
}
@@ -303,7 +309,7 @@ public class HotSpotGraphBuilderPlugins {
if (folded != null) {
b.addPush(JavaKind.Object, folded);
} else {
- b.addPush(JavaKind.Object, new CallSiteTargetNode(b.getInvokeKind(), targetMethod, b.bci(), b.getInvokeReturnStamp(b.getAssumptions()), callSite));
+ b.addPush(JavaKind.Object, new CallSiteTargetNode(MacroParams.of(b, targetMethod, callSite)));
}
return true;
}
@@ -323,7 +329,7 @@ public class HotSpotGraphBuilderPlugins {
r.register0("getCallerClass", new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
- b.addPush(JavaKind.Object, new ReflectionGetCallerClassNode(b.getInvokeKind(), targetMethod, b.bci(), b.getInvokeReturnStamp(b.getAssumptions())));
+ b.addPush(JavaKind.Object, new HotSpotReflectionGetCallerClassNode(MacroParams.of(b, targetMethod)));
return true;
}
@@ -345,6 +351,22 @@ public class HotSpotGraphBuilderPlugins {
String substituteMethodName = config.doingUnsafeAccessOffset != Integer.MAX_VALUE ? "copyMemoryGuarded" : "copyMemory";
r.registerMethodSubstitution(HotSpotUnsafeSubstitutions.class, HotSpotUnsafeSubstitutions.copyMemoryName, substituteMethodName, Receiver.class, Object.class, long.class, Object.class,
long.class, long.class);
+
+ r.register2("allocateInstance", Receiver.class, Class.class, new InvocationPlugin() {
+ @Override
+ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode clazz) {
+ /* Emits a null-check for the otherwise unused receiver. */
+ unsafe.get();
+ /*
+ * Note that the provided clazz might not be initialized. The HotSpot lowering
+ * snippet for DynamicNewInstanceNode performs the necessary class initialization
+ * check. Such a DynamicNewInstanceNode is also never constant folded to a
+ * NewInstanceNode.
+ */
+ b.addPush(JavaKind.Object, new DynamicNewInstanceNode(b.nullCheckedValue(clazz, DeoptimizationAction.None), true));
+ return true;
+ }
+ });
}
private static final LocationIdentity INSTANCE_KLASS_CONSTANTS = NamedLocationIdentity.immutable("InstanceKlass::_constants");
@@ -426,14 +448,14 @@ public class HotSpotGraphBuilderPlugins {
});
}
- private static void registerSystemPlugins(InvocationPlugins plugins, ForeignCallsProvider foreignCalls) {
+ private static void registerSystemPlugins(InvocationPlugins plugins) {
Registration r = new Registration(plugins, System.class);
- r.register0("currentTimeMillis", new ForeignCallPlugin(foreignCalls, HotSpotHostForeignCallsProvider.JAVA_TIME_MILLIS));
- r.register0("nanoTime", new ForeignCallPlugin(foreignCalls, HotSpotHostForeignCallsProvider.JAVA_TIME_NANOS));
+ r.register0("currentTimeMillis", new ForeignCallPlugin(HotSpotHostForeignCallsProvider.JAVA_TIME_MILLIS));
+ r.register0("nanoTime", new ForeignCallPlugin(HotSpotHostForeignCallsProvider.JAVA_TIME_NANOS));
r.register1("identityHashCode", Object.class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
- b.addPush(JavaKind.Int, new IdentityHashCodeNode(object));
+ b.addPush(JavaKind.Int, new IdentityHashCodeNode(object, b.bci()));
return true;
}
@@ -550,6 +572,7 @@ public class HotSpotGraphBuilderPlugins {
assert config.cipherBlockChainingEncryptAESCryptStub != 0L;
assert config.cipherBlockChainingDecryptAESCryptStub != 0L;
String arch = config.osArch;
+ String decryptSuffix = arch.equals("sparc") ? "WithOriginalKey" : "";
Registration r = new Registration(plugins, "com.sun.crypto.provider.CipherBlockChaining", replacements);
@@ -558,7 +581,7 @@ public class HotSpotGraphBuilderPlugins {
byte[].class, int.class);
Pair cbcDecryptName = selectIntrinsicName(config, "com/sun/crypto/provider/CipherBlockChaining", "implDecrypt", "decrypt");
- registerAndCheckMismatch(r, CipherBlockChainingSubstitutions.class, cbcDecryptName, cbcDecryptName.getLeft(), Receiver.class, byte[].class, int.class, int.class,
+ registerAndCheckMismatch(r, CipherBlockChainingSubstitutions.class, cbcDecryptName, cbcDecryptName.getLeft() + decryptSuffix, Receiver.class, byte[].class, int.class, int.class,
byte[].class, int.class);
r = new Registration(plugins, "com.sun.crypto.provider.AESCrypt", replacements);
@@ -567,7 +590,7 @@ public class HotSpotGraphBuilderPlugins {
registerAndCheckMismatch(r, AESCryptSubstitutions.class, aesEncryptName, Receiver.class, byte[].class, int.class, byte[].class, int.class);
Pair aesDecryptName = selectIntrinsicName(config, "com/sun/crypto/provider/AESCrypt", "implDecryptBlock", "decryptBlock");
- registerAndCheckMismatch(r, AESCryptSubstitutions.class, aesDecryptName, aesDecryptName.getLeft(), Receiver.class, byte[].class, int.class, byte[].class, int.class);
+ registerAndCheckMismatch(r, AESCryptSubstitutions.class, aesDecryptName, aesDecryptName.getLeft() + decryptSuffix, Receiver.class, byte[].class, int.class, byte[].class, int.class);
}
}
@@ -635,7 +658,7 @@ public class HotSpotGraphBuilderPlugins {
}
}
- private static void registerGHASHPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls) {
+ private static void registerGHASHPlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, MetaAccessProvider metaAccess) {
if (config.useGHASHIntrinsics()) {
assert config.ghashProcessBlocks != 0L;
Registration r = new Registration(plugins, "com.sun.crypto.provider.GHASH");
@@ -661,7 +684,7 @@ public class HotSpotGraphBuilderPlugins {
ComputeObjectAddressNode dataAddress = b.add(new ComputeObjectAddressNode(data, dataOffset));
ComputeObjectAddressNode stateAddress = b.add(new ComputeObjectAddressNode(state, ConstantNode.forInt(longArrayBaseOffset)));
ComputeObjectAddressNode hashSubkeyAddress = b.add(new ComputeObjectAddressNode(hashSubkey, ConstantNode.forInt(longArrayBaseOffset)));
- b.add(new ForeignCallNode(foreignCalls, GHASH_PROCESS_BLOCKS, stateAddress, hashSubkeyAddress, dataAddress, blocks));
+ b.add(new ForeignCallNode(GHASH_PROCESS_BLOCKS, stateAddress, hashSubkeyAddress, dataAddress, blocks));
return true;
}
});
@@ -677,7 +700,7 @@ public class HotSpotGraphBuilderPlugins {
}
}
- private static void registerBase64Plugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls) {
+ private static void registerBase64Plugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, MetaAccessProvider metaAccess) {
if (config.useBase64Intrinsics()) {
Registration r = new Registration(plugins, "java.util.Base64$Encoder");
r.register7("encodeBlock",
@@ -702,7 +725,7 @@ public class HotSpotGraphBuilderPlugins {
int byteArrayBaseOffset = metaAccess.getArrayBaseOffset(JavaKind.Byte);
ComputeObjectAddressNode srcAddress = b.add(new ComputeObjectAddressNode(src, ConstantNode.forInt(byteArrayBaseOffset)));
ComputeObjectAddressNode dstAddress = b.add(new ComputeObjectAddressNode(dst, ConstantNode.forInt(byteArrayBaseOffset)));
- b.add(new ForeignCallNode(foreignCalls, BASE64_ENCODE_BLOCK, srcAddress, sp, sl, dstAddress, dp, isURL));
+ b.add(new ForeignCallNode(BASE64_ENCODE_BLOCK, srcAddress, sp, sl, dstAddress, dp, isURL));
return true;
}
});
diff --git a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java
index b483fd4d174..8d711426e82 100644
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java
@@ -67,32 +67,28 @@ import static org.graalvm.compiler.hotspot.HotSpotBackend.UNWIND_EXCEPTION_TO_CA
import static org.graalvm.compiler.hotspot.HotSpotBackend.VECTORIZED_MISMATCHED;
import static org.graalvm.compiler.hotspot.HotSpotBackend.VM_ERROR;
import static org.graalvm.compiler.hotspot.HotSpotBackend.WRONG_METHOD_HANDLER;
-import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability.NOT_REEXECUTABLE;
-import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Reexecutability.REEXECUTABLE;
import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.DESTROYS_ALL_CALLER_SAVE_REGISTERS;
-import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.LEAF;
-import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.LEAF_NO_VZERO;
-import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.SAFEPOINT;
-import static org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage.Transition.STACK_INSPECTABLE_LEAF;
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.DEOPT_BLOB_UNCOMMON_TRAP;
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.DEOPT_BLOB_UNPACK;
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.DEOPT_BLOB_UNPACK_WITH_EXCEPTION_IN_TLS;
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.ENABLE_STACK_RESERVED_ZONE;
import static org.graalvm.compiler.hotspot.HotSpotHostBackend.THROW_DELAYED_STACKOVERFLOW_ERROR;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Reexecutability.NOT_REEXECUTABLE;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Reexecutability.REEXECUTABLE;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Transition.LEAF;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Transition.LEAF_NO_VZERO;
+import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Transition.SAFEPOINT;
import static org.graalvm.compiler.hotspot.replacements.AssertionSnippets.ASSERTION_VM_MESSAGE_C;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotAllocationSnippets.DYNAMIC_NEW_INSTANCE;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotAllocationSnippets.DYNAMIC_NEW_INSTANCE_OR_NULL;
import static org.graalvm.compiler.hotspot.replacements.HotSpotG1WriteBarrierSnippets.G1WBPOSTCALL;
import static org.graalvm.compiler.hotspot.replacements.HotSpotG1WriteBarrierSnippets.G1WBPRECALL;
import static org.graalvm.compiler.hotspot.replacements.HotSpotG1WriteBarrierSnippets.VALIDATE_OBJECT;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.MARK_WORD_LOCATION;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_END_LOCATION;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_TOP_LOCATION;
import static org.graalvm.compiler.hotspot.replacements.Log.LOG_OBJECT;
import static org.graalvm.compiler.hotspot.replacements.Log.LOG_PRIMITIVE;
import static org.graalvm.compiler.hotspot.replacements.Log.LOG_PRINTF;
import static org.graalvm.compiler.hotspot.replacements.MonitorSnippets.MONITORENTER;
import static org.graalvm.compiler.hotspot.replacements.MonitorSnippets.MONITOREXIT;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotAllocationSnippets.DYNAMIC_NEW_INSTANCE;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotAllocationSnippets.DYNAMIC_NEW_INSTANCE_OR_NULL;
import static org.graalvm.compiler.hotspot.stubs.ExceptionHandlerStub.EXCEPTION_HANDLER_FOR_PC;
import static org.graalvm.compiler.hotspot.stubs.StubUtil.VM_MESSAGE_C;
import static org.graalvm.compiler.hotspot.stubs.UnwindExceptionToCallerStub.EXCEPTION_HANDLER_FOR_RETURN_ADDRESS;
@@ -110,11 +106,11 @@ import java.util.EnumMap;
import jdk.internal.vm.compiler.collections.EconomicMap;
import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
+import org.graalvm.compiler.core.common.spi.ForeignCallSignature;
import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.hotspot.CompilerRuntimeHotSpotVMConfig;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
-import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
import org.graalvm.compiler.hotspot.stubs.ArrayStoreExceptionStub;
import org.graalvm.compiler.hotspot.stubs.ClassCastExceptionStub;
@@ -146,11 +142,11 @@ import jdk.vm.ci.meta.MetaAccessProvider;
*/
public abstract class HotSpotHostForeignCallsProvider extends HotSpotForeignCallsProviderImpl implements ArrayCopyForeignCalls {
- public static final ForeignCallDescriptor JAVA_TIME_MILLIS = new ForeignCallDescriptor("javaTimeMillis", long.class);
- public static final ForeignCallDescriptor JAVA_TIME_NANOS = new ForeignCallDescriptor("javaTimeNanos", long.class);
+ public static final HotSpotForeignCallDescriptor JAVA_TIME_MILLIS = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS, "javaTimeMillis", long.class);
+ public static final HotSpotForeignCallDescriptor JAVA_TIME_NANOS = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, REEXECUTABLE, NO_LOCATIONS, "javaTimeNanos", long.class);
- public static final ForeignCallDescriptor NOTIFY = new ForeignCallDescriptor("object_notify", boolean.class, Object.class);
- public static final ForeignCallDescriptor NOTIFY_ALL = new ForeignCallDescriptor("object_notifyAll", boolean.class, Object.class);
+ public static final HotSpotForeignCallDescriptor NOTIFY = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, NOT_REEXECUTABLE, any(), "object_notify", boolean.class, Object.class);
+ public static final HotSpotForeignCallDescriptor NOTIFY_ALL = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, NOT_REEXECUTABLE, any(), "object_notifyAll", boolean.class, Object.class);
public HotSpotHostForeignCallsProvider(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalRuntimeProvider runtime, MetaAccessProvider metaAccess, CodeCacheProvider codeCache,
WordTypes wordTypes) {
@@ -167,56 +163,68 @@ public abstract class HotSpotHostForeignCallsProvider extends HotSpotForeignCall
}
@Override
- public ForeignCallDescriptor lookupArraycopyDescriptor(JavaKind kind, boolean aligned, boolean disjoint, boolean uninit, boolean killAny) {
- if (uninit) {
- assert kind == JavaKind.Object;
+ public ForeignCallDescriptor lookupArraycopyDescriptor(JavaKind kind, boolean aligned, boolean disjoint, boolean uninit, LocationIdentity killedLocation) {
+ // We support Object arraycopy killing the Object array location or ANY. We support
+ // primitive arraycopy killing the kind's array location or INIT.
+ // This is enough for well-typed copies and for the kind of type punning done by
+ // StringUTF16Substitutions#getChars. This will need more work if at some point we need to
+ // support more general type punning, e.g., writing char-typed data into a byte array.
+ boolean killAny = killedLocation.isAny();
+ boolean killInit = killedLocation.isInit();
+ if (kind.isObject()) {
+ assert !killInit : "unsupported";
+ assert killAny || killedLocation.equals(NamedLocationIdentity.getArrayLocation(kind));
+ return objectArraycopyDescriptors[aligned ? 1 : 0][disjoint ? 1 : 0][uninit ? 1 : 0][killAny ? 1 : 0];
+ } else {
+ assert kind.isPrimitive();
assert !killAny : "unsupported";
- return uninitObjectArraycopyDescriptors[aligned ? 1 : 0][disjoint ? 1 : 0];
+ assert killInit || killedLocation.equals(NamedLocationIdentity.getArrayLocation(kind));
+ return primitiveArraycopyDescriptors[aligned ? 1 : 0][disjoint ? 1 : 0][killInit ? 1 : 0].get(kind);
}
- if (killAny) {
- return arraycopyDescriptorsKillAny[aligned ? 1 : 0][disjoint ? 1 : 0].get(kind);
- }
- return arraycopyDescriptors[aligned ? 1 : 0][disjoint ? 1 : 0].get(kind);
}
- @SuppressWarnings("unchecked") private static final EnumMap