annotate graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java @ 11265:ef6915cf1e59

Add illegal stamp Remove ValueNode.(object|integer)Stamp: use explicit tests/casts Fix ObjectStamp.join Introduce ObjectStamp.castTo Add some tests for ObjectStamp.join
author Gilles Duboscq <duboscq@ssw.jku.at>
date Thu, 08 Aug 2013 18:17:47 +0200
parents 747b2517feae
children da9db8331658
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
9691
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
1 /*
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
4 *
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
7 * published by the Free Software Foundation.
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
8 *
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
13 * accompanied this code).
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
14 *
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
18 *
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
21 * questions.
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
22 */
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
23 package com.oracle.graal.hotspot.replacements;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
24
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
25 import java.lang.reflect.Modifier;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
26 import java.util.Arrays;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
27
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
28 import com.oracle.graal.api.meta.Constant;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
29 import com.oracle.graal.api.meta.JavaType;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
30 import com.oracle.graal.api.meta.ResolvedJavaField;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
31 import com.oracle.graal.api.meta.ResolvedJavaMethod;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
32 import com.oracle.graal.api.meta.ResolvedJavaType;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
33 import com.oracle.graal.graph.GraalInternalError;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
34 import com.oracle.graal.graph.NodeInputList;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
35 import com.oracle.graal.hotspot.meta.HotSpotResolvedJavaMethod;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
36 import com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
37 import com.oracle.graal.hotspot.meta.HotSpotSignature;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
38 import com.oracle.graal.nodes.CallTargetNode;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
39 import com.oracle.graal.nodes.Invoke;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
40 import com.oracle.graal.nodes.InvokeNode;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
41 import com.oracle.graal.nodes.PiNode;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
42 import com.oracle.graal.nodes.ValueNode;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
43 import com.oracle.graal.nodes.java.MethodCallTargetNode;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
44 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
45 import com.oracle.graal.nodes.java.SelfReplacingMethodCallTargetNode;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
46 import com.oracle.graal.nodes.spi.Canonicalizable;
11265
ef6915cf1e59 Add illegal stamp
Gilles Duboscq <duboscq@ssw.jku.at>
parents: 9784
diff changeset
47 import com.oracle.graal.nodes.type.*;
9691
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
48 import com.oracle.graal.replacements.nodes.MacroNode;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
49
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
50 /**
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
51 * Common base class for method handle invoke nodes.
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
52 */
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
53 public abstract class AbstractMethodHandleNode extends MacroNode implements Canonicalizable {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
54
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
55 private static final ResolvedJavaField methodHandleFormField;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
56 private static final ResolvedJavaField lambdaFormVmentryField;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
57 private static final ResolvedJavaField memberNameClazzField;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
58 private static final ResolvedJavaField memberNameVmtargetField;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
59
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
60 // Replacement method data
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
61 private ResolvedJavaMethod replacementTargetMethod;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
62 private JavaType replacementReturnType;
9715
badabdca0c53 fix final-ness of @Input node inputs
Lukas Stadler <lukas.stadler@jku.at>
parents: 9691
diff changeset
63 @Input private final NodeInputList<ValueNode> replacementArguments;
9691
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
64
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
65 /**
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
66 * Search for an instance field with the given name in a class.
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
67 *
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
68 * @param className name of the class to search in
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
69 * @param fieldName name of the field to be searched
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
70 * @return resolved java field
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
71 * @throws ClassNotFoundException
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
72 */
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
73 private static ResolvedJavaField findFieldInClass(String className, String fieldName) throws ClassNotFoundException {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
74 Class<?> clazz = Class.forName(className);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
75 ResolvedJavaType type = HotSpotResolvedObjectType.fromClass(clazz);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
76 ResolvedJavaField[] fields = type.getInstanceFields(false);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
77 for (ResolvedJavaField field : fields) {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
78 if (field.getName().equals(fieldName)) {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
79 return field;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
80 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
81 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
82 return null;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
83 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
84
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
85 static {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
86 try {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
87 methodHandleFormField = findFieldInClass("java.lang.invoke.MethodHandle", "form");
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
88 lambdaFormVmentryField = findFieldInClass("java.lang.invoke.LambdaForm", "vmentry");
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
89 memberNameClazzField = findFieldInClass("java.lang.invoke.MemberName", "clazz");
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
90 memberNameVmtargetField = findFieldInClass("java.lang.invoke.MemberName", "vmtarget");
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
91 } catch (ClassNotFoundException | SecurityException ex) {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
92 throw GraalInternalError.shouldNotReachHere();
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
93 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
94 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
95
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
96 public AbstractMethodHandleNode(Invoke invoke) {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
97 super(invoke);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
98
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
99 // See if we need to save some replacement method data.
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
100 CallTargetNode callTarget = invoke.callTarget();
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
101 if (callTarget instanceof SelfReplacingMethodCallTargetNode) {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
102 SelfReplacingMethodCallTargetNode selfReplacingMethodCallTargetNode = (SelfReplacingMethodCallTargetNode) callTarget;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
103 replacementTargetMethod = selfReplacingMethodCallTargetNode.replacementTargetMethod();
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
104 replacementReturnType = selfReplacingMethodCallTargetNode.replacementReturnType();
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
105 replacementArguments = selfReplacingMethodCallTargetNode.replacementArguments();
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
106 } else {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
107 // NodeInputList can't be null.
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
108 replacementArguments = new NodeInputList<>(this);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
109 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
110 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
111
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
112 /**
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
113 * Get the receiver of a MethodHandle.invokeBasic call.
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
114 *
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
115 * @return the receiver argument node
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
116 */
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
117 private ValueNode getReceiver() {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
118 return arguments.first();
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
119 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
120
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
121 /**
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
122 * Get the MemberName argument of a MethodHandle.linkTo* call.
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
123 *
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
124 * @return the MemberName argument node (which is the last argument)
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
125 */
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
126 private ValueNode getMemberName() {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
127 return arguments.last();
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
128 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
129
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
130 /**
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
131 * Used from {@link MethodHandleInvokeBasicNode} to get the target {@link InvokeNode} if the
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
132 * method handle receiver is constant.
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
133 *
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
134 * @return invoke node for the {@link java.lang.invoke.MethodHandle} target
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
135 */
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
136 protected InvokeNode getInvokeBasicTarget() {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
137 ValueNode methodHandleNode = getReceiver();
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
138 if (methodHandleNode.isConstant() && !methodHandleNode.isNullConstant()) {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
139 // Get the data we need from MethodHandle.LambdaForm.MemberName
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
140 Constant methodHandle = methodHandleNode.asConstant();
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
141 Constant lambdaForm = methodHandleFormField.readValue(methodHandle);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
142 Constant memberName = lambdaFormVmentryField.readValue(lambdaForm);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
143 return getTargetInvokeNode(memberName);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
144 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
145 return null;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
146 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
147
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
148 /**
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
149 * Used from {@link MethodHandleLinkToStaticNode}, {@link MethodHandleLinkToSpecialNode},
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
150 * {@link MethodHandleLinkToVirtualNode}, and {@link MethodHandleLinkToInterfaceNode} to get the
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
151 * target {@link InvokeNode} if the member name argument is constant.
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
152 *
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
153 * @return invoke node for the member name target
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
154 */
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
155 protected InvokeNode getLinkToTarget() {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
156 ValueNode memberNameNode = getMemberName();
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
157 if (memberNameNode.isConstant() && !memberNameNode.isNullConstant()) {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
158 Constant memberName = memberNameNode.asConstant();
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
159 return getTargetInvokeNode(memberName);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
160 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
161 return null;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
162 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
163
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
164 /**
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
165 * Helper function to get the {@link InvokeNode} for the vmtarget of a
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
166 * java.lang.invoke.MemberName.
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
167 *
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
168 * @param memberName constant member name node
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
169 * @return invoke node for the member name target
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
170 */
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
171 private InvokeNode getTargetInvokeNode(Constant memberName) {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
172 // Get the data we need from MemberName
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
173 Constant clazz = memberNameClazzField.readValue(memberName);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
174 Constant vmtarget = memberNameVmtargetField.readValue(memberName);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
175
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
176 // Create a method from the vmtarget pointer
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
177 Class<?> c = (Class<?>) clazz.asObject();
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
178 HotSpotResolvedObjectType holderClass = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromClass(c);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
179 HotSpotResolvedJavaMethod targetMethod = holderClass.createMethod(vmtarget.asLong());
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
180
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
181 // In lamda forms we erase signature types to avoid resolving issues
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
182 // involving class loaders. When we optimize a method handle invoke
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
183 // to a direct call we must cast the receiver and arguments to its
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
184 // actual types.
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
185 HotSpotSignature signature = targetMethod.getSignature();
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
186 final boolean isStatic = Modifier.isStatic(targetMethod.getModifiers());
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
187 final int receiverSkip = isStatic ? 0 : 1;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
188
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
189 // Cast receiver to its type.
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
190 if (!isStatic) {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
191 JavaType receiverType = holderClass;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
192 maybeCastArgument(0, receiverType);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
193 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
194
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
195 // Cast reference arguments to its type.
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
196 for (int index = 0; index < signature.getParameterCount(false); index++) {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
197 JavaType parameterType = signature.getParameterType(index, holderClass);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
198 maybeCastArgument(receiverSkip + index, parameterType);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
199 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
200
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
201 // Try to get the most accurate receiver type
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
202 if (this instanceof MethodHandleLinkToVirtualNode || this instanceof MethodHandleLinkToInterfaceNode) {
11265
ef6915cf1e59 Add illegal stamp
Gilles Duboscq <duboscq@ssw.jku.at>
parents: 9784
diff changeset
203 ResolvedJavaType receiverType = ObjectStamp.typeOrNull(getReceiver().stamp());
9691
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
204 if (receiverType != null) {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
205 ResolvedJavaMethod concreteMethod = receiverType.findUniqueConcreteMethod(targetMethod);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
206 if (concreteMethod != null) {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
207 return createTargetInvokeNode(concreteMethod);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
208 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
209 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
210 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
211
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
212 if (targetMethod.canBeStaticallyBound()) {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
213 return createTargetInvokeNode(targetMethod);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
214 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
215
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
216 ResolvedJavaMethod concreteMethod = targetMethod.uniqueConcreteMethod();
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
217 if (concreteMethod != null) {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
218 return createTargetInvokeNode(concreteMethod);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
219 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
220
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
221 return null;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
222 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
223
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
224 /**
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
225 * Inserts a node to cast the argument at index to the given type if the given type is more
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
226 * concrete than the argument type.
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
227 *
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
228 * @param index of the argument to be cast
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
229 * @param type the type the argument should be cast to
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
230 */
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
231 private void maybeCastArgument(int index, JavaType type) {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
232 if (type instanceof ResolvedJavaType) {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
233 ResolvedJavaType targetType = (ResolvedJavaType) type;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
234 if (!targetType.isPrimitive()) {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
235 ValueNode argument = arguments.get(index);
11265
ef6915cf1e59 Add illegal stamp
Gilles Duboscq <duboscq@ssw.jku.at>
parents: 9784
diff changeset
236 ResolvedJavaType argumentType = ObjectStamp.typeOrNull(argument.stamp());
9691
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
237 if (argumentType == null || (argumentType.isAssignableFrom(targetType) && !argumentType.equals(targetType))) {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
238 PiNode piNode = graph().unique(new PiNode(argument, StampFactory.declared(targetType)));
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
239 arguments.set(index, piNode);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
240 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
241 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
242 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
243 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
244
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
245 /**
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
246 * Creates an {@link InvokeNode} for the given target method. The {@link CallTargetNode} passed
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
247 * to the InvokeNode is in fact a {@link SelfReplacingMethodCallTargetNode}.
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
248 *
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
249 * @param targetMethod the method the be called
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
250 * @return invoke node for the member name target
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
251 */
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
252 private InvokeNode createTargetInvokeNode(ResolvedJavaMethod targetMethod) {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
253 InvokeKind invokeKind = Modifier.isStatic(targetMethod.getModifiers()) ? InvokeKind.Static : InvokeKind.Special;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
254 JavaType returnType = targetMethod.getSignature().getReturnType(null);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
255
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
256 // MethodHandleLinkTo* nodes have a trailing MemberName argument which
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
257 // needs to be popped.
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
258 ValueNode[] originalArguments = arguments.toArray(new ValueNode[arguments.size()]);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
259 ValueNode[] targetArguments;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
260 if (this instanceof MethodHandleInvokeBasicNode) {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
261 targetArguments = originalArguments;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
262 } else {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
263 assert this instanceof MethodHandleLinkToStaticNode || this instanceof MethodHandleLinkToSpecialNode || this instanceof MethodHandleLinkToVirtualNode ||
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
264 this instanceof MethodHandleLinkToInterfaceNode : this;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
265 targetArguments = Arrays.copyOfRange(originalArguments, 0, arguments.size() - 1);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
266 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
267
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
268 // If there is already replacement information, use that instead.
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
269 MethodCallTargetNode callTarget;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
270 if (replacementTargetMethod == null) {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
271 callTarget = new SelfReplacingMethodCallTargetNode(invokeKind, targetMethod, targetArguments, returnType, getTargetMethod(), originalArguments, getReturnType());
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
272 } else {
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
273 ValueNode[] args = replacementArguments.toArray(new ValueNode[replacementArguments.size()]);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
274 callTarget = new SelfReplacingMethodCallTargetNode(invokeKind, targetMethod, targetArguments, returnType, replacementTargetMethod, args, replacementReturnType);
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
275 }
9784
747b2517feae use invoker's stamp if target's return stamp is of different type
twisti
parents: 9715
diff changeset
276 graph().add(callTarget);
9691
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
277
9784
747b2517feae use invoker's stamp if target's return stamp is of different type
twisti
parents: 9715
diff changeset
278 // The call target can have a different return type than the invoker,
747b2517feae use invoker's stamp if target's return stamp is of different type
twisti
parents: 9715
diff changeset
279 // e.g. the target returns an Object but the invoker void. In this case
747b2517feae use invoker's stamp if target's return stamp is of different type
twisti
parents: 9715
diff changeset
280 // we need to use the stamp of the invoker. Note: always using the
747b2517feae use invoker's stamp if target's return stamp is of different type
twisti
parents: 9715
diff changeset
281 // invoker's stamp would be wrong because it's a less concrete type
747b2517feae use invoker's stamp if target's return stamp is of different type
twisti
parents: 9715
diff changeset
282 // (usually java.lang.Object).
747b2517feae use invoker's stamp if target's return stamp is of different type
twisti
parents: 9715
diff changeset
283 InvokeNode invoke;
747b2517feae use invoker's stamp if target's return stamp is of different type
twisti
parents: 9715
diff changeset
284 if (callTarget.returnStamp().kind() != stamp().kind()) {
747b2517feae use invoker's stamp if target's return stamp is of different type
twisti
parents: 9715
diff changeset
285 invoke = new InvokeNode(callTarget, getBci(), stamp());
747b2517feae use invoker's stamp if target's return stamp is of different type
twisti
parents: 9715
diff changeset
286 } else {
747b2517feae use invoker's stamp if target's return stamp is of different type
twisti
parents: 9715
diff changeset
287 invoke = new InvokeNode(callTarget, getBci());
747b2517feae use invoker's stamp if target's return stamp is of different type
twisti
parents: 9715
diff changeset
288 }
747b2517feae use invoker's stamp if target's return stamp is of different type
twisti
parents: 9715
diff changeset
289 graph().add(invoke);
9691
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
290 invoke.setStateAfter(stateAfter());
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
291 return invoke;
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
292 }
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
293
bd5c6b3dedc5 implement inlining support for JSR 292
twisti
parents:
diff changeset
294 }