8227068: [Graal] MappedByteBuffer bulk access memory failures are not handled gracefully
Summary: Unsafe.copyMemory access failures are handled gracefully.
Reviewed-by: dnsimon, kvn
--- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp Fri Jul 12 10:44:11 2019 -0700
+++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp Fri Jul 12 11:51:07 2019 -0700
@@ -173,6 +173,7 @@
volatile_nonstatic_field(JavaThread, _exception_oop, oop) \
volatile_nonstatic_field(JavaThread, _exception_pc, address) \
volatile_nonstatic_field(JavaThread, _is_method_handle_return, int) \
+ volatile_nonstatic_field(JavaThread, _doing_unsafe_access, bool) \
nonstatic_field(JavaThread, _osthread, OSThread*) \
nonstatic_field(JavaThread, _pending_deoptimization, int) \
nonstatic_field(JavaThread, _pending_failed_speculation, jlong) \
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Fri Jul 12 10:44:11 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Fri Jul 12 11:51:07 2019 -0700
@@ -344,6 +344,7 @@
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 boolean requiresReservedStackCheck(List<ResolvedJavaMethod> methods) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java Fri Jul 12 10:44:11 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java Fri Jul 12 11:51:07 2019 -0700
@@ -175,7 +175,7 @@
registerGHASHPlugins(invocationPlugins, config, metaAccess, foreignCalls);
registerCounterModePlugins(invocationPlugins, config, replacementBytecodeProvider);
registerBase64Plugins(invocationPlugins, config, metaAccess, foreignCalls);
- registerUnsafePlugins(invocationPlugins, replacementBytecodeProvider);
+ registerUnsafePlugins(invocationPlugins, config, replacementBytecodeProvider);
StandardGraphBuilderPlugins.registerInvocationPlugins(metaAccess, snippetReflection, invocationPlugins, replacementBytecodeProvider, true, false);
registerArrayPlugins(invocationPlugins, replacementBytecodeProvider);
registerStringPlugins(invocationPlugins, replacementBytecodeProvider);
@@ -276,15 +276,16 @@
r.registerMethodSubstitution(ReflectionSubstitutions.class, "getClassAccessFlags", Class.class);
}
- private static void registerUnsafePlugins(InvocationPlugins plugins, BytecodeProvider replacementBytecodeProvider) {
+ private static void registerUnsafePlugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, BytecodeProvider replacementBytecodeProvider) {
Registration r;
if (JavaVersionUtil.JAVA_SPEC <= 8) {
r = new Registration(plugins, Unsafe.class, replacementBytecodeProvider);
} else {
r = new Registration(plugins, "jdk.internal.misc.Unsafe", replacementBytecodeProvider);
}
- r.registerMethodSubstitution(HotSpotUnsafeSubstitutions.class, HotSpotUnsafeSubstitutions.copyMemoryName, "copyMemory", Receiver.class, Object.class, long.class, Object.class, long.class,
- long.class);
+ 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);
}
private static final LocationIdentity INSTANCE_KLASS_CONSTANTS = NamedLocationIdentity.immutable("InstanceKlass::_constants");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotUnsafeSubstitutions.java Fri Jul 12 10:44:11 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotUnsafeSubstitutions.java Fri Jul 12 11:51:07 2019 -0700
@@ -24,12 +24,17 @@
package org.graalvm.compiler.hotspot.meta;
+import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.doingUnsafeAccessOffset;
+
import org.graalvm.compiler.api.replacements.ClassSubstitution;
import org.graalvm.compiler.api.replacements.MethodSubstitution;
import org.graalvm.compiler.hotspot.HotSpotBackend;
+import org.graalvm.compiler.hotspot.nodes.CurrentJavaThreadNode;
import org.graalvm.compiler.nodes.ComputeObjectAddressNode;
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.WordFactory;
@ClassSubstitution(className = {"jdk.internal.misc.Unsafe", "sun.misc.Unsafe"})
@@ -43,6 +48,24 @@
Word srcAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(srcBase, srcOffset));
Word dstAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(destBase, destOffset));
Word size = WordFactory.signed(bytes);
+
HotSpotBackend.unsafeArraycopy(srcAddr, dstAddr, size);
}
+
+ @SuppressWarnings("unused")
+ @MethodSubstitution(value = "copyMemory", isStatic = false)
+ static void copyMemoryGuarded(Object receiver, Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes) {
+ Word srcAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(srcBase, srcOffset));
+ Word dstAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(destBase, destOffset));
+ Word size = WordFactory.signed(bytes);
+ Word javaThread = CurrentJavaThreadNode.get();
+ int offset = doingUnsafeAccessOffset(INJECTED_VMCONFIG);
+ LocationIdentity any = LocationIdentity.any();
+
+ /* Set doingUnsafeAccess to guard and handle unsafe memory access failures */
+ javaThread.writeByte(offset, (byte) 1, any);
+ HotSpotBackend.unsafeArraycopy(srcAddr, dstAddr, size);
+ /* Reset doingUnsafeAccess */
+ javaThread.writeByte(offset, (byte) 0, any);
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java Fri Jul 12 10:44:11 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java Fri Jul 12 11:51:07 2019 -0700
@@ -187,6 +187,14 @@
return config.verifyOops;
}
+ /**
+ * @see GraalHotSpotVMConfig#doingUnsafeAccessOffset
+ */
+ @Fold
+ public static int doingUnsafeAccessOffset(@InjectedParameter GraalHotSpotVMConfig config) {
+ return config.doingUnsafeAccessOffset;
+ }
+
public static final LocationIdentity EXCEPTION_OOP_LOCATION = NamedLocationIdentity.mutable("ExceptionOop");
/**