Mercurial > hg > truffle
annotate src/share/vm/c1/c1_ValueStack.cpp @ 6862:8a5ea0a9ccc4
7127708: G1: change task num types from int to uint in concurrent mark
Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich.
Reviewed-by: johnc
Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>
author | johnc |
---|---|
date | Sat, 06 Oct 2012 01:17:44 -0700 |
parents | 1d7922586cf6 |
children | b9a9ed0f8eeb |
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(); |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
1972
diff
changeset
|
198 tty->cr(); |
0 | 199 if (stack_is_empty()) { |
200 tty->print_cr("empty stack"); | |
201 } else { | |
202 InstructionPrinter ip; | |
203 for (int i = 0; i < stack_size();) { | |
204 Value t = stack_at_inc(i); | |
205 tty->print("%2d ", i); | |
1819 | 206 tty->print("%c%d ", t->type()->tchar(), t->id()); |
0 | 207 ip.print_instr(t); |
208 tty->cr(); | |
209 } | |
210 } | |
211 if (!no_active_locks()) { | |
212 InstructionPrinter ip; | |
1819 | 213 for (int i = 0; i < locks_size(); i++) { |
0 | 214 Value t = lock_at(i); |
215 tty->print("lock %2d ", i); | |
216 if (t == NULL) { | |
217 tty->print("this"); | |
218 } else { | |
1819 | 219 tty->print("%c%d ", t->type()->tchar(), t->id()); |
0 | 220 ip.print_instr(t); |
221 } | |
222 tty->cr(); | |
223 } | |
224 } | |
225 if (locals_size() > 0) { | |
226 InstructionPrinter ip; | |
227 for (int i = 0; i < locals_size();) { | |
228 Value l = _locals[i]; | |
229 tty->print("local %d ", i); | |
230 if (l == NULL) { | |
231 tty->print("null"); | |
232 i ++; | |
233 } else { | |
1819 | 234 tty->print("%c%d ", l->type()->tchar(), l->id()); |
0 | 235 ip.print_instr(l); |
236 if (l->type()->is_illegal() || l->type()->is_single_word()) i ++; else i += 2; | |
237 } | |
238 tty->cr(); | |
239 } | |
240 } | |
1819 | 241 |
242 if (caller_state() != NULL) { | |
243 caller_state()->print(); | |
244 } | |
0 | 245 } |
246 | |
247 | |
248 void ValueStack::verify() { | |
1819 | 249 assert(scope() != NULL, "scope must exist"); |
250 if (caller_state() != NULL) { | |
251 assert(caller_state()->scope() == scope()->caller(), "invalid caller scope"); | |
252 caller_state()->verify(); | |
253 } | |
254 | |
255 if (kind() == Parsing) { | |
256 assert(bci() == -99, "bci not defined during parsing"); | |
257 } else { | |
258 assert(bci() >= -1, "bci out of range"); | |
259 assert(bci() < scope()->method()->code_size(), "bci out of range"); | |
260 assert(bci() == SynchronizationEntryBCI || Bytecodes::is_defined(scope()->method()->java_code_at_bci(bci())), "make sure bci points at a real bytecode"); | |
261 assert(scope()->method()->liveness_at_bci(bci()).is_valid(), "liveness at bci must be valid"); | |
262 } | |
263 | |
264 int i; | |
265 for (i = 0; i < stack_size(); i++) { | |
266 Value v = _stack.at(i); | |
267 if (v == NULL) { | |
268 assert(_stack.at(i - 1)->type()->is_double_word(), "only hi-words are NULL on stack"); | |
269 } else if (v->type()->is_double_word()) { | |
270 assert(_stack.at(i + 1) == NULL, "hi-word must be NULL"); | |
271 } | |
272 } | |
273 | |
274 for (i = 0; i < locals_size(); i++) { | |
275 Value v = _locals.at(i); | |
276 if (v != NULL && v->type()->is_double_word()) { | |
277 assert(_locals.at(i + 1) == NULL, "hi-word must be NULL"); | |
278 } | |
279 } | |
280 | |
281 for_each_state_value(this, v, | |
282 assert(v != NULL, "just test if state-iteration succeeds"); | |
283 ); | |
0 | 284 } |
285 #endif // PRODUCT |