Mercurial > hg > truffle
annotate src/share/vm/c1/c1_ValueStack.cpp @ 2607:008adfd6d850
Fixed the stateBefore of invokes and monitorenter instructions to include the arguments of the instruction.
This is necessary to ensure correct continuation in the interpreter when the stateBefore is used as a deoptimization point.
author | Thomas Wuerthinger <thomas@wuerthinger.net> |
---|---|
date | Fri, 06 May 2011 17:47:17 +0200 |
parents | f95d63e2154a |
children | 1d7922586cf6 |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "c1/c1_IR.hpp" | |
27 #include "c1/c1_InstructionPrinter.hpp" | |
28 #include "c1/c1_ValueStack.hpp" | |
0 | 29 |
30 | |
31 // Implementation of ValueStack | |
32 | |
1819 | 33 ValueStack::ValueStack(IRScope* scope, ValueStack* caller_state) |
0 | 34 : _scope(scope) |
1819 | 35 , _caller_state(caller_state) |
36 , _bci(-99) | |
37 , _kind(Parsing) | |
38 , _locals(scope->method()->max_locals(), NULL) | |
39 , _stack(scope->method()->max_stack()) | |
40 , _locks() | |
0 | 41 { |
1819 | 42 verify(); |
0 | 43 } |
44 | |
45 | |
1819 | 46 ValueStack::ValueStack(ValueStack* copy_from, Kind kind, int bci) |
47 : _scope(copy_from->scope()) | |
48 , _caller_state(copy_from->caller_state()) | |
49 , _bci(bci) | |
50 , _kind(kind) | |
51 , _locals() | |
52 , _stack() | |
53 , _locks(copy_from->locks_size()) | |
54 { | |
55 assert(kind != EmptyExceptionState || !Compilation::current()->env()->jvmti_can_access_local_variables(), "need locals"); | |
56 if (kind != EmptyExceptionState) { | |
57 // only allocate space if we need to copy the locals-array | |
58 _locals = Values(copy_from->locals_size()); | |
59 _locals.appendAll(©_from->_locals); | |
0 | 60 } |
1819 | 61 |
62 if (kind != ExceptionState && kind != EmptyExceptionState) { | |
63 if (kind == Parsing) { | |
64 // stack will be modified, so reserve enough space to avoid resizing | |
65 _stack = Values(scope()->method()->max_stack()); | |
66 } else { | |
67 // stack will not be modified, so do not waste space | |
68 _stack = Values(copy_from->stack_size()); | |
0 | 69 } |
1819 | 70 _stack.appendAll(©_from->_stack); |
0 | 71 } |
72 | |
1819 | 73 _locks.appendAll(©_from->_locks); |
74 | |
75 verify(); | |
0 | 76 } |
77 | |
78 | |
1819 | 79 bool ValueStack::is_same(ValueStack* s) { |
80 if (scope() != s->scope()) return false; | |
81 if (caller_state() != s->caller_state()) return false; | |
82 | |
83 if (locals_size() != s->locals_size()) return false; | |
84 if (stack_size() != s->stack_size()) return false; | |
85 if (locks_size() != s->locks_size()) return false; | |
86 | |
0 | 87 // compare each stack element with the corresponding stack element of s |
88 int index; | |
89 Value value; | |
90 for_each_stack_value(this, index, value) { | |
91 if (value->type()->tag() != s->stack_at(index)->type()->tag()) return false; | |
92 } | |
93 for_each_lock_value(this, index, value) { | |
94 if (value != s->lock_at(index)) return false; | |
95 } | |
96 return true; | |
97 } | |
98 | |
99 void ValueStack::clear_locals() { | |
100 for (int i = _locals.length() - 1; i >= 0; i--) { | |
101 _locals.at_put(i, NULL); | |
102 } | |
103 } | |
104 | |
105 | |
106 void ValueStack::pin_stack_for_linear_scan() { | |
107 for_each_state_value(this, v, | |
108 if (v->as_Constant() == NULL && v->as_Local() == NULL) { | |
109 v->pin(Instruction::PinStackForStateSplit); | |
110 } | |
111 ); | |
112 } | |
113 | |
114 | |
115 // apply function to all values of a list; factored out from values_do(f) | |
1584 | 116 void ValueStack::apply(Values list, ValueVisitor* f) { |
0 | 117 for (int i = 0; i < list.length(); i++) { |
118 Value* va = list.adr_at(i); | |
119 Value v0 = *va; | |
1819 | 120 if (v0 != NULL && !v0->type()->is_illegal()) { |
121 f->visit(va); | |
0 | 122 #ifdef ASSERT |
1819 | 123 Value v1 = *va; |
124 assert(v1->type()->is_illegal() || v0->type()->tag() == v1->type()->tag(), "types must match"); | |
125 assert(!v1->type()->is_double_word() || list.at(i + 1) == NULL, "hi-word of doubleword value must be NULL"); | |
0 | 126 #endif |
1819 | 127 if (v0->type()->is_double_word()) i++; |
0 | 128 } |
129 } | |
130 } | |
131 | |
132 | |
1584 | 133 void ValueStack::values_do(ValueVisitor* f) { |
0 | 134 ValueStack* state = this; |
135 for_each_state(state) { | |
136 apply(state->_locals, f); | |
1819 | 137 apply(state->_stack, f); |
138 apply(state->_locks, f); | |
0 | 139 } |
140 } | |
141 | |
142 | |
143 Values* ValueStack::pop_arguments(int argument_size) { | |
144 assert(stack_size() >= argument_size, "stack too small or too many arguments"); | |
145 int base = stack_size() - argument_size; | |
146 Values* args = new Values(argument_size); | |
147 for (int i = base; i < stack_size();) args->push(stack_at_inc(i)); | |
148 truncate_stack(base); | |
149 return args; | |
150 } | |
151 | |
152 | |
1819 | 153 int ValueStack::total_locks_size() const { |
154 int num_locks = 0; | |
155 const ValueStack* state = this; | |
156 for_each_state(state) { | |
157 num_locks += state->locks_size(); | |
158 } | |
159 return num_locks; | |
160 } | |
161 | |
162 int ValueStack::lock(Value obj) { | |
0 | 163 _locks.push(obj); |
1819 | 164 int num_locks = total_locks_size(); |
165 scope()->set_min_number_of_locks(num_locks); | |
166 return num_locks - 1; | |
0 | 167 } |
168 | |
169 | |
170 int ValueStack::unlock() { | |
171 _locks.pop(); | |
1819 | 172 return total_locks_size(); |
0 | 173 } |
174 | |
175 | |
176 void ValueStack::setup_phi_for_stack(BlockBegin* b, int index) { | |
177 assert(stack_at(index)->as_Phi() == NULL || stack_at(index)->as_Phi()->block() != b, "phi function already created"); | |
178 | |
179 ValueType* t = stack_at(index)->type(); | |
180 Value phi = new Phi(t, b, -index - 1); | |
181 _stack[index] = phi; | |
182 | |
1819 | 183 assert(!t->is_double_word() || _stack.at(index + 1) == NULL, "hi-word of doubleword value must be NULL"); |
0 | 184 } |
185 | |
186 void ValueStack::setup_phi_for_local(BlockBegin* b, int index) { | |
187 assert(local_at(index)->as_Phi() == NULL || local_at(index)->as_Phi()->block() != b, "phi function already created"); | |
188 | |
189 ValueType* t = local_at(index)->type(); | |
190 Value phi = new Phi(t, b, index); | |
191 store_local(index, phi); | |
192 } | |
193 | |
194 #ifndef PRODUCT | |
1819 | 195 |
0 | 196 void ValueStack::print() { |
1819 | 197 scope()->method()->print_name(); |
0 | 198 if (stack_is_empty()) { |
199 tty->print_cr("empty stack"); | |
200 } else { | |
201 InstructionPrinter ip; | |
202 for (int i = 0; i < stack_size();) { | |
203 Value t = stack_at_inc(i); | |
204 tty->print("%2d ", i); | |
1819 | 205 tty->print("%c%d ", t->type()->tchar(), t->id()); |
0 | 206 ip.print_instr(t); |
207 tty->cr(); | |
208 } | |
209 } | |
210 if (!no_active_locks()) { | |
211 InstructionPrinter ip; | |
1819 | 212 for (int i = 0; i < locks_size(); i++) { |
0 | 213 Value t = lock_at(i); |
214 tty->print("lock %2d ", i); | |
215 if (t == NULL) { | |
216 tty->print("this"); | |
217 } else { | |
1819 | 218 tty->print("%c%d ", t->type()->tchar(), t->id()); |
0 | 219 ip.print_instr(t); |
220 } | |
221 tty->cr(); | |
222 } | |
223 } | |
224 if (locals_size() > 0) { | |
225 InstructionPrinter ip; | |
226 for (int i = 0; i < locals_size();) { | |
227 Value l = _locals[i]; | |
228 tty->print("local %d ", i); | |
229 if (l == NULL) { | |
230 tty->print("null"); | |
231 i ++; | |
232 } else { | |
1819 | 233 tty->print("%c%d ", l->type()->tchar(), l->id()); |
0 | 234 ip.print_instr(l); |
235 if (l->type()->is_illegal() || l->type()->is_single_word()) i ++; else i += 2; | |
236 } | |
237 tty->cr(); | |
238 } | |
239 } | |
1819 | 240 |
241 if (caller_state() != NULL) { | |
242 caller_state()->print(); | |
243 } | |
0 | 244 } |
245 | |
246 | |
247 void ValueStack::verify() { | |
1819 | 248 assert(scope() != NULL, "scope must exist"); |
249 if (caller_state() != NULL) { | |
250 assert(caller_state()->scope() == scope()->caller(), "invalid caller scope"); | |
251 caller_state()->verify(); | |
252 } | |
253 | |
254 if (kind() == Parsing) { | |
255 assert(bci() == -99, "bci not defined during parsing"); | |
256 } else { | |
257 assert(bci() >= -1, "bci out of range"); | |
258 assert(bci() < scope()->method()->code_size(), "bci out of range"); | |
259 assert(bci() == SynchronizationEntryBCI || Bytecodes::is_defined(scope()->method()->java_code_at_bci(bci())), "make sure bci points at a real bytecode"); | |
260 assert(scope()->method()->liveness_at_bci(bci()).is_valid(), "liveness at bci must be valid"); | |
261 } | |
262 | |
263 int i; | |
264 for (i = 0; i < stack_size(); i++) { | |
265 Value v = _stack.at(i); | |
266 if (v == NULL) { | |
267 assert(_stack.at(i - 1)->type()->is_double_word(), "only hi-words are NULL on stack"); | |
268 } else if (v->type()->is_double_word()) { | |
269 assert(_stack.at(i + 1) == NULL, "hi-word must be NULL"); | |
270 } | |
271 } | |
272 | |
273 for (i = 0; i < locals_size(); i++) { | |
274 Value v = _locals.at(i); | |
275 if (v != NULL && v->type()->is_double_word()) { | |
276 assert(_locals.at(i + 1) == NULL, "hi-word must be NULL"); | |
277 } | |
278 } | |
279 | |
280 for_each_state_value(this, v, | |
281 assert(v != NULL, "just test if state-iteration succeeds"); | |
282 ); | |
0 | 283 } |
284 #endif // PRODUCT |