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;