13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package org.graalvm.compiler.replacements;
24
25 import static jdk.vm.ci.code.MemoryBarriers.JMM_POST_VOLATILE_READ;
26 import static jdk.vm.ci.code.MemoryBarriers.JMM_POST_VOLATILE_WRITE;
27 import static jdk.vm.ci.code.MemoryBarriers.JMM_PRE_VOLATILE_READ;
28 import static jdk.vm.ci.code.MemoryBarriers.JMM_PRE_VOLATILE_WRITE;
29 import static jdk.vm.ci.code.MemoryBarriers.LOAD_LOAD;
30 import static jdk.vm.ci.code.MemoryBarriers.LOAD_STORE;
31 import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD;
32 import static jdk.vm.ci.code.MemoryBarriers.STORE_STORE;
33 import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier;
34
35 import java.lang.reflect.Array;
36 import java.lang.reflect.Field;
37 import java.util.Arrays;
38
39 import org.graalvm.compiler.api.directives.GraalDirectives;
40 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
41 import org.graalvm.compiler.bytecode.BytecodeProvider;
42 import org.graalvm.compiler.core.common.calc.Condition;
43 import org.graalvm.compiler.core.common.calc.UnsignedMath;
44 import org.graalvm.compiler.core.common.type.ObjectStamp;
45 import org.graalvm.compiler.core.common.type.Stamp;
46 import org.graalvm.compiler.core.common.type.StampFactory;
47 import org.graalvm.compiler.core.common.type.TypeReference;
48 import org.graalvm.compiler.debug.GraalError;
49 import org.graalvm.compiler.graph.Edges;
50 import org.graalvm.compiler.graph.Node;
51 import org.graalvm.compiler.graph.NodeList;
52 import org.graalvm.compiler.nodes.ConstantNode;
633 void register(InvocationPlugins plugins) {
634 String name = kind.toJavaClass().getSimpleName() + "Value";
635 plugins.register(this, kind.toBoxedJavaClass(), name, Receiver.class);
636 }
637 }
638
639 public static class UnsafeGetPlugin implements InvocationPlugin {
640
641 private final JavaKind returnKind;
642 private final boolean isVolatile;
643
644 public UnsafeGetPlugin(JavaKind returnKind, boolean isVolatile) {
645 this.returnKind = returnKind;
646 this.isVolatile = isVolatile;
647 }
648
649 @Override
650 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode address) {
651 // Emits a null-check for the otherwise unused receiver
652 unsafe.get();
653 b.addPush(returnKind, new UnsafeMemoryLoadNode(address, returnKind, LocationIdentity.any()));
654 b.getGraph().markUnsafeAccess();
655 return true;
656 }
657
658 @Override
659 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode object, ValueNode offset) {
660 // Emits a null-check for the otherwise unused receiver
661 unsafe.get();
662 if (isVolatile) {
663 b.add(new MembarNode(JMM_PRE_VOLATILE_READ));
664 }
665 b.addPush(returnKind, new RawLoadNode(object, offset, returnKind, LocationIdentity.any()));
666 if (isVolatile) {
667 b.add(new MembarNode(JMM_POST_VOLATILE_READ));
668 }
669 b.getGraph().markUnsafeAccess();
670 return true;
671 }
672 }
673
674 public static class UnsafePutPlugin implements InvocationPlugin {
675
676 private final JavaKind kind;
677 private final boolean isVolatile;
678
679 public UnsafePutPlugin(JavaKind kind, boolean isVolatile) {
680 this.kind = kind;
681 this.isVolatile = isVolatile;
682 }
683
684 @Override
685 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode address, ValueNode value) {
686 // Emits a null-check for the otherwise unused receiver
687 unsafe.get();
688 b.add(new UnsafeMemoryStoreNode(address, value, kind, LocationIdentity.any()));
689 b.getGraph().markUnsafeAccess();
690 return true;
691 }
692
693 @Override
694 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode object, ValueNode offset, ValueNode value) {
695 // Emits a null-check for the otherwise unused receiver
696 unsafe.get();
697 if (isVolatile) {
698 b.add(new MembarNode(JMM_PRE_VOLATILE_WRITE));
699 }
700 b.add(new RawStoreNode(object, offset, value, kind, LocationIdentity.any()));
701 if (isVolatile) {
702 b.add(new MembarNode(JMM_POST_VOLATILE_WRITE));
703 }
704 b.getGraph().markUnsafeAccess();
705 return true;
706 }
707 }
708
709 public static class UnsafeFencePlugin implements InvocationPlugin {
710
711 private final int barriers;
712
713 public UnsafeFencePlugin(int barriers) {
714 this.barriers = barriers;
715 }
716
717 @Override
718 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe) {
719 // Emits a null-check for the otherwise unused receiver
720 unsafe.get();
|
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package org.graalvm.compiler.replacements;
24
25 import static jdk.vm.ci.code.MemoryBarriers.JMM_POST_VOLATILE_READ;
26 import static jdk.vm.ci.code.MemoryBarriers.JMM_POST_VOLATILE_WRITE;
27 import static jdk.vm.ci.code.MemoryBarriers.JMM_PRE_VOLATILE_READ;
28 import static jdk.vm.ci.code.MemoryBarriers.JMM_PRE_VOLATILE_WRITE;
29 import static jdk.vm.ci.code.MemoryBarriers.LOAD_LOAD;
30 import static jdk.vm.ci.code.MemoryBarriers.LOAD_STORE;
31 import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD;
32 import static jdk.vm.ci.code.MemoryBarriers.STORE_STORE;
33 import static org.graalvm.compiler.nodes.NamedLocationIdentity.OFF_HEAP_LOCATION;
34 import static org.graalvm.compiler.serviceprovider.JDK9Method.Java8OrEarlier;
35
36 import java.lang.reflect.Array;
37 import java.lang.reflect.Field;
38 import java.util.Arrays;
39
40 import org.graalvm.compiler.api.directives.GraalDirectives;
41 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
42 import org.graalvm.compiler.bytecode.BytecodeProvider;
43 import org.graalvm.compiler.core.common.calc.Condition;
44 import org.graalvm.compiler.core.common.calc.UnsignedMath;
45 import org.graalvm.compiler.core.common.type.ObjectStamp;
46 import org.graalvm.compiler.core.common.type.Stamp;
47 import org.graalvm.compiler.core.common.type.StampFactory;
48 import org.graalvm.compiler.core.common.type.TypeReference;
49 import org.graalvm.compiler.debug.GraalError;
50 import org.graalvm.compiler.graph.Edges;
51 import org.graalvm.compiler.graph.Node;
52 import org.graalvm.compiler.graph.NodeList;
53 import org.graalvm.compiler.nodes.ConstantNode;
634 void register(InvocationPlugins plugins) {
635 String name = kind.toJavaClass().getSimpleName() + "Value";
636 plugins.register(this, kind.toBoxedJavaClass(), name, Receiver.class);
637 }
638 }
639
640 public static class UnsafeGetPlugin implements InvocationPlugin {
641
642 private final JavaKind returnKind;
643 private final boolean isVolatile;
644
645 public UnsafeGetPlugin(JavaKind returnKind, boolean isVolatile) {
646 this.returnKind = returnKind;
647 this.isVolatile = isVolatile;
648 }
649
650 @Override
651 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode address) {
652 // Emits a null-check for the otherwise unused receiver
653 unsafe.get();
654 b.addPush(returnKind, new UnsafeMemoryLoadNode(address, returnKind, OFF_HEAP_LOCATION));
655 b.getGraph().markUnsafeAccess();
656 return true;
657 }
658
659 @Override
660 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode object, ValueNode offset) {
661 // Emits a null-check for the otherwise unused receiver
662 unsafe.get();
663 if (isVolatile) {
664 b.add(new MembarNode(JMM_PRE_VOLATILE_READ));
665 }
666 LocationIdentity locationIdentity = object.isNullConstant() ? OFF_HEAP_LOCATION : LocationIdentity.any();
667 b.addPush(returnKind, new RawLoadNode(object, offset, returnKind, locationIdentity));
668 if (isVolatile) {
669 b.add(new MembarNode(JMM_POST_VOLATILE_READ));
670 }
671 b.getGraph().markUnsafeAccess();
672 return true;
673 }
674 }
675
676 public static class UnsafePutPlugin implements InvocationPlugin {
677
678 private final JavaKind kind;
679 private final boolean isVolatile;
680
681 public UnsafePutPlugin(JavaKind kind, boolean isVolatile) {
682 this.kind = kind;
683 this.isVolatile = isVolatile;
684 }
685
686 @Override
687 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode address, ValueNode value) {
688 // Emits a null-check for the otherwise unused receiver
689 unsafe.get();
690 b.add(new UnsafeMemoryStoreNode(address, value, kind, OFF_HEAP_LOCATION));
691 b.getGraph().markUnsafeAccess();
692 return true;
693 }
694
695 @Override
696 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode object, ValueNode offset, ValueNode value) {
697 // Emits a null-check for the otherwise unused receiver
698 unsafe.get();
699 if (isVolatile) {
700 b.add(new MembarNode(JMM_PRE_VOLATILE_WRITE));
701 }
702 LocationIdentity locationIdentity = object.isNullConstant() ? OFF_HEAP_LOCATION : LocationIdentity.any();
703 b.add(new RawStoreNode(object, offset, value, kind, locationIdentity));
704 if (isVolatile) {
705 b.add(new MembarNode(JMM_POST_VOLATILE_WRITE));
706 }
707 b.getGraph().markUnsafeAccess();
708 return true;
709 }
710 }
711
712 public static class UnsafeFencePlugin implements InvocationPlugin {
713
714 private final int barriers;
715
716 public UnsafeFencePlugin(int barriers) {
717 this.barriers = barriers;
718 }
719
720 @Override
721 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe) {
722 // Emits a null-check for the otherwise unused receiver
723 unsafe.get();
|