Mercurial > hg > graal-compiler
comparison src/share/vm/c1/c1_Instruction.cpp @ 1819:f02a8bbe6ed4
6986046: C1 valuestack cleanup
Summary: fixes an historical oddity in C1 with inlining where all of the expression stacks are kept in the topmost ValueStack instead of being in their respective ValueStacks.
Reviewed-by: never
Contributed-by: Christian Wimmer <cwimmer@uci.edu>
author | roland |
---|---|
date | Tue, 29 Dec 2009 19:08:54 +0100 |
parents | d5d065957597 |
children | 42a10fc37986 |
comparison
equal
deleted
inserted
replaced
1817:c40600e85311 | 1819:f02a8bbe6ed4 |
---|---|
27 | 27 |
28 | 28 |
29 // Implementation of Instruction | 29 // Implementation of Instruction |
30 | 30 |
31 | 31 |
32 #ifdef ASSERT | |
33 void Instruction::create_hi_word() { | |
34 assert(type()->is_double_word() && _hi_word == NULL, "only double word has high word"); | |
35 _hi_word = new HiWord(this); | |
36 } | |
37 #endif | |
38 | |
39 Instruction::Condition Instruction::mirror(Condition cond) { | 32 Instruction::Condition Instruction::mirror(Condition cond) { |
40 switch (cond) { | 33 switch (cond) { |
41 case eql: return eql; | 34 case eql: return eql; |
42 case neq: return neq; | 35 case neq: return neq; |
43 case lss: return gtr; | 36 case lss: return gtr; |
61 } | 54 } |
62 ShouldNotReachHere(); | 55 ShouldNotReachHere(); |
63 return eql; | 56 return eql; |
64 } | 57 } |
65 | 58 |
59 void Instruction::update_exception_state(ValueStack* state) { | |
60 if (state != NULL && (state->kind() == ValueStack::EmptyExceptionState || state->kind() == ValueStack::ExceptionState)) { | |
61 assert(state->kind() == ValueStack::EmptyExceptionState || Compilation::current()->env()->jvmti_can_access_local_variables(), "unexpected state kind"); | |
62 _exception_state = state; | |
63 } else { | |
64 _exception_state = NULL; | |
65 } | |
66 } | |
67 | |
66 | 68 |
67 Instruction* Instruction::prev(BlockBegin* block) { | 69 Instruction* Instruction::prev(BlockBegin* block) { |
68 Instruction* p = NULL; | 70 Instruction* p = NULL; |
69 Instruction* q = block; | 71 Instruction* q = block; |
70 while (q != this) { | 72 while (q != this) { |
73 } | 75 } |
74 return p; | 76 return p; |
75 } | 77 } |
76 | 78 |
77 | 79 |
80 void Instruction::state_values_do(ValueVisitor* f) { | |
81 if (state_before() != NULL) { | |
82 state_before()->values_do(f); | |
83 } | |
84 if (exception_state() != NULL){ | |
85 exception_state()->values_do(f); | |
86 } | |
87 } | |
88 | |
89 | |
78 #ifndef PRODUCT | 90 #ifndef PRODUCT |
91 void Instruction::check_state(ValueStack* state) { | |
92 if (state != NULL) { | |
93 state->verify(); | |
94 } | |
95 } | |
96 | |
97 | |
79 void Instruction::print() { | 98 void Instruction::print() { |
80 InstructionPrinter ip; | 99 InstructionPrinter ip; |
81 print(ip); | 100 print(ip); |
82 } | 101 } |
83 | 102 |
187 return ik; | 206 return ik; |
188 } | 207 } |
189 } | 208 } |
190 return NULL; | 209 return NULL; |
191 } | 210 } |
192 | |
193 | |
194 void ArithmeticOp::other_values_do(ValueVisitor* f) { | |
195 if (lock_stack() != NULL) lock_stack()->values_do(f); | |
196 } | |
197 | |
198 void NullCheck::other_values_do(ValueVisitor* f) { | |
199 lock_stack()->values_do(f); | |
200 } | |
201 | |
202 void AccessArray::other_values_do(ValueVisitor* f) { | |
203 if (lock_stack() != NULL) lock_stack()->values_do(f); | |
204 } | |
205 | |
206 | |
207 // Implementation of AccessField | |
208 | |
209 void AccessField::other_values_do(ValueVisitor* f) { | |
210 if (state_before() != NULL) state_before()->values_do(f); | |
211 if (lock_stack() != NULL) lock_stack()->values_do(f); | |
212 } | |
213 | |
214 | |
215 // Implementation of StoreIndexed | |
216 | |
217 IRScope* StoreIndexed::scope() const { | |
218 return lock_stack()->scope(); | |
219 } | |
220 | |
221 | 211 |
222 // Implementation of ArithmeticOp | 212 // Implementation of ArithmeticOp |
223 | 213 |
224 bool ArithmeticOp::is_commutative() const { | 214 bool ArithmeticOp::is_commutative() const { |
225 switch (op()) { | 215 switch (op()) { |
264 // all LogicOps are commutative | 254 // all LogicOps are commutative |
265 return true; | 255 return true; |
266 } | 256 } |
267 | 257 |
268 | 258 |
269 // Implementation of CompareOp | |
270 | |
271 void CompareOp::other_values_do(ValueVisitor* f) { | |
272 if (state_before() != NULL) state_before()->values_do(f); | |
273 } | |
274 | |
275 | |
276 // Implementation of IfOp | 259 // Implementation of IfOp |
277 | 260 |
278 bool IfOp::is_commutative() const { | 261 bool IfOp::is_commutative() const { |
279 return cond() == eql || cond() == neq; | 262 return cond() == eql || cond() == neq; |
280 } | 263 } |
299 return _state->scope(); | 282 return _state->scope(); |
300 } | 283 } |
301 | 284 |
302 | 285 |
303 void StateSplit::state_values_do(ValueVisitor* f) { | 286 void StateSplit::state_values_do(ValueVisitor* f) { |
287 Instruction::state_values_do(f); | |
304 if (state() != NULL) state()->values_do(f); | 288 if (state() != NULL) state()->values_do(f); |
305 } | 289 } |
306 | 290 |
307 | 291 |
308 void BlockBegin::state_values_do(ValueVisitor* f) { | 292 void BlockBegin::state_values_do(ValueVisitor* f) { |
314 } | 298 } |
315 } | 299 } |
316 } | 300 } |
317 | 301 |
318 | 302 |
319 void MonitorEnter::state_values_do(ValueVisitor* f) { | |
320 StateSplit::state_values_do(f); | |
321 _lock_stack_before->values_do(f); | |
322 } | |
323 | |
324 | |
325 void Intrinsic::state_values_do(ValueVisitor* f) { | |
326 StateSplit::state_values_do(f); | |
327 if (lock_stack() != NULL) lock_stack()->values_do(f); | |
328 } | |
329 | |
330 | |
331 // Implementation of Invoke | 303 // Implementation of Invoke |
332 | 304 |
333 | 305 |
334 Invoke::Invoke(Bytecodes::Code code, ValueType* result_type, Value recv, Values* args, | 306 Invoke::Invoke(Bytecodes::Code code, ValueType* result_type, Value recv, Values* args, |
335 int vtable_index, ciMethod* target, ValueStack* state_before) | 307 int vtable_index, ciMethod* target, ValueStack* state_before) |
336 : StateSplit(result_type) | 308 : StateSplit(result_type, state_before) |
337 , _code(code) | 309 , _code(code) |
338 , _recv(recv) | 310 , _recv(recv) |
339 , _args(args) | 311 , _args(args) |
340 , _vtable_index(vtable_index) | 312 , _vtable_index(vtable_index) |
341 , _target(target) | 313 , _target(target) |
342 , _state_before(state_before) | |
343 { | 314 { |
344 set_flag(TargetIsLoadedFlag, target->is_loaded()); | 315 set_flag(TargetIsLoadedFlag, target->is_loaded()); |
345 set_flag(TargetIsFinalFlag, target_is_loaded() && target->is_final_method()); | 316 set_flag(TargetIsFinalFlag, target_is_loaded() && target->is_final_method()); |
346 set_flag(TargetIsStrictfpFlag, target_is_loaded() && target->is_strict()); | 317 set_flag(TargetIsStrictfpFlag, target_is_loaded() && target->is_strict()); |
347 | 318 |
374 } | 345 } |
375 | 346 |
376 | 347 |
377 // Implementation of Contant | 348 // Implementation of Contant |
378 intx Constant::hash() const { | 349 intx Constant::hash() const { |
379 if (_state == NULL) { | 350 if (state_before() == NULL) { |
380 switch (type()->tag()) { | 351 switch (type()->tag()) { |
381 case intTag: | 352 case intTag: |
382 return HASH2(name(), type()->as_IntConstant()->value()); | 353 return HASH2(name(), type()->as_IntConstant()->value()); |
383 case longTag: | 354 case longTag: |
384 { | 355 { |
497 } | 468 } |
498 return NULL; | 469 return NULL; |
499 } | 470 } |
500 | 471 |
501 | 472 |
502 void Constant::other_values_do(ValueVisitor* f) { | |
503 if (state() != NULL) state()->values_do(f); | |
504 } | |
505 | |
506 | |
507 // Implementation of NewArray | |
508 | |
509 void NewArray::other_values_do(ValueVisitor* f) { | |
510 if (state_before() != NULL) state_before()->values_do(f); | |
511 } | |
512 | |
513 | |
514 // Implementation of TypeCheck | |
515 | |
516 void TypeCheck::other_values_do(ValueVisitor* f) { | |
517 if (state_before() != NULL) state_before()->values_do(f); | |
518 } | |
519 | |
520 | |
521 // Implementation of BlockBegin | 473 // Implementation of BlockBegin |
522 | 474 |
523 void BlockBegin::set_end(BlockEnd* end) { | 475 void BlockBegin::set_end(BlockEnd* end) { |
524 assert(end != NULL, "should not reset block end to NULL"); | 476 assert(end != NULL, "should not reset block end to NULL"); |
525 BlockEnd* old_end = _end; | 477 BlockEnd* old_end = _end; |
602 | 554 |
603 // In general it is not possible to calculate a value for the field "depth_first_number" | 555 // In general it is not possible to calculate a value for the field "depth_first_number" |
604 // of the inserted block, without recomputing the values of the other blocks | 556 // of the inserted block, without recomputing the values of the other blocks |
605 // in the CFG. Therefore the value of "depth_first_number" in BlockBegin becomes meaningless. | 557 // in the CFG. Therefore the value of "depth_first_number" in BlockBegin becomes meaningless. |
606 BlockBegin* BlockBegin::insert_block_between(BlockBegin* sux) { | 558 BlockBegin* BlockBegin::insert_block_between(BlockBegin* sux) { |
607 // Try to make the bci close to a block with a single pred or sux, | 559 BlockBegin* new_sux = new BlockBegin(-99); |
608 // since this make the block layout algorithm work better. | |
609 int bci = -1; | |
610 if (sux->number_of_preds() == 1) { | |
611 bci = sux->bci(); | |
612 } else { | |
613 bci = end()->bci(); | |
614 } | |
615 | |
616 BlockBegin* new_sux = new BlockBegin(bci); | |
617 | 560 |
618 // mark this block (special treatment when block order is computed) | 561 // mark this block (special treatment when block order is computed) |
619 new_sux->set(critical_edge_split_flag); | 562 new_sux->set(critical_edge_split_flag); |
620 | 563 |
621 // This goto is not a safepoint. | 564 // This goto is not a safepoint. |
622 Goto* e = new Goto(sux, false); | 565 Goto* e = new Goto(sux, false); |
623 new_sux->set_next(e, bci); | 566 new_sux->set_next(e, end()->state()->bci()); |
624 new_sux->set_end(e); | 567 new_sux->set_end(e); |
625 // setup states | 568 // setup states |
626 ValueStack* s = end()->state(); | 569 ValueStack* s = end()->state(); |
627 new_sux->set_state(s->copy()); | 570 new_sux->set_state(s->copy()); |
628 e->set_state(s->copy()); | 571 e->set_state(s->copy()); |
761 // this actually happens for complicated jsr/ret structures | 704 // this actually happens for complicated jsr/ret structures |
762 return false; // BAILOUT in caller | 705 return false; // BAILOUT in caller |
763 } | 706 } |
764 | 707 |
765 // copy state because it is altered | 708 // copy state because it is altered |
766 new_state = new_state->copy(); | 709 new_state = new_state->copy(ValueStack::BlockBeginState, bci()); |
767 | 710 |
768 // Use method liveness to invalidate dead locals | 711 // Use method liveness to invalidate dead locals |
769 MethodLivenessResult liveness = new_state->scope()->method()->liveness_at_bci(bci()); | 712 MethodLivenessResult liveness = new_state->scope()->method()->liveness_at_bci(bci()); |
770 if (liveness.is_valid()) { | 713 if (liveness.is_valid()) { |
771 assert((int)liveness.size() == new_state->locals_size(), "error in use of liveness"); | 714 assert((int)liveness.size() == new_state->locals_size(), "error in use of liveness"); |
798 } | 741 } |
799 | 742 |
800 // initialize state of block | 743 // initialize state of block |
801 set_state(new_state); | 744 set_state(new_state); |
802 | 745 |
803 } else if (existing_state->is_same_across_scopes(new_state)) { | 746 } else if (existing_state->is_same(new_state)) { |
804 TRACE_PHI(tty->print_cr("exisiting state found")); | 747 TRACE_PHI(tty->print_cr("exisiting state found")); |
805 | |
806 // Inlining may cause the local state not to match up, so walk up | |
807 // the new state until we get to the same scope as the | |
808 // existing and then start processing from there. | |
809 while (existing_state->scope() != new_state->scope()) { | |
810 new_state = new_state->caller_state(); | |
811 assert(new_state != NULL, "could not match up scopes"); | |
812 | |
813 assert(false, "check if this is necessary"); | |
814 } | |
815 | 748 |
816 assert(existing_state->scope() == new_state->scope(), "not matching"); | 749 assert(existing_state->scope() == new_state->scope(), "not matching"); |
817 assert(existing_state->locals_size() == new_state->locals_size(), "not matching"); | 750 assert(existing_state->locals_size() == new_state->locals_size(), "not matching"); |
818 assert(existing_state->stack_size() == new_state->stack_size(), "not matching"); | 751 assert(existing_state->stack_size() == new_state->stack_size(), "not matching"); |
819 | 752 |
967 void BlockEnd::substitute_sux(BlockBegin* old_sux, BlockBegin* new_sux) { | 900 void BlockEnd::substitute_sux(BlockBegin* old_sux, BlockBegin* new_sux) { |
968 substitute(*_sux, old_sux, new_sux); | 901 substitute(*_sux, old_sux, new_sux); |
969 } | 902 } |
970 | 903 |
971 | 904 |
972 void BlockEnd::other_values_do(ValueVisitor* f) { | |
973 if (state_before() != NULL) state_before()->values_do(f); | |
974 } | |
975 | |
976 | |
977 // Implementation of Phi | 905 // Implementation of Phi |
978 | 906 |
979 // Normal phi functions take their operands from the last instruction of the | 907 // Normal phi functions take their operands from the last instruction of the |
980 // predecessor. Special handling is needed for xhanlder entries because there | 908 // predecessor. Special handling is needed for xhanlder entries because there |
981 // the state of arbitrary instructions are needed. | 909 // the state of arbitrary instructions are needed. |
1004 return _block->number_of_preds(); | 932 return _block->number_of_preds(); |
1005 } | 933 } |
1006 } | 934 } |
1007 | 935 |
1008 | 936 |
1009 // Implementation of Throw | |
1010 | |
1011 void Throw::state_values_do(ValueVisitor* f) { | |
1012 BlockEnd::state_values_do(f); | |
1013 } | |
1014 | 937 |
1015 void ProfileInvoke::state_values_do(ValueVisitor* f) { | 938 void ProfileInvoke::state_values_do(ValueVisitor* f) { |
1016 if (state() != NULL) state()->values_do(f); | 939 if (state() != NULL) state()->values_do(f); |
1017 } | 940 } |