Mercurial > hg > graal-compiler
comparison graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/MethodCallTargetNode.java @ 3733:e233f5660da4
Added Java files from Maxine project.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sat, 17 Dec 2011 19:59:18 +0100 |
parents | |
children | aaac4894175c |
comparison
equal
deleted
inserted
replaced
3732:3e2e8b8abdaf | 3733:e233f5660da4 |
---|---|
1 /* | |
2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 */ | |
23 package com.oracle.max.graal.nodes.java; | |
24 | |
25 import com.oracle.max.graal.graph.*; | |
26 import com.oracle.max.graal.nodes.*; | |
27 import com.oracle.max.graal.nodes.spi.*; | |
28 import com.oracle.max.graal.nodes.type.*; | |
29 import com.sun.cri.ci.*; | |
30 import com.sun.cri.ri.*; | |
31 | |
32 public class MethodCallTargetNode extends CallTargetNode implements Node.IterableNodeType, Canonicalizable { | |
33 public enum InvokeKind { | |
34 Interface, | |
35 Special, | |
36 Static, | |
37 Virtual | |
38 } | |
39 | |
40 @Data private final RiType returnType; | |
41 @Data private RiResolvedMethod targetMethod; | |
42 @Data private InvokeKind invokeKind; | |
43 private final Stamp returnStamp; | |
44 | |
45 /** | |
46 * @param arguments | |
47 */ | |
48 public MethodCallTargetNode(InvokeKind invokeKind, RiResolvedMethod targetMethod, ValueNode[] arguments, RiType returnType) { | |
49 super(arguments); | |
50 this.invokeKind = invokeKind; | |
51 this.returnType = returnType; | |
52 this.targetMethod = targetMethod; | |
53 CiKind returnKind = targetMethod.signature().returnKind(false); | |
54 if (returnKind == CiKind.Object && returnType instanceof RiResolvedType) { | |
55 returnStamp = StampFactory.declared((RiResolvedType) returnType); | |
56 } else { | |
57 returnStamp = StampFactory.forKind(returnKind); | |
58 } | |
59 } | |
60 | |
61 @Override | |
62 public RiType returnType() { | |
63 return returnType; | |
64 } | |
65 | |
66 /** | |
67 * Gets the target method for this invocation instruction. | |
68 * @return the target method | |
69 */ | |
70 public RiResolvedMethod targetMethod() { | |
71 return targetMethod; | |
72 } | |
73 | |
74 public InvokeKind invokeKind() { | |
75 return invokeKind; | |
76 } | |
77 | |
78 public void setInvokeKind(InvokeKind kind) { | |
79 this.invokeKind = kind; | |
80 } | |
81 | |
82 public void setTargetMethod(RiResolvedMethod method) { | |
83 targetMethod = method; | |
84 } | |
85 | |
86 /** | |
87 * Gets the instruction that produces the receiver object for this invocation, if any. | |
88 * @return the instruction that produces the receiver object for this invocation if any, {@code null} if this | |
89 * invocation does not take a receiver object | |
90 */ | |
91 public ValueNode receiver() { | |
92 return isStatic() ? null : arguments().get(0); | |
93 } | |
94 | |
95 /** | |
96 * Checks whether this is an invocation of a static method. | |
97 * @return {@code true} if the invocation is a static invocation | |
98 */ | |
99 public boolean isStatic() { | |
100 return invokeKind() == InvokeKind.Static; | |
101 } | |
102 | |
103 @Override | |
104 public CiKind returnKind() { | |
105 return targetMethod().signature().returnKind(false); | |
106 } | |
107 | |
108 public Invoke invoke() { | |
109 if (this.usages().size() == 0) { | |
110 return null; | |
111 } | |
112 return (Invoke) this.usages().iterator().next(); | |
113 } | |
114 | |
115 | |
116 @Override | |
117 public boolean verify() { | |
118 assert usages().size() <= 1 : "call target may only be used by a single invoke"; | |
119 for (Node n : usages()) { | |
120 assertTrue(n instanceof Invoke, "call target can only be used from an invoke (%s)", n); | |
121 } | |
122 return super.verify(); | |
123 } | |
124 | |
125 @Override | |
126 public String toString(Verbosity verbosity) { | |
127 if (verbosity == Verbosity.Long) { | |
128 return super.toString(Verbosity.Short) + "(" + targetMethod() + ")"; | |
129 } else { | |
130 return super.toString(verbosity); | |
131 } | |
132 } | |
133 | |
134 @Override | |
135 public Node canonical(CanonicalizerTool tool) { | |
136 if (!isStatic()) { | |
137 ValueNode receiver = receiver(); | |
138 if (receiver != null && receiver.exactType() != null) { | |
139 if (invokeKind == InvokeKind.Interface) { | |
140 invokeKind = InvokeKind.Virtual; | |
141 targetMethod = receiver.exactType().resolveMethodImpl(targetMethod); | |
142 } | |
143 if (receiver.isConstant() && invokeKind == InvokeKind.Virtual) { | |
144 invokeKind = InvokeKind.Special; | |
145 targetMethod = receiver.exactType().resolveMethodImpl(targetMethod); | |
146 } | |
147 } | |
148 } | |
149 return this; | |
150 } | |
151 | |
152 public Stamp returnStamp() { | |
153 return returnStamp; | |
154 } | |
155 } |