Mercurial > hg > truffle
comparison src/share/vm/c1/c1_Canonicalizer.cpp @ 4943:80107dc493db
7126041: jdk7u4 b05 and b06 crash with RubyMine 3.2.4, works well with b04
Summary: Goto that replaces a If mistaken to be a back branch and triggers erroneous OSR compilation.
Reviewed-by: never, iveresov
author | roland |
---|---|
date | Wed, 15 Feb 2012 09:43:16 +0100 |
parents | 425688247f3d |
children | 701a83c86f28 |
comparison
equal
deleted
inserted
replaced
4942:8f4eb44b3b76 | 4943:80107dc493db |
---|---|
592 } | 592 } |
593 ShouldNotReachHere(); | 593 ShouldNotReachHere(); |
594 return false; | 594 return false; |
595 } | 595 } |
596 | 596 |
597 static bool is_safepoint(BlockEnd* x, BlockBegin* sux) { | |
598 // An Instruction with multiple successors, x, is replaced by a Goto | |
599 // to a single successor, sux. Is a safepoint check needed = was the | |
600 // instruction being replaced a safepoint and the single remaining | |
601 // successor a back branch? | |
602 return x->is_safepoint() && (sux->bci() < x->state_before()->bci()); | |
603 } | |
597 | 604 |
598 void Canonicalizer::do_If(If* x) { | 605 void Canonicalizer::do_If(If* x) { |
599 // move const to right | 606 // move const to right |
600 if (x->x()->type()->is_constant()) x->swap_operands(); | 607 if (x->x()->type()->is_constant()) x->swap_operands(); |
601 // simplify | 608 // simplify |
612 case If::leq: sux = x->sux_for(true); break; | 619 case If::leq: sux = x->sux_for(true); break; |
613 case If::gtr: sux = x->sux_for(false); break; | 620 case If::gtr: sux = x->sux_for(false); break; |
614 case If::geq: sux = x->sux_for(true); break; | 621 case If::geq: sux = x->sux_for(true); break; |
615 } | 622 } |
616 // If is a safepoint then the debug information should come from the state_before of the If. | 623 // If is a safepoint then the debug information should come from the state_before of the If. |
617 set_canonical(new Goto(sux, x->state_before(), x->is_safepoint())); | 624 set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux))); |
618 return; | 625 return; |
619 } | 626 } |
620 | 627 |
621 if (lt->is_constant() && rt->is_constant()) { | 628 if (lt->is_constant() && rt->is_constant()) { |
622 if (x->x()->as_Constant() != NULL) { | 629 if (x->x()->as_Constant() != NULL) { |
624 BlockBegin* sux = x->x()->as_Constant()->compare(x->cond(), x->y(), | 631 BlockBegin* sux = x->x()->as_Constant()->compare(x->cond(), x->y(), |
625 x->sux_for(true), | 632 x->sux_for(true), |
626 x->sux_for(false)); | 633 x->sux_for(false)); |
627 if (sux != NULL) { | 634 if (sux != NULL) { |
628 // If is a safepoint then the debug information should come from the state_before of the If. | 635 // If is a safepoint then the debug information should come from the state_before of the If. |
629 set_canonical(new Goto(sux, x->state_before(), x->is_safepoint())); | 636 set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux))); |
630 } | 637 } |
631 } | 638 } |
632 } else if (rt->as_IntConstant() != NULL) { | 639 } else if (rt->as_IntConstant() != NULL) { |
633 // pattern: If (l cond rc) => investigate further | 640 // pattern: If (l cond rc) => investigate further |
634 const jint rc = rt->as_IntConstant()->value(); | 641 const jint rc = rt->as_IntConstant()->value(); |
692 set_canonical(new IfInstanceOf(inst->klass(), inst->obj(), true, inst->state_before()->bci(), is_inst_sux, no_inst_sux)); | 699 set_canonical(new IfInstanceOf(inst->klass(), inst->obj(), true, inst->state_before()->bci(), is_inst_sux, no_inst_sux)); |
693 } | 700 } |
694 } | 701 } |
695 } else if (rt == objectNull && (l->as_NewInstance() || l->as_NewArray())) { | 702 } else if (rt == objectNull && (l->as_NewInstance() || l->as_NewArray())) { |
696 if (x->cond() == Instruction::eql) { | 703 if (x->cond() == Instruction::eql) { |
697 set_canonical(new Goto(x->fsux(), x->state_before(), x->is_safepoint())); | 704 BlockBegin* sux = x->fsux(); |
705 set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux))); | |
698 } else { | 706 } else { |
699 assert(x->cond() == Instruction::neq, "only other valid case"); | 707 assert(x->cond() == Instruction::neq, "only other valid case"); |
700 set_canonical(new Goto(x->tsux(), x->state_before(), x->is_safepoint())); | 708 BlockBegin* sux = x->tsux(); |
709 set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux))); | |
701 } | 710 } |
702 } | 711 } |
703 } | 712 } |
704 | 713 |
705 | 714 |
708 int v = x->tag()->type()->as_IntConstant()->value(); | 717 int v = x->tag()->type()->as_IntConstant()->value(); |
709 BlockBegin* sux = x->default_sux(); | 718 BlockBegin* sux = x->default_sux(); |
710 if (v >= x->lo_key() && v <= x->hi_key()) { | 719 if (v >= x->lo_key() && v <= x->hi_key()) { |
711 sux = x->sux_at(v - x->lo_key()); | 720 sux = x->sux_at(v - x->lo_key()); |
712 } | 721 } |
713 set_canonical(new Goto(sux, x->state_before(), x->is_safepoint())); | 722 set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux))); |
714 } else if (x->number_of_sux() == 1) { | 723 } else if (x->number_of_sux() == 1) { |
715 // NOTE: Code permanently disabled for now since the switch statement's | 724 // NOTE: Code permanently disabled for now since the switch statement's |
716 // tag expression may produce side-effects in which case it must | 725 // tag expression may produce side-effects in which case it must |
717 // be executed. | 726 // be executed. |
718 return; | 727 return; |
739 for (int i = 0; i < x->length(); i++) { | 748 for (int i = 0; i < x->length(); i++) { |
740 if (v == x->key_at(i)) { | 749 if (v == x->key_at(i)) { |
741 sux = x->sux_at(i); | 750 sux = x->sux_at(i); |
742 } | 751 } |
743 } | 752 } |
744 set_canonical(new Goto(sux, x->state_before(), x->is_safepoint())); | 753 set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux))); |
745 } else if (x->number_of_sux() == 1) { | 754 } else if (x->number_of_sux() == 1) { |
746 // NOTE: Code permanently disabled for now since the switch statement's | 755 // NOTE: Code permanently disabled for now since the switch statement's |
747 // tag expression may produce side-effects in which case it must | 756 // tag expression may produce side-effects in which case it must |
748 // be executed. | 757 // be executed. |
749 return; | 758 return; |