comparison graal/Compiler/src/com/sun/c1x/value/MutableFrameState.java @ 2507:9ec15d6914ca

Pull over of compiler from maxine repository.
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Wed, 27 Apr 2011 11:43:22 +0200
parents
children
comparison
equal deleted inserted replaced
2506:4a3bf8a5bf41 2507:9ec15d6914ca
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 }