--- old/src/share/vm/opto/parse1.cpp Thu Jan 7 16:01:56 2010 +++ new/src/share/vm/opto/parse1.cpp Thu Jan 7 16:01:56 2010 @@ -1378,17 +1378,21 @@ // Parse bytecodes while (!stopped() && !failing()) { iter().next(); - + // Learn the current bci from the iterator: set_parse_bci(iter().cur_bci()); if (bci() == block()->limit()) { + //insert a predicate if it falls through to a loop head block + if(should_add_predicate(bci())){ + add_predicate(); + } // Do not walk into the next block until directed by do_all_blocks. merge(bci()); break; } assert(bci() < block()->limit(), "bci still in block"); - + if (log != NULL) { // Output an optional context marker, to help place actions // that occur during parsing of this BC. If there is no log @@ -2083,6 +2087,37 @@ } } +//------------------------------should_add_predicate-------------------------- +bool Parse::should_add_predicate(int target_bci) { + if (!UseLoopPredicate) return false; + Block* target = successor_for_bci(target_bci); + if (target != NULL && + target->is_loop_head() && + block()->rpo() < target->rpo()) { + return true; + } + return false; +} + +//------------------------------add_predicate--------------------------------- +void Parse::add_predicate() { + assert(UseLoopPredicate,"use only for loop predicate"); + Node *cont = _gvn.intcon(1); + Node* opq = _gvn.transform(new (C, 2) Opaque1Node(C, cont)); + Node *bol = _gvn.transform(new (C, 2) Conv2BNode(opq)); + IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN); + Node* iffalse = _gvn.transform(new (C, 1) IfFalseNode(iff)); + C->add_predicate_opaq(opq); + { + PreserveJVMState pjvms(this); + set_control(iffalse); + uncommon_trap(Deoptimization::Reason_predicate, + Deoptimization::Action_maybe_recompile); + } + Node* iftrue = _gvn.transform(new (C, 1) IfTrueNode(iff)); + set_control(iftrue); +} + #ifndef PRODUCT //------------------------show_parse_info-------------------------------------- void Parse::show_parse_info() {