Mercurial > hg > truffle
annotate src/share/vm/c1/c1_Instruction.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 | da91efe96a93 |
children | 37c18711a0df |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
2 * Copyright (c) 1999, 2012, 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:
1295
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1295
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:
1295
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "c1/c1_IR.hpp" | |
27 #include "c1/c1_Instruction.hpp" | |
28 #include "c1/c1_InstructionPrinter.hpp" | |
29 #include "c1/c1_ValueStack.hpp" | |
30 #include "ci/ciObjArrayKlass.hpp" | |
31 #include "ci/ciTypeArrayKlass.hpp" | |
0 | 32 |
33 | |
34 // Implementation of Instruction | |
35 | |
36 | |
37 Instruction::Condition Instruction::mirror(Condition cond) { | |
38 switch (cond) { | |
39 case eql: return eql; | |
40 case neq: return neq; | |
41 case lss: return gtr; | |
42 case leq: return geq; | |
43 case gtr: return lss; | |
44 case geq: return leq; | |
45 } | |
46 ShouldNotReachHere(); | |
47 return eql; | |
48 } | |
49 | |
50 | |
51 Instruction::Condition Instruction::negate(Condition cond) { | |
52 switch (cond) { | |
53 case eql: return neq; | |
54 case neq: return eql; | |
55 case lss: return geq; | |
56 case leq: return gtr; | |
57 case gtr: return leq; | |
58 case geq: return lss; | |
59 } | |
60 ShouldNotReachHere(); | |
61 return eql; | |
62 } | |
63 | |
1819 | 64 void Instruction::update_exception_state(ValueStack* state) { |
65 if (state != NULL && (state->kind() == ValueStack::EmptyExceptionState || state->kind() == ValueStack::ExceptionState)) { | |
66 assert(state->kind() == ValueStack::EmptyExceptionState || Compilation::current()->env()->jvmti_can_access_local_variables(), "unexpected state kind"); | |
67 _exception_state = state; | |
68 } else { | |
69 _exception_state = NULL; | |
70 } | |
71 } | |
72 | |
0 | 73 |
74 Instruction* Instruction::prev(BlockBegin* block) { | |
75 Instruction* p = NULL; | |
76 Instruction* q = block; | |
77 while (q != this) { | |
78 assert(q != NULL, "this is not in the block's instruction list"); | |
79 p = q; q = q->next(); | |
80 } | |
81 return p; | |
82 } | |
83 | |
84 | |
1819 | 85 void Instruction::state_values_do(ValueVisitor* f) { |
86 if (state_before() != NULL) { | |
87 state_before()->values_do(f); | |
88 } | |
89 if (exception_state() != NULL){ | |
90 exception_state()->values_do(f); | |
91 } | |
92 } | |
93 | |
94 | |
0 | 95 #ifndef PRODUCT |
1819 | 96 void Instruction::check_state(ValueStack* state) { |
97 if (state != NULL) { | |
98 state->verify(); | |
99 } | |
100 } | |
101 | |
102 | |
0 | 103 void Instruction::print() { |
104 InstructionPrinter ip; | |
105 print(ip); | |
106 } | |
107 | |
108 | |
109 void Instruction::print_line() { | |
110 InstructionPrinter ip; | |
111 ip.print_line(this); | |
112 } | |
113 | |
114 | |
115 void Instruction::print(InstructionPrinter& ip) { | |
116 ip.print_head(); | |
117 ip.print_line(this); | |
118 tty->cr(); | |
119 } | |
120 #endif // PRODUCT | |
121 | |
122 | |
123 // perform constant and interval tests on index value | |
124 bool AccessIndexed::compute_needs_range_check() { | |
125 Constant* clength = length()->as_Constant(); | |
126 Constant* cindex = index()->as_Constant(); | |
127 if (clength && cindex) { | |
128 IntConstant* l = clength->type()->as_IntConstant(); | |
129 IntConstant* i = cindex->type()->as_IntConstant(); | |
130 if (l && i && i->value() < l->value() && i->value() >= 0) { | |
131 return false; | |
132 } | |
133 } | |
134 return true; | |
135 } | |
136 | |
137 | |
2446 | 138 ciType* Local::exact_type() const { |
139 ciType* type = declared_type(); | |
140 | |
141 // for primitive arrays, the declared type is the exact type | |
142 if (type->is_type_array_klass()) { | |
143 return type; | |
144 } else if (type->is_instance_klass()) { | |
145 ciInstanceKlass* ik = (ciInstanceKlass*)type; | |
146 if (ik->is_loaded() && ik->is_final() && !ik->is_interface()) { | |
147 return type; | |
148 } | |
149 } else if (type->is_obj_array_klass()) { | |
150 ciObjArrayKlass* oak = (ciObjArrayKlass*)type; | |
151 ciType* base = oak->base_element_type(); | |
152 if (base->is_instance_klass()) { | |
153 ciInstanceKlass* ik = base->as_instance_klass(); | |
154 if (ik->is_loaded() && ik->is_final()) { | |
155 return type; | |
156 } | |
157 } else if (base->is_primitive_type()) { | |
158 return type; | |
159 } | |
160 } | |
161 return NULL; | |
162 } | |
163 | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3900
diff
changeset
|
164 ciType* Constant::exact_type() const { |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3900
diff
changeset
|
165 if (type()->is_object()) { |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3900
diff
changeset
|
166 return type()->as_ObjectType()->exact_type(); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3900
diff
changeset
|
167 } |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3900
diff
changeset
|
168 return NULL; |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3900
diff
changeset
|
169 } |
2446 | 170 |
0 | 171 ciType* LoadIndexed::exact_type() const { |
172 ciType* array_type = array()->exact_type(); | |
173 if (array_type == NULL) { | |
174 return NULL; | |
175 } | |
176 assert(array_type->is_array_klass(), "what else?"); | |
177 ciArrayKlass* ak = (ciArrayKlass*)array_type; | |
178 | |
179 if (ak->element_type()->is_instance_klass()) { | |
180 ciInstanceKlass* ik = (ciInstanceKlass*)ak->element_type(); | |
181 if (ik->is_loaded() && ik->is_final()) { | |
182 return ik; | |
183 } | |
184 } | |
185 return NULL; | |
186 } | |
187 | |
188 | |
189 ciType* LoadIndexed::declared_type() const { | |
190 ciType* array_type = array()->declared_type(); | |
191 if (array_type == NULL) { | |
192 return NULL; | |
193 } | |
194 assert(array_type->is_array_klass(), "what else?"); | |
195 ciArrayKlass* ak = (ciArrayKlass*)array_type; | |
196 return ak->element_type(); | |
197 } | |
198 | |
199 | |
200 ciType* LoadField::declared_type() const { | |
201 return field()->type(); | |
202 } | |
203 | |
204 | |
205 ciType* LoadField::exact_type() const { | |
206 ciType* type = declared_type(); | |
207 // for primitive arrays, the declared type is the exact type | |
208 if (type->is_type_array_klass()) { | |
209 return type; | |
210 } | |
211 if (type->is_instance_klass()) { | |
212 ciInstanceKlass* ik = (ciInstanceKlass*)type; | |
213 if (ik->is_loaded() && ik->is_final()) { | |
214 return type; | |
215 } | |
216 } | |
217 return NULL; | |
218 } | |
219 | |
220 | |
221 ciType* NewTypeArray::exact_type() const { | |
222 return ciTypeArrayKlass::make(elt_type()); | |
223 } | |
224 | |
225 ciType* NewObjectArray::exact_type() const { | |
226 return ciObjArrayKlass::make(klass()); | |
227 } | |
228 | |
2446 | 229 ciType* NewArray::declared_type() const { |
230 return exact_type(); | |
231 } | |
0 | 232 |
233 ciType* NewInstance::exact_type() const { | |
234 return klass(); | |
235 } | |
236 | |
2446 | 237 ciType* NewInstance::declared_type() const { |
238 return exact_type(); | |
239 } | |
0 | 240 |
241 ciType* CheckCast::declared_type() const { | |
242 return klass(); | |
243 } | |
244 | |
245 ciType* CheckCast::exact_type() const { | |
246 if (klass()->is_instance_klass()) { | |
247 ciInstanceKlass* ik = (ciInstanceKlass*)klass(); | |
248 if (ik->is_loaded() && ik->is_final()) { | |
249 return ik; | |
250 } | |
251 } | |
252 return NULL; | |
253 } | |
254 | |
255 // Implementation of ArithmeticOp | |
256 | |
257 bool ArithmeticOp::is_commutative() const { | |
258 switch (op()) { | |
259 case Bytecodes::_iadd: // fall through | |
260 case Bytecodes::_ladd: // fall through | |
261 case Bytecodes::_fadd: // fall through | |
262 case Bytecodes::_dadd: // fall through | |
263 case Bytecodes::_imul: // fall through | |
264 case Bytecodes::_lmul: // fall through | |
265 case Bytecodes::_fmul: // fall through | |
266 case Bytecodes::_dmul: return true; | |
267 } | |
268 return false; | |
269 } | |
270 | |
271 | |
272 bool ArithmeticOp::can_trap() const { | |
273 switch (op()) { | |
274 case Bytecodes::_idiv: // fall through | |
275 case Bytecodes::_ldiv: // fall through | |
276 case Bytecodes::_irem: // fall through | |
277 case Bytecodes::_lrem: return true; | |
278 } | |
279 return false; | |
280 } | |
281 | |
282 | |
283 // Implementation of LogicOp | |
284 | |
285 bool LogicOp::is_commutative() const { | |
286 #ifdef ASSERT | |
287 switch (op()) { | |
288 case Bytecodes::_iand: // fall through | |
289 case Bytecodes::_land: // fall through | |
290 case Bytecodes::_ior : // fall through | |
291 case Bytecodes::_lor : // fall through | |
292 case Bytecodes::_ixor: // fall through | |
293 case Bytecodes::_lxor: break; | |
294 default : ShouldNotReachHere(); | |
295 } | |
296 #endif | |
297 // all LogicOps are commutative | |
298 return true; | |
299 } | |
300 | |
301 | |
302 // Implementation of IfOp | |
303 | |
304 bool IfOp::is_commutative() const { | |
305 return cond() == eql || cond() == neq; | |
306 } | |
307 | |
308 | |
309 // Implementation of StateSplit | |
310 | |
311 void StateSplit::substitute(BlockList& list, BlockBegin* old_block, BlockBegin* new_block) { | |
312 NOT_PRODUCT(bool assigned = false;) | |
313 for (int i = 0; i < list.length(); i++) { | |
314 BlockBegin** b = list.adr_at(i); | |
315 if (*b == old_block) { | |
316 *b = new_block; | |
317 NOT_PRODUCT(assigned = true;) | |
318 } | |
319 } | |
320 assert(assigned == true, "should have assigned at least once"); | |
321 } | |
322 | |
323 | |
324 IRScope* StateSplit::scope() const { | |
325 return _state->scope(); | |
326 } | |
327 | |
328 | |
1584 | 329 void StateSplit::state_values_do(ValueVisitor* f) { |
1819 | 330 Instruction::state_values_do(f); |
0 | 331 if (state() != NULL) state()->values_do(f); |
332 } | |
333 | |
334 | |
1584 | 335 void BlockBegin::state_values_do(ValueVisitor* f) { |
0 | 336 StateSplit::state_values_do(f); |
337 | |
338 if (is_set(BlockBegin::exception_entry_flag)) { | |
339 for (int i = 0; i < number_of_exception_states(); i++) { | |
340 exception_state_at(i)->values_do(f); | |
341 } | |
342 } | |
343 } | |
344 | |
345 | |
346 // Implementation of Invoke | |
347 | |
348 | |
349 Invoke::Invoke(Bytecodes::Code code, ValueType* result_type, Value recv, Values* args, | |
1295 | 350 int vtable_index, ciMethod* target, ValueStack* state_before) |
1819 | 351 : StateSplit(result_type, state_before) |
0 | 352 , _code(code) |
353 , _recv(recv) | |
354 , _args(args) | |
355 , _vtable_index(vtable_index) | |
356 , _target(target) | |
357 { | |
358 set_flag(TargetIsLoadedFlag, target->is_loaded()); | |
359 set_flag(TargetIsFinalFlag, target_is_loaded() && target->is_final_method()); | |
360 set_flag(TargetIsStrictfpFlag, target_is_loaded() && target->is_strict()); | |
361 | |
362 assert(args != NULL, "args must exist"); | |
363 #ifdef ASSERT | |
1584 | 364 AssertValues assert_value; |
365 values_do(&assert_value); | |
366 #endif | |
0 | 367 |
368 // provide an initial guess of signature size. | |
369 _signature = new BasicTypeList(number_of_arguments() + (has_receiver() ? 1 : 0)); | |
370 if (has_receiver()) { | |
371 _signature->append(as_BasicType(receiver()->type())); | |
372 } | |
373 for (int i = 0; i < number_of_arguments(); i++) { | |
374 ValueType* t = argument_at(i)->type(); | |
375 BasicType bt = as_BasicType(t); | |
376 _signature->append(bt); | |
377 } | |
378 } | |
379 | |
380 | |
1584 | 381 void Invoke::state_values_do(ValueVisitor* f) { |
1295 | 382 StateSplit::state_values_do(f); |
383 if (state_before() != NULL) state_before()->values_do(f); | |
384 if (state() != NULL) state()->values_do(f); | |
385 } | |
386 | |
2446 | 387 ciType* Invoke::declared_type() const { |
388 ciType *t = _target->signature()->return_type(); | |
389 assert(t->basic_type() != T_VOID, "need return value of void method?"); | |
390 return t; | |
391 } | |
1295 | 392 |
0 | 393 // Implementation of Contant |
394 intx Constant::hash() const { | |
1819 | 395 if (state_before() == NULL) { |
0 | 396 switch (type()->tag()) { |
397 case intTag: | |
398 return HASH2(name(), type()->as_IntConstant()->value()); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
399 case addressTag: |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
400 return HASH2(name(), type()->as_AddressConstant()->value()); |
0 | 401 case longTag: |
402 { | |
403 jlong temp = type()->as_LongConstant()->value(); | |
404 return HASH3(name(), high(temp), low(temp)); | |
405 } | |
406 case floatTag: | |
407 return HASH2(name(), jint_cast(type()->as_FloatConstant()->value())); | |
408 case doubleTag: | |
409 { | |
410 jlong temp = jlong_cast(type()->as_DoubleConstant()->value()); | |
411 return HASH3(name(), high(temp), low(temp)); | |
412 } | |
413 case objectTag: | |
414 assert(type()->as_ObjectType()->is_loaded(), "can't handle unloaded values"); | |
415 return HASH2(name(), type()->as_ObjectType()->constant_value()); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
416 case metaDataTag: |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
417 assert(type()->as_MetadataType()->is_loaded(), "can't handle unloaded values"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
418 return HASH2(name(), type()->as_MetadataType()->constant_value()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
419 default: |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
420 ShouldNotReachHere(); |
0 | 421 } |
422 } | |
423 return 0; | |
424 } | |
425 | |
426 bool Constant::is_equal(Value v) const { | |
427 if (v->as_Constant() == NULL) return false; | |
428 | |
429 switch (type()->tag()) { | |
430 case intTag: | |
431 { | |
432 IntConstant* t1 = type()->as_IntConstant(); | |
433 IntConstant* t2 = v->type()->as_IntConstant(); | |
434 return (t1 != NULL && t2 != NULL && | |
435 t1->value() == t2->value()); | |
436 } | |
437 case longTag: | |
438 { | |
439 LongConstant* t1 = type()->as_LongConstant(); | |
440 LongConstant* t2 = v->type()->as_LongConstant(); | |
441 return (t1 != NULL && t2 != NULL && | |
442 t1->value() == t2->value()); | |
443 } | |
444 case floatTag: | |
445 { | |
446 FloatConstant* t1 = type()->as_FloatConstant(); | |
447 FloatConstant* t2 = v->type()->as_FloatConstant(); | |
448 return (t1 != NULL && t2 != NULL && | |
449 jint_cast(t1->value()) == jint_cast(t2->value())); | |
450 } | |
451 case doubleTag: | |
452 { | |
453 DoubleConstant* t1 = type()->as_DoubleConstant(); | |
454 DoubleConstant* t2 = v->type()->as_DoubleConstant(); | |
455 return (t1 != NULL && t2 != NULL && | |
456 jlong_cast(t1->value()) == jlong_cast(t2->value())); | |
457 } | |
458 case objectTag: | |
459 { | |
460 ObjectType* t1 = type()->as_ObjectType(); | |
461 ObjectType* t2 = v->type()->as_ObjectType(); | |
462 return (t1 != NULL && t2 != NULL && | |
463 t1->is_loaded() && t2->is_loaded() && | |
464 t1->constant_value() == t2->constant_value()); | |
465 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
466 case metaDataTag: |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
467 { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
468 MetadataType* t1 = type()->as_MetadataType(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
469 MetadataType* t2 = v->type()->as_MetadataType(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
470 return (t1 != NULL && t2 != NULL && |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
471 t1->is_loaded() && t2->is_loaded() && |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
472 t1->constant_value() == t2->constant_value()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
473 } |
0 | 474 } |
475 return false; | |
476 } | |
477 | |
1899 | 478 Constant::CompareResult Constant::compare(Instruction::Condition cond, Value right) const { |
0 | 479 Constant* rc = right->as_Constant(); |
480 // other is not a constant | |
1899 | 481 if (rc == NULL) return not_comparable; |
0 | 482 |
483 ValueType* lt = type(); | |
484 ValueType* rt = rc->type(); | |
485 // different types | |
1899 | 486 if (lt->base() != rt->base()) return not_comparable; |
0 | 487 switch (lt->tag()) { |
488 case intTag: { | |
489 int x = lt->as_IntConstant()->value(); | |
490 int y = rt->as_IntConstant()->value(); | |
491 switch (cond) { | |
1899 | 492 case If::eql: return x == y ? cond_true : cond_false; |
493 case If::neq: return x != y ? cond_true : cond_false; | |
494 case If::lss: return x < y ? cond_true : cond_false; | |
495 case If::leq: return x <= y ? cond_true : cond_false; | |
496 case If::gtr: return x > y ? cond_true : cond_false; | |
497 case If::geq: return x >= y ? cond_true : cond_false; | |
0 | 498 } |
499 break; | |
500 } | |
501 case longTag: { | |
502 jlong x = lt->as_LongConstant()->value(); | |
503 jlong y = rt->as_LongConstant()->value(); | |
504 switch (cond) { | |
1899 | 505 case If::eql: return x == y ? cond_true : cond_false; |
506 case If::neq: return x != y ? cond_true : cond_false; | |
507 case If::lss: return x < y ? cond_true : cond_false; | |
508 case If::leq: return x <= y ? cond_true : cond_false; | |
509 case If::gtr: return x > y ? cond_true : cond_false; | |
510 case If::geq: return x >= y ? cond_true : cond_false; | |
0 | 511 } |
512 break; | |
513 } | |
514 case objectTag: { | |
515 ciObject* xvalue = lt->as_ObjectType()->constant_value(); | |
516 ciObject* yvalue = rt->as_ObjectType()->constant_value(); | |
517 assert(xvalue != NULL && yvalue != NULL, "not constants"); | |
518 if (xvalue->is_loaded() && yvalue->is_loaded()) { | |
519 switch (cond) { | |
1899 | 520 case If::eql: return xvalue == yvalue ? cond_true : cond_false; |
521 case If::neq: return xvalue != yvalue ? cond_true : cond_false; | |
0 | 522 } |
523 } | |
524 break; | |
525 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
526 case metaDataTag: { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
527 ciMetadata* xvalue = lt->as_MetadataType()->constant_value(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
528 ciMetadata* yvalue = rt->as_MetadataType()->constant_value(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
529 assert(xvalue != NULL && yvalue != NULL, "not constants"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
530 if (xvalue->is_loaded() && yvalue->is_loaded()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
531 switch (cond) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
532 case If::eql: return xvalue == yvalue ? cond_true : cond_false; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
533 case If::neq: return xvalue != yvalue ? cond_true : cond_false; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
534 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
535 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
536 break; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6616
diff
changeset
|
537 } |
0 | 538 } |
1899 | 539 return not_comparable; |
0 | 540 } |
541 | |
542 | |
543 // Implementation of BlockBegin | |
544 | |
545 void BlockBegin::set_end(BlockEnd* end) { | |
546 assert(end != NULL, "should not reset block end to NULL"); | |
3900
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3243
diff
changeset
|
547 if (end == _end) { |
0 | 548 return; |
549 } | |
3900
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3243
diff
changeset
|
550 clear_end(); |
0 | 551 |
3900
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3243
diff
changeset
|
552 // Set the new end |
0 | 553 _end = end; |
554 | |
555 _successors.clear(); | |
556 // Now reset successors list based on BlockEnd | |
3900
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3243
diff
changeset
|
557 for (int i = 0; i < end->number_of_sux(); i++) { |
0 | 558 BlockBegin* sux = end->sux_at(i); |
559 _successors.append(sux); | |
560 sux->_predecessors.append(this); | |
561 } | |
562 _end->set_begin(this); | |
563 } | |
564 | |
565 | |
3900
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3243
diff
changeset
|
566 void BlockBegin::clear_end() { |
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3243
diff
changeset
|
567 // Must make the predecessors/successors match up with the |
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3243
diff
changeset
|
568 // BlockEnd's notion. |
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3243
diff
changeset
|
569 if (_end != NULL) { |
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3243
diff
changeset
|
570 // disconnect from the old end |
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3243
diff
changeset
|
571 _end->set_begin(NULL); |
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3243
diff
changeset
|
572 |
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3243
diff
changeset
|
573 // disconnect this block from it's current successors |
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3243
diff
changeset
|
574 for (int i = 0; i < _successors.length(); i++) { |
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3243
diff
changeset
|
575 _successors.at(i)->remove_predecessor(this); |
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3243
diff
changeset
|
576 } |
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3243
diff
changeset
|
577 _end = NULL; |
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3243
diff
changeset
|
578 } |
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3243
diff
changeset
|
579 } |
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3243
diff
changeset
|
580 |
a32de5085326
7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents:
3243
diff
changeset
|
581 |
0 | 582 void BlockBegin::disconnect_edge(BlockBegin* from, BlockBegin* to) { |
583 // disconnect any edges between from and to | |
584 #ifndef PRODUCT | |
585 if (PrintIR && Verbose) { | |
586 tty->print_cr("Disconnected edge B%d -> B%d", from->block_id(), to->block_id()); | |
587 } | |
588 #endif | |
589 for (int s = 0; s < from->number_of_sux();) { | |
590 BlockBegin* sux = from->sux_at(s); | |
591 if (sux == to) { | |
592 int index = sux->_predecessors.index_of(from); | |
593 if (index >= 0) { | |
594 sux->_predecessors.remove_at(index); | |
595 } | |
596 from->_successors.remove_at(s); | |
597 } else { | |
598 s++; | |
599 } | |
600 } | |
601 } | |
602 | |
603 | |
604 void BlockBegin::disconnect_from_graph() { | |
605 // disconnect this block from all other blocks | |
606 for (int p = 0; p < number_of_preds(); p++) { | |
607 pred_at(p)->remove_successor(this); | |
608 } | |
609 for (int s = 0; s < number_of_sux(); s++) { | |
610 sux_at(s)->remove_predecessor(this); | |
611 } | |
612 } | |
613 | |
614 void BlockBegin::substitute_sux(BlockBegin* old_sux, BlockBegin* new_sux) { | |
615 // modify predecessors before substituting successors | |
616 for (int i = 0; i < number_of_sux(); i++) { | |
617 if (sux_at(i) == old_sux) { | |
618 // remove old predecessor before adding new predecessor | |
619 // otherwise there is a dead predecessor in the list | |
620 new_sux->remove_predecessor(old_sux); | |
621 new_sux->add_predecessor(this); | |
622 } | |
623 } | |
624 old_sux->remove_predecessor(this); | |
625 end()->substitute_sux(old_sux, new_sux); | |
626 } | |
627 | |
628 | |
629 | |
630 // In general it is not possible to calculate a value for the field "depth_first_number" | |
631 // of the inserted block, without recomputing the values of the other blocks | |
632 // in the CFG. Therefore the value of "depth_first_number" in BlockBegin becomes meaningless. | |
633 BlockBegin* BlockBegin::insert_block_between(BlockBegin* sux) { | |
3241 | 634 BlockBegin* new_sux = new BlockBegin(end()->state()->bci()); |
0 | 635 |
636 // mark this block (special treatment when block order is computed) | |
637 new_sux->set(critical_edge_split_flag); | |
638 | |
639 // This goto is not a safepoint. | |
640 Goto* e = new Goto(sux, false); | |
1819 | 641 new_sux->set_next(e, end()->state()->bci()); |
0 | 642 new_sux->set_end(e); |
643 // setup states | |
644 ValueStack* s = end()->state(); | |
645 new_sux->set_state(s->copy()); | |
646 e->set_state(s->copy()); | |
647 assert(new_sux->state()->locals_size() == s->locals_size(), "local size mismatch!"); | |
648 assert(new_sux->state()->stack_size() == s->stack_size(), "stack size mismatch!"); | |
649 assert(new_sux->state()->locks_size() == s->locks_size(), "locks size mismatch!"); | |
650 | |
651 // link predecessor to new block | |
652 end()->substitute_sux(sux, new_sux); | |
653 | |
654 // The ordering needs to be the same, so remove the link that the | |
655 // set_end call above added and substitute the new_sux for this | |
656 // block. | |
657 sux->remove_predecessor(new_sux); | |
658 | |
659 // the successor could be the target of a switch so it might have | |
660 // multiple copies of this predecessor, so substitute the new_sux | |
661 // for the first and delete the rest. | |
662 bool assigned = false; | |
663 BlockList& list = sux->_predecessors; | |
664 for (int i = 0; i < list.length(); i++) { | |
665 BlockBegin** b = list.adr_at(i); | |
666 if (*b == this) { | |
667 if (assigned) { | |
668 list.remove_at(i); | |
669 // reprocess this index | |
670 i--; | |
671 } else { | |
672 assigned = true; | |
673 *b = new_sux; | |
674 } | |
675 // link the new block back to it's predecessors. | |
676 new_sux->add_predecessor(this); | |
677 } | |
678 } | |
679 assert(assigned == true, "should have assigned at least once"); | |
680 return new_sux; | |
681 } | |
682 | |
683 | |
684 void BlockBegin::remove_successor(BlockBegin* pred) { | |
685 int idx; | |
686 while ((idx = _successors.index_of(pred)) >= 0) { | |
687 _successors.remove_at(idx); | |
688 } | |
689 } | |
690 | |
691 | |
692 void BlockBegin::add_predecessor(BlockBegin* pred) { | |
693 _predecessors.append(pred); | |
694 } | |
695 | |
696 | |
697 void BlockBegin::remove_predecessor(BlockBegin* pred) { | |
698 int idx; | |
699 while ((idx = _predecessors.index_of(pred)) >= 0) { | |
700 _predecessors.remove_at(idx); | |
701 } | |
702 } | |
703 | |
704 | |
705 void BlockBegin::add_exception_handler(BlockBegin* b) { | |
706 assert(b != NULL && (b->is_set(exception_entry_flag)), "exception handler must exist"); | |
707 // add only if not in the list already | |
708 if (!_exception_handlers.contains(b)) _exception_handlers.append(b); | |
709 } | |
710 | |
711 int BlockBegin::add_exception_state(ValueStack* state) { | |
712 assert(is_set(exception_entry_flag), "only for xhandlers"); | |
713 if (_exception_states == NULL) { | |
714 _exception_states = new ValueStackStack(4); | |
715 } | |
716 _exception_states->append(state); | |
717 return _exception_states->length() - 1; | |
718 } | |
719 | |
720 | |
721 void BlockBegin::iterate_preorder(boolArray& mark, BlockClosure* closure) { | |
722 if (!mark.at(block_id())) { | |
723 mark.at_put(block_id(), true); | |
724 closure->block_do(this); | |
725 BlockEnd* e = end(); // must do this after block_do because block_do may change it! | |
726 { for (int i = number_of_exception_handlers() - 1; i >= 0; i--) exception_handler_at(i)->iterate_preorder(mark, closure); } | |
727 { for (int i = e->number_of_sux () - 1; i >= 0; i--) e->sux_at (i)->iterate_preorder(mark, closure); } | |
728 } | |
729 } | |
730 | |
731 | |
732 void BlockBegin::iterate_postorder(boolArray& mark, BlockClosure* closure) { | |
733 if (!mark.at(block_id())) { | |
734 mark.at_put(block_id(), true); | |
735 BlockEnd* e = end(); | |
736 { for (int i = number_of_exception_handlers() - 1; i >= 0; i--) exception_handler_at(i)->iterate_postorder(mark, closure); } | |
737 { for (int i = e->number_of_sux () - 1; i >= 0; i--) e->sux_at (i)->iterate_postorder(mark, closure); } | |
738 closure->block_do(this); | |
739 } | |
740 } | |
741 | |
742 | |
743 void BlockBegin::iterate_preorder(BlockClosure* closure) { | |
744 boolArray mark(number_of_blocks(), false); | |
745 iterate_preorder(mark, closure); | |
746 } | |
747 | |
748 | |
749 void BlockBegin::iterate_postorder(BlockClosure* closure) { | |
750 boolArray mark(number_of_blocks(), false); | |
751 iterate_postorder(mark, closure); | |
752 } | |
753 | |
754 | |
1584 | 755 void BlockBegin::block_values_do(ValueVisitor* f) { |
0 | 756 for (Instruction* n = this; n != NULL; n = n->next()) n->values_do(f); |
757 } | |
758 | |
759 | |
760 #ifndef PRODUCT | |
1783 | 761 #define TRACE_PHI(code) if (PrintPhiFunctions) { code; } |
0 | 762 #else |
1783 | 763 #define TRACE_PHI(coce) |
0 | 764 #endif |
765 | |
766 | |
767 bool BlockBegin::try_merge(ValueStack* new_state) { | |
768 TRACE_PHI(tty->print_cr("********** try_merge for block B%d", block_id())); | |
769 | |
770 // local variables used for state iteration | |
771 int index; | |
772 Value new_value, existing_value; | |
773 | |
774 ValueStack* existing_state = state(); | |
775 if (existing_state == NULL) { | |
776 TRACE_PHI(tty->print_cr("first call of try_merge for this block")); | |
777 | |
778 if (is_set(BlockBegin::was_visited_flag)) { | |
779 // this actually happens for complicated jsr/ret structures | |
780 return false; // BAILOUT in caller | |
781 } | |
782 | |
783 // copy state because it is altered | |
1819 | 784 new_state = new_state->copy(ValueStack::BlockBeginState, bci()); |
0 | 785 |
786 // Use method liveness to invalidate dead locals | |
787 MethodLivenessResult liveness = new_state->scope()->method()->liveness_at_bci(bci()); | |
788 if (liveness.is_valid()) { | |
789 assert((int)liveness.size() == new_state->locals_size(), "error in use of liveness"); | |
790 | |
791 for_each_local_value(new_state, index, new_value) { | |
792 if (!liveness.at(index) || new_value->type()->is_illegal()) { | |
793 new_state->invalidate_local(index); | |
794 TRACE_PHI(tty->print_cr("invalidating dead local %d", index)); | |
795 } | |
796 } | |
797 } | |
798 | |
799 if (is_set(BlockBegin::parser_loop_header_flag)) { | |
800 TRACE_PHI(tty->print_cr("loop header block, initializing phi functions")); | |
801 | |
802 for_each_stack_value(new_state, index, new_value) { | |
803 new_state->setup_phi_for_stack(this, index); | |
804 TRACE_PHI(tty->print_cr("creating phi-function %c%d for stack %d", new_state->stack_at(index)->type()->tchar(), new_state->stack_at(index)->id(), index)); | |
805 } | |
806 | |
807 BitMap requires_phi_function = new_state->scope()->requires_phi_function(); | |
808 | |
809 for_each_local_value(new_state, index, new_value) { | |
810 bool requires_phi = requires_phi_function.at(index) || (new_value->type()->is_double_word() && requires_phi_function.at(index + 1)); | |
811 if (requires_phi || !SelectivePhiFunctions) { | |
812 new_state->setup_phi_for_local(this, index); | |
813 TRACE_PHI(tty->print_cr("creating phi-function %c%d for local %d", new_state->local_at(index)->type()->tchar(), new_state->local_at(index)->id(), index)); | |
814 } | |
815 } | |
816 } | |
817 | |
818 // initialize state of block | |
819 set_state(new_state); | |
820 | |
1819 | 821 } else if (existing_state->is_same(new_state)) { |
0 | 822 TRACE_PHI(tty->print_cr("exisiting state found")); |
823 | |
824 assert(existing_state->scope() == new_state->scope(), "not matching"); | |
825 assert(existing_state->locals_size() == new_state->locals_size(), "not matching"); | |
826 assert(existing_state->stack_size() == new_state->stack_size(), "not matching"); | |
827 | |
828 if (is_set(BlockBegin::was_visited_flag)) { | |
829 TRACE_PHI(tty->print_cr("loop header block, phis must be present")); | |
830 | |
831 if (!is_set(BlockBegin::parser_loop_header_flag)) { | |
832 // this actually happens for complicated jsr/ret structures | |
833 return false; // BAILOUT in caller | |
834 } | |
835 | |
836 for_each_local_value(existing_state, index, existing_value) { | |
837 Value new_value = new_state->local_at(index); | |
838 if (new_value == NULL || new_value->type()->tag() != existing_value->type()->tag()) { | |
839 // The old code invalidated the phi function here | |
840 // Because dead locals are replaced with NULL, this is a very rare case now, so simply bail out | |
841 return false; // BAILOUT in caller | |
842 } | |
843 } | |
844 | |
845 #ifdef ASSERT | |
846 // check that all necessary phi functions are present | |
847 for_each_stack_value(existing_state, index, existing_value) { | |
848 assert(existing_value->as_Phi() != NULL && existing_value->as_Phi()->block() == this, "phi function required"); | |
849 } | |
850 for_each_local_value(existing_state, index, existing_value) { | |
851 assert(existing_value == new_state->local_at(index) || (existing_value->as_Phi() != NULL && existing_value->as_Phi()->as_Phi()->block() == this), "phi function required"); | |
852 } | |
853 #endif | |
854 | |
855 } else { | |
856 TRACE_PHI(tty->print_cr("creating phi functions on demand")); | |
857 | |
858 // create necessary phi functions for stack | |
859 for_each_stack_value(existing_state, index, existing_value) { | |
860 Value new_value = new_state->stack_at(index); | |
861 Phi* existing_phi = existing_value->as_Phi(); | |
862 | |
863 if (new_value != existing_value && (existing_phi == NULL || existing_phi->block() != this)) { | |
864 existing_state->setup_phi_for_stack(this, index); | |
865 TRACE_PHI(tty->print_cr("creating phi-function %c%d for stack %d", existing_state->stack_at(index)->type()->tchar(), existing_state->stack_at(index)->id(), index)); | |
866 } | |
867 } | |
868 | |
869 // create necessary phi functions for locals | |
870 for_each_local_value(existing_state, index, existing_value) { | |
871 Value new_value = new_state->local_at(index); | |
872 Phi* existing_phi = existing_value->as_Phi(); | |
873 | |
874 if (new_value == NULL || new_value->type()->tag() != existing_value->type()->tag()) { | |
875 existing_state->invalidate_local(index); | |
876 TRACE_PHI(tty->print_cr("invalidating local %d because of type mismatch", index)); | |
877 } else if (new_value != existing_value && (existing_phi == NULL || existing_phi->block() != this)) { | |
878 existing_state->setup_phi_for_local(this, index); | |
879 TRACE_PHI(tty->print_cr("creating phi-function %c%d for local %d", existing_state->local_at(index)->type()->tchar(), existing_state->local_at(index)->id(), index)); | |
880 } | |
881 } | |
882 } | |
883 | |
884 assert(existing_state->caller_state() == new_state->caller_state(), "caller states must be equal"); | |
885 | |
886 } else { | |
887 assert(false, "stack or locks not matching (invalid bytecodes)"); | |
888 return false; | |
889 } | |
890 | |
891 TRACE_PHI(tty->print_cr("********** try_merge for block B%d successful", block_id())); | |
892 | |
893 return true; | |
894 } | |
895 | |
896 | |
897 #ifndef PRODUCT | |
898 void BlockBegin::print_block() { | |
899 InstructionPrinter ip; | |
900 print_block(ip, false); | |
901 } | |
902 | |
903 | |
904 void BlockBegin::print_block(InstructionPrinter& ip, bool live_only) { | |
905 ip.print_instr(this); tty->cr(); | |
906 ip.print_stack(this->state()); tty->cr(); | |
907 ip.print_inline_level(this); | |
908 ip.print_head(); | |
909 for (Instruction* n = next(); n != NULL; n = n->next()) { | |
910 if (!live_only || n->is_pinned() || n->use_count() > 0) { | |
911 ip.print_line(n); | |
912 } | |
913 } | |
914 tty->cr(); | |
915 } | |
916 #endif // PRODUCT | |
917 | |
918 | |
919 // Implementation of BlockList | |
920 | |
921 void BlockList::iterate_forward (BlockClosure* closure) { | |
922 const int l = length(); | |
923 for (int i = 0; i < l; i++) closure->block_do(at(i)); | |
924 } | |
925 | |
926 | |
927 void BlockList::iterate_backward(BlockClosure* closure) { | |
928 for (int i = length() - 1; i >= 0; i--) closure->block_do(at(i)); | |
929 } | |
930 | |
931 | |
932 void BlockList::blocks_do(void f(BlockBegin*)) { | |
933 for (int i = length() - 1; i >= 0; i--) f(at(i)); | |
934 } | |
935 | |
936 | |
1584 | 937 void BlockList::values_do(ValueVisitor* f) { |
0 | 938 for (int i = length() - 1; i >= 0; i--) at(i)->block_values_do(f); |
939 } | |
940 | |
941 | |
942 #ifndef PRODUCT | |
943 void BlockList::print(bool cfg_only, bool live_only) { | |
944 InstructionPrinter ip; | |
945 for (int i = 0; i < length(); i++) { | |
946 BlockBegin* block = at(i); | |
947 if (cfg_only) { | |
948 ip.print_instr(block); tty->cr(); | |
949 } else { | |
950 block->print_block(ip, live_only); | |
951 } | |
952 } | |
953 } | |
954 #endif // PRODUCT | |
955 | |
956 | |
957 // Implementation of BlockEnd | |
958 | |
959 void BlockEnd::set_begin(BlockBegin* begin) { | |
960 BlockList* sux = NULL; | |
961 if (begin != NULL) { | |
962 sux = begin->successors(); | |
963 } else if (_begin != NULL) { | |
964 // copy our sux list | |
965 BlockList* sux = new BlockList(_begin->number_of_sux()); | |
966 for (int i = 0; i < _begin->number_of_sux(); i++) { | |
967 sux->append(_begin->sux_at(i)); | |
968 } | |
969 } | |
970 _sux = sux; | |
971 _begin = begin; | |
972 } | |
973 | |
974 | |
975 void BlockEnd::substitute_sux(BlockBegin* old_sux, BlockBegin* new_sux) { | |
976 substitute(*_sux, old_sux, new_sux); | |
977 } | |
978 | |
979 | |
980 // Implementation of Phi | |
981 | |
982 // Normal phi functions take their operands from the last instruction of the | |
983 // predecessor. Special handling is needed for xhanlder entries because there | |
984 // the state of arbitrary instructions are needed. | |
985 | |
986 Value Phi::operand_at(int i) const { | |
987 ValueStack* state; | |
988 if (_block->is_set(BlockBegin::exception_entry_flag)) { | |
989 state = _block->exception_state_at(i); | |
990 } else { | |
991 state = _block->pred_at(i)->end()->state(); | |
992 } | |
993 assert(state != NULL, ""); | |
994 | |
995 if (is_local()) { | |
996 return state->local_at(local_index()); | |
997 } else { | |
998 return state->stack_at(stack_index()); | |
999 } | |
1000 } | |
1001 | |
1002 | |
1003 int Phi::operand_count() const { | |
1004 if (_block->is_set(BlockBegin::exception_entry_flag)) { | |
1005 return _block->number_of_exception_states(); | |
1006 } else { | |
1007 return _block->number_of_preds(); | |
1008 } | |
1009 } | |
1010 | |
1011 | |
1783 | 1012 |
1013 void ProfileInvoke::state_values_do(ValueVisitor* f) { | |
1014 if (state() != NULL) state()->values_do(f); | |
1015 } |