src/share/vm/ci/ciTypeFlow.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6877170 Sdiff src/share/vm/ci

src/share/vm/ci/ciTypeFlow.cpp

Print this page




 196       analyzer->make_jsr_record(str->get_dest(), str->next_bci());
 197     insert_jsr_record(record);
 198   } else if (code == Bytecodes::_jsr_w) {
 199     JsrRecord* record =
 200       analyzer->make_jsr_record(str->get_far_dest(), str->next_bci());
 201     insert_jsr_record(record);
 202   } else if (code == Bytecodes::_ret) {
 203     Cell local = state->local(str->get_index());
 204     ciType* return_address = state->type_at(local);
 205     assert(return_address->is_return_address(), "verify: wrong type");
 206     if (size() == 0) {
 207       // Ret-state underflow:  Hit a ret w/o any previous jsrs.  Bail out.
 208       // This can happen when a loop is inside a finally clause (4614060).
 209       analyzer->record_failure("OSR in finally clause");
 210       return;
 211     }
 212     remove_jsr_record(return_address->as_return_address()->bci());
 213   }
 214 }
 215 



























 216 #ifndef PRODUCT
 217 // ------------------------------------------------------------------
 218 // ciTypeFlow::JsrSet::print_on
 219 void ciTypeFlow::JsrSet::print_on(outputStream* st) const {
 220   st->print("{ ");
 221   int num_elements = size();
 222   if (num_elements > 0) {
 223     int i = 0;
 224     for( ; i < num_elements - 1; i++) {
 225       _set->at(i)->print_on(st);
 226       st->print(", ");
 227     }
 228     _set->at(i)->print_on(st);
 229     st->print(" ");
 230   }
 231   st->print("}");
 232 }
 233 #endif
 234 
 235 // ciTypeFlow::StateVector


1568     new (outer->arena()) JsrSet(outer->arena(), jsrs->size());
1569   jsrs->copy_into(new_jsrs);
1570   _jsrs = new_jsrs;
1571   _next = NULL;
1572   _on_work_list = false;
1573   _backedge_copy = false;
1574   _exception_entry = false;
1575   _trap_bci = -1;
1576   _trap_index = 0;
1577   df_init();
1578 
1579   if (CITraceTypeFlow) {
1580     tty->print_cr(">> Created new block");
1581     print_on(tty);
1582   }
1583 
1584   assert(this->outer() == outer, "outer link set up");
1585   assert(!outer->have_block_count(), "must not have mapped blocks yet");
1586 }
1587 



































