--- old/src/share/vm/ci/ciTypeFlow.cpp Fri Aug 28 13:01:20 2009 +++ new/src/share/vm/ci/ciTypeFlow.cpp Fri Aug 28 13:01:20 2009 @@ -213,6 +213,33 @@ } } + +// ------------------------------------------------------------------ +// ciTypeFlow::JsrSet::apply_state +// remove any JsrRecords which refer to address that aren't in state +void ciTypeFlow::JsrSet::apply_state(StateVector* state) { + int len = size(); + for (int i = 0; i < len; i++) { + int ra = record_at(i)->return_address(); + bool found = false; + Cell limit = state->limit_cell(); + for (Cell c = state->start_cell(); c < limit; c = state->next_cell(c)) { + ciType* cell_type = state->type_at(c); + if (cell_type->is_return_address() && cell_type->as_return_address()->bci() == ra) { + found = true; + break; + } + } + if (!found) { + remove_jsr_record(ra); + i--; + len--; + } + } +} + + + #ifndef PRODUCT // ------------------------------------------------------------------ // ciTypeFlow::JsrSet::print_on @@ -1585,6 +1612,41 @@ assert(!outer->have_block_count(), "must not have mapped blocks yet"); } + +bool ciTypeFlow::Block::delete_dead_addresses() { + bool changed = false; + if (_jsrs->size() != 0) { + ciMethod* method = outer()->method(); + MethodLivenessResult live_locals = method->liveness_at_bci(start(), true); + if (live_locals.is_valid()) { + int addresses = 0; + for (int i = 0; i < stack_size(); i++) { + ciType* local = stack_type_at(i); + if (local->is_return_address()) { + addresses++; + } + } + for (int i = 0; i < method->max_locals(); i++) { + ciType* local = local_type_at(i); + if (local->is_return_address()) { + if (!live_locals.at(i)) { + state()->set_type_at(state()->local(i), StateVector::bottom_type()); + changed = true; + } else { + addresses++; + } + } + } + if (addresses != _jsrs->size()) { + // The size of the JsrSet and the number of address in the + // state disagree so trim any unreachable JsrRecords. + _jsrs->apply_state(state()); + } + } + } + return changed; +} + // ------------------------------------------------------------------ // ciTypeFlow::Block::df_init void ciTypeFlow::Block::df_init() { @@ -2271,6 +2333,14 @@ } assert(block->has_pre_order(), "pre-order is assigned before 1st flow"); + if (UseNewCode3 && block->delete_dead_addresses()) { + // Trimming addresses changed some locals to bottom so reflow the block + if (block->has_post_order() && + !block->is_on_work_list()) { + add_to_work_list(block); + } + } + int start = block->start(); int limit = block->limit(); int control = block->control(); @@ -2836,6 +2906,10 @@ map_blocks(); + if (UseNewCode) { + tty->print_cr("*** ciTypeFlow blocks = %d", _next_pre_order); + } + if (CIPrintTypeFlow || CITraceTypeFlow) { rpo_print_on(tty); }