diff --git a/compiler/src/jdk.graal.compiler.hotspot.jdk21.test/src/jdk/graal/compiler/hotspot/jdk21/test/UnsafeSetMemoryTest.java b/compiler/src/jdk.graal.compiler.hotspot.jdk21.test/src/jdk/graal/compiler/hotspot/jdk21/test/UnsafeSetMemoryTest.java new file mode 100644 index 000000000000..0c0ce4936fac --- /dev/null +++ b/compiler/src/jdk.graal.compiler.hotspot.jdk21.test/src/jdk/graal/compiler/hotspot/jdk21/test/UnsafeSetMemoryTest.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2024, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.graal.compiler.hotspot.jdk21.test; + +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; + +import org.junit.Assume; +import org.junit.Test; + +import jdk.graal.compiler.core.test.GraalCompilerTest; +import jdk.graal.compiler.serviceprovider.JavaVersionUtil; +import jdk.graal.compiler.test.AddExports; +import jdk.internal.misc.Unsafe; +import jdk.vm.ci.code.InstalledCode; +import jdk.vm.ci.code.InvalidInstalledCodeException; + +@AddExports("java.base/jdk.internal.misc") +public class UnsafeSetMemoryTest extends GraalCompilerTest { + + static void snippet(long address, long size, byte value) { + Unsafe.getUnsafe().setMemory(address, size, value); + } + + static void validate(long address, long size, byte value) { + for (long i = 0; i < size; i++) { + assertTrue(Unsafe.getUnsafe().getByte(address + i) == value); + } + } + + @SuppressWarnings("preview") + @Test + public void testSetMemory() throws InvalidInstalledCodeException { + Assume.assumeTrue(JavaVersionUtil.JAVA_SPEC >= 23); + InstalledCode code = getCode(getResolvedJavaMethod("snippet"), null, true); + + for (long size : new long[]{1, 2, 3, 4, 5, 6, 7, 8, 15, 16, 63, 64, 255, 256}) { + Arena arena = Arena.global(); + long alignment; + if (size == 2 || size == 3) { + alignment = 2; + } else if (size >= 4 && size <= 7) { + alignment = 4; + } else { + alignment = 8; + } + + MemorySegment segment = arena.allocate(size, alignment); + long address = segment.address(); + + code.executeVarargs(address, size, (byte) 0xCE); + validate(address, size, (byte) 0xCE); + + segment = arena.allocate(size + 1, alignment).asSlice(1); + address = segment.address(); + code.executeVarargs(address, size, (byte) 0xCE); + validate(address, size, (byte) 0xCE); + } + } +} diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/GraalHotSpotVMConfig.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/GraalHotSpotVMConfig.java index 7c641510e12d..d6d5852184d6 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/GraalHotSpotVMConfig.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/GraalHotSpotVMConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, 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 @@ -485,6 +485,9 @@ public int threadTlabTopOffset() { public final long poly1305ProcessBlocks = getFieldValue("StubRoutines::_poly1305_processBlocks", Long.class, "address"); public final long chacha20Block = getFieldValue("StubRoutines::_chacha20Block", Long.class, "address"); + public final long intpolyMontgomeryMultP256 = getFieldValue("StubRoutines::_intpoly_montgomeryMult_P256", Long.class, "address", 0L, JDK >= 23); + public final long intpolyAssign = getFieldValue("StubRoutines::_intpoly_assign", Long.class, "address", 0L, JDK >= 23); + public final long throwDelayedStackOverflowErrorEntry = getFieldValue("StubRoutines::_throw_delayed_StackOverflowError_entry", Long.class, "address"); public final long jbyteArraycopy = getFieldValue("StubRoutines::_jbyte_arraycopy", Long.class, "address"); @@ -515,6 +518,7 @@ public int threadTlabTopOffset() { public final long checkcastArraycopyUninit = getFieldValue("StubRoutines::_checkcast_arraycopy_uninit", Long.class, "address"); public final long unsafeArraycopy = getFieldValue("StubRoutines::_unsafe_arraycopy", Long.class, "address"); public final long genericArraycopy = getFieldValue("StubRoutines::_generic_arraycopy", Long.class, "address"); + public final long unsafeSetMemory = getFieldValue("StubRoutines::_unsafe_setmemory", Long.class, "address", 0L, JDK >= 23); // Allocation stubs that return null when allocation fails public final long newInstanceOrNullAddress = getAddress("JVMCIRuntime::new_instance_or_null"); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotBackend.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotBackend.java index a3ff3acb093e..fb9b6debc004 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotBackend.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/HotSpotBackend.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, 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 @@ -192,6 +192,13 @@ public static int sha3ImplCompressMBStub(Word bufAddr, Object stateAddr, int blo @NodeIntrinsic(ForeignCallNode.class) private static native int sha3ImplCompressMBStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word bufAddr, Object state, int blockSize, int ofs, int limit); + public static void unsafeSetMemory(Word objAddr, Word size, byte value) { + unsafeSetMemoryStub(UNSAFE_SETMEMORY, objAddr, size, value); + } + + @NodeIntrinsic(ForeignCallNode.class) + private static native void unsafeSetMemoryStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word objAddr, Word size, byte value); + public static void unsafeArraycopy(Word srcAddr, Word dstAddr, Word size) { unsafeArraycopyStub(UNSAFE_ARRAYCOPY, srcAddr, dstAddr, size); } @@ -245,6 +252,12 @@ public static void unsafeArraycopy(Word srcAddr, Word dstAddr, Word size) { public static final HotSpotForeignCallDescriptor CHACHA20Block = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, HAS_SIDE_EFFECT, any(), "_chacha20Block", int.class, WordBase.class, WordBase.class); + public static final HotSpotForeignCallDescriptor INTPOLY_MONTGOMERYMULT_P256 = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, HAS_SIDE_EFFECT, any(), "_intpoly_montgomeryMult_P256", int.class, + WordBase.class, WordBase.class, WordBase.class); + + public static final HotSpotForeignCallDescriptor INTPOLY_ASSIGN = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, HAS_SIDE_EFFECT, any(), "_intpoly_assign", void.class, + int.class, WordBase.class, WordBase.class, int.class); + public static final HotSpotForeignCallDescriptor SHAREDRUNTIME_NOTIFY_JVMTI_VTHREAD_START = new HotSpotForeignCallDescriptor(SAFEPOINT, HAS_SIDE_EFFECT, any(), "notify_jvmti_vthread_start", void.class, Object.class, boolean.class, Word.class); @@ -261,6 +274,9 @@ public static void unsafeArraycopy(Word srcAddr, Word dstAddr, Word size) { "notify_jvmti_vthread_unmount", void.class, Object.class, boolean.class, Word.class); + public static final HotSpotForeignCallDescriptor UNSAFE_SETMEMORY = new HotSpotForeignCallDescriptor(LEAF_NO_VZERO, HAS_SIDE_EFFECT, any(), + "unsafe_setmemory", void.class, Word.class, Word.class, byte.class); + /** * @see VMErrorNode */ diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java index a921294a8492..0644b841feea 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java @@ -95,6 +95,7 @@ import jdk.graal.compiler.hotspot.replacements.RegisterFinalizerSnippets; import jdk.graal.compiler.hotspot.replacements.StringToBytesSnippets; import jdk.graal.compiler.hotspot.replacements.UnsafeCopyMemoryNode; +import jdk.graal.compiler.hotspot.replacements.UnsafeSetMemoryNode; import jdk.graal.compiler.hotspot.replacements.UnsafeSnippets; import jdk.graal.compiler.hotspot.replacements.VirtualThreadUpdateJFRSnippets; import jdk.graal.compiler.hotspot.replacements.arraycopy.CheckcastArrayCopyCallNode; @@ -557,6 +558,10 @@ private boolean lowerWithoutDelegation(Node n, LoweringTool tool) { if (graph.getGuardsStage() == GuardsStage.AFTER_FSA) { unsafeSnippets.lower((UnsafeCopyMemoryNode) n, tool); } + } else if (n instanceof UnsafeSetMemoryNode) { + if (graph.getGuardsStage() == GuardsStage.AFTER_FSA) { + unsafeSnippets.lower((UnsafeSetMemoryNode) n, tool); + } } else if (n instanceof RegisterFinalizerNode) { lowerRegisterFinalizer((RegisterFinalizerNode) n, tool); } else if (n instanceof DeadEndNode) { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java index 17adb8ed2466..5c1453c05457 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java @@ -31,6 +31,8 @@ import static jdk.graal.compiler.hotspot.HotSpotBackend.ELECTRONIC_CODEBOOK_DECRYPT_AESCRYPT; import static jdk.graal.compiler.hotspot.HotSpotBackend.ELECTRONIC_CODEBOOK_ENCRYPT_AESCRYPT; import static jdk.graal.compiler.hotspot.HotSpotBackend.GALOIS_COUNTER_MODE_CRYPT; +import static jdk.graal.compiler.hotspot.HotSpotBackend.INTPOLY_ASSIGN; +import static jdk.graal.compiler.hotspot.HotSpotBackend.INTPOLY_MONTGOMERYMULT_P256; import static jdk.graal.compiler.hotspot.HotSpotBackend.POLY1305_PROCESSBLOCKS; import static jdk.graal.compiler.hotspot.HotSpotBackend.SHAREDRUNTIME_NOTIFY_JVMTI_VTHREAD_END; import static jdk.graal.compiler.hotspot.HotSpotBackend.SHAREDRUNTIME_NOTIFY_JVMTI_VTHREAD_MOUNT; @@ -81,6 +83,7 @@ import jdk.graal.compiler.hotspot.replacements.HubGetClassNode; import jdk.graal.compiler.hotspot.replacements.ObjectCloneNode; import jdk.graal.compiler.hotspot.replacements.UnsafeCopyMemoryNode; +import jdk.graal.compiler.hotspot.replacements.UnsafeSetMemoryNode; import jdk.graal.compiler.hotspot.word.HotSpotWordTypes; import jdk.graal.compiler.java.BytecodeParser; import jdk.graal.compiler.lir.SyncPort; @@ -264,6 +267,7 @@ public void run() { } registerPoly1305Plugins(invocationPlugins, config, replacements); registerChaCha20Plugins(invocationPlugins, config, replacements); + registerP256Plugins(invocationPlugins, config, replacements); } }); @@ -498,6 +502,13 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec return true; } }); + r.registerConditional(config.unsafeSetMemory != 0L, new InvocationPlugin("setMemory0", Receiver.class, Object.class, long.class, long.class, byte.class) { + @Override + public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode obj, ValueNode offset, ValueNode bytes, ValueNode value) { + b.add(new UnsafeSetMemoryNode(receiver.get(true), obj, offset, bytes, value)); + return true; + } + }); r.register(new InvocationPlugin("allocateInstance", Receiver.class, Class.class) { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode clazz) { @@ -1221,6 +1232,47 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec }); } + private static void registerP256Plugins(InvocationPlugins plugins, GraalHotSpotVMConfig config, Replacements replacements) { + Registration r = new Registration(plugins, "sun.security.util.math.intpoly.MontgomeryIntegerPolynomialP256", replacements); + r.registerConditional(config.intpolyMontgomeryMultP256 != 0L, new InvocationPlugin("mult", Receiver.class, long[].class, long[].class, long[].class) { + @Override + public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode aIn, ValueNode bIn, ValueNode rOut) { + try (InvocationPluginHelper helper = new InvocationPluginHelper(b, targetMethod)) { + ValueNode aNotNull = b.nullCheckedValue(aIn); + ValueNode bNotNull = b.nullCheckedValue(bIn); + ValueNode rNotNull = b.nullCheckedValue(rOut); + + ValueNode aStart = helper.arrayStart(aNotNull, JavaKind.Long); + ValueNode bStart = helper.arrayStart(bNotNull, JavaKind.Long); + ValueNode rStart = helper.arrayStart(rNotNull, JavaKind.Long); + + ForeignCallNode call = new ForeignCallNode(INTPOLY_MONTGOMERYMULT_P256, aStart, bStart, rStart); + b.addPush(JavaKind.Int, call); + } + return true; + } + }); + + r = new Registration(plugins, "sun.security.util.math.intpoly.IntegerPolynomial", replacements); + r.registerConditional(config.intpolyAssign != 0L, new InvocationPlugin("conditionalAssign", int.class, long[].class, long[].class) { + @Override + public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode set, ValueNode aIn, ValueNode bIn) { + try (InvocationPluginHelper helper = new InvocationPluginHelper(b, targetMethod)) { + ValueNode aNotNull = b.nullCheckedValue(aIn); + ValueNode bNotNull = b.nullCheckedValue(bIn); + + ValueNode aStart = helper.arrayStart(aNotNull, JavaKind.Long); + ValueNode bStart = helper.arrayStart(bNotNull, JavaKind.Long); + + ValueNode aLength = helper.arraylength(aStart); + + b.add(new ForeignCallNode(INTPOLY_ASSIGN, set, aStart, bStart, aLength)); + } + return true; + } + }); + } + private static void registerArraysSupportPlugins(InvocationPlugins plugins, Replacements replacements, Architecture arch) { Registration r = new Registration(plugins, "jdk.internal.util.ArraysSupport", replacements); r.registerConditional(VectorizedMismatchNode.isSupported(arch), new InvocationPlugin("vectorizedMismatch", Object.class, long.class, Object.class, long.class, int.class, int.class) { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java index 4a87752c4c83..5a1807f98771 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, 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,8 @@ import static jdk.graal.compiler.hotspot.HotSpotBackend.EXCEPTION_HANDLER; import static jdk.graal.compiler.hotspot.HotSpotBackend.GALOIS_COUNTER_MODE_CRYPT; import static jdk.graal.compiler.hotspot.HotSpotBackend.IC_MISS_HANDLER; +import static jdk.graal.compiler.hotspot.HotSpotBackend.INTPOLY_ASSIGN; +import static jdk.graal.compiler.hotspot.HotSpotBackend.INTPOLY_MONTGOMERYMULT_P256; import static jdk.graal.compiler.hotspot.HotSpotBackend.MD5_IMPL_COMPRESS_MB; import static jdk.graal.compiler.hotspot.HotSpotBackend.MONTGOMERY_MULTIPLY; import static jdk.graal.compiler.hotspot.HotSpotBackend.MONTGOMERY_SQUARE; @@ -54,6 +56,7 @@ import static jdk.graal.compiler.hotspot.HotSpotBackend.SHAREDRUNTIME_NOTIFY_JVMTI_VTHREAD_START; import static jdk.graal.compiler.hotspot.HotSpotBackend.SHAREDRUNTIME_NOTIFY_JVMTI_VTHREAD_UNMOUNT; import static jdk.graal.compiler.hotspot.HotSpotBackend.SHA_IMPL_COMPRESS_MB; +import static jdk.graal.compiler.hotspot.HotSpotBackend.UNSAFE_SETMEMORY; import static jdk.graal.compiler.hotspot.HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER; import static jdk.graal.compiler.hotspot.HotSpotBackend.UPDATE_BYTES_ADLER32; import static jdk.graal.compiler.hotspot.HotSpotBackend.UPDATE_BYTES_CRC32; @@ -567,6 +570,9 @@ public void initialize(HotSpotProviders providers, OptionValues options) { registerForeignCall(createDescriptor(GENERIC_ARRAYCOPY, LEAF_NO_VZERO, HAS_SIDE_EFFECT, NamedLocationIdentity.any()), c.genericArraycopy, NativeCall); registerForeignCall(createDescriptor(UNSAFE_ARRAYCOPY, LEAF_NO_VZERO, HAS_SIDE_EFFECT, NamedLocationIdentity.any()), c.unsafeArraycopy, NativeCall); + if (c.unsafeSetMemory != 0L) { + registerForeignCall(UNSAFE_SETMEMORY, c.unsafeSetMemory, NativeCall); + } if (c.md5ImplCompressMultiBlock != 0L) { registerForeignCall(MD5_IMPL_COMPRESS_MB, c.md5ImplCompressMultiBlock, NativeCall); @@ -626,6 +632,12 @@ public void initialize(HotSpotProviders providers, OptionValues options) { if (c.chacha20Block != 0L) { registerForeignCall(CHACHA20Block, c.chacha20Block, NativeCall); } + if (c.intpolyMontgomeryMultP256 != 0L) { + registerForeignCall(INTPOLY_MONTGOMERYMULT_P256, c.intpolyMontgomeryMultP256, NativeCall); + } + if (c.intpolyAssign != 0L) { + registerForeignCall(INTPOLY_ASSIGN, c.intpolyAssign, NativeCall); + } registerSnippetStubs(providers, options); registerStubCallFunctions(options, providers, runtime.getVMConfig()); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/UnimplementedGraalIntrinsics.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/UnimplementedGraalIntrinsics.java index f15cf339a1fe..4d550d5df4d6 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/UnimplementedGraalIntrinsics.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/UnimplementedGraalIntrinsics.java @@ -134,8 +134,6 @@ public UnimplementedGraalIntrinsics(Architecture arch) { // JDK-8309130: x86_64 AVX512 intrinsics for Arrays.sort methods (GR-48679) "java/util/DualPivotQuicksort.partition(Ljava/lang/Class;Ljava/lang/Object;JIIIILjava/util/DualPivotQuicksort$PartitionOperation;)[I", "java/util/DualPivotQuicksort.sort(Ljava/lang/Class;Ljava/lang/Object;JIILjava/util/DualPivotQuicksort$SortOperation;)V", - // JDK-8329331: Intrinsify Unsafe::setMemory - "jdk/internal/misc/Unsafe.setMemory0(Ljava/lang/Object;JJB)V", // JDK-8223347: Integration of Vector API "jdk/internal/vm/vector/VectorSupport.compressExpandOp(ILjava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$VectorMask;Ljdk/internal/vm/vector/VectorSupport$CompressExpandOperation;)Ljdk/internal/vm/vector/VectorSupport$VectorPayload;", jdk == 21 ? "jdk/internal/vm/vector/VectorSupport.extract(Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;ILjdk/internal/vm/vector/VectorSupport$VecExtractOp;)J": @@ -152,9 +150,7 @@ public UnimplementedGraalIntrinsics(Architecture arch) { jdk == 21 ? "jdk/internal/vm/vector/VectorSupport.storeMasked(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjava/lang/Object;JLjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$VectorMask;Ljava/lang/Object;JLjdk/internal/vm/vector/VectorSupport$StoreVectorMaskedOperation;)V": "jdk/internal/vm/vector/VectorSupport.storeMasked(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjava/lang/Object;JZLjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$VectorMask;Ljava/lang/Object;JLjdk/internal/vm/vector/VectorSupport$StoreVectorMaskedOperation;)V", "jdk/internal/vm/vector/VectorSupport.storeWithMap(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/Object;JLjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$VectorMask;Ljava/lang/Object;I[IILjdk/internal/vm/vector/VectorSupport$StoreVectorOperationWithMap;)V", - "jdk/internal/vm/vector/VectorSupport.ternaryOp(ILjava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$VectorMask;Ljdk/internal/vm/vector/VectorSupport$TernaryOperation;)Ljdk/internal/vm/vector/VectorSupport$Vector;", - "sun/security/util/math/intpoly/IntegerPolynomial.conditionalAssign(I[J[J)V", - "sun/security/util/math/intpoly/MontgomeryIntegerPolynomialP256.mult([J[J[J)I" + "jdk/internal/vm/vector/VectorSupport.ternaryOp(ILjava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;ILjdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$Vector;Ljdk/internal/vm/vector/VectorSupport$VectorMask;Ljdk/internal/vm/vector/VectorSupport$TernaryOperation;)Ljdk/internal/vm/vector/VectorSupport$Vector;" // @formatter:on ); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replacements/UnsafeSetMemoryNode.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replacements/UnsafeSetMemoryNode.java new file mode 100644 index 000000000000..c79e7a602a5a --- /dev/null +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replacements/UnsafeSetMemoryNode.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2024, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.graal.compiler.hotspot.replacements; + +import static jdk.graal.compiler.nodeinfo.InputType.Memory; +import static jdk.graal.compiler.nodeinfo.NodeCycles.CYCLES_64; +import static jdk.graal.compiler.nodeinfo.NodeSize.SIZE_16; + +import org.graalvm.word.LocationIdentity; + +import jdk.graal.compiler.core.common.type.StampFactory; +import jdk.graal.compiler.graph.NodeClass; +import jdk.graal.compiler.nodeinfo.NodeInfo; +import jdk.graal.compiler.nodes.AbstractStateSplit; +import jdk.graal.compiler.nodes.ValueNode; +import jdk.graal.compiler.nodes.memory.MemoryAccess; +import jdk.graal.compiler.nodes.memory.MemoryKill; +import jdk.graal.compiler.nodes.memory.SingleMemoryKill; +import jdk.graal.compiler.nodes.spi.Lowerable; + +@NodeInfo(cycles = CYCLES_64, size = SIZE_16, allowedUsageTypes = {Memory}) +public class UnsafeSetMemoryNode extends AbstractStateSplit implements Lowerable, SingleMemoryKill, MemoryAccess { + + public static final NodeClass TYPE = NodeClass.create(UnsafeSetMemoryNode.class); + + @Input ValueNode receiver; + @Input ValueNode obj; + @Input ValueNode offset; + @Input ValueNode bytes; + @Input ValueNode value; + + @OptionalInput(Memory) MemoryKill lastLocationAccess; + + public UnsafeSetMemoryNode(ValueNode receiver, ValueNode obj, ValueNode offset, ValueNode bytes, ValueNode value) { + super(TYPE, StampFactory.forVoid()); + this.receiver = receiver; + this.obj = obj; + this.offset = offset; + this.bytes = bytes; + this.value = value; + } + + @Override + public LocationIdentity getKilledLocationIdentity() { + return LocationIdentity.any(); + } + + @Override + public LocationIdentity getLocationIdentity() { + return getKilledLocationIdentity(); + } + + @Override + public MemoryKill getLastLocationAccess() { + return lastLocationAccess; + } + + @Override + public void setLastLocationAccess(MemoryKill lla) { + updateUsagesInterface(lastLocationAccess, lla); + lastLocationAccess = lla; + } +} diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replacements/UnsafeSnippets.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replacements/UnsafeSnippets.java index e92003045a3f..eba48cf73708 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replacements/UnsafeSnippets.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replacements/UnsafeSnippets.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, 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,9 @@ import static jdk.graal.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG; import static jdk.graal.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER; +import org.graalvm.word.LocationIdentity; +import org.graalvm.word.WordFactory; + import jdk.graal.compiler.api.replacements.Snippet; import jdk.graal.compiler.hotspot.HotSpotBackend; import jdk.graal.compiler.hotspot.meta.HotSpotProviders; @@ -41,13 +44,9 @@ import jdk.graal.compiler.replacements.SnippetTemplate.SnippetInfo; import jdk.graal.compiler.replacements.Snippets; import jdk.graal.compiler.word.Word; -import org.graalvm.word.LocationIdentity; -import org.graalvm.word.WordFactory; public class UnsafeSnippets implements Snippets { - public static final String copyMemoryName = "copyMemory0"; - @SuppressWarnings("unused") @Snippet static void copyMemory(Object receiver, Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes) { @@ -65,15 +64,33 @@ static void copyMemory(Object receiver, Object srcBase, long srcOffset, Object d javaThread.writeByte(offset, (byte) 0, any); } + @SuppressWarnings("unused") + @Snippet + static void setMemory(Object receiver, Object objBase, long objOffset, long bytes, byte value) { + Word objAddr = WordFactory.unsigned(ComputeObjectAddressNode.get(objBase, objOffset)); + Word size = WordFactory.signed(bytes); + Word javaThread = CurrentJavaThreadNode.get(); + int offset = HotSpotReplacementsUtil.doingUnsafeAccessOffset(INJECTED_VMCONFIG); + LocationIdentity any = LocationIdentity.any(); + + /* Set doingUnsafeAccess to guard and handle unsafe memory access failures */ + javaThread.writeByte(offset, (byte) 1, any); + HotSpotBackend.unsafeSetMemory(objAddr, size, value); + /* Reset doingUnsafeAccess */ + javaThread.writeByte(offset, (byte) 0, any); + } + public static class Templates extends AbstractTemplates { private final SnippetInfo copyMemory; + private final SnippetInfo setMemory; @SuppressWarnings("this-escape") public Templates(OptionValues options, HotSpotProviders providers) { super(options, providers); this.copyMemory = snippet(providers, UnsafeSnippets.class, "copyMemory"); + this.setMemory = snippet(providers, UnsafeSnippets.class, "setMemory"); } public void lower(UnsafeCopyMemoryNode copyMemoryNode, LoweringTool tool) { @@ -88,5 +105,17 @@ public void lower(UnsafeCopyMemoryNode copyMemoryNode, LoweringTool tool) { SnippetTemplate template = template(tool, copyMemoryNode, args); template.instantiate(tool.getMetaAccess(), copyMemoryNode, DEFAULT_REPLACER, args); } + + public void lower(UnsafeSetMemoryNode setMemoryNode, LoweringTool tool) { + StructuredGraph graph = setMemoryNode.graph(); + Arguments args = new Arguments(setMemory, graph.getGuardsStage(), tool.getLoweringStage()); + args.add("receiver", setMemoryNode.receiver); + args.add("objBase", setMemoryNode.obj); + args.add("objOffset", setMemoryNode.offset); + args.add("bytes", setMemoryNode.bytes); + args.add("value", setMemoryNode.value); + SnippetTemplate template = template(tool, setMemoryNode, args); + template.instantiate(tool.getMetaAccess(), setMemoryNode, DEFAULT_REPLACER, args); + } } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/dfa/LocationMarker.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/dfa/LocationMarker.java index 67083b2f2b10..f8a8020afa10 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/dfa/LocationMarker.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/dfa/LocationMarker.java @@ -32,6 +32,7 @@ import jdk.graal.compiler.core.common.LIRKind; import jdk.graal.compiler.core.common.cfg.BasicBlock; import jdk.graal.compiler.core.common.cfg.BlockMap; +import jdk.graal.compiler.core.common.util.CompilationAlarm; import jdk.graal.compiler.debug.DebugContext; import jdk.graal.compiler.debug.GraalError; import jdk.graal.compiler.debug.Indent; @@ -79,6 +80,7 @@ void build() { liveInMap.put(block, newLiveValueSet()); } while (!worklist.isEmpty()) { + CompilationAlarm.checkProgress(lir.getOptions(), lir); BasicBlock block = worklist.poll(); processBlock(block, worklist); }