Mercurial > hg > truffle
comparison graal/GraalCompiler/src/com/sun/c1x/value/MutableFrameState.java @ 2509:16b9a8b5ad39
Renamings Runtime=>GraalRuntime and Compiler=>GraalCompiler
author | Thomas Wuerthinger <thomas@wuerthinger.net> |
---|---|
date | Wed, 27 Apr 2011 11:50:44 +0200 |
parents | graal/Compiler/src/com/sun/c1x/value/MutableFrameState.java@9ec15d6914ca |
children | 4fdef1464592 |
comparison
equal
deleted
inserted
replaced
2508:fea94949e0a2 | 2509:16b9a8b5ad39 |
---|---|
1 /* | |
2 * Copyright (c) 2010, 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.sun.c1x.value; | |
24 | |
25 import java.util.*; | |
26 | |
27 import com.sun.c1x.*; | |
28 import com.sun.c1x.ir.*; | |
29 import com.sun.c1x.util.*; | |
30 import com.sun.cri.ci.*; | |
31 | |
32 | |
33 /** | |
34 * The {@code MutableFrameState} class extends abstract {@link FrameState} with methods modifying the frame state. | |
35 * Only {@code MutableFrameState} can be instantiated and thus the object references in which it is stored decide | |
36 * whether it is used as immutable or not. Thus and because they can be shared at different places in the compiler, | |
37 * {@link FrameState}s must not be cast to {@code MutableFrameState}s. Instead, a new copy must be created using | |
38 * {@link FrameState#copy()}. | |
39 * Contrariwise and as an optimization, an instance referenced as {@code MutableFrameState} can be assigned to | |
40 * a variable, field, or method parameter of type {@link FrameState} without creating an immutable copy before | |
41 * (using {@link #immutableCopy(int)}) if the state is not mutated after the assignment. | |
42 * | |
43 * @author Michael Duller | |
44 */ | |
45 public final class MutableFrameState extends FrameState { | |
46 | |
47 public MutableFrameState(IRScope irScope, int bci, int maxLocals, int maxStack) { | |
48 super(irScope, bci, maxLocals, maxStack); | |
49 } | |
50 | |
51 /** | |
52 * Replace the local variables in this frame state with the local variables from the specified frame state. This is | |
53 * used in inlining. | |
54 * | |
55 * @param with the frame state containing the new local variables | |
56 */ | |
57 public void replaceLocals(FrameState with) { | |
58 assert with.maxLocals == maxLocals; | |
59 System.arraycopy(with.values, 0, values, 0, maxLocals); | |
60 } | |
61 | |
62 /** | |
63 * Replace the stack in this frame state with the stack from the specified frame state. This is used in inlining. | |
64 * | |
65 * @param with the frame state containing the new local variables | |
66 */ | |
67 public void replaceStack(FrameState with) { | |
68 System.arraycopy(with.values, with.maxLocals, values, maxLocals, with.stackIndex); | |
69 stackIndex = with.stackIndex; | |
70 assert stackIndex >= 0; | |
71 } | |
72 | |
73 /** | |
74 * Replace the locks in this frame state with the locks from the specified frame state. This is used in inlining. | |
75 * | |
76 * @param with the frame state containing the new local variables | |
77 */ | |
78 public void replaceLocks(FrameState with) { | |
79 if (with.locks == null) { | |
80 locks = null; | |
81 } else { | |
82 locks = Util.uncheckedCast(with.locks.clone()); | |
83 } | |
84 } | |
85 | |
86 /** | |
87 * Clears all values on this stack. | |
88 */ | |
89 public void clearStack() { | |
90 stackIndex = 0; | |
91 } | |
92 | |
93 public void clearLocals() { | |
94 for (int i = 0; i < maxLocals; i++) { | |
95 values[i] = null; | |
96 } | |
97 } | |
98 | |
99 /** | |
100 * Truncates this stack to the specified size. | |
101 * @param size the size to truncate to | |
102 */ | |
103 public void truncateStack(int size) { | |
104 stackIndex = size; | |
105 assert stackIndex >= 0; | |
106 } | |
107 | |
108 /** | |
109 * Pushes an instruction onto the stack with the expected type. | |
110 * @param kind the type expected for this instruction | |
111 * @param x the instruction to push onto the stack | |
112 */ | |
113 public void push(CiKind kind, Value x) { | |
114 assert kind != CiKind.Void; | |
115 xpush(assertKind(kind, x)); | |
116 if (kind.sizeInSlots() == 2) { | |
117 xpush(null); | |
118 } | |
119 } | |
120 | |
121 /** | |
122 * Pushes a value onto the stack without checking the type. | |
123 * @param x the instruction to push onto the stack | |
124 */ | |
125 public void xpush(Value x) { | |
126 assert stackIndex >= 0; | |
127 assert maxLocals + stackIndex < values.length; | |
128 values[maxLocals + stackIndex++] = x; | |
129 } | |
130 | |
131 /** | |
132 * Pushes a value onto the stack and checks that it is an int. | |
133 * @param x the instruction to push onto the stack | |
134 */ | |
135 public void ipush(Value x) { | |
136 xpush(assertInt(x)); | |
137 } | |
138 | |
139 /** | |
140 * Pushes a value onto the stack and checks that it is a float. | |
141 * @param x the instruction to push onto the stack | |
142 */ | |
143 public void fpush(Value x) { | |
144 xpush(assertFloat(x)); | |
145 } | |
146 | |
147 /** | |
148 * Pushes a value onto the stack and checks that it is an object. | |
149 * @param x the instruction to push onto the stack | |
150 */ | |
151 public void apush(Value x) { | |
152 xpush(assertObject(x)); | |
153 } | |
154 | |
155 /** | |
156 * Pushes a value onto the stack and checks that it is a word. | |
157 * @param x the instruction to push onto the stack | |
158 */ | |
159 public void wpush(Value x) { | |
160 xpush(assertWord(x)); | |
161 } | |
162 | |
163 /** | |
164 * Pushes a value onto the stack and checks that it is a JSR return address. | |
165 * @param x the instruction to push onto the stack | |
166 */ | |
167 public void jpush(Value x) { | |
168 xpush(assertJsr(x)); | |
169 } | |
170 | |
171 /** | |
172 * Pushes a value onto the stack and checks that it is a long. | |
173 * | |
174 * @param x the instruction to push onto the stack | |
175 */ | |
176 public void lpush(Value x) { | |
177 xpush(assertLong(x)); | |
178 xpush(null); | |
179 } | |
180 | |
181 /** | |
182 * Pushes a value onto the stack and checks that it is a double. | |
183 * @param x the instruction to push onto the stack | |
184 */ | |
185 public void dpush(Value x) { | |
186 xpush(assertDouble(x)); | |
187 xpush(null); | |
188 } | |
189 | |
190 /** | |
191 * Pops an instruction off the stack with the expected type. | |
192 * @param kind the expected type | |
193 * @return the instruction on the top of the stack | |
194 */ | |
195 public Value pop(CiKind kind) { | |
196 if (kind.sizeInSlots() == 2) { | |
197 xpop(); | |
198 } | |
199 return assertKind(kind, xpop()); | |
200 } | |
201 | |
202 /** | |
203 * Pops a value off of the stack without checking the type. | |
204 * @return x the instruction popped off the stack | |
205 */ | |
206 public Value xpop() { | |
207 assert stackIndex >= 1; | |
208 return values[maxLocals + --stackIndex]; | |
209 } | |
210 | |
211 /** | |
212 * Pops a value off of the stack and checks that it is an int. | |
213 * @return x the instruction popped off the stack | |
214 */ | |
215 public Value ipop() { | |
216 return assertInt(xpop()); | |
217 } | |
218 | |
219 /** | |
220 * Pops a value off of the stack and checks that it is a float. | |
221 * @return x the instruction popped off the stack | |
222 */ | |
223 public Value fpop() { | |
224 return assertFloat(xpop()); | |
225 } | |
226 | |
227 /** | |
228 * Pops a value off of the stack and checks that it is an object. | |
229 * @return x the instruction popped off the stack | |
230 */ | |
231 public Value apop() { | |
232 return assertObject(xpop()); | |
233 } | |
234 | |
235 /** | |
236 * Pops a value off of the stack and checks that it is a word. | |
237 * @return x the instruction popped off the stack | |
238 */ | |
239 public Value wpop() { | |
240 return assertWord(xpop()); | |
241 } | |
242 | |
243 /** | |
244 * Pops a value off of the stack and checks that it is a JSR return address. | |
245 * @return x the instruction popped off the stack | |
246 */ | |
247 public Value jpop() { | |
248 return assertJsr(xpop()); | |
249 } | |
250 | |
251 /** | |
252 * Pops a value off of the stack and checks that it is a long. | |
253 * @return x the instruction popped off the stack | |
254 */ | |
255 public Value lpop() { | |
256 assertHigh(xpop()); | |
257 return assertLong(xpop()); | |
258 } | |
259 | |
260 /** | |
261 * Pops a value off of the stack and checks that it is a double. | |
262 * @return x the instruction popped off the stack | |
263 */ | |
264 public Value dpop() { | |
265 assertHigh(xpop()); | |
266 return assertDouble(xpop()); | |
267 } | |
268 | |
269 private static Value assertKind(CiKind kind, Value x) { | |
270 assert x != null && (x.kind == kind || !isTypesafe()) : "kind=" + kind + ", value=" + x + ((x == null) ? "" : ", value.kind=" + x.kind); | |
271 return x; | |
272 } | |
273 | |
274 private static Value assertLong(Value x) { | |
275 assert x != null && (x.kind == CiKind.Long || !isTypesafe()); | |
276 return x; | |
277 } | |
278 | |
279 private static Value assertJsr(Value x) { | |
280 assert x != null && (x.kind == CiKind.Jsr || !isTypesafe()); | |
281 return x; | |
282 } | |
283 | |
284 private static Value assertInt(Value x) { | |
285 assert x != null && (x.kind == CiKind.Int || !isTypesafe()); | |
286 return x; | |
287 } | |
288 | |
289 private static Value assertFloat(Value x) { | |
290 assert x != null && (x.kind == CiKind.Float || !isTypesafe()); | |
291 return x; | |
292 } | |
293 | |
294 private static Value assertObject(Value x) { | |
295 assert x != null && (x.kind == CiKind.Object || !isTypesafe()); | |
296 return x; | |
297 } | |
298 | |
299 private static Value assertWord(Value x) { | |
300 assert x != null && (x.kind == CiKind.Word || !isTypesafe()); | |
301 return x; | |
302 } | |
303 | |
304 private static Value assertDouble(Value x) { | |
305 assert x != null && (x.kind == CiKind.Double || !isTypesafe()); | |
306 return x; | |
307 } | |
308 | |
309 /** | |
310 * Pop the specified number of slots off of this stack and return them as an array of instructions. | |
311 * @param size the number of arguments off of the stack | |
312 * @return an array containing the arguments off of the stack | |
313 */ | |
314 public Value[] popArguments(int size) { | |
315 int base = stackIndex - size; | |
316 Value[] r = new Value[size]; | |
317 int y = maxLocals + base; | |
318 for (int i = 0; i < size; ++i) { | |
319 assert values[y] != null || values[y - 1].kind.jvmSlots == 2; | |
320 r[i] = values[y++]; | |
321 } | |
322 stackIndex = base; | |
323 assert stackIndex >= 0; | |
324 return r; | |
325 } | |
326 | |
327 /** | |
328 * Locks a new object within the specified IRScope. | |
329 * @param scope the IRScope in which this locking operation occurs | |
330 * @param obj the object being locked | |
331 */ | |
332 public void lock(IRScope scope, Value obj, int totalNumberOfLocks) { | |
333 if (locks == null) { | |
334 locks = new ArrayList<Value>(4); | |
335 } | |
336 locks.add(obj); | |
337 scope.updateMaxLocks(totalNumberOfLocks); | |
338 } | |
339 | |
340 /** | |
341 * Unlock the lock on the top of the stack. | |
342 */ | |
343 public void unlock() { | |
344 locks.remove(locks.size() - 1); | |
345 } | |
346 | |
347 /** | |
348 * Gets an immutable copy of this state. | |
349 * @param bci the bytecode index of the new frame state | |
350 */ | |
351 public FrameState immutableCopy(int bci) { | |
352 return copy(bci, true, true, true); | |
353 } | |
354 | |
355 /** | |
356 * Determines if the current compilation is typesafe. | |
357 */ | |
358 private static boolean isTypesafe() { | |
359 return C1XCompilation.compilation().isTypesafe(); | |
360 } | |
361 | |
362 private static void assertHigh(Value x) { | |
363 assert x == null; | |
364 } | |
365 | |
366 } |