8227068: [Graal] MappedByteBuffer bulk access memory failures are not handled gracefully

Unsafe.copyMemory access failures are handled gracefully.

Reviewed-by: dnsimon, kvn
This commit is contained in:
Jamsheed Mohammed C M 2019-07-12 11:51:07 -07:00
parent 7821fee0db
commit da3672a299
5 changed files with 38 additions and 4 deletions

View File

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

View File

@ -344,6 +344,7 @@ public class GraalHotSpotVMConfig extends GraalHotSpotVMConfigBase {
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) {

View File

@ -175,7 +175,7 @@ public class HotSpotGraphBuilderPlugins {
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 @@ public class HotSpotGraphBuilderPlugins {
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");

View File

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

View File

@ -187,6 +187,14 @@ public class HotSpotReplacementsUtil {
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");
/**