8227068: [Graal] MappedByteBuffer bulk access memory failures are not handled gracefully
authorjcm
Fri, 12 Jul 2019 11:51:07 -0700
changeset 55674 ff76baab1c90
parent 55673 0bf678dd8951
child 55675 a33465cf8774
8227068: [Graal] MappedByteBuffer bulk access memory failures are not handled gracefully Summary: Unsafe.copyMemory access failures are handled gracefully. Reviewed-by: dnsimon, kvn
src/hotspot/share/jvmci/vmStructs_jvmci.cpp
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotUnsafeSubstitutions.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java
--- 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");
 
     /**