changeset 20852:1f7ef92cb660

use InvocationPlugin instead of Unsafe to access String.value from within substitution for String.equals
author Doug Simon <doug.simon@oracle.com>
date Wed, 08 Apr 2015 11:06:07 +0200
parents 91a25b017111
children a74c785068e0
files graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StringSubstitutions.java
diffstat 2 files changed, 31 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java	Wed Apr 08 10:50:06 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java	Wed Apr 08 11:06:07 2015 +0200
@@ -32,6 +32,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.directives.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.calc.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
@@ -71,6 +72,7 @@
         registerIntegerLongPlugins(plugins, Kind.Long);
         registerFloatPlugins(plugins);
         registerDoublePlugins(plugins);
+        registerStringPlugins(plugins);
         registerArraysPlugins(plugins);
         registerArrayPlugins(plugins);
         registerUnsafePlugins(plugins);
@@ -84,6 +86,26 @@
         }
     }
 
+    private static final Field STRING_VALUE_FIELD;
+    static {
+        try {
+            STRING_VALUE_FIELD = String.class.getDeclaredField("value");
+        } catch (NoSuchFieldException e) {
+            throw new GraalInternalError(e);
+        }
+    }
+
+    private static void registerStringPlugins(InvocationPlugins plugins) {
+        Registration r = new Registration(plugins, StringSubstitutions.class);
+        r.register1("getValue", String.class, new InvocationPlugin() {
+            public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
+                ResolvedJavaField field = b.getMetaAccess().lookupJavaField(STRING_VALUE_FIELD);
+                b.addPush(new LoadFieldNode(value, field));
+                return true;
+            }
+        });
+    }
+
     private static void registerArraysPlugins(InvocationPlugins plugins) {
         Registration r = new Registration(plugins, Arrays.class);
         r.registerMethodSubstitution(ArraysSubstitutions.class, "equals", boolean[].class, boolean[].class);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StringSubstitutions.java	Wed Apr 08 10:50:06 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StringSubstitutions.java	Wed Apr 08 11:06:07 2015 +0200
@@ -22,12 +22,9 @@
  */
 package com.oracle.graal.replacements;
 
-import static com.oracle.graal.compiler.common.UnsafeAccess.*;
-
-import java.lang.reflect.*;
-
 import com.oracle.graal.api.replacements.*;
-import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.graphbuilderconf.*;
+import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.replacements.nodes.*;
 
 import edu.umd.cs.findbugs.annotations.*;
@@ -38,20 +35,6 @@
 @ClassSubstitution(value = java.lang.String.class)
 public class StringSubstitutions {
 
-    /**
-     * Offset of the {@link String#value} field.
-     */
-    @java.lang.SuppressWarnings("javadoc") private static final long valueOffset;
-
-    static {
-        try {
-            Field valueField = String.class.getDeclaredField("value");
-            valueOffset = unsafe.objectFieldOffset(valueField);
-        } catch (NoSuchFieldException | SecurityException | IllegalArgumentException e) {
-            throw new GraalInternalError(e);
-        }
-    }
-
     @MethodSubstitution(isStatic = false)
     @SuppressFBWarnings(value = "ES_COMPARING_PARAMETER_STRING_WITH_EQ", justification = "reference equality on the receiver is what we want")
     public static boolean equals(final String thisString, Object obj) {
@@ -69,9 +52,14 @@
             return true;
         }
 
-        final char[] array1 = (char[]) unsafe.getObject(thisString, valueOffset);
-        final char[] array2 = (char[]) unsafe.getObject(thatString, valueOffset);
+        final char[] array1 = getValue(thisString);
+        final char[] array2 = getValue(thatString);
 
         return ArrayEqualsNode.equals(array1, array2, array1.length);
     }
+
+    /**
+     * Will be intrinsified with an {@link InvocationPlugin} to a {@link LoadFieldNode}.
+     */
+    private static native char[] getValue(String s);
 }