# HG changeset patch # User Doug Simon # Date 1428483967 -7200 # Node ID 1f7ef92cb660baf27db97f8c4a96fa57ff236c1a # Parent 91a25b017111628a9ab7cb87c89b5988469c3de2 use InvocationPlugin instead of Unsafe to access String.value from within substitution for String.equals diff -r 91a25b017111 -r 1f7ef92cb660 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java --- 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); diff -r 91a25b017111 -r 1f7ef92cb660 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StringSubstitutions.java --- 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); }