comparison graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java @ 19962:9b669776bf8a

added null checking for the receiver when inlining or applying an InvocationPlugin during graph parsing
author Doug Simon <doug.simon@oracle.com>
date Thu, 19 Mar 2015 22:31:42 +0100
parents 812fc403db8c
children 30ad420c16fd
comparison
equal deleted inserted replaced
19961:71040f48cc34 19962:9b669776bf8a
31 import com.oracle.graal.api.meta.*; 31 import com.oracle.graal.api.meta.*;
32 import com.oracle.graal.compiler.common.*; 32 import com.oracle.graal.compiler.common.*;
33 import com.oracle.graal.graph.Node; 33 import com.oracle.graal.graph.Node;
34 import com.oracle.graal.graph.iterators.*; 34 import com.oracle.graal.graph.iterators.*;
35 import com.oracle.graal.nodes.*; 35 import com.oracle.graal.nodes.*;
36 import com.oracle.graal.nodes.type.*;
36 37
37 /** 38 /**
38 * Manages a set of {@link InvocationPlugin}s. 39 * Manages a set of {@link InvocationPlugin}s.
39 */ 40 */
40 public class InvocationPlugins { 41 public class InvocationPlugins {
41 42
42 /** 43 /**
43 * Sentinel class for use with 44 * Access to the receiver in an {@link InvocationPlugin} for a non-static method. The class
45 * literal for this interface must be used with
44 * {@link InvocationPlugins#register(InvocationPlugin, Class, String, Class...)} to denote the 46 * {@link InvocationPlugins#register(InvocationPlugin, Class, String, Class...)} to denote the
45 * receiver argument for a non-static method. 47 * receiver argument for such a non-static method.
46 */ 48 */
47 public static final class Receiver { 49 public interface Receiver {
48 private Receiver() { 50 /**
49 throw GraalInternalError.shouldNotReachHere(); 51 * Gets the receiver value, null checking it first if necessary.
50 } 52 *
53 * @return the receiver value with a {@linkplain StampTool#isPointerNonNull(ValueNode)
54 * non-null} stamp
55 */
56 ValueNode get();
57
58 /**
59 * Determines if the receiver is constant.
60 */
61 boolean isConstant();
62
63 /**
64 * Determines if the receiver is the null constant.
65 */
66 boolean isNullConstant();
51 } 67 }
52 68
53 /** 69 /**
54 * Utility for 70 * Utility for
55 * {@linkplain InvocationPlugins#register(InvocationPlugin, Class, String, Class...) 71 * {@linkplain InvocationPlugins#register(InvocationPlugin, Class, String, Class...)
342 for (Method method : InvocationPlugin.class.getDeclaredMethods()) { 358 for (Method method : InvocationPlugin.class.getDeclaredMethods()) {
343 if (!Modifier.isStatic(method.getModifiers()) && method.getName().equals("apply")) { 359 if (!Modifier.isStatic(method.getModifiers()) && method.getName().equals("apply")) {
344 Class<?>[] sig = method.getParameterTypes(); 360 Class<?>[] sig = method.getParameterTypes();
345 assert sig[0] == GraphBuilderContext.class; 361 assert sig[0] == GraphBuilderContext.class;
346 assert sig[1] == ResolvedJavaMethod.class; 362 assert sig[1] == ResolvedJavaMethod.class;
347 assert Arrays.asList(Arrays.copyOfRange(sig, 2, sig.length)).stream().allMatch(c -> c == ValueNode.class); 363 assert sig[2] == Receiver.class;
348 while (sigs.size() < sig.length - 1) { 364 assert Arrays.asList(Arrays.copyOfRange(sig, 3, sig.length)).stream().allMatch(c -> c == ValueNode.class);
365 while (sigs.size() < sig.length - 2) {
349 sigs.add(null); 366 sigs.add(null);
350 } 367 }
351 sigs.set(sig.length - 2, sig); 368 sigs.set(sig.length - 3, sig);
352 } 369 }
353 } 370 }
354 assert sigs.indexOf(null) == -1 : format("need to add an apply() method to %s that takes %d %s arguments ", InvocationPlugin.class.getName(), sigs.indexOf(null), 371 assert sigs.indexOf(null) == -1 : format("need to add an apply() method to %s that takes %d %s arguments ", InvocationPlugin.class.getName(), sigs.indexOf(null),
355 ValueNode.class.getSimpleName()); 372 ValueNode.class.getSimpleName());
356 SIGS = sigs.toArray(new Class<?>[sigs.size()][]); 373 SIGS = sigs.toArray(new Class<?>[sigs.size()][]);
360 InvocationPlugins p = plugins; 377 InvocationPlugins p = plugins;
361 while (p != null) { 378 while (p != null) {
362 assert !p.registrations.contains(method) : "a plugin is already registered for " + method; 379 assert !p.registrations.contains(method) : "a plugin is already registered for " + method;
363 p = p.parent; 380 p = p.parent;
364 } 381 }
365 int arguments = method.argumentTypes.length; 382 int arguments = method.isStatic ? method.argumentTypes.length : method.argumentTypes.length - 1;
366 assert arguments < SIGS.length : format("need to extend %s to support method with %d arguments: %s", InvocationPlugin.class.getSimpleName(), arguments, method); 383 assert arguments < SIGS.length : format("need to extend %s to support method with %d arguments: %s", InvocationPlugin.class.getSimpleName(), arguments, method);
367 for (Method m : plugin.getClass().getDeclaredMethods()) { 384 for (Method m : plugin.getClass().getDeclaredMethods()) {
368 if (m.getName().equals("apply")) { 385 if (m.getName().equals("apply")) {
369 Class<?>[] parameterTypes = m.getParameterTypes(); 386 Class<?>[] parameterTypes = m.getParameterTypes();
370 if (Arrays.equals(SIGS[arguments], parameterTypes)) { 387 if (Arrays.equals(SIGS[arguments], parameterTypes)) {