1588 // ------------------------------------------------------------------
1589 // ciTypeFlow::Block::df_init
1590 void ciTypeFlow::Block::df_init() {
1591   _pre_order = -1; assert(!has_pre_order(), "");
1592   _post_order = -1; assert(!has_post_order(), "");
1593   _loop = NULL;
1594   _irreducible_entry = false;
1595   _rpo_next = NULL;
1596 }
1597 
1598 // ------------------------------------------------------------------
1599 // ciTypeFlow::Block::successors
1600 //
1601 // Get the successors for this Block.
1602 GrowableArray<ciTypeFlow::Block*>*
1603 ciTypeFlow::Block::successors(ciBytecodeStream* str,
1604                               ciTypeFlow::StateVector* state,
1605                               ciTypeFlow::JsrSet* jsrs) {
1606   if (_successors == NULL) {
1607     if (CITraceTypeFlow) {


2254 
2255   return clone;
2256 }
2257 
2258 // ------------------------------------------------------------------
2259 // ciTypeFlow::flow_block
2260 //
2261 // Interpret the effects of the bytecodes on the incoming state
2262 // vector of a basic block.  Push the changed state to succeeding
2263 // basic blocks.
2264 void ciTypeFlow::flow_block(ciTypeFlow::Block* block,
2265                             ciTypeFlow::StateVector* state,
2266                             ciTypeFlow::JsrSet* jsrs) {
2267   if (CITraceTypeFlow) {
2268     tty->print("\n>> ANALYZING BLOCK : ");
2269     tty->cr();
2270     block->print_on(tty);
2271   }
2272   assert(block->has_pre_order(), "pre-order is assigned before 1st flow");
2273 








2274   int start = block->start();
2275   int limit = block->limit();
2276   int control = block->control();
2277   if (control != ciBlock::fall_through_bci) {
2278     limit = control;
2279   }
2280 
2281   // Grab the state from the current block.
2282   block->copy_state_into(state);
2283   state->def_locals()->clear();
2284 
2285   GrowableArray<Block*>*           exceptions = block->exceptions();
2286   GrowableArray<ciInstanceKlass*>* exc_klasses = block->exc_klasses();
2287   bool has_exceptions = exceptions->length() > 0;
2288 
2289   bool exceptions_used = false;
2290 
2291   ciBytecodeStream str(method());
2292   str.reset_to_bci(start);
2293   Bytecodes::Code code;


2819 void ciTypeFlow::do_flow() {
2820   if (CITraceTypeFlow) {
2821     tty->print_cr("\nPerforming flow analysis on method");
2822     method()->print();
2823     if (is_osr_flow())  tty->print(" at OSR bci %d", start_bci());
2824     tty->cr();
2825     method()->print_codes();
2826   }
2827   if (CITraceTypeFlow) {
2828     tty->print_cr("Initial CI Blocks");
2829     print_on(tty);
2830   }
2831   flow_types();
2832   // Watch for bailouts.
2833   if (failing()) {
2834     return;
2835   }
2836 
2837   map_blocks();
2838 




2839   if (CIPrintTypeFlow || CITraceTypeFlow) {
2840     rpo_print_on(tty);
2841   }
2842 }
2843 
2844 // ------------------------------------------------------------------
2845 // ciTypeFlow::record_failure()
2846 // The ciTypeFlow object keeps track of failure reasons separately from the ciEnv.
2847 // This is required because there is not a 1-1 relation between the ciEnv and
2848 // the TypeFlow passes within a compilation task.  For example, if the compiler
2849 // is considering inlining a method, it will request a TypeFlow.  If that fails,
2850 // the compilation as a whole may continue without the inlining.  Some TypeFlow
2851 // requests are not optional; if they fail the requestor is responsible for
2852 // copying the failure reason up to the ciEnv.  (See Parse::Parse.)
2853 void ciTypeFlow::record_failure(const char* reason) {
2854   if (env()->log() != NULL) {
2855     env()->log()->elem("failure reason='%s' phase='typeflow'", reason);
2856   }
2857   if (_failure_reason == NULL) {
2858     // Record the first failure reason.




 196       analyzer->make_jsr_record(str->get_dest(), str->next_bci());
 197     insert_jsr_record(record);
 198   } else if (code == Bytecodes::_jsr_w) {
 199     JsrRecord* record =
 200       analyzer->make_jsr_record(str->get_far_dest(), str->next_bci());
 201     insert_jsr_record(record);
 202   } else if (code == Bytecodes::_ret) {
 203     Cell local = state->local(str->get_index());
 204     ciType* return_address = state->type_at(local);
 205     assert(return_address->is_return_address(), "verify: wrong type");
 206     if (size() == 0) {
 207       // Ret-state underflow:  Hit a ret w/o any previous jsrs.  Bail out.
 208       // This can happen when a loop is inside a finally clause (4614060).
 209       analyzer->record_failure("OSR in finally clause");
 210       return;
 211     }
 212     remove_jsr_record(return_address->as_return_address()->bci());
 213   }
 214 }
 215 
 216 
 217 // ------------------------------------------------------------------
 218 // ciTypeFlow::JsrSet::apply_state
 219 //   remove any JsrRecords which refer to address that aren't in state
 220 void ciTypeFlow::JsrSet::apply_state(StateVector* state) {
 221   int len = size();
 222   for (int i = 0; i < len; i++) {
 223     int ra = record_at(i)->return_address();
 224     bool found = false;
 225     Cell limit = state->limit_cell();
 226     for (Cell c = state->start_cell(); c < limit; c = state->next_cell(c)) {
 227       ciType* cell_type = state->type_at(c);
 228       if (cell_type->is_return_address() && cell_type->as_return_address()->bci() == ra) {
 229         found = true;
 230         break;
 231       }
 232     }
 233     if (!found) {
 234       remove_jsr_record(ra);
 235       i--;
 236       len--;
 237     }
 238   }
 239 }
 240 
 241 
 242 
 243 #ifndef PRODUCT
 244 // ------------------------------------------------------------------
 245 // ciTypeFlow::JsrSet::print_on
 246 void ciTypeFlow::JsrSet::print_on(outputStream* st) const {
 247   st->print("{ ");
 248   int num_elements = size();
 249   if (num_elements > 0) {
 250     int i = 0;
 251     for( ; i < num_elements - 1; i++) {
 252       _set->at(i)->print_on(st);
 253       st->print(", ");
 254     }
 255     _set->at(i)->print_on(st);
 256     st->print(" ");
 257   }
 258   st->print("}");
 259 }
 260 #endif
 261 
 262 // ciTypeFlow::StateVector


1595     new (outer->arena()) JsrSet(outer->arena(), jsrs->size());
1596   jsrs->copy_into(new_jsrs);
1597   _jsrs = new_jsrs;
1598   _next = NULL;
1599   _on_work_list = false;
1600   _backedge_copy = false;
1601   _exception_entry = false;
1602   _trap_bci = -1;
1603   _trap_index = 0;
1604   df_init();
1605 
1606   if (CITraceTypeFlow) {
1607     tty->print_cr(">> Created new block");
1608     print_on(tty);
1609   }
1610 
1611   assert(this->outer() == outer, "outer link set up");
1612   assert(!outer->have_block_count(), "must not have mapped blocks yet");
1613 }
1614 
1615 
1616 bool ciTypeFlow::Block::delete_dead_addresses() {
1617   bool changed = false;
1618   if (_jsrs->size() != 0) {
1619     ciMethod* method = outer()->method();
1620     MethodLivenessResult live_locals = method->liveness_at_bci(start(), true);
1621     if (live_locals.is_valid()) {
1622       int addresses = 0;
1623       for (int i = 0; i < stack_size(); i++) {
1624         ciType* local = stack_type_at(i);
1625         if (local->is_return_address()) {
1626           addresses++;
1627         }
1628       }
1629       for (int i = 0; i < method->max_locals(); i++) {
1630         ciType* local = local_type_at(i);
1631         if (local->is_return_address()) {
1632           if (!live_locals.at(i)) {
1633             state()->set_type_at(state()->local(i), StateVector::bottom_type());
1634             changed = true;
1635           } else {
1636             addresses++;
1637           }
1638         }
1639       }
1640       if (addresses != _jsrs->size()) {
1641         // The size of the JsrSet and the number of address in the
1642         // state disagree so trim any unreachable JsrRecords.
1643         _jsrs->apply_state(state());
1644       }
1645     }
1646   }
1647   return changed;
1648 }
1649 
1650 // ------------------------------------------------------------------
1651 // ciTypeFlow::Block::df_init
1652 void ciTypeFlow::Block::df_init() {
1653   _pre_order = -1; assert(!has_pre_order(), "");
1654   _post_order = -1; assert(!has_post_order(), "");
1655   _loop = NULL;
1656   _irreducible_entry = false;
1657   _rpo_next = NULL;
1658 }
1659 
1660 // ------------------------------------------------------------------
1661 // ciTypeFlow::Block::successors
1662 //
1663 // Get the successors for this Block.
1664 GrowableArray<ciTypeFlow::Block*>*
1665 ciTypeFlow::Block::successors(ciBytecodeStream* str,
1666                               ciTypeFlow::StateVector* state,
1667                               ciTypeFlow::JsrSet* jsrs) {
1668   if (_successors == NULL) {
1669     if (CITraceTypeFlow) {


2316 
2317   return clone;
2318 }
2319 
2320 // ------------------------------------------------------------------
2321 // ciTypeFlow::flow_block
2322 //
2323 // Interpret the effects of the bytecodes on the incoming state
2324 // vector of a basic block.  Push the changed state to succeeding
2325 // basic blocks.
2326 void ciTypeFlow::flow_block(ciTypeFlow::Block* block,
2327                             ciTypeFlow::StateVector* state,
2328                             ciTypeFlow::JsrSet* jsrs) {
2329   if (CITraceTypeFlow) {
2330     tty->print("\n>> ANALYZING BLOCK : ");
2331     tty->cr();
2332     block->print_on(tty);
2333   }
2334   assert(block->has_pre_order(), "pre-order is assigned before 1st flow");
2335 
2336   if (UseNewCode3 && block->delete_dead_addresses()) {
2337     // Trimming addresses changed some locals to bottom so reflow the block
2338     if (block->has_post_order() &&
2339         !block->is_on_work_list()) {
2340       add_to_work_list(block);
2341     }
2342   }
2343 
2344   int start = block->start();
2345   int limit = block->limit();
2346   int control = block->control();
2347   if (control != ciBlock::fall_through_bci) {
2348     limit = control;
2349   }
2350 
2351   // Grab the state from the current block.
2352   block->copy_state_into(state);
2353   state->def_locals()->clear();
2354 
2355   GrowableArray<Block*>*           exceptions = block->exceptions();
2356   GrowableArray<ciInstanceKlass*>* exc_klasses = block->exc_klasses();
2357   bool has_exceptions = exceptions->length() > 0;
2358 
2359   bool exceptions_used = false;
2360 
2361   ciBytecodeStream str(method());
2362   str.reset_to_bci(start);
2363   Bytecodes::Code code;


2889 void ciTypeFlow::do_flow() {
2890   if (CITraceTypeFlow) {
2891     tty->print_cr("\nPerforming flow analysis on method");
2892     method()->print();
2893     if (is_osr_flow())  tty->print(" at OSR bci %d", start_bci());
2894     tty->cr();
2895     method()->print_codes();
2896   }
2897   if (CITraceTypeFlow) {
2898     tty->print_cr("Initial CI Blocks");
2899     print_on(tty);
2900   }
2901   flow_types();
2902   // Watch for bailouts.
2903   if (failing()) {
2904     return;
2905   }
2906 
2907   map_blocks();
2908 
2909   if (UseNewCode) {
2910     tty->print_cr("*** ciTypeFlow blocks = %d", _next_pre_order);
2911   }
2912 
2913   if (CIPrintTypeFlow || CITraceTypeFlow) {
2914     rpo_print_on(tty);
2915   }
2916 }
2917 
2918 // ------------------------------------------------------------------
2919 // ciTypeFlow::record_failure()
2920 // The ciTypeFlow object keeps track of failure reasons separately from the ciEnv.
2921 // This is required because there is not a 1-1 relation between the ciEnv and
2922 // the TypeFlow passes within a compilation task.  For example, if the compiler
2923 // is considering inlining a method, it will request a TypeFlow.  If that fails,
2924 // the compilation as a whole may continue without the inlining.  Some TypeFlow
2925 // requests are not optional; if they fail the requestor is responsible for
2926 // copying the failure reason up to the ciEnv.  (See Parse::Parse.)
2927 void ciTypeFlow::record_failure(const char* reason) {
2928   if (env()->log() != NULL) {
2929     env()->log()->elem("failure reason='%s' phase='typeflow'", reason);
2930   }
2931   if (_failure_reason == NULL) {
2932     // Record the first failure reason.


src/share/vm/ci/ciTypeFlow.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File