Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/compiler/methodLiveness.cpp
32285 views
/*1* Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "ci/ciMethod.hpp"26#include "ci/ciMethodBlocks.hpp"27#include "ci/ciStreams.hpp"28#include "compiler/methodLiveness.hpp"29#include "interpreter/bytecode.hpp"30#include "interpreter/bytecodes.hpp"31#include "memory/allocation.inline.hpp"32#include "utilities/bitMap.inline.hpp"3334PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC3536// The MethodLiveness class performs a simple liveness analysis on a method37// in order to decide which locals are live (that is, will be used again) at38// a particular bytecode index (bci).39//40// The algorithm goes:41//42// 1. Break the method into a set of basic blocks. For each basic block we43// also keep track of its set of predecessors through normal control flow44// and predecessors through exceptional control flow.45//46// 2. For each basic block, compute two sets, gen (the set of values used before47// they are defined) and kill (the set of values defined before they are used)48// in the basic block. A basic block "needs" the locals in its gen set to49// perform its computation. A basic block "provides" values for the locals in50// its kill set, allowing a need from a successor to be ignored.51//52// 3. Liveness information (the set of locals which are needed) is pushed backwards through53// the program, from blocks to their predecessors. We compute and store liveness54// information for the normal/exceptional exit paths for each basic block. When55// this process reaches a fixed point, we are done.56//57// 4. When we are asked about the liveness at a particular bci with a basic block, we58// compute gen/kill sets which represent execution from that bci to the exit of59// its blocks. We then compose this range gen/kill information with the normal60// and exceptional exit information for the block to produce liveness information61// at that bci.62//63// The algorithm is approximate in many respects. Notably:64//65// 1. We do not do the analysis necessary to match jsr's with the appropriate ret.66// Instead we make the conservative assumption that any ret can return to any67// jsr return site.68// 2. Instead of computing the effects of exceptions at every instruction, we69// summarize the effects of all exceptional continuations from the block as70// a single set (_exception_exit), losing some information but simplifying the71// analysis.727374//--------------------------------------------------------------------------75// The BitCounter class is used for counting the number of bits set in76// some BitMap. It is only used when collecting liveness statistics.7778#ifndef PRODUCT7980class BitCounter: public BitMapClosure {81private:82int _count;83public:84BitCounter() : _count(0) {}8586// Callback when bit in map is set87virtual bool do_bit(size_t offset) {88_count++;89return true;90}9192int count() {93return _count;94}95};969798//--------------------------------------------------------------------------99100101// Counts102long MethodLiveness::_total_bytes = 0;103int MethodLiveness::_total_methods = 0;104105long MethodLiveness::_total_blocks = 0;106int MethodLiveness::_max_method_blocks = 0;107108long MethodLiveness::_total_edges = 0;109int MethodLiveness::_max_block_edges = 0;110111long MethodLiveness::_total_exc_edges = 0;112int MethodLiveness::_max_block_exc_edges = 0;113114long MethodLiveness::_total_method_locals = 0;115int MethodLiveness::_max_method_locals = 0;116117long MethodLiveness::_total_locals_queried = 0;118long MethodLiveness::_total_live_locals_queried = 0;119120long MethodLiveness::_total_visits = 0;121122#endif123124// Timers125elapsedTimer MethodLiveness::_time_build_graph;126elapsedTimer MethodLiveness::_time_gen_kill;127elapsedTimer MethodLiveness::_time_flow;128elapsedTimer MethodLiveness::_time_query;129elapsedTimer MethodLiveness::_time_total;130131MethodLiveness::MethodLiveness(Arena* arena, ciMethod* method)132#ifdef COMPILER1133: _bci_block_start((uintptr_t*)arena->Amalloc((method->code_size() >> LogBitsPerByte) + 1), method->code_size())134#endif135{136_arena = arena;137_method = method;138_bit_map_size_bits = method->max_locals();139_bit_map_size_words = (_bit_map_size_bits / sizeof(unsigned int)) + 1;140141#ifdef COMPILER1142_bci_block_start.clear();143#endif144}145146void MethodLiveness::compute_liveness() {147#ifndef PRODUCT148if (TraceLivenessGen) {149tty->print_cr("################################################################");150tty->print("# Computing liveness information for ");151method()->print_short_name();152}153154if (TimeLivenessAnalysis) _time_total.start();155#endif156157{158TraceTime buildGraph(NULL, &_time_build_graph, TimeLivenessAnalysis);159init_basic_blocks();160}161{162TraceTime genKill(NULL, &_time_gen_kill, TimeLivenessAnalysis);163init_gen_kill();164}165{166TraceTime flow(NULL, &_time_flow, TimeLivenessAnalysis);167propagate_liveness();168}169170#ifndef PRODUCT171if (TimeLivenessAnalysis) _time_total.stop();172173if (TimeLivenessAnalysis) {174// Collect statistics175_total_bytes += method()->code_size();176_total_methods++;177178int num_blocks = _block_count;179_total_blocks += num_blocks;180_max_method_blocks = MAX2(num_blocks,_max_method_blocks);181182for (int i=0; i<num_blocks; i++) {183BasicBlock *block = _block_list[i];184185int numEdges = block->_normal_predecessors->length();186int numExcEdges = block->_exception_predecessors->length();187188_total_edges += numEdges;189_total_exc_edges += numExcEdges;190_max_block_edges = MAX2(numEdges,_max_block_edges);191_max_block_exc_edges = MAX2(numExcEdges,_max_block_exc_edges);192}193194int numLocals = _bit_map_size_bits;195_total_method_locals += numLocals;196_max_method_locals = MAX2(numLocals,_max_method_locals);197}198#endif199}200201202void MethodLiveness::init_basic_blocks() {203bool bailout = false;204205int method_len = method()->code_size();206ciMethodBlocks *mblocks = method()->get_method_blocks();207208// Create an array to store the bci->BasicBlock mapping.209_block_map = new (arena()) GrowableArray<BasicBlock*>(arena(), method_len, method_len, NULL);210211_block_count = mblocks->num_blocks();212_block_list = (BasicBlock **) arena()->Amalloc(sizeof(BasicBlock *) * _block_count);213214// Used for patching up jsr/ret control flow.215GrowableArray<BasicBlock*>* jsr_exit_list = new GrowableArray<BasicBlock*>(5);216GrowableArray<BasicBlock*>* ret_list = new GrowableArray<BasicBlock*>(5);217218// generate our block list from ciMethodBlocks219for (int blk = 0; blk < _block_count; blk++) {220ciBlock *cib = mblocks->block(blk);221int start_bci = cib->start_bci();222_block_list[blk] = new (arena()) BasicBlock(this, start_bci, cib->limit_bci());223_block_map->at_put(start_bci, _block_list[blk]);224#ifdef COMPILER1225// mark all bcis where a new basic block starts226_bci_block_start.set_bit(start_bci);227#endif // COMPILER1228}229// fill in the predecessors of blocks230ciBytecodeStream bytes(method());231232for (int blk = 0; blk < _block_count; blk++) {233BasicBlock *current_block = _block_list[blk];234int bci = mblocks->block(blk)->control_bci();235236if (bci == ciBlock::fall_through_bci) {237int limit = current_block->limit_bci();238if (limit < method_len) {239BasicBlock *next = _block_map->at(limit);240assert( next != NULL, "must be a block immediately following this one.");241next->add_normal_predecessor(current_block);242}243continue;244}245bytes.reset_to_bci(bci);246Bytecodes::Code code = bytes.next();247BasicBlock *dest;248249// Now we need to interpret the instruction's effect250// on control flow.251assert (current_block != NULL, "we must have a current block");252switch (code) {253case Bytecodes::_ifeq:254case Bytecodes::_ifne:255case Bytecodes::_iflt:256case Bytecodes::_ifge:257case Bytecodes::_ifgt:258case Bytecodes::_ifle:259case Bytecodes::_if_icmpeq:260case Bytecodes::_if_icmpne:261case Bytecodes::_if_icmplt:262case Bytecodes::_if_icmpge:263case Bytecodes::_if_icmpgt:264case Bytecodes::_if_icmple:265case Bytecodes::_if_acmpeq:266case Bytecodes::_if_acmpne:267case Bytecodes::_ifnull:268case Bytecodes::_ifnonnull:269// Two way branch. Set predecessors at each destination.270dest = _block_map->at(bytes.next_bci());271assert(dest != NULL, "must be a block immediately following this one.");272dest->add_normal_predecessor(current_block);273274dest = _block_map->at(bytes.get_dest());275assert(dest != NULL, "branch desination must start a block.");276dest->add_normal_predecessor(current_block);277break;278case Bytecodes::_goto:279dest = _block_map->at(bytes.get_dest());280assert(dest != NULL, "branch desination must start a block.");281dest->add_normal_predecessor(current_block);282break;283case Bytecodes::_goto_w:284dest = _block_map->at(bytes.get_far_dest());285assert(dest != NULL, "branch desination must start a block.");286dest->add_normal_predecessor(current_block);287break;288case Bytecodes::_tableswitch:289{290Bytecode_tableswitch tableswitch(&bytes);291292int len = tableswitch.length();293294dest = _block_map->at(bci + tableswitch.default_offset());295assert(dest != NULL, "branch desination must start a block.");296dest->add_normal_predecessor(current_block);297while (--len >= 0) {298dest = _block_map->at(bci + tableswitch.dest_offset_at(len));299assert(dest != NULL, "branch desination must start a block.");300dest->add_normal_predecessor(current_block);301}302break;303}304305case Bytecodes::_lookupswitch:306{307Bytecode_lookupswitch lookupswitch(&bytes);308309int npairs = lookupswitch.number_of_pairs();310311dest = _block_map->at(bci + lookupswitch.default_offset());312assert(dest != NULL, "branch desination must start a block.");313dest->add_normal_predecessor(current_block);314while(--npairs >= 0) {315LookupswitchPair pair = lookupswitch.pair_at(npairs);316dest = _block_map->at( bci + pair.offset());317assert(dest != NULL, "branch desination must start a block.");318dest->add_normal_predecessor(current_block);319}320break;321}322323case Bytecodes::_jsr:324{325assert(bytes.is_wide()==false, "sanity check");326dest = _block_map->at(bytes.get_dest());327assert(dest != NULL, "branch desination must start a block.");328dest->add_normal_predecessor(current_block);329BasicBlock *jsrExit = _block_map->at(current_block->limit_bci());330assert(jsrExit != NULL, "jsr return bci must start a block.");331jsr_exit_list->append(jsrExit);332break;333}334case Bytecodes::_jsr_w:335{336dest = _block_map->at(bytes.get_far_dest());337assert(dest != NULL, "branch desination must start a block.");338dest->add_normal_predecessor(current_block);339BasicBlock *jsrExit = _block_map->at(current_block->limit_bci());340assert(jsrExit != NULL, "jsr return bci must start a block.");341jsr_exit_list->append(jsrExit);342break;343}344345case Bytecodes::_wide:346assert(false, "wide opcodes should not be seen here");347break;348case Bytecodes::_athrow:349case Bytecodes::_ireturn:350case Bytecodes::_lreturn:351case Bytecodes::_freturn:352case Bytecodes::_dreturn:353case Bytecodes::_areturn:354case Bytecodes::_return:355// These opcodes are not the normal predecessors of any other opcodes.356break;357case Bytecodes::_ret:358// We will patch up jsr/rets in a subsequent pass.359ret_list->append(current_block);360break;361case Bytecodes::_breakpoint:362// Bail out of there are breakpoints in here.363bailout = true;364break;365default:366// Do nothing.367break;368}369}370// Patch up the jsr/ret's. We conservatively assume that any ret371// can return to any jsr site.372int ret_list_len = ret_list->length();373int jsr_exit_list_len = jsr_exit_list->length();374if (ret_list_len > 0 && jsr_exit_list_len > 0) {375for (int i = jsr_exit_list_len - 1; i >= 0; i--) {376BasicBlock *jsrExit = jsr_exit_list->at(i);377for (int i = ret_list_len - 1; i >= 0; i--) {378jsrExit->add_normal_predecessor(ret_list->at(i));379}380}381}382383// Compute exception edges.384for (int b=_block_count-1; b >= 0; b--) {385BasicBlock *block = _block_list[b];386int block_start = block->start_bci();387int block_limit = block->limit_bci();388ciExceptionHandlerStream handlers(method());389for (; !handlers.is_done(); handlers.next()) {390ciExceptionHandler* handler = handlers.handler();391int start = handler->start();392int limit = handler->limit();393int handler_bci = handler->handler_bci();394395int intersect_start = MAX2(block_start, start);396int intersect_limit = MIN2(block_limit, limit);397if (intersect_start < intersect_limit) {398// The catch range has a nonempty intersection with this399// basic block. That means this basic block can be an400// exceptional predecessor.401_block_map->at(handler_bci)->add_exception_predecessor(block);402403if (handler->is_catch_all()) {404// This is a catch-all block.405if (intersect_start == block_start && intersect_limit == block_limit) {406// The basic block is entirely contained in this catch-all block.407// Skip the rest of the exception handlers -- they can never be408// reached in execution.409break;410}411}412}413}414}415}416417void MethodLiveness::init_gen_kill() {418for (int i=_block_count-1; i >= 0; i--) {419_block_list[i]->compute_gen_kill(method());420}421}422423void MethodLiveness::propagate_liveness() {424int num_blocks = _block_count;425BasicBlock *block;426427// We start our work list off with all blocks in it.428// Alternately, we could start off the work list with the list of all429// blocks which could exit the method directly, along with one block430// from any infinite loop. If this matters, it can be changed. It431// may not be clear from looking at the code, but the order of the432// workList will be the opposite of the creation order of the basic433// blocks, which should be decent for quick convergence (with the434// possible exception of exception handlers, which are all created435// early).436_work_list = NULL;437for (int i = 0; i < num_blocks; i++) {438block = _block_list[i];439block->set_next(_work_list);440block->set_on_work_list(true);441_work_list = block;442}443444445while ((block = work_list_get()) != NULL) {446block->propagate(this);447NOT_PRODUCT(_total_visits++;)448}449}450451void MethodLiveness::work_list_add(BasicBlock *block) {452if (!block->on_work_list()) {453block->set_next(_work_list);454block->set_on_work_list(true);455_work_list = block;456}457}458459MethodLiveness::BasicBlock *MethodLiveness::work_list_get() {460BasicBlock *block = _work_list;461if (block != NULL) {462block->set_on_work_list(false);463_work_list = block->next();464}465return block;466}467468469MethodLivenessResult MethodLiveness::get_liveness_at(int entry_bci) {470int bci = entry_bci;471bool is_entry = false;472if (entry_bci == InvocationEntryBci) {473is_entry = true;474bci = 0;475}476477MethodLivenessResult answer((BitMap::bm_word_t*)NULL,0);478479if (_block_count > 0) {480if (TimeLivenessAnalysis) _time_total.start();481if (TimeLivenessAnalysis) _time_query.start();482483assert( 0 <= bci && bci < method()->code_size(), "bci out of range" );484BasicBlock *block = _block_map->at(bci);485// We may not be at the block start, so search backwards to find the block486// containing bci.487int t = bci;488while (block == NULL && t > 0) {489block = _block_map->at(--t);490}491assert( block != NULL, "invalid bytecode index; must be instruction index" );492assert(bci >= block->start_bci() && bci < block->limit_bci(), "block must contain bci.");493494answer = block->get_liveness_at(method(), bci);495496if (is_entry && method()->is_synchronized() && !method()->is_static()) {497// Synchronized methods use the receiver once on entry.498answer.at_put(0, true);499}500501#ifndef PRODUCT502if (TraceLivenessQuery) {503tty->print("Liveness query of ");504method()->print_short_name();505tty->print(" @ %d : result is ", bci);506answer.print_on(tty);507}508509if (TimeLivenessAnalysis) _time_query.stop();510if (TimeLivenessAnalysis) _time_total.stop();511#endif512}513514#ifndef PRODUCT515if (TimeLivenessAnalysis) {516// Collect statistics.517_total_locals_queried += _bit_map_size_bits;518BitCounter counter;519answer.iterate(&counter);520_total_live_locals_queried += counter.count();521}522#endif523524return answer;525}526527528#ifndef PRODUCT529530void MethodLiveness::print_times() {531tty->print_cr ("Accumulated liveness analysis times/statistics:");532tty->print_cr ("-----------------------------------------------");533tty->print_cr (" Total : %3.3f sec.", _time_total.seconds());534tty->print_cr (" Build graph : %3.3f sec. (%2.2f%%)", _time_build_graph.seconds(),535_time_build_graph.seconds() * 100 / _time_total.seconds());536tty->print_cr (" Gen / Kill : %3.3f sec. (%2.2f%%)", _time_gen_kill.seconds(),537_time_gen_kill.seconds() * 100 / _time_total.seconds());538tty->print_cr (" Dataflow : %3.3f sec. (%2.2f%%)", _time_flow.seconds(),539_time_flow.seconds() * 100 / _time_total.seconds());540tty->print_cr (" Query : %3.3f sec. (%2.2f%%)", _time_query.seconds(),541_time_query.seconds() * 100 / _time_total.seconds());542tty->print_cr (" #bytes : %8d (%3.0f bytes per sec)",543_total_bytes,544_total_bytes / _time_total.seconds());545tty->print_cr (" #methods : %8d (%3.0f methods per sec)",546_total_methods,547_total_methods / _time_total.seconds());548tty->print_cr (" avg locals : %3.3f max locals : %3d",549(float)_total_method_locals / _total_methods,550_max_method_locals);551tty->print_cr (" avg blocks : %3.3f max blocks : %3d",552(float)_total_blocks / _total_methods,553_max_method_blocks);554tty->print_cr (" avg bytes : %3.3f",555(float)_total_bytes / _total_methods);556tty->print_cr (" #blocks : %8d",557_total_blocks);558tty->print_cr (" avg normal predecessors : %3.3f max normal predecessors : %3d",559(float)_total_edges / _total_blocks,560_max_block_edges);561tty->print_cr (" avg exception predecessors : %3.3f max exception predecessors : %3d",562(float)_total_exc_edges / _total_blocks,563_max_block_exc_edges);564tty->print_cr (" avg visits : %3.3f",565(float)_total_visits / _total_blocks);566tty->print_cr (" #locals queried : %8d #live : %8d %%live : %2.2f%%",567_total_locals_queried,568_total_live_locals_queried,569100.0 * _total_live_locals_queried / _total_locals_queried);570}571572#endif573574575MethodLiveness::BasicBlock::BasicBlock(MethodLiveness *analyzer, int start, int limit) :576_gen((uintptr_t*)analyzer->arena()->Amalloc(BytesPerWord * analyzer->bit_map_size_words()),577analyzer->bit_map_size_bits()),578_kill((uintptr_t*)analyzer->arena()->Amalloc(BytesPerWord * analyzer->bit_map_size_words()),579analyzer->bit_map_size_bits()),580_entry((uintptr_t*)analyzer->arena()->Amalloc(BytesPerWord * analyzer->bit_map_size_words()),581analyzer->bit_map_size_bits()),582_normal_exit((uintptr_t*)analyzer->arena()->Amalloc(BytesPerWord * analyzer->bit_map_size_words()),583analyzer->bit_map_size_bits()),584_exception_exit((uintptr_t*)analyzer->arena()->Amalloc(BytesPerWord * analyzer->bit_map_size_words()),585analyzer->bit_map_size_bits()),586_last_bci(-1) {587_analyzer = analyzer;588_start_bci = start;589_limit_bci = limit;590_normal_predecessors =591new (analyzer->arena()) GrowableArray<MethodLiveness::BasicBlock*>(analyzer->arena(), 5, 0, NULL);592_exception_predecessors =593new (analyzer->arena()) GrowableArray<MethodLiveness::BasicBlock*>(analyzer->arena(), 5, 0, NULL);594_normal_exit.clear();595_exception_exit.clear();596_entry.clear();597598// this initialization is not strictly necessary.599// _gen and _kill are cleared at the beginning of compute_gen_kill_range()600_gen.clear();601_kill.clear();602}603604605606MethodLiveness::BasicBlock *MethodLiveness::BasicBlock::split(int split_bci) {607int start = _start_bci;608int limit = _limit_bci;609610if (TraceLivenessGen) {611tty->print_cr(" ** Splitting block (%d,%d) at %d", start, limit, split_bci);612}613614GrowableArray<BasicBlock*>* save_predecessors = _normal_predecessors;615616assert (start < split_bci && split_bci < limit, "improper split");617618// Make a new block to cover the first half of the range.619BasicBlock *first_half = new (_analyzer->arena()) BasicBlock(_analyzer, start, split_bci);620621// Assign correct values to the second half (this)622_normal_predecessors = first_half->_normal_predecessors;623_start_bci = split_bci;624add_normal_predecessor(first_half);625626// Assign correct predecessors to the new first half627first_half->_normal_predecessors = save_predecessors;628629return first_half;630}631632void MethodLiveness::BasicBlock::compute_gen_kill(ciMethod* method) {633ciBytecodeStream bytes(method);634bytes.reset_to_bci(start_bci());635bytes.set_max_bci(limit_bci());636compute_gen_kill_range(&bytes);637638}639640void MethodLiveness::BasicBlock::compute_gen_kill_range(ciBytecodeStream *bytes) {641_gen.clear();642_kill.clear();643644while (bytes->next() != ciBytecodeStream::EOBC()) {645compute_gen_kill_single(bytes);646}647}648649void MethodLiveness::BasicBlock::compute_gen_kill_single(ciBytecodeStream *instruction) {650int localNum;651652// We prohibit _gen and _kill from having locals in common. If we653// know that one is definitely going to be applied before the other,654// we could save some computation time by relaxing this prohibition.655656switch (instruction->cur_bc()) {657case Bytecodes::_nop:658case Bytecodes::_goto:659case Bytecodes::_goto_w:660case Bytecodes::_aconst_null:661case Bytecodes::_new:662case Bytecodes::_iconst_m1:663case Bytecodes::_iconst_0:664case Bytecodes::_iconst_1:665case Bytecodes::_iconst_2:666case Bytecodes::_iconst_3:667case Bytecodes::_iconst_4:668case Bytecodes::_iconst_5:669case Bytecodes::_fconst_0:670case Bytecodes::_fconst_1:671case Bytecodes::_fconst_2:672case Bytecodes::_bipush:673case Bytecodes::_sipush:674case Bytecodes::_lconst_0:675case Bytecodes::_lconst_1:676case Bytecodes::_dconst_0:677case Bytecodes::_dconst_1:678case Bytecodes::_ldc2_w:679case Bytecodes::_ldc:680case Bytecodes::_ldc_w:681case Bytecodes::_iaload:682case Bytecodes::_faload:683case Bytecodes::_baload:684case Bytecodes::_caload:685case Bytecodes::_saload:686case Bytecodes::_laload:687case Bytecodes::_daload:688case Bytecodes::_aaload:689case Bytecodes::_iastore:690case Bytecodes::_fastore:691case Bytecodes::_bastore:692case Bytecodes::_castore:693case Bytecodes::_sastore:694case Bytecodes::_lastore:695case Bytecodes::_dastore:696case Bytecodes::_aastore:697case Bytecodes::_pop:698case Bytecodes::_pop2:699case Bytecodes::_dup:700case Bytecodes::_dup_x1:701case Bytecodes::_dup_x2:702case Bytecodes::_dup2:703case Bytecodes::_dup2_x1:704case Bytecodes::_dup2_x2:705case Bytecodes::_swap:706case Bytecodes::_iadd:707case Bytecodes::_fadd:708case Bytecodes::_isub:709case Bytecodes::_fsub:710case Bytecodes::_imul:711case Bytecodes::_fmul:712case Bytecodes::_idiv:713case Bytecodes::_fdiv:714case Bytecodes::_irem:715case Bytecodes::_frem:716case Bytecodes::_ishl:717case Bytecodes::_ishr:718case Bytecodes::_iushr:719case Bytecodes::_iand:720case Bytecodes::_ior:721case Bytecodes::_ixor:722case Bytecodes::_l2f:723case Bytecodes::_l2i:724case Bytecodes::_d2f:725case Bytecodes::_d2i:726case Bytecodes::_fcmpl:727case Bytecodes::_fcmpg:728case Bytecodes::_ladd:729case Bytecodes::_dadd:730case Bytecodes::_lsub:731case Bytecodes::_dsub:732case Bytecodes::_lmul:733case Bytecodes::_dmul:734case Bytecodes::_ldiv:735case Bytecodes::_ddiv:736case Bytecodes::_lrem:737case Bytecodes::_drem:738case Bytecodes::_land:739case Bytecodes::_lor:740case Bytecodes::_lxor:741case Bytecodes::_ineg:742case Bytecodes::_fneg:743case Bytecodes::_i2f:744case Bytecodes::_f2i:745case Bytecodes::_i2c:746case Bytecodes::_i2s:747case Bytecodes::_i2b:748case Bytecodes::_lneg:749case Bytecodes::_dneg:750case Bytecodes::_l2d:751case Bytecodes::_d2l:752case Bytecodes::_lshl:753case Bytecodes::_lshr:754case Bytecodes::_lushr:755case Bytecodes::_i2l:756case Bytecodes::_i2d:757case Bytecodes::_f2l:758case Bytecodes::_f2d:759case Bytecodes::_lcmp:760case Bytecodes::_dcmpl:761case Bytecodes::_dcmpg:762case Bytecodes::_ifeq:763case Bytecodes::_ifne:764case Bytecodes::_iflt:765case Bytecodes::_ifge:766case Bytecodes::_ifgt:767case Bytecodes::_ifle:768case Bytecodes::_tableswitch:769case Bytecodes::_ireturn:770case Bytecodes::_freturn:771case Bytecodes::_if_icmpeq:772case Bytecodes::_if_icmpne:773case Bytecodes::_if_icmplt:774case Bytecodes::_if_icmpge:775case Bytecodes::_if_icmpgt:776case Bytecodes::_if_icmple:777case Bytecodes::_lreturn:778case Bytecodes::_dreturn:779case Bytecodes::_if_acmpeq:780case Bytecodes::_if_acmpne:781case Bytecodes::_jsr:782case Bytecodes::_jsr_w:783case Bytecodes::_getstatic:784case Bytecodes::_putstatic:785case Bytecodes::_getfield:786case Bytecodes::_putfield:787case Bytecodes::_invokevirtual:788case Bytecodes::_invokespecial:789case Bytecodes::_invokestatic:790case Bytecodes::_invokeinterface:791case Bytecodes::_invokedynamic:792case Bytecodes::_newarray:793case Bytecodes::_anewarray:794case Bytecodes::_checkcast:795case Bytecodes::_arraylength:796case Bytecodes::_instanceof:797case Bytecodes::_athrow:798case Bytecodes::_areturn:799case Bytecodes::_monitorenter:800case Bytecodes::_monitorexit:801case Bytecodes::_ifnull:802case Bytecodes::_ifnonnull:803case Bytecodes::_multianewarray:804case Bytecodes::_lookupswitch:805// These bytecodes have no effect on the method's locals.806break;807808case Bytecodes::_return:809if (instruction->method()->intrinsic_id() == vmIntrinsics::_Object_init) {810// return from Object.init implicitly registers a finalizer811// for the receiver if needed, so keep it alive.812load_one(0);813}814break;815816817case Bytecodes::_lload:818case Bytecodes::_dload:819load_two(instruction->get_index());820break;821822case Bytecodes::_lload_0:823case Bytecodes::_dload_0:824load_two(0);825break;826827case Bytecodes::_lload_1:828case Bytecodes::_dload_1:829load_two(1);830break;831832case Bytecodes::_lload_2:833case Bytecodes::_dload_2:834load_two(2);835break;836837case Bytecodes::_lload_3:838case Bytecodes::_dload_3:839load_two(3);840break;841842case Bytecodes::_iload:843case Bytecodes::_iinc:844case Bytecodes::_fload:845case Bytecodes::_aload:846case Bytecodes::_ret:847load_one(instruction->get_index());848break;849850case Bytecodes::_iload_0:851case Bytecodes::_fload_0:852case Bytecodes::_aload_0:853load_one(0);854break;855856case Bytecodes::_iload_1:857case Bytecodes::_fload_1:858case Bytecodes::_aload_1:859load_one(1);860break;861862case Bytecodes::_iload_2:863case Bytecodes::_fload_2:864case Bytecodes::_aload_2:865load_one(2);866break;867868case Bytecodes::_iload_3:869case Bytecodes::_fload_3:870case Bytecodes::_aload_3:871load_one(3);872break;873874case Bytecodes::_lstore:875case Bytecodes::_dstore:876store_two(localNum = instruction->get_index());877break;878879case Bytecodes::_lstore_0:880case Bytecodes::_dstore_0:881store_two(0);882break;883884case Bytecodes::_lstore_1:885case Bytecodes::_dstore_1:886store_two(1);887break;888889case Bytecodes::_lstore_2:890case Bytecodes::_dstore_2:891store_two(2);892break;893894case Bytecodes::_lstore_3:895case Bytecodes::_dstore_3:896store_two(3);897break;898899case Bytecodes::_istore:900case Bytecodes::_fstore:901case Bytecodes::_astore:902store_one(instruction->get_index());903break;904905case Bytecodes::_istore_0:906case Bytecodes::_fstore_0:907case Bytecodes::_astore_0:908store_one(0);909break;910911case Bytecodes::_istore_1:912case Bytecodes::_fstore_1:913case Bytecodes::_astore_1:914store_one(1);915break;916917case Bytecodes::_istore_2:918case Bytecodes::_fstore_2:919case Bytecodes::_astore_2:920store_one(2);921break;922923case Bytecodes::_istore_3:924case Bytecodes::_fstore_3:925case Bytecodes::_astore_3:926store_one(3);927break;928929case Bytecodes::_wide:930fatal("Iterator should skip this bytecode");931break;932933default:934tty->print("unexpected opcode: %d\n", instruction->cur_bc());935ShouldNotReachHere();936break;937}938}939940void MethodLiveness::BasicBlock::load_two(int local) {941load_one(local);942load_one(local+1);943}944945void MethodLiveness::BasicBlock::load_one(int local) {946if (!_kill.at(local)) {947_gen.at_put(local, true);948}949}950951void MethodLiveness::BasicBlock::store_two(int local) {952store_one(local);953store_one(local+1);954}955956void MethodLiveness::BasicBlock::store_one(int local) {957if (!_gen.at(local)) {958_kill.at_put(local, true);959}960}961962void MethodLiveness::BasicBlock::propagate(MethodLiveness *ml) {963// These set operations could be combined for efficiency if the964// performance of this analysis becomes an issue.965_entry.set_union(_normal_exit);966_entry.set_difference(_kill);967_entry.set_union(_gen);968969// Note that we merge information from our exceptional successors970// just once, rather than at individual bytecodes.971_entry.set_union(_exception_exit);972973if (TraceLivenessGen) {974tty->print_cr(" ** Visiting block at %d **", start_bci());975print_on(tty);976}977978int i;979for (i=_normal_predecessors->length()-1; i>=0; i--) {980BasicBlock *block = _normal_predecessors->at(i);981if (block->merge_normal(_entry)) {982ml->work_list_add(block);983}984}985for (i=_exception_predecessors->length()-1; i>=0; i--) {986BasicBlock *block = _exception_predecessors->at(i);987if (block->merge_exception(_entry)) {988ml->work_list_add(block);989}990}991}992993bool MethodLiveness::BasicBlock::merge_normal(BitMap other) {994return _normal_exit.set_union_with_result(other);995}996997bool MethodLiveness::BasicBlock::merge_exception(BitMap other) {998return _exception_exit.set_union_with_result(other);999}10001001MethodLivenessResult MethodLiveness::BasicBlock::get_liveness_at(ciMethod* method, int bci) {1002MethodLivenessResult answer(NEW_RESOURCE_ARRAY(BitMap::bm_word_t, _analyzer->bit_map_size_words()),1003_analyzer->bit_map_size_bits());1004answer.set_is_valid();10051006#ifndef ASSERT1007if (bci == start_bci()) {1008answer.set_from(_entry);1009return answer;1010}1011#endif10121013#ifdef ASSERT1014ResourceMark rm;1015BitMap g(_gen.size()); g.set_from(_gen);1016BitMap k(_kill.size()); k.set_from(_kill);1017#endif1018if (_last_bci != bci || trueInDebug) {1019ciBytecodeStream bytes(method);1020bytes.reset_to_bci(bci);1021bytes.set_max_bci(limit_bci());1022compute_gen_kill_range(&bytes);1023assert(_last_bci != bci ||1024(g.is_same(_gen) && k.is_same(_kill)), "cached computation is incorrect");1025_last_bci = bci;1026}10271028answer.clear();1029answer.set_union(_normal_exit);1030answer.set_difference(_kill);1031answer.set_union(_gen);1032answer.set_union(_exception_exit);10331034#ifdef ASSERT1035if (bci == start_bci()) {1036assert(answer.is_same(_entry), "optimized answer must be accurate");1037}1038#endif10391040return answer;1041}10421043#ifndef PRODUCT10441045void MethodLiveness::BasicBlock::print_on(outputStream *os) const {1046os->print_cr("===================================================================");1047os->print_cr(" Block start: %4d, limit: %4d", _start_bci, _limit_bci);1048os->print (" Normal predecessors (%2d) @", _normal_predecessors->length());1049int i;1050for (i=0; i < _normal_predecessors->length(); i++) {1051os->print(" %4d", _normal_predecessors->at(i)->start_bci());1052}1053os->cr();1054os->print (" Exceptional predecessors (%2d) @", _exception_predecessors->length());1055for (i=0; i < _exception_predecessors->length(); i++) {1056os->print(" %4d", _exception_predecessors->at(i)->start_bci());1057}1058os->cr();1059os->print (" Normal Exit : ");1060_normal_exit.print_on(os);1061os->print (" Gen : ");1062_gen.print_on(os);1063os->print (" Kill : ");1064_kill.print_on(os);1065os->print (" Exception Exit: ");1066_exception_exit.print_on(os);1067os->print (" Entry : ");1068_entry.print_on(os);1069}10701071#endif // PRODUCT107210731074