Mercurial > hg > truffle
annotate src/share/vm/c1/c1_ValueStack.hpp @ 1994:6cd6d394f280
7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps
Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages.
Reviewed-by: johnc, tonyp
author | ysr |
---|---|
date | Tue, 07 Dec 2010 21:55:53 -0800 |
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 #ifndef SHARE_VM_C1_C1_VALUESTACK_HPP |
26 #define SHARE_VM_C1_C1_VALUESTACK_HPP | |
27 | |
28 #include "c1/c1_Instruction.hpp" | |
29 | |
0 | 30 class ValueStack: public CompilationResourceObj { |
1819 | 31 public: |
32 enum Kind { | |
33 Parsing, // During abstract interpretation in GraphBuilder | |
34 CallerState, // Caller state when inlining | |
35 StateBefore, // Before before execution of instruction | |
36 StateAfter, // After execution of instruction | |
37 ExceptionState, // Exception handling of instruction | |
38 EmptyExceptionState, // Exception handling of instructions not covered by an xhandler | |
39 BlockBeginState // State of BlockBegin instruction with phi functions of this block | |
40 }; | |
41 | |
0 | 42 private: |
43 IRScope* _scope; // the enclosing scope | |
1819 | 44 ValueStack* _caller_state; |
45 int _bci; | |
46 Kind _kind; | |
47 | |
0 | 48 Values _locals; // the locals |
49 Values _stack; // the expression stack | |
50 Values _locks; // the monitor stack (holding the locked values) | |
51 | |
52 Value check(ValueTag tag, Value t) { | |
53 assert(tag == t->type()->tag() || tag == objectTag && t->type()->tag() == addressTag, "types must correspond"); | |
54 return t; | |
55 } | |
56 | |
57 Value check(ValueTag tag, Value t, Value h) { | |
1819 | 58 assert(h == NULL, "hi-word of doubleword value must be NULL"); |
0 | 59 return check(tag, t); |
60 } | |
61 | |
62 // helper routine | |
1584 | 63 static void apply(Values list, ValueVisitor* f); |
0 | 64 |
1819 | 65 // for simplified copying |
66 ValueStack(ValueStack* copy_from, Kind kind, int bci); | |
67 | |
0 | 68 public: |
69 // creation | |
1819 | 70 ValueStack(IRScope* scope, ValueStack* caller_state); |
0 | 71 |
1819 | 72 ValueStack* copy() { return new ValueStack(this, _kind, _bci); } |
73 ValueStack* copy(Kind new_kind, int new_bci) { return new ValueStack(this, new_kind, new_bci); } | |
74 ValueStack* copy_for_parsing() { return new ValueStack(this, Parsing, -99); } | |
75 | |
1822
1375bc8922e4
6987763: assert(kind() == EmptyExceptionState) failed: only EmptyExceptionStates can be modified
never
parents:
1819
diff
changeset
|
76 void set_caller_state(ValueStack* s) { |
1375bc8922e4
6987763: assert(kind() == EmptyExceptionState) failed: only EmptyExceptionStates can be modified
never
parents:
1819
diff
changeset
|
77 assert(kind() == EmptyExceptionState || |
1375bc8922e4
6987763: assert(kind() == EmptyExceptionState) failed: only EmptyExceptionStates can be modified
never
parents:
1819
diff
changeset
|
78 (Compilation::current()->env()->jvmti_can_access_local_variables() && kind() == ExceptionState), |
1375bc8922e4
6987763: assert(kind() == EmptyExceptionState) failed: only EmptyExceptionStates can be modified
never
parents:
1819
diff
changeset
|
79 "only EmptyExceptionStates can be modified"); |
1375bc8922e4
6987763: assert(kind() == EmptyExceptionState) failed: only EmptyExceptionStates can be modified
never
parents:
1819
diff
changeset
|
80 _caller_state = s; |
1375bc8922e4
6987763: assert(kind() == EmptyExceptionState) failed: only EmptyExceptionStates can be modified
never
parents:
1819
diff
changeset
|
81 } |
1819 | 82 |
0 | 83 bool is_same(ValueStack* s); // returns true if this & s's types match (w/o checking locals) |
84 | |
85 // accessors | |
86 IRScope* scope() const { return _scope; } | |
1819 | 87 ValueStack* caller_state() const { return _caller_state; } |
88 int bci() const { return _bci; } | |
89 Kind kind() const { return _kind; } | |
90 | |
0 | 91 int locals_size() const { return _locals.length(); } |
92 int stack_size() const { return _stack.length(); } | |
93 int locks_size() const { return _locks.length(); } | |
94 bool stack_is_empty() const { return _stack.is_empty(); } | |
95 bool no_active_locks() const { return _locks.is_empty(); } | |
1819 | 96 int total_locks_size() const; |
0 | 97 |
98 // locals access | |
99 void clear_locals(); // sets all locals to NULL; | |
100 | |
101 void invalidate_local(int i) { | |
1819 | 102 assert(_locals.at(i)->type()->is_single_word() || |
103 _locals.at(i + 1) == NULL, "hi-word of doubleword value must be NULL"); | |
0 | 104 _locals.at_put(i, NULL); |
105 } | |
106 | |
1819 | 107 Value local_at(int i) const { |
0 | 108 Value x = _locals.at(i); |
1819 | 109 assert(x == NULL || x->type()->is_single_word() || |
110 _locals.at(i + 1) == NULL, "hi-word of doubleword value must be NULL"); | |
0 | 111 return x; |
112 } | |
113 | |
114 void store_local(int i, Value x) { | |
1819 | 115 // When overwriting local i, check if i - 1 was the start of a |
116 // double word local and kill it. | |
0 | 117 if (i > 0) { |
118 Value prev = _locals.at(i - 1); | |
119 if (prev != NULL && prev->type()->is_double_word()) { | |
120 _locals.at_put(i - 1, NULL); | |
121 } | |
122 } | |
1819 | 123 |
124 _locals.at_put(i, x); | |
125 if (x->type()->is_double_word()) { | |
126 // hi-word of doubleword value is always NULL | |
127 _locals.at_put(i + 1, NULL); | |
128 } | |
0 | 129 } |
130 | |
131 // stack access | |
132 Value stack_at(int i) const { | |
133 Value x = _stack.at(i); | |
134 assert(x->type()->is_single_word() || | |
1819 | 135 _stack.at(i + 1) == NULL, "hi-word of doubleword value must be NULL"); |
0 | 136 return x; |
137 } | |
138 | |
139 Value stack_at_inc(int& i) const { | |
140 Value x = stack_at(i); | |
141 i += x->type()->size(); | |
142 return x; | |
143 } | |
144 | |
145 // pinning support | |
146 void pin_stack_for_linear_scan(); | |
147 | |
148 // iteration | |
1584 | 149 void values_do(ValueVisitor* f); |
0 | 150 |
151 // untyped manipulation (for dup_x1, etc.) | |
152 void truncate_stack(int size) { _stack.trunc_to(size); } | |
153 void raw_push(Value t) { _stack.push(t); } | |
154 Value raw_pop() { return _stack.pop(); } | |
155 | |
156 // typed manipulation | |
157 void ipush(Value t) { _stack.push(check(intTag , t)); } | |
158 void fpush(Value t) { _stack.push(check(floatTag , t)); } | |
159 void apush(Value t) { _stack.push(check(objectTag , t)); } | |
160 void rpush(Value t) { _stack.push(check(addressTag, t)); } | |
161 void lpush(Value t) { _stack.push(check(longTag , t)); _stack.push(NULL); } | |
162 void dpush(Value t) { _stack.push(check(doubleTag , t)); _stack.push(NULL); } | |
163 | |
164 void push(ValueType* type, Value t) { | |
165 switch (type->tag()) { | |
166 case intTag : ipush(t); return; | |
167 case longTag : lpush(t); return; | |
168 case floatTag : fpush(t); return; | |
169 case doubleTag : dpush(t); return; | |
170 case objectTag : apush(t); return; | |
171 case addressTag: rpush(t); return; | |
172 } | |
173 ShouldNotReachHere(); | |
174 } | |
175 | |
176 Value ipop() { return check(intTag , _stack.pop()); } | |
177 Value fpop() { return check(floatTag , _stack.pop()); } | |
178 Value apop() { return check(objectTag , _stack.pop()); } | |
179 Value rpop() { return check(addressTag, _stack.pop()); } | |
180 Value lpop() { Value h = _stack.pop(); return check(longTag , _stack.pop(), h); } | |
181 Value dpop() { Value h = _stack.pop(); return check(doubleTag, _stack.pop(), h); } | |
182 | |
183 Value pop(ValueType* type) { | |
184 switch (type->tag()) { | |
185 case intTag : return ipop(); | |
186 case longTag : return lpop(); | |
187 case floatTag : return fpop(); | |
188 case doubleTag : return dpop(); | |
189 case objectTag : return apop(); | |
190 case addressTag: return rpop(); | |
191 } | |
192 ShouldNotReachHere(); | |
193 return NULL; | |
194 } | |
195 | |
196 Values* pop_arguments(int argument_size); | |
197 | |
198 // locks access | |
1819 | 199 int lock (Value obj); |
0 | 200 int unlock(); |
201 Value lock_at(int i) const { return _locks.at(i); } | |
202 | |
203 // SSA form IR support | |
204 void setup_phi_for_stack(BlockBegin* b, int index); | |
205 void setup_phi_for_local(BlockBegin* b, int index); | |
206 | |
207 // debugging | |
208 void print() PRODUCT_RETURN; | |
209 void verify() PRODUCT_RETURN; | |
210 }; | |
211 | |
212 | |
213 | |
214 // Macro definitions for simple iteration of stack and local values of a ValueStack | |
215 // The macros can be used like a for-loop. All variables (state, index and value) | |
216 // must be defined before the loop. | |
217 // When states are nested because of inlining, the stack of the innermost state | |
218 // cumulates also the stack of the nested states. In contrast, the locals of all | |
219 // states must be iterated each. | |
220 // Use the following code pattern to iterate all stack values and all nested local values: | |
221 // | |
222 // ValueStack* state = ... // state that is iterated | |
223 // int index; // current loop index (overwritten in loop) | |
224 // Value value; // value at current loop index (overwritten in loop) | |
225 // | |
226 // for_each_stack_value(state, index, value { | |
227 // do something with value and index | |
228 // } | |
229 // | |
230 // for_each_state(state) { | |
231 // for_each_local_value(state, index, value) { | |
232 // do something with value and index | |
233 // } | |
234 // } | |
235 // as an invariant, state is NULL now | |
236 | |
237 | |
238 // construct a unique variable name with the line number where the macro is used | |
239 #define temp_var3(x) temp__ ## x | |
240 #define temp_var2(x) temp_var3(x) | |
241 #define temp_var temp_var2(__LINE__) | |
242 | |
243 #define for_each_state(state) \ | |
244 for (; state != NULL; state = state->caller_state()) | |
245 | |
246 #define for_each_local_value(state, index, value) \ | |
247 int temp_var = state->locals_size(); \ | |
248 for (index = 0; \ | |
249 index < temp_var && (value = state->local_at(index), true); \ | |
250 index += (value == NULL || value->type()->is_illegal() ? 1 : value->type()->size())) \ | |
251 if (value != NULL) | |
252 | |
253 | |
254 #define for_each_stack_value(state, index, value) \ | |
255 int temp_var = state->stack_size(); \ | |
256 for (index = 0; \ | |
257 index < temp_var && (value = state->stack_at(index), true); \ | |
258 index += value->type()->size()) | |
259 | |
260 | |
261 #define for_each_lock_value(state, index, value) \ | |
262 int temp_var = state->locks_size(); \ | |
263 for (index = 0; \ | |
264 index < temp_var && (value = state->lock_at(index), true); \ | |
265 index++) \ | |
266 if (value != NULL) | |
267 | |
268 | |
269 // Macro definition for simple iteration of all state values of a ValueStack | |
270 // Because the code cannot be executed in a single loop, the code must be passed | |
271 // as a macro parameter. | |
272 // Use the following code pattern to iterate all stack values and all nested local values: | |
273 // | |
274 // ValueStack* state = ... // state that is iterated | |
275 // for_each_state_value(state, value, | |
276 // do something with value (note that this is a macro parameter) | |
277 // ); | |
278 | |
279 #define for_each_state_value(v_state, v_value, v_code) \ | |
280 { \ | |
281 int cur_index; \ | |
282 ValueStack* cur_state = v_state; \ | |
1819 | 283 Value v_value; \ |
284 for_each_state(cur_state) { \ | |
285 { \ | |
286 for_each_local_value(cur_state, cur_index, v_value) { \ | |
287 v_code; \ | |
288 } \ | |
0 | 289 } \ |
1819 | 290 { \ |
291 for_each_stack_value(cur_state, cur_index, v_value) { \ | |
292 v_code; \ | |
293 } \ | |
294 } \ | |
0 | 295 } \ |
296 } | |
297 | |
298 | |
299 // Macro definition for simple iteration of all phif functions of a block, i.e all | |
300 // phi functions of the ValueStack where the block matches. | |
301 // Use the following code pattern to iterate all phi functions of a block: | |
302 // | |
303 // BlockBegin* block = ... // block that is iterated | |
304 // for_each_phi_function(block, phi, | |
305 // do something with the phi function phi (note that this is a macro parameter) | |
306 // ); | |
307 | |
308 #define for_each_phi_fun(v_block, v_phi, v_code) \ | |
309 { \ | |
310 int cur_index; \ | |
311 ValueStack* cur_state = v_block->state(); \ | |
312 Value value; \ | |
313 { \ | |
314 for_each_stack_value(cur_state, cur_index, value) { \ | |
315 Phi* v_phi = value->as_Phi(); \ | |
316 if (v_phi != NULL && v_phi->block() == v_block) { \ | |
317 v_code; \ | |
318 } \ | |
319 } \ | |
320 } \ | |
321 { \ | |
322 for_each_local_value(cur_state, cur_index, value) { \ | |
323 Phi* v_phi = value->as_Phi(); \ | |
324 if (v_phi != NULL && v_phi->block() == v_block) { \ | |
325 v_code; \ | |
326 } \ | |
327 } \ | |
328 } \ | |
329 } | |
1972 | 330 |
331 #endif // SHARE_VM_C1_C1_VALUESTACK_HPP |