Mercurial > hg > graal-jvmci-8
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)) { |