Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/oops/generateOopMap.cpp
32285 views
/*1* Copyright (c) 1997, 2018, 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 "interpreter/bytecodeStream.hpp"26#include "oops/generateOopMap.hpp"27#include "oops/oop.inline.hpp"28#include "oops/symbol.hpp"29#include "runtime/handles.inline.hpp"30#include "runtime/java.hpp"31#include "runtime/os.hpp"32#include "runtime/relocator.hpp"33#include "utilities/bitMap.inline.hpp"34#include "prims/methodHandles.hpp"3536//37//38// Compute stack layouts for each instruction in method.39//40// Problems:41// - What to do about jsr with different types of local vars?42// Need maps that are conditional on jsr path?43// - Jsr and exceptions should be done more efficiently (the retAddr stuff)44//45// Alternative:46// - Could extend verifier to provide this information.47// For: one fewer abstract interpreter to maintain. Against: the verifier48// solves a bigger problem so slower (undesirable to force verification of49// everything?).50//51// Algorithm:52// Partition bytecodes into basic blocks53// For each basic block: store entry state (vars, stack). For instructions54// inside basic blocks we do not store any state (instead we recompute it55// from state produced by previous instruction).56//57// Perform abstract interpretation of bytecodes over this lattice:58//59// _--'#'--_60// / / \ \61// / / \ \62// / | | \63// 'r' 'v' 'p' ' '64// \ | | /65// \ \ / /66// \ \ / /67// -- '@' --68//69// '#' top, result of conflict merge70// 'r' reference type71// 'v' value type72// 'p' pc type for jsr/ret73// ' ' uninitialized; never occurs on operand stack in Java74// '@' bottom/unexecuted; initial state each bytecode.75//76// Basic block headers are the only merge points. We use this iteration to77// compute the information:78//79// find basic blocks;80// initialize them with uninitialized state;81// initialize first BB according to method signature;82// mark first BB changed83// while (some BB is changed) do {84// perform abstract interpration of all bytecodes in BB;85// merge exit state of BB into entry state of all successor BBs,86// noting if any of these change;87// }88//89// One additional complication is necessary. The jsr instruction pushes90// a return PC on the stack (a 'p' type in the abstract interpretation).91// To be able to process "ret" bytecodes, we keep track of these return92// PC's in a 'retAddrs' structure in abstract interpreter context (when93// processing a "ret" bytecodes, it is not sufficient to know that it gets94// an argument of the right type 'p'; we need to know which address it95// returns to).96//97// (Note this comment is borrowed form the original author of the algorithm)9899// ComputeCallStack100//101// Specialization of SignatureIterator - compute the effects of a call102//103class ComputeCallStack : public SignatureIterator {104CellTypeState *_effect;105int _idx;106107void setup();108void set(CellTypeState state) { _effect[_idx++] = state; }109int length() { return _idx; };110111virtual void do_bool () { set(CellTypeState::value); };112virtual void do_char () { set(CellTypeState::value); };113virtual void do_float () { set(CellTypeState::value); };114virtual void do_byte () { set(CellTypeState::value); };115virtual void do_short () { set(CellTypeState::value); };116virtual void do_int () { set(CellTypeState::value); };117virtual void do_void () { set(CellTypeState::bottom);};118virtual void do_object(int begin, int end) { set(CellTypeState::ref); };119virtual void do_array (int begin, int end) { set(CellTypeState::ref); };120121void do_double() { set(CellTypeState::value);122set(CellTypeState::value); }123void do_long () { set(CellTypeState::value);124set(CellTypeState::value); }125126public:127ComputeCallStack(Symbol* signature) : SignatureIterator(signature) {};128129// Compute methods130int compute_for_parameters(bool is_static, CellTypeState *effect) {131_idx = 0;132_effect = effect;133134if (!is_static)135effect[_idx++] = CellTypeState::ref;136137iterate_parameters();138139return length();140};141142int compute_for_returntype(CellTypeState *effect) {143_idx = 0;144_effect = effect;145iterate_returntype();146set(CellTypeState::bottom); // Always terminate with a bottom state, so ppush works147148return length();149}150};151152//=========================================================================================153// ComputeEntryStack154//155// Specialization of SignatureIterator - in order to set up first stack frame156//157class ComputeEntryStack : public SignatureIterator {158CellTypeState *_effect;159int _idx;160161void setup();162void set(CellTypeState state) { _effect[_idx++] = state; }163int length() { return _idx; };164165virtual void do_bool () { set(CellTypeState::value); };166virtual void do_char () { set(CellTypeState::value); };167virtual void do_float () { set(CellTypeState::value); };168virtual void do_byte () { set(CellTypeState::value); };169virtual void do_short () { set(CellTypeState::value); };170virtual void do_int () { set(CellTypeState::value); };171virtual void do_void () { set(CellTypeState::bottom);};172virtual void do_object(int begin, int end) { set(CellTypeState::make_slot_ref(_idx)); }173virtual void do_array (int begin, int end) { set(CellTypeState::make_slot_ref(_idx)); }174175void do_double() { set(CellTypeState::value);176set(CellTypeState::value); }177void do_long () { set(CellTypeState::value);178set(CellTypeState::value); }179180public:181ComputeEntryStack(Symbol* signature) : SignatureIterator(signature) {};182183// Compute methods184int compute_for_parameters(bool is_static, CellTypeState *effect) {185_idx = 0;186_effect = effect;187188if (!is_static)189effect[_idx++] = CellTypeState::make_slot_ref(0);190191iterate_parameters();192193return length();194};195196int compute_for_returntype(CellTypeState *effect) {197_idx = 0;198_effect = effect;199iterate_returntype();200set(CellTypeState::bottom); // Always terminate with a bottom state, so ppush works201202return length();203}204};205206//=====================================================================================207//208// Implementation of RetTable/RetTableEntry209//210// Contains function to itereate through all bytecodes211// and find all return entry points212//213int RetTable::_init_nof_entries = 10;214int RetTableEntry::_init_nof_jsrs = 5;215216void RetTableEntry::add_delta(int bci, int delta) {217if (_target_bci > bci) _target_bci += delta;218219for (int k = 0; k < _jsrs->length(); k++) {220int jsr = _jsrs->at(k);221if (jsr > bci) _jsrs->at_put(k, jsr+delta);222}223}224225void RetTable::compute_ret_table(methodHandle method) {226BytecodeStream i(method);227Bytecodes::Code bytecode;228229while( (bytecode = i.next()) >= 0) {230switch (bytecode) {231case Bytecodes::_jsr:232add_jsr(i.next_bci(), i.dest());233break;234case Bytecodes::_jsr_w:235add_jsr(i.next_bci(), i.dest_w());236break;237}238}239}240241void RetTable::add_jsr(int return_bci, int target_bci) {242RetTableEntry* entry = _first;243244// Scan table for entry245for (;entry && entry->target_bci() != target_bci; entry = entry->next());246247if (!entry) {248// Allocate new entry and put in list249entry = new RetTableEntry(target_bci, _first);250_first = entry;251}252253// Now "entry" is set. Make sure that the entry is initialized254// and has room for the new jsr.255entry->add_jsr(return_bci);256}257258RetTableEntry* RetTable::find_jsrs_for_target(int targBci) {259RetTableEntry *cur = _first;260261while(cur) {262assert(cur->target_bci() != -1, "sanity check");263if (cur->target_bci() == targBci) return cur;264cur = cur->next();265}266ShouldNotReachHere();267return NULL;268}269270// The instruction at bci is changing size by "delta". Update the return map.271void RetTable::update_ret_table(int bci, int delta) {272RetTableEntry *cur = _first;273while(cur) {274cur->add_delta(bci, delta);275cur = cur->next();276}277}278279//280// Celltype state281//282283CellTypeState CellTypeState::bottom = CellTypeState::make_bottom();284CellTypeState CellTypeState::uninit = CellTypeState::make_any(uninit_value);285CellTypeState CellTypeState::ref = CellTypeState::make_any(ref_conflict);286CellTypeState CellTypeState::value = CellTypeState::make_any(val_value);287CellTypeState CellTypeState::refUninit = CellTypeState::make_any(ref_conflict | uninit_value);288CellTypeState CellTypeState::top = CellTypeState::make_top();289CellTypeState CellTypeState::addr = CellTypeState::make_any(addr_conflict);290291// Commonly used constants292static CellTypeState epsilonCTS[1] = { CellTypeState::bottom };293static CellTypeState refCTS = CellTypeState::ref;294static CellTypeState valCTS = CellTypeState::value;295static CellTypeState vCTS[2] = { CellTypeState::value, CellTypeState::bottom };296static CellTypeState rCTS[2] = { CellTypeState::ref, CellTypeState::bottom };297static CellTypeState rrCTS[3] = { CellTypeState::ref, CellTypeState::ref, CellTypeState::bottom };298static CellTypeState vrCTS[3] = { CellTypeState::value, CellTypeState::ref, CellTypeState::bottom };299static CellTypeState vvCTS[3] = { CellTypeState::value, CellTypeState::value, CellTypeState::bottom };300static CellTypeState rvrCTS[4] = { CellTypeState::ref, CellTypeState::value, CellTypeState::ref, CellTypeState::bottom };301static CellTypeState vvrCTS[4] = { CellTypeState::value, CellTypeState::value, CellTypeState::ref, CellTypeState::bottom };302static CellTypeState vvvCTS[4] = { CellTypeState::value, CellTypeState::value, CellTypeState::value, CellTypeState::bottom };303static CellTypeState vvvrCTS[5] = { CellTypeState::value, CellTypeState::value, CellTypeState::value, CellTypeState::ref, CellTypeState::bottom };304static CellTypeState vvvvCTS[5] = { CellTypeState::value, CellTypeState::value, CellTypeState::value, CellTypeState::value, CellTypeState::bottom };305306char CellTypeState::to_char() const {307if (can_be_reference()) {308if (can_be_value() || can_be_address())309return '#'; // Conflict that needs to be rewritten310else311return 'r';312} else if (can_be_value())313return 'v';314else if (can_be_address())315return 'p';316else if (can_be_uninit())317return ' ';318else319return '@';320}321322323// Print a detailed CellTypeState. Indicate all bits that are set. If324// the CellTypeState represents an address or a reference, print the325// value of the additional information.326void CellTypeState::print(outputStream *os) {327if (can_be_address()) {328os->print("(p");329} else {330os->print("( ");331}332if (can_be_reference()) {333os->print("r");334} else {335os->print(" ");336}337if (can_be_value()) {338os->print("v");339} else {340os->print(" ");341}342if (can_be_uninit()) {343os->print("u|");344} else {345os->print(" |");346}347if (is_info_top()) {348os->print("Top)");349} else if (is_info_bottom()) {350os->print("Bot)");351} else {352if (is_reference()) {353int info = get_info();354int data = info & ~(ref_not_lock_bit | ref_slot_bit);355if (info & ref_not_lock_bit) {356// Not a monitor lock reference.357if (info & ref_slot_bit) {358// slot359os->print("slot%d)", data);360} else {361// line362os->print("line%d)", data);363}364} else {365// lock366os->print("lock%d)", data);367}368} else {369os->print("%d)", get_info());370}371}372}373374//375// Basicblock handling methods376//377378void GenerateOopMap ::initialize_bb() {379_gc_points = 0;380_bb_count = 0;381_bb_hdr_bits.clear();382_bb_hdr_bits.resize(method()->code_size());383}384385void GenerateOopMap::bb_mark_fct(GenerateOopMap *c, int bci, int *data) {386assert(bci>= 0 && bci < c->method()->code_size(), "index out of bounds");387if (c->is_bb_header(bci))388return;389390if (TraceNewOopMapGeneration) {391tty->print_cr("Basicblock#%d begins at: %d", c->_bb_count, bci);392}393c->set_bbmark_bit(bci);394c->_bb_count++;395}396397398void GenerateOopMap::mark_bbheaders_and_count_gc_points() {399initialize_bb();400401bool fellThrough = false; // False to get first BB marked.402403// First mark all exception handlers as start of a basic-block404ExceptionTable excps(method());405for(int i = 0; i < excps.length(); i ++) {406bb_mark_fct(this, excps.handler_pc(i), NULL);407}408409// Then iterate through the code410BytecodeStream bcs(_method);411Bytecodes::Code bytecode;412413while( (bytecode = bcs.next()) >= 0) {414int bci = bcs.bci();415416if (!fellThrough)417bb_mark_fct(this, bci, NULL);418419fellThrough = jump_targets_do(&bcs, &GenerateOopMap::bb_mark_fct, NULL);420421/* We will also mark successors of jsr's as basic block headers. */422switch (bytecode) {423case Bytecodes::_jsr:424assert(!fellThrough, "should not happen");425bb_mark_fct(this, bci + Bytecodes::length_for(bytecode), NULL);426break;427case Bytecodes::_jsr_w:428assert(!fellThrough, "should not happen");429bb_mark_fct(this, bci + Bytecodes::length_for(bytecode), NULL);430break;431}432433if (possible_gc_point(&bcs))434_gc_points++;435}436}437438void GenerateOopMap::reachable_basicblock(GenerateOopMap *c, int bci, int *data) {439assert(bci>= 0 && bci < c->method()->code_size(), "index out of bounds");440BasicBlock* bb = c->get_basic_block_at(bci);441if (bb->is_dead()) {442bb->mark_as_alive();443*data = 1; // Mark basicblock as changed444}445}446447448void GenerateOopMap::mark_reachable_code() {449int change = 1; // int to get function pointers to work450451// Mark entry basic block as alive and all exception handlers452_basic_blocks[0].mark_as_alive();453ExceptionTable excps(method());454for(int i = 0; i < excps.length(); i++) {455BasicBlock *bb = get_basic_block_at(excps.handler_pc(i));456// If block is not already alive (due to multiple exception handlers to same bb), then457// make it alive458if (bb->is_dead()) bb->mark_as_alive();459}460461BytecodeStream bcs(_method);462463// Iterate through all basic blocks until we reach a fixpoint464while (change) {465change = 0;466467for (int i = 0; i < _bb_count; i++) {468BasicBlock *bb = &_basic_blocks[i];469if (bb->is_alive()) {470// Position bytecodestream at last bytecode in basicblock471bcs.set_start(bb->_end_bci);472bcs.next();473Bytecodes::Code bytecode = bcs.code();474int bci = bcs.bci();475assert(bci == bb->_end_bci, "wrong bci");476477bool fell_through = jump_targets_do(&bcs, &GenerateOopMap::reachable_basicblock, &change);478479// We will also mark successors of jsr's as alive.480switch (bytecode) {481case Bytecodes::_jsr:482case Bytecodes::_jsr_w:483assert(!fell_through, "should not happen");484reachable_basicblock(this, bci + Bytecodes::length_for(bytecode), &change);485break;486}487if (fell_through) {488// Mark successor as alive489if (bb[1].is_dead()) {490bb[1].mark_as_alive();491change = 1;492}493}494}495}496}497}498499/* If the current instruction in "c" has no effect on control flow,500returns "true". Otherwise, calls "jmpFct" one or more times, with501"c", an appropriate "pcDelta", and "data" as arguments, then502returns "false". There is one exception: if the current503instruction is a "ret", returns "false" without calling "jmpFct".504Arrangements for tracking the control flow of a "ret" must be made505externally. */506bool GenerateOopMap::jump_targets_do(BytecodeStream *bcs, jmpFct_t jmpFct, int *data) {507int bci = bcs->bci();508509switch (bcs->code()) {510case Bytecodes::_ifeq:511case Bytecodes::_ifne:512case Bytecodes::_iflt:513case Bytecodes::_ifge:514case Bytecodes::_ifgt:515case Bytecodes::_ifle:516case Bytecodes::_if_icmpeq:517case Bytecodes::_if_icmpne:518case Bytecodes::_if_icmplt:519case Bytecodes::_if_icmpge:520case Bytecodes::_if_icmpgt:521case Bytecodes::_if_icmple:522case Bytecodes::_if_acmpeq:523case Bytecodes::_if_acmpne:524case Bytecodes::_ifnull:525case Bytecodes::_ifnonnull:526(*jmpFct)(this, bcs->dest(), data);527(*jmpFct)(this, bci + 3, data);528break;529530case Bytecodes::_goto:531(*jmpFct)(this, bcs->dest(), data);532break;533case Bytecodes::_goto_w:534(*jmpFct)(this, bcs->dest_w(), data);535break;536case Bytecodes::_tableswitch:537{ Bytecode_tableswitch tableswitch(method(), bcs->bcp());538int len = tableswitch.length();539540(*jmpFct)(this, bci + tableswitch.default_offset(), data); /* Default. jump address */541while (--len >= 0) {542(*jmpFct)(this, bci + tableswitch.dest_offset_at(len), data);543}544break;545}546547case Bytecodes::_lookupswitch:548{ Bytecode_lookupswitch lookupswitch(method(), bcs->bcp());549int npairs = lookupswitch.number_of_pairs();550(*jmpFct)(this, bci + lookupswitch.default_offset(), data); /* Default. */551while(--npairs >= 0) {552LookupswitchPair pair = lookupswitch.pair_at(npairs);553(*jmpFct)(this, bci + pair.offset(), data);554}555break;556}557case Bytecodes::_jsr:558assert(bcs->is_wide()==false, "sanity check");559(*jmpFct)(this, bcs->dest(), data);560561562563break;564case Bytecodes::_jsr_w:565(*jmpFct)(this, bcs->dest_w(), data);566break;567case Bytecodes::_wide:568ShouldNotReachHere();569return true;570break;571case Bytecodes::_athrow:572case Bytecodes::_ireturn:573case Bytecodes::_lreturn:574case Bytecodes::_freturn:575case Bytecodes::_dreturn:576case Bytecodes::_areturn:577case Bytecodes::_return:578case Bytecodes::_ret:579break;580default:581return true;582}583return false;584}585586/* Requires "pc" to be the head of a basic block; returns that basic587block. */588BasicBlock *GenerateOopMap::get_basic_block_at(int bci) const {589BasicBlock* bb = get_basic_block_containing(bci);590assert(bb->_bci == bci, "should have found BB");591return bb;592}593594// Requires "pc" to be the start of an instruction; returns the basic595// block containing that instruction. */596BasicBlock *GenerateOopMap::get_basic_block_containing(int bci) const {597BasicBlock *bbs = _basic_blocks;598int lo = 0, hi = _bb_count - 1;599600while (lo <= hi) {601int m = (lo + hi) / 2;602int mbci = bbs[m]._bci;603int nbci;604605if ( m == _bb_count-1) {606assert( bci >= mbci && bci < method()->code_size(), "sanity check failed");607return bbs+m;608} else {609nbci = bbs[m+1]._bci;610}611612if ( mbci <= bci && bci < nbci) {613return bbs+m;614} else if (mbci < bci) {615lo = m + 1;616} else {617assert(mbci > bci, "sanity check");618hi = m - 1;619}620}621622fatal("should have found BB");623return NULL;624}625626void GenerateOopMap::restore_state(BasicBlock *bb)627{628memcpy(_state, bb->_state, _state_len*sizeof(CellTypeState));629_stack_top = bb->_stack_top;630_monitor_top = bb->_monitor_top;631}632633int GenerateOopMap::next_bb_start_pc(BasicBlock *bb) {634int bbNum = bb - _basic_blocks + 1;635if (bbNum == _bb_count)636return method()->code_size();637638return _basic_blocks[bbNum]._bci;639}640641//642// CellType handling methods643//644645// Allocate memory and throw LinkageError if failure.646#define ALLOC_RESOURCE_ARRAY(var, type, count) \647var = NEW_RESOURCE_ARRAY_RETURN_NULL(type, count); \648if (var == NULL) { \649report_error("Cannot reserve enough memory to analyze this method"); \650return; \651}652653654void GenerateOopMap::init_state() {655_state_len = _max_locals + _max_stack + _max_monitors;656ALLOC_RESOURCE_ARRAY(_state, CellTypeState, _state_len);657memset(_state, 0, _state_len * sizeof(CellTypeState));658int count = MAX3(_max_locals, _max_stack, _max_monitors) + 1/*for null terminator char */;659ALLOC_RESOURCE_ARRAY(_state_vec_buf, char, count);660}661662void GenerateOopMap::make_context_uninitialized() {663CellTypeState* vs = vars();664665for (int i = 0; i < _max_locals; i++)666vs[i] = CellTypeState::uninit;667668_stack_top = 0;669_monitor_top = 0;670}671672int GenerateOopMap::methodsig_to_effect(Symbol* signature, bool is_static, CellTypeState* effect) {673ComputeEntryStack ces(signature);674return ces.compute_for_parameters(is_static, effect);675}676677// Return result of merging cts1 and cts2.678CellTypeState CellTypeState::merge(CellTypeState cts, int slot) const {679CellTypeState result;680681assert(!is_bottom() && !cts.is_bottom(),682"merge of bottom values is handled elsewhere");683684result._state = _state | cts._state;685686// If the top bit is set, we don't need to do any more work.687if (!result.is_info_top()) {688assert((result.can_be_address() || result.can_be_reference()),689"only addresses and references have non-top info");690691if (!equal(cts)) {692// The two values being merged are different. Raise to top.693if (result.is_reference()) {694result = CellTypeState::make_slot_ref(slot);695} else {696result._state |= info_conflict;697}698}699}700assert(result.is_valid_state(), "checking that CTS merge maintains legal state");701702return result;703}704705// Merge the variable state for locals and stack from cts into bbts.706bool GenerateOopMap::merge_local_state_vectors(CellTypeState* cts,707CellTypeState* bbts) {708int i;709int len = _max_locals + _stack_top;710bool change = false;711712for (i = len - 1; i >= 0; i--) {713CellTypeState v = cts[i].merge(bbts[i], i);714change = change || !v.equal(bbts[i]);715bbts[i] = v;716}717718return change;719}720721// Merge the monitor stack state from cts into bbts.722bool GenerateOopMap::merge_monitor_state_vectors(CellTypeState* cts,723CellTypeState* bbts) {724bool change = false;725if (_max_monitors > 0 && _monitor_top != bad_monitors) {726// If there are no monitors in the program, or there has been727// a monitor matching error before this point in the program,728// then we do not merge in the monitor state.729730int base = _max_locals + _max_stack;731int len = base + _monitor_top;732for (int i = len - 1; i >= base; i--) {733CellTypeState v = cts[i].merge(bbts[i], i);734735// Can we prove that, when there has been a change, it will already736// have been detected at this point? That would make this equal737// check here unnecessary.738change = change || !v.equal(bbts[i]);739bbts[i] = v;740}741}742743return change;744}745746void GenerateOopMap::copy_state(CellTypeState *dst, CellTypeState *src) {747int len = _max_locals + _stack_top;748for (int i = 0; i < len; i++) {749if (src[i].is_nonlock_reference()) {750dst[i] = CellTypeState::make_slot_ref(i);751} else {752dst[i] = src[i];753}754}755if (_max_monitors > 0 && _monitor_top != bad_monitors) {756int base = _max_locals + _max_stack;757len = base + _monitor_top;758for (int i = base; i < len; i++) {759dst[i] = src[i];760}761}762}763764765// Merge the states for the current block and the next. As long as a766// block is reachable the locals and stack must be merged. If the767// stack heights don't match then this is a verification error and768// it's impossible to interpret the code. Simultaneously monitor769// states are being check to see if they nest statically. If monitor770// depths match up then their states are merged. Otherwise the771// mismatch is simply recorded and interpretation continues since772// monitor matching is purely informational and doesn't say anything773// about the correctness of the code.774void GenerateOopMap::merge_state_into_bb(BasicBlock *bb) {775guarantee(bb != NULL, "null basicblock");776assert(bb->is_alive(), "merging state into a dead basicblock");777778if (_stack_top == bb->_stack_top) {779// always merge local state even if monitors don't match.780if (merge_local_state_vectors(_state, bb->_state)) {781bb->set_changed(true);782}783if (_monitor_top == bb->_monitor_top) {784// monitors still match so continue merging monitor states.785if (merge_monitor_state_vectors(_state, bb->_state)) {786bb->set_changed(true);787}788} else {789if (TraceMonitorMismatch) {790report_monitor_mismatch("monitor stack height merge conflict");791}792// When the monitor stacks are not matched, we set _monitor_top to793// bad_monitors. This signals that, from here on, the monitor stack cannot794// be trusted. In particular, monitorexit bytecodes may throw795// exceptions. We mark this block as changed so that the change796// propagates properly.797bb->_monitor_top = bad_monitors;798bb->set_changed(true);799_monitor_safe = false;800}801} else if (!bb->is_reachable()) {802// First time we look at this BB803copy_state(bb->_state, _state);804bb->_stack_top = _stack_top;805bb->_monitor_top = _monitor_top;806bb->set_changed(true);807} else {808verify_error("stack height conflict: %d vs. %d", _stack_top, bb->_stack_top);809}810}811812void GenerateOopMap::merge_state(GenerateOopMap *gom, int bci, int* data) {813gom->merge_state_into_bb(gom->get_basic_block_at(bci));814}815816void GenerateOopMap::set_var(int localNo, CellTypeState cts) {817assert(cts.is_reference() || cts.is_value() || cts.is_address(),818"wrong celltypestate");819if (localNo < 0 || localNo > _max_locals) {820verify_error("variable write error: r%d", localNo);821return;822}823vars()[localNo] = cts;824}825826CellTypeState GenerateOopMap::get_var(int localNo) {827assert(localNo < _max_locals + _nof_refval_conflicts, "variable read error");828if (localNo < 0 || localNo > _max_locals) {829verify_error("variable read error: r%d", localNo);830return valCTS; // just to pick something;831}832return vars()[localNo];833}834835CellTypeState GenerateOopMap::pop() {836if ( _stack_top <= 0) {837verify_error("stack underflow");838return valCTS; // just to pick something839}840return stack()[--_stack_top];841}842843void GenerateOopMap::push(CellTypeState cts) {844if ( _stack_top >= _max_stack) {845verify_error("stack overflow");846return;847}848stack()[_stack_top++] = cts;849}850851CellTypeState GenerateOopMap::monitor_pop() {852assert(_monitor_top != bad_monitors, "monitor_pop called on error monitor stack");853if (_monitor_top == 0) {854// We have detected a pop of an empty monitor stack.855_monitor_safe = false;856_monitor_top = bad_monitors;857858if (TraceMonitorMismatch) {859report_monitor_mismatch("monitor stack underflow");860}861return CellTypeState::ref; // just to keep the analysis going.862}863return monitors()[--_monitor_top];864}865866void GenerateOopMap::monitor_push(CellTypeState cts) {867assert(_monitor_top != bad_monitors, "monitor_push called on error monitor stack");868if (_monitor_top >= _max_monitors) {869// Some monitorenter is being executed more than once.870// This means that the monitor stack cannot be simulated.871_monitor_safe = false;872_monitor_top = bad_monitors;873874if (TraceMonitorMismatch) {875report_monitor_mismatch("monitor stack overflow");876}877return;878}879monitors()[_monitor_top++] = cts;880}881882//883// Interpretation handling methods884//885886void GenerateOopMap::do_interpretation()887{888// "i" is just for debugging, so we can detect cases where this loop is889// iterated more than once.890int i = 0;891do {892#ifndef PRODUCT893if (TraceNewOopMapGeneration) {894tty->print("\n\nIteration #%d of do_interpretation loop, method:\n", i);895method()->print_name(tty);896tty->print("\n\n");897}898#endif899_conflict = false;900_monitor_safe = true;901// init_state is now called from init_basic_blocks. The length of a902// state vector cannot be determined until we have made a pass through903// the bytecodes counting the possible monitor entries.904if (!_got_error) init_basic_blocks();905if (!_got_error) setup_method_entry_state();906if (!_got_error) interp_all();907if (!_got_error) rewrite_refval_conflicts();908i++;909} while (_conflict && !_got_error);910}911912void GenerateOopMap::init_basic_blocks() {913// Note: Could consider reserving only the needed space for each BB's state914// (entry stack may not be of maximal height for every basic block).915// But cumbersome since we don't know the stack heights yet. (Nor the916// monitor stack heights...)917918ALLOC_RESOURCE_ARRAY(_basic_blocks, BasicBlock, _bb_count);919920// Make a pass through the bytecodes. Count the number of monitorenters.921// This can be used an upper bound on the monitor stack depth in programs922// which obey stack discipline with their monitor usage. Initialize the923// known information about basic blocks.924BytecodeStream j(_method);925Bytecodes::Code bytecode;926927int bbNo = 0;928int monitor_count = 0;929int prev_bci = -1;930while( (bytecode = j.next()) >= 0) {931if (j.code() == Bytecodes::_monitorenter) {932monitor_count++;933}934935int bci = j.bci();936if (is_bb_header(bci)) {937// Initialize the basicblock structure938BasicBlock *bb = _basic_blocks + bbNo;939bb->_bci = bci;940bb->_max_locals = _max_locals;941bb->_max_stack = _max_stack;942bb->set_changed(false);943bb->_stack_top = BasicBlock::_dead_basic_block; // Initialize all basicblocks are dead.944bb->_monitor_top = bad_monitors;945946if (bbNo > 0) {947_basic_blocks[bbNo - 1]._end_bci = prev_bci;948}949950bbNo++;951}952// Remember prevous bci.953prev_bci = bci;954}955// Set956_basic_blocks[bbNo-1]._end_bci = prev_bci;957958959// Check that the correct number of basicblocks was found960if (bbNo !=_bb_count) {961if (bbNo < _bb_count) {962verify_error("jump into the middle of instruction?");963return;964} else {965verify_error("extra basic blocks - should not happen?");966return;967}968}969970_max_monitors = monitor_count;971972// Now that we have a bound on the depth of the monitor stack, we can973// initialize the CellTypeState-related information.974init_state();975976// We allocate space for all state-vectors for all basicblocks in one huge977// chunk. Then in the next part of the code, we set a pointer in each978// _basic_block that points to each piece.979980// The product of bbNo and _state_len can get large if there are lots of981// basic blocks and stack/locals/monitors. Need to check to make sure982// we don't overflow the capacity of a pointer.983if ((unsigned)bbNo > UINTPTR_MAX / sizeof(CellTypeState) / _state_len) {984report_error("The amount of memory required to analyze this method "985"exceeds addressable range");986return;987}988989CellTypeState *basicBlockState;990ALLOC_RESOURCE_ARRAY(basicBlockState, CellTypeState, bbNo * _state_len);991memset(basicBlockState, 0, bbNo * _state_len * sizeof(CellTypeState));992993// Make a pass over the basicblocks and assign their state vectors.994for (int blockNum=0; blockNum < bbNo; blockNum++) {995BasicBlock *bb = _basic_blocks + blockNum;996bb->_state = basicBlockState + blockNum * _state_len;997998#ifdef ASSERT999if (blockNum + 1 < bbNo) {1000address bcp = _method->bcp_from(bb->_end_bci);1001int bc_len = Bytecodes::java_length_at(_method(), bcp);1002assert(bb->_end_bci + bc_len == bb[1]._bci, "unmatched bci info in basicblock");1003}1004#endif1005}1006#ifdef ASSERT1007{ BasicBlock *bb = &_basic_blocks[bbNo-1];1008address bcp = _method->bcp_from(bb->_end_bci);1009int bc_len = Bytecodes::java_length_at(_method(), bcp);1010assert(bb->_end_bci + bc_len == _method->code_size(), "wrong end bci");1011}1012#endif10131014// Mark all alive blocks1015mark_reachable_code();1016}10171018void GenerateOopMap::setup_method_entry_state() {10191020// Initialize all locals to 'uninit' and set stack-height to 01021make_context_uninitialized();10221023// Initialize CellState type of arguments1024methodsig_to_effect(method()->signature(), method()->is_static(), vars());10251026// If some references must be pre-assigned to null, then set that up1027initialize_vars();10281029// This is the start state1030merge_state_into_bb(&_basic_blocks[0]);10311032assert(_basic_blocks[0].changed(), "we are not getting off the ground");1033}10341035// The instruction at bci is changing size by "delta". Update the basic blocks.1036void GenerateOopMap::update_basic_blocks(int bci, int delta,1037int new_method_size) {1038assert(new_method_size >= method()->code_size() + delta,1039"new method size is too small");10401041BitMap::bm_word_t* new_bb_hdr_bits =1042NEW_RESOURCE_ARRAY(BitMap::bm_word_t,1043BitMap::word_align_up(new_method_size));1044_bb_hdr_bits.set_map(new_bb_hdr_bits);1045_bb_hdr_bits.set_size(new_method_size);1046_bb_hdr_bits.clear();104710481049for(int k = 0; k < _bb_count; k++) {1050if (_basic_blocks[k]._bci > bci) {1051_basic_blocks[k]._bci += delta;1052_basic_blocks[k]._end_bci += delta;1053}1054_bb_hdr_bits.at_put(_basic_blocks[k]._bci, true);1055}1056}10571058//1059// Initvars handling1060//10611062void GenerateOopMap::initialize_vars() {1063for (int k = 0; k < _init_vars->length(); k++)1064_state[_init_vars->at(k)] = CellTypeState::make_slot_ref(k);1065}10661067void GenerateOopMap::add_to_ref_init_set(int localNo) {10681069if (TraceNewOopMapGeneration)1070tty->print_cr("Added init vars: %d", localNo);10711072// Is it already in the set?1073if (_init_vars->contains(localNo) )1074return;10751076_init_vars->append(localNo);1077}10781079//1080// Interpreration code1081//10821083void GenerateOopMap::interp_all() {1084bool change = true;10851086while (change && !_got_error) {1087change = false;1088for (int i = 0; i < _bb_count && !_got_error; i++) {1089BasicBlock *bb = &_basic_blocks[i];1090if (bb->changed()) {1091if (_got_error) return;1092change = true;1093bb->set_changed(false);1094interp_bb(bb);1095}1096}1097}1098}10991100void GenerateOopMap::interp_bb(BasicBlock *bb) {11011102// We do not want to do anything in case the basic-block has not been initialized. This1103// will happen in the case where there is dead-code hang around in a method.1104assert(bb->is_reachable(), "should be reachable or deadcode exist");1105restore_state(bb);11061107BytecodeStream itr(_method);11081109// Set iterator interval to be the current basicblock1110int lim_bci = next_bb_start_pc(bb);1111itr.set_interval(bb->_bci, lim_bci);1112assert(lim_bci != bb->_bci, "must be at least one instruction in a basicblock");1113itr.next(); // read first instruction11141115// Iterates through all bytecodes except the last in a basic block.1116// We handle the last one special, since there is controlflow change.1117while(itr.next_bci() < lim_bci && !_got_error) {1118if (_has_exceptions || _monitor_top != 0) {1119// We do not need to interpret the results of exceptional1120// continuation from this instruction when the method has no1121// exception handlers and the monitor stack is currently1122// empty.1123do_exception_edge(&itr);1124}1125interp1(&itr);1126itr.next();1127}11281129// Handle last instruction.1130if (!_got_error) {1131assert(itr.next_bci() == lim_bci, "must point to end");1132if (_has_exceptions || _monitor_top != 0) {1133do_exception_edge(&itr);1134}1135interp1(&itr);11361137bool fall_through = jump_targets_do(&itr, GenerateOopMap::merge_state, NULL);1138if (_got_error) return;11391140if (itr.code() == Bytecodes::_ret) {1141assert(!fall_through, "cannot be set if ret instruction");1142// Automatically handles 'wide' ret indicies1143ret_jump_targets_do(&itr, GenerateOopMap::merge_state, itr.get_index(), NULL);1144} else if (fall_through) {1145// Hit end of BB, but the instr. was a fall-through instruction,1146// so perform transition as if the BB ended in a "jump".1147if (lim_bci != bb[1]._bci) {1148verify_error("bytecodes fell through last instruction");1149return;1150}1151merge_state_into_bb(bb + 1);1152}1153}1154}11551156void GenerateOopMap::do_exception_edge(BytecodeStream* itr) {1157// Only check exception edge, if bytecode can trap1158if (!Bytecodes::can_trap(itr->code())) return;1159switch (itr->code()) {1160case Bytecodes::_aload_0:1161// These bytecodes can trap for rewriting. We need to assume that1162// they do not throw exceptions to make the monitor analysis work.1163return;11641165case Bytecodes::_ireturn:1166case Bytecodes::_lreturn:1167case Bytecodes::_freturn:1168case Bytecodes::_dreturn:1169case Bytecodes::_areturn:1170case Bytecodes::_return:1171// If the monitor stack height is not zero when we leave the method,1172// then we are either exiting with a non-empty stack or we have1173// found monitor trouble earlier in our analysis. In either case,1174// assume an exception could be taken here.1175if (_monitor_top == 0) {1176return;1177}1178break;11791180case Bytecodes::_monitorexit:1181// If the monitor stack height is bad_monitors, then we have detected a1182// monitor matching problem earlier in the analysis. If the1183// monitor stack height is 0, we are about to pop a monitor1184// off of an empty stack. In either case, the bytecode1185// could throw an exception.1186if (_monitor_top != bad_monitors && _monitor_top != 0) {1187return;1188}1189break;1190}11911192if (_has_exceptions) {1193int bci = itr->bci();1194ExceptionTable exct(method());1195for(int i = 0; i< exct.length(); i++) {1196int start_pc = exct.start_pc(i);1197int end_pc = exct.end_pc(i);1198int handler_pc = exct.handler_pc(i);1199int catch_type = exct.catch_type_index(i);12001201if (start_pc <= bci && bci < end_pc) {1202BasicBlock *excBB = get_basic_block_at(handler_pc);1203guarantee(excBB != NULL, "no basic block for exception");1204CellTypeState *excStk = excBB->stack();1205CellTypeState *cOpStck = stack();1206CellTypeState cOpStck_0 = cOpStck[0];1207int cOpStackTop = _stack_top;12081209// Exception stacks are always the same.1210assert(method()->max_stack() > 0, "sanity check");12111212// We remembered the size and first element of "cOpStck"1213// above; now we temporarily set them to the appropriate1214// values for an exception handler. */1215cOpStck[0] = CellTypeState::make_slot_ref(_max_locals);1216_stack_top = 1;12171218merge_state_into_bb(excBB);12191220// Now undo the temporary change.1221cOpStck[0] = cOpStck_0;1222_stack_top = cOpStackTop;12231224// If this is a "catch all" handler, then we do not need to1225// consider any additional handlers.1226if (catch_type == 0) {1227return;1228}1229}1230}1231}12321233// It is possible that none of the exception handlers would have caught1234// the exception. In this case, we will exit the method. We must1235// ensure that the monitor stack is empty in this case.1236if (_monitor_top == 0) {1237return;1238}12391240// We pessimistically assume that this exception can escape the1241// method. (It is possible that it will always be caught, but1242// we don't care to analyse the types of the catch clauses.)12431244// We don't set _monitor_top to bad_monitors because there are no successors1245// to this exceptional exit.12461247if (TraceMonitorMismatch && _monitor_safe) {1248// We check _monitor_safe so that we only report the first mismatched1249// exceptional exit.1250report_monitor_mismatch("non-empty monitor stack at exceptional exit");1251}1252_monitor_safe = false;12531254}12551256void GenerateOopMap::report_monitor_mismatch(const char *msg) {1257#ifndef PRODUCT1258tty->print(" Monitor mismatch in method ");1259method()->print_short_name(tty);1260tty->print_cr(": %s", msg);1261#endif1262}12631264void GenerateOopMap::print_states(outputStream *os,1265CellTypeState* vec, int num) {1266for (int i = 0; i < num; i++) {1267vec[i].print(tty);1268}1269}12701271// Print the state values at the current bytecode.1272void GenerateOopMap::print_current_state(outputStream *os,1273BytecodeStream *currentBC,1274bool detailed) {12751276if (detailed) {1277os->print(" %4d vars = ", currentBC->bci());1278print_states(os, vars(), _max_locals);1279os->print(" %s", Bytecodes::name(currentBC->code()));1280switch(currentBC->code()) {1281case Bytecodes::_invokevirtual:1282case Bytecodes::_invokespecial:1283case Bytecodes::_invokestatic:1284case Bytecodes::_invokedynamic:1285case Bytecodes::_invokeinterface:1286int idx = currentBC->has_index_u4() ? currentBC->get_index_u4() : currentBC->get_index_u2_cpcache();1287ConstantPool* cp = method()->constants();1288int nameAndTypeIdx = cp->name_and_type_ref_index_at(idx);1289int signatureIdx = cp->signature_ref_index_at(nameAndTypeIdx);1290Symbol* signature = cp->symbol_at(signatureIdx);1291os->print("%s", signature->as_C_string());1292}1293os->cr();1294os->print(" stack = ");1295print_states(os, stack(), _stack_top);1296os->cr();1297if (_monitor_top != bad_monitors) {1298os->print(" monitors = ");1299print_states(os, monitors(), _monitor_top);1300} else {1301os->print(" [bad monitor stack]");1302}1303os->cr();1304} else {1305os->print(" %4d vars = '%s' ", currentBC->bci(), state_vec_to_string(vars(), _max_locals));1306os->print(" stack = '%s' ", state_vec_to_string(stack(), _stack_top));1307if (_monitor_top != bad_monitors) {1308os->print(" monitors = '%s' \t%s", state_vec_to_string(monitors(), _monitor_top), Bytecodes::name(currentBC->code()));1309} else {1310os->print(" [bad monitor stack]");1311}1312switch(currentBC->code()) {1313case Bytecodes::_invokevirtual:1314case Bytecodes::_invokespecial:1315case Bytecodes::_invokestatic:1316case Bytecodes::_invokedynamic:1317case Bytecodes::_invokeinterface:1318int idx = currentBC->has_index_u4() ? currentBC->get_index_u4() : currentBC->get_index_u2_cpcache();1319ConstantPool* cp = method()->constants();1320int nameAndTypeIdx = cp->name_and_type_ref_index_at(idx);1321int signatureIdx = cp->signature_ref_index_at(nameAndTypeIdx);1322Symbol* signature = cp->symbol_at(signatureIdx);1323os->print("%s", signature->as_C_string());1324}1325os->cr();1326}1327}13281329// Sets the current state to be the state after executing the1330// current instruction, starting in the current state.1331void GenerateOopMap::interp1(BytecodeStream *itr) {1332if (TraceNewOopMapGeneration) {1333print_current_state(tty, itr, TraceNewOopMapGenerationDetailed);1334}13351336// Should we report the results? Result is reported *before* the instruction at the current bci is executed.1337// However, not for calls. For calls we do not want to include the arguments, so we postpone the reporting until1338// they have been popped (in method ppl).1339if (_report_result == true) {1340switch(itr->code()) {1341case Bytecodes::_invokevirtual:1342case Bytecodes::_invokespecial:1343case Bytecodes::_invokestatic:1344case Bytecodes::_invokedynamic:1345case Bytecodes::_invokeinterface:1346_itr_send = itr;1347_report_result_for_send = true;1348break;1349default:1350fill_stackmap_for_opcodes(itr, vars(), stack(), _stack_top);1351break;1352}1353}13541355// abstract interpretation of current opcode1356switch(itr->code()) {1357case Bytecodes::_nop: break;1358case Bytecodes::_goto: break;1359case Bytecodes::_goto_w: break;1360case Bytecodes::_iinc: break;1361case Bytecodes::_return: do_return_monitor_check();1362break;13631364case Bytecodes::_aconst_null:1365case Bytecodes::_new: ppush1(CellTypeState::make_line_ref(itr->bci()));1366break;13671368case Bytecodes::_iconst_m1:1369case Bytecodes::_iconst_0:1370case Bytecodes::_iconst_1:1371case Bytecodes::_iconst_2:1372case Bytecodes::_iconst_3:1373case Bytecodes::_iconst_4:1374case Bytecodes::_iconst_5:1375case Bytecodes::_fconst_0:1376case Bytecodes::_fconst_1:1377case Bytecodes::_fconst_2:1378case Bytecodes::_bipush:1379case Bytecodes::_sipush: ppush1(valCTS); break;13801381case Bytecodes::_lconst_0:1382case Bytecodes::_lconst_1:1383case Bytecodes::_dconst_0:1384case Bytecodes::_dconst_1: ppush(vvCTS); break;13851386case Bytecodes::_ldc2_w: ppush(vvCTS); break;13871388case Bytecodes::_ldc: // fall through:1389case Bytecodes::_ldc_w: do_ldc(itr->bci()); break;13901391case Bytecodes::_iload:1392case Bytecodes::_fload: ppload(vCTS, itr->get_index()); break;13931394case Bytecodes::_lload:1395case Bytecodes::_dload: ppload(vvCTS,itr->get_index()); break;13961397case Bytecodes::_aload: ppload(rCTS, itr->get_index()); break;13981399case Bytecodes::_iload_0:1400case Bytecodes::_fload_0: ppload(vCTS, 0); break;1401case Bytecodes::_iload_1:1402case Bytecodes::_fload_1: ppload(vCTS, 1); break;1403case Bytecodes::_iload_2:1404case Bytecodes::_fload_2: ppload(vCTS, 2); break;1405case Bytecodes::_iload_3:1406case Bytecodes::_fload_3: ppload(vCTS, 3); break;14071408case Bytecodes::_lload_0:1409case Bytecodes::_dload_0: ppload(vvCTS, 0); break;1410case Bytecodes::_lload_1:1411case Bytecodes::_dload_1: ppload(vvCTS, 1); break;1412case Bytecodes::_lload_2:1413case Bytecodes::_dload_2: ppload(vvCTS, 2); break;1414case Bytecodes::_lload_3:1415case Bytecodes::_dload_3: ppload(vvCTS, 3); break;14161417case Bytecodes::_aload_0: ppload(rCTS, 0); break;1418case Bytecodes::_aload_1: ppload(rCTS, 1); break;1419case Bytecodes::_aload_2: ppload(rCTS, 2); break;1420case Bytecodes::_aload_3: ppload(rCTS, 3); break;14211422case Bytecodes::_iaload:1423case Bytecodes::_faload:1424case Bytecodes::_baload:1425case Bytecodes::_caload:1426case Bytecodes::_saload: pp(vrCTS, vCTS); break;14271428case Bytecodes::_laload: pp(vrCTS, vvCTS); break;1429case Bytecodes::_daload: pp(vrCTS, vvCTS); break;14301431case Bytecodes::_aaload: pp_new_ref(vrCTS, itr->bci()); break;14321433case Bytecodes::_istore:1434case Bytecodes::_fstore: ppstore(vCTS, itr->get_index()); break;14351436case Bytecodes::_lstore:1437case Bytecodes::_dstore: ppstore(vvCTS, itr->get_index()); break;14381439case Bytecodes::_astore: do_astore(itr->get_index()); break;14401441case Bytecodes::_istore_0:1442case Bytecodes::_fstore_0: ppstore(vCTS, 0); break;1443case Bytecodes::_istore_1:1444case Bytecodes::_fstore_1: ppstore(vCTS, 1); break;1445case Bytecodes::_istore_2:1446case Bytecodes::_fstore_2: ppstore(vCTS, 2); break;1447case Bytecodes::_istore_3:1448case Bytecodes::_fstore_3: ppstore(vCTS, 3); break;14491450case Bytecodes::_lstore_0:1451case Bytecodes::_dstore_0: ppstore(vvCTS, 0); break;1452case Bytecodes::_lstore_1:1453case Bytecodes::_dstore_1: ppstore(vvCTS, 1); break;1454case Bytecodes::_lstore_2:1455case Bytecodes::_dstore_2: ppstore(vvCTS, 2); break;1456case Bytecodes::_lstore_3:1457case Bytecodes::_dstore_3: ppstore(vvCTS, 3); break;14581459case Bytecodes::_astore_0: do_astore(0); break;1460case Bytecodes::_astore_1: do_astore(1); break;1461case Bytecodes::_astore_2: do_astore(2); break;1462case Bytecodes::_astore_3: do_astore(3); break;14631464case Bytecodes::_iastore:1465case Bytecodes::_fastore:1466case Bytecodes::_bastore:1467case Bytecodes::_castore:1468case Bytecodes::_sastore: ppop(vvrCTS); break;1469case Bytecodes::_lastore:1470case Bytecodes::_dastore: ppop(vvvrCTS); break;1471case Bytecodes::_aastore: ppop(rvrCTS); break;14721473case Bytecodes::_pop: ppop_any(1); break;1474case Bytecodes::_pop2: ppop_any(2); break;14751476case Bytecodes::_dup: ppdupswap(1, "11"); break;1477case Bytecodes::_dup_x1: ppdupswap(2, "121"); break;1478case Bytecodes::_dup_x2: ppdupswap(3, "1321"); break;1479case Bytecodes::_dup2: ppdupswap(2, "2121"); break;1480case Bytecodes::_dup2_x1: ppdupswap(3, "21321"); break;1481case Bytecodes::_dup2_x2: ppdupswap(4, "214321"); break;1482case Bytecodes::_swap: ppdupswap(2, "12"); break;14831484case Bytecodes::_iadd:1485case Bytecodes::_fadd:1486case Bytecodes::_isub:1487case Bytecodes::_fsub:1488case Bytecodes::_imul:1489case Bytecodes::_fmul:1490case Bytecodes::_idiv:1491case Bytecodes::_fdiv:1492case Bytecodes::_irem:1493case Bytecodes::_frem:1494case Bytecodes::_ishl:1495case Bytecodes::_ishr:1496case Bytecodes::_iushr:1497case Bytecodes::_iand:1498case Bytecodes::_ior:1499case Bytecodes::_ixor:1500case Bytecodes::_l2f:1501case Bytecodes::_l2i:1502case Bytecodes::_d2f:1503case Bytecodes::_d2i:1504case Bytecodes::_fcmpl:1505case Bytecodes::_fcmpg: pp(vvCTS, vCTS); break;15061507case Bytecodes::_ladd:1508case Bytecodes::_dadd:1509case Bytecodes::_lsub:1510case Bytecodes::_dsub:1511case Bytecodes::_lmul:1512case Bytecodes::_dmul:1513case Bytecodes::_ldiv:1514case Bytecodes::_ddiv:1515case Bytecodes::_lrem:1516case Bytecodes::_drem:1517case Bytecodes::_land:1518case Bytecodes::_lor:1519case Bytecodes::_lxor: pp(vvvvCTS, vvCTS); break;15201521case Bytecodes::_ineg:1522case Bytecodes::_fneg:1523case Bytecodes::_i2f:1524case Bytecodes::_f2i:1525case Bytecodes::_i2c:1526case Bytecodes::_i2s:1527case Bytecodes::_i2b: pp(vCTS, vCTS); break;15281529case Bytecodes::_lneg:1530case Bytecodes::_dneg:1531case Bytecodes::_l2d:1532case Bytecodes::_d2l: pp(vvCTS, vvCTS); break;15331534case Bytecodes::_lshl:1535case Bytecodes::_lshr:1536case Bytecodes::_lushr: pp(vvvCTS, vvCTS); break;15371538case Bytecodes::_i2l:1539case Bytecodes::_i2d:1540case Bytecodes::_f2l:1541case Bytecodes::_f2d: pp(vCTS, vvCTS); break;15421543case Bytecodes::_lcmp: pp(vvvvCTS, vCTS); break;1544case Bytecodes::_dcmpl:1545case Bytecodes::_dcmpg: pp(vvvvCTS, vCTS); break;15461547case Bytecodes::_ifeq:1548case Bytecodes::_ifne:1549case Bytecodes::_iflt:1550case Bytecodes::_ifge:1551case Bytecodes::_ifgt:1552case Bytecodes::_ifle:1553case Bytecodes::_tableswitch: ppop1(valCTS);1554break;1555case Bytecodes::_ireturn:1556case Bytecodes::_freturn: do_return_monitor_check();1557ppop1(valCTS);1558break;1559case Bytecodes::_if_icmpeq:1560case Bytecodes::_if_icmpne:1561case Bytecodes::_if_icmplt:1562case Bytecodes::_if_icmpge:1563case Bytecodes::_if_icmpgt:1564case Bytecodes::_if_icmple: ppop(vvCTS);1565break;15661567case Bytecodes::_lreturn: do_return_monitor_check();1568ppop(vvCTS);1569break;15701571case Bytecodes::_dreturn: do_return_monitor_check();1572ppop(vvCTS);1573break;15741575case Bytecodes::_if_acmpeq:1576case Bytecodes::_if_acmpne: ppop(rrCTS); break;15771578case Bytecodes::_jsr: do_jsr(itr->dest()); break;1579case Bytecodes::_jsr_w: do_jsr(itr->dest_w()); break;15801581case Bytecodes::_getstatic: do_field(true, true, itr->get_index_u2_cpcache(), itr->bci()); break;1582case Bytecodes::_putstatic: do_field(false, true, itr->get_index_u2_cpcache(), itr->bci()); break;1583case Bytecodes::_getfield: do_field(true, false, itr->get_index_u2_cpcache(), itr->bci()); break;1584case Bytecodes::_putfield: do_field(false, false, itr->get_index_u2_cpcache(), itr->bci()); break;15851586case Bytecodes::_invokevirtual:1587case Bytecodes::_invokespecial: do_method(false, false, itr->get_index_u2_cpcache(), itr->bci()); break;1588case Bytecodes::_invokestatic: do_method(true, false, itr->get_index_u2_cpcache(), itr->bci()); break;1589case Bytecodes::_invokedynamic: do_method(true, false, itr->get_index_u4(), itr->bci()); break;1590case Bytecodes::_invokeinterface: do_method(false, true, itr->get_index_u2_cpcache(), itr->bci()); break;1591case Bytecodes::_newarray:1592case Bytecodes::_anewarray: pp_new_ref(vCTS, itr->bci()); break;1593case Bytecodes::_checkcast: do_checkcast(); break;1594case Bytecodes::_arraylength:1595case Bytecodes::_instanceof: pp(rCTS, vCTS); break;1596case Bytecodes::_monitorenter: do_monitorenter(itr->bci()); break;1597case Bytecodes::_monitorexit: do_monitorexit(itr->bci()); break;15981599case Bytecodes::_athrow: // handled by do_exception_edge() BUT ...1600// vlh(apple): do_exception_edge() does not get1601// called if method has no exception handlers1602if ((!_has_exceptions) && (_monitor_top > 0)) {1603_monitor_safe = false;1604}1605break;16061607case Bytecodes::_areturn: do_return_monitor_check();1608ppop1(refCTS);1609break;1610case Bytecodes::_ifnull:1611case Bytecodes::_ifnonnull: ppop1(refCTS); break;1612case Bytecodes::_multianewarray: do_multianewarray(*(itr->bcp()+3), itr->bci()); break;16131614case Bytecodes::_wide: fatal("Iterator should skip this bytecode"); break;1615case Bytecodes::_ret: break;16161617// Java opcodes1618case Bytecodes::_lookupswitch: ppop1(valCTS); break;16191620default:1621tty->print("unexpected opcode: %d\n", itr->code());1622ShouldNotReachHere();1623break;1624}1625}16261627void GenerateOopMap::check_type(CellTypeState expected, CellTypeState actual) {1628if (!expected.equal_kind(actual)) {1629verify_error("wrong type on stack (found: %c expected: %c)", actual.to_char(), expected.to_char());1630}1631}16321633void GenerateOopMap::ppstore(CellTypeState *in, int loc_no) {1634while(!(*in).is_bottom()) {1635CellTypeState expected =*in++;1636CellTypeState actual = pop();1637check_type(expected, actual);1638assert(loc_no >= 0, "sanity check");1639set_var(loc_no++, actual);1640}1641}16421643void GenerateOopMap::ppload(CellTypeState *out, int loc_no) {1644while(!(*out).is_bottom()) {1645CellTypeState out1 = *out++;1646CellTypeState vcts = get_var(loc_no);1647assert(out1.can_be_reference() || out1.can_be_value(),1648"can only load refs. and values.");1649if (out1.is_reference()) {1650assert(loc_no>=0, "sanity check");1651if (!vcts.is_reference()) {1652// We were asked to push a reference, but the type of the1653// variable can be something else1654_conflict = true;1655if (vcts.can_be_uninit()) {1656// It is a ref-uninit conflict (at least). If there are other1657// problems, we'll get them in the next round1658add_to_ref_init_set(loc_no);1659vcts = out1;1660} else {1661// It wasn't a ref-uninit conflict. So must be a1662// ref-val or ref-pc conflict. Split the variable.1663record_refval_conflict(loc_no);1664vcts = out1;1665}1666push(out1); // recover...1667} else {1668push(vcts); // preserve reference.1669}1670// Otherwise it is a conflict, but one that verification would1671// have caught if illegal. In particular, it can't be a topCTS1672// resulting from mergeing two difference pcCTS's since the verifier1673// would have rejected any use of such a merge.1674} else {1675push(out1); // handle val/init conflict1676}1677loc_no++;1678}1679}16801681void GenerateOopMap::ppdupswap(int poplen, const char *out) {1682CellTypeState actual[5];1683assert(poplen < 5, "this must be less than length of actual vector");16841685// pop all arguments1686for(int i = 0; i < poplen; i++) actual[i] = pop();16871688// put them back1689char push_ch = *out++;1690while (push_ch != '\0') {1691int idx = push_ch - '1';1692assert(idx >= 0 && idx < poplen, "wrong arguments");1693push(actual[idx]);1694push_ch = *out++;1695}1696}16971698void GenerateOopMap::ppop1(CellTypeState out) {1699CellTypeState actual = pop();1700check_type(out, actual);1701}17021703void GenerateOopMap::ppop(CellTypeState *out) {1704while (!(*out).is_bottom()) {1705ppop1(*out++);1706}1707}17081709void GenerateOopMap::ppush1(CellTypeState in) {1710assert(in.is_reference() | in.is_value(), "sanity check");1711push(in);1712}17131714void GenerateOopMap::ppush(CellTypeState *in) {1715while (!(*in).is_bottom()) {1716ppush1(*in++);1717}1718}17191720void GenerateOopMap::pp(CellTypeState *in, CellTypeState *out) {1721ppop(in);1722ppush(out);1723}17241725void GenerateOopMap::pp_new_ref(CellTypeState *in, int bci) {1726ppop(in);1727ppush1(CellTypeState::make_line_ref(bci));1728}17291730void GenerateOopMap::ppop_any(int poplen) {1731if (_stack_top >= poplen) {1732_stack_top -= poplen;1733} else {1734verify_error("stack underflow");1735}1736}17371738// Replace all occurences of the state 'match' with the state 'replace'1739// in our current state vector.1740void GenerateOopMap::replace_all_CTS_matches(CellTypeState match,1741CellTypeState replace) {1742int i;1743int len = _max_locals + _stack_top;1744bool change = false;17451746for (i = len - 1; i >= 0; i--) {1747if (match.equal(_state[i])) {1748_state[i] = replace;1749}1750}17511752if (_monitor_top > 0) {1753int base = _max_locals + _max_stack;1754len = base + _monitor_top;1755for (i = len - 1; i >= base; i--) {1756if (match.equal(_state[i])) {1757_state[i] = replace;1758}1759}1760}1761}17621763void GenerateOopMap::do_checkcast() {1764CellTypeState actual = pop();1765check_type(refCTS, actual);1766push(actual);1767}17681769void GenerateOopMap::do_monitorenter(int bci) {1770CellTypeState actual = pop();1771if (_monitor_top == bad_monitors) {1772return;1773}17741775// Bail out when we get repeated locks on an identical monitor. This case1776// isn't too hard to handle and can be made to work if supporting nested1777// redundant synchronized statements becomes a priority.1778//1779// See also "Note" in do_monitorexit(), below.1780if (actual.is_lock_reference()) {1781_monitor_top = bad_monitors;1782_monitor_safe = false;17831784if (TraceMonitorMismatch) {1785report_monitor_mismatch("nested redundant lock -- bailout...");1786}1787return;1788}17891790CellTypeState lock = CellTypeState::make_lock_ref(bci);1791check_type(refCTS, actual);1792if (!actual.is_info_top()) {1793replace_all_CTS_matches(actual, lock);1794monitor_push(lock);1795}1796}17971798void GenerateOopMap::do_monitorexit(int bci) {1799CellTypeState actual = pop();1800if (_monitor_top == bad_monitors) {1801return;1802}1803check_type(refCTS, actual);1804CellTypeState expected = monitor_pop();1805if (!actual.is_lock_reference() || !expected.equal(actual)) {1806// The monitor we are exiting is not verifiably the one1807// on the top of our monitor stack. This causes a monitor1808// mismatch.1809_monitor_top = bad_monitors;1810_monitor_safe = false;18111812// We need to mark this basic block as changed so that1813// this monitorexit will be visited again. We need to1814// do this to ensure that we have accounted for the1815// possibility that this bytecode will throw an1816// exception.1817BasicBlock* bb = get_basic_block_containing(bci);1818guarantee(bb != NULL, "no basic block for bci");1819bb->set_changed(true);1820bb->_monitor_top = bad_monitors;18211822if (TraceMonitorMismatch) {1823report_monitor_mismatch("improper monitor pair");1824}1825} else {1826// This code is a fix for the case where we have repeated1827// locking of the same object in straightline code. We clear1828// out the lock when it is popped from the monitor stack1829// and replace it with an unobtrusive reference value that can1830// be locked again.1831//1832// Note: when generateOopMap is fixed to properly handle repeated,1833// nested, redundant locks on the same object, then this1834// fix will need to be removed at that time.1835replace_all_CTS_matches(actual, CellTypeState::make_line_ref(bci));1836}1837}18381839void GenerateOopMap::do_return_monitor_check() {1840if (_monitor_top > 0) {1841// The monitor stack must be empty when we leave the method1842// for the monitors to be properly matched.1843_monitor_safe = false;18441845// Since there are no successors to the *return bytecode, it1846// isn't necessary to set _monitor_top to bad_monitors.18471848if (TraceMonitorMismatch) {1849report_monitor_mismatch("non-empty monitor stack at return");1850}1851}1852}18531854void GenerateOopMap::do_jsr(int targ_bci) {1855push(CellTypeState::make_addr(targ_bci));1856}1857185818591860void GenerateOopMap::do_ldc(int bci) {1861Bytecode_loadconstant ldc(method(), bci);1862ConstantPool* cp = method()->constants();1863constantTag tag = cp->tag_at(ldc.pool_index()); // idx is index in resolved_references1864BasicType bt = ldc.result_type();1865CellTypeState cts;1866if (tag.basic_type() == T_OBJECT) {1867assert(!tag.is_string_index() && !tag.is_klass_index(), "Unexpected index tag");1868assert(bt == T_OBJECT, "Guard is incorrect");1869cts = CellTypeState::make_line_ref(bci);1870} else {1871assert(bt != T_OBJECT, "Guard is incorrect");1872cts = valCTS;1873}1874ppush1(cts);1875}18761877void GenerateOopMap::do_multianewarray(int dims, int bci) {1878assert(dims >= 1, "sanity check");1879for(int i = dims -1; i >=0; i--) {1880ppop1(valCTS);1881}1882ppush1(CellTypeState::make_line_ref(bci));1883}18841885void GenerateOopMap::do_astore(int idx) {1886CellTypeState r_or_p = pop();1887if (!r_or_p.is_address() && !r_or_p.is_reference()) {1888// We actually expected ref or pc, but we only report that we expected a ref. It does not1889// really matter (at least for now)1890verify_error("wrong type on stack (found: %c, expected: {pr})", r_or_p.to_char());1891return;1892}1893set_var(idx, r_or_p);1894}18951896// Copies bottom/zero terminated CTS string from "src" into "dst".1897// Does NOT terminate with a bottom. Returns the number of cells copied.1898int GenerateOopMap::copy_cts(CellTypeState *dst, CellTypeState *src) {1899int idx = 0;1900while (!src[idx].is_bottom()) {1901dst[idx] = src[idx];1902idx++;1903}1904return idx;1905}19061907void GenerateOopMap::do_field(int is_get, int is_static, int idx, int bci) {1908// Dig up signature for field in constant pool1909ConstantPool* cp = method()->constants();1910int nameAndTypeIdx = cp->name_and_type_ref_index_at(idx);1911int signatureIdx = cp->signature_ref_index_at(nameAndTypeIdx);1912Symbol* signature = cp->symbol_at(signatureIdx);19131914// Parse signature (espcially simple for fields)1915assert(signature->utf8_length() > 0, "field signatures cannot have zero length");1916// The signature is UFT8 encoded, but the first char is always ASCII for signatures.1917char sigch = (char)*(signature->base());1918CellTypeState temp[4];1919CellTypeState *eff = sigchar_to_effect(sigch, bci, temp);19201921CellTypeState in[4];1922CellTypeState *out;1923int i = 0;19241925if (is_get) {1926out = eff;1927} else {1928out = epsilonCTS;1929i = copy_cts(in, eff);1930}1931if (!is_static) in[i++] = CellTypeState::ref;1932in[i] = CellTypeState::bottom;1933assert(i<=3, "sanity check");1934pp(in, out);1935}19361937void GenerateOopMap::do_method(int is_static, int is_interface, int idx, int bci) {1938// Dig up signature for field in constant pool1939ConstantPool* cp = _method->constants();1940Symbol* signature = cp->signature_ref_at(idx);19411942// Parse method signature1943CellTypeState out[4];1944CellTypeState in[MAXARGSIZE+1]; // Includes result1945ComputeCallStack cse(signature);19461947// Compute return type1948int res_length= cse.compute_for_returntype(out);19491950// Temporary hack.1951if (out[0].equal(CellTypeState::ref) && out[1].equal(CellTypeState::bottom)) {1952out[0] = CellTypeState::make_line_ref(bci);1953}19541955assert(res_length<=4, "max value should be vv");19561957// Compute arguments1958int arg_length = cse.compute_for_parameters(is_static != 0, in);1959assert(arg_length<=MAXARGSIZE, "too many locals");19601961// Pop arguments1962for (int i = arg_length - 1; i >= 0; i--) ppop1(in[i]);// Do args in reverse order.19631964// Report results1965if (_report_result_for_send == true) {1966fill_stackmap_for_opcodes(_itr_send, vars(), stack(), _stack_top);1967_report_result_for_send = false;1968}19691970// Push return address1971ppush(out);1972}19731974// This is used to parse the signature for fields, since they are very simple...1975CellTypeState *GenerateOopMap::sigchar_to_effect(char sigch, int bci, CellTypeState *out) {1976// Object and array1977if (sigch=='L' || sigch=='[') {1978out[0] = CellTypeState::make_line_ref(bci);1979out[1] = CellTypeState::bottom;1980return out;1981}1982if (sigch == 'J' || sigch == 'D' ) return vvCTS; // Long and Double1983if (sigch == 'V' ) return epsilonCTS; // Void1984return vCTS; // Otherwise1985}19861987long GenerateOopMap::_total_byte_count = 0;1988elapsedTimer GenerateOopMap::_total_oopmap_time;19891990// This function assumes "bcs" is at a "ret" instruction and that the vars1991// state is valid for that instruction. Furthermore, the ret instruction1992// must be the last instruction in "bb" (we store information about the1993// "ret" in "bb").1994void GenerateOopMap::ret_jump_targets_do(BytecodeStream *bcs, jmpFct_t jmpFct, int varNo, int *data) {1995CellTypeState ra = vars()[varNo];1996if (!ra.is_good_address()) {1997verify_error("ret returns from two jsr subroutines?");1998return;1999}2000int target = ra.get_info();20012002RetTableEntry* rtEnt = _rt.find_jsrs_for_target(target);2003int bci = bcs->bci();2004for (int i = 0; i < rtEnt->nof_jsrs(); i++) {2005int target_bci = rtEnt->jsrs(i);2006// Make sure a jrtRet does not set the changed bit for dead basicblock.2007BasicBlock* jsr_bb = get_basic_block_containing(target_bci - 1);2008debug_only(BasicBlock* target_bb = &jsr_bb[1];)2009assert(target_bb == get_basic_block_at(target_bci), "wrong calc. of successor basicblock");2010bool alive = jsr_bb->is_alive();2011if (TraceNewOopMapGeneration) {2012tty->print("pc = %d, ret -> %d alive: %s\n", bci, target_bci, alive ? "true" : "false");2013}2014if (alive) jmpFct(this, target_bci, data);2015}2016}20172018//2019// Debug method2020//2021char* GenerateOopMap::state_vec_to_string(CellTypeState* vec, int len) {2022#ifdef ASSERT2023int checklen = MAX3(_max_locals, _max_stack, _max_monitors) + 1;2024assert(len < checklen, "state_vec_buf overflow");2025#endif2026for (int i = 0; i < len; i++) _state_vec_buf[i] = vec[i].to_char();2027_state_vec_buf[len] = 0;2028return _state_vec_buf;2029}20302031void GenerateOopMap::print_time() {2032tty->print_cr ("Accumulated oopmap times:");2033tty->print_cr ("---------------------------");2034tty->print_cr (" Total : %3.3f sec.", GenerateOopMap::_total_oopmap_time.seconds());2035tty->print_cr (" (%3.0f bytecodes per sec) ",2036GenerateOopMap::_total_byte_count / GenerateOopMap::_total_oopmap_time.seconds());2037}20382039//2040// ============ Main Entry Point ===========2041//2042GenerateOopMap::GenerateOopMap(methodHandle method) {2043// We have to initialize all variables here, that can be queried directly2044_method = method;2045_max_locals=0;2046_init_vars = NULL;20472048#ifndef PRODUCT2049// If we are doing a detailed trace, include the regular trace information.2050if (TraceNewOopMapGenerationDetailed) {2051TraceNewOopMapGeneration = true;2052}2053#endif2054}20552056void GenerateOopMap::compute_map(TRAPS) {2057#ifndef PRODUCT2058if (TimeOopMap2) {2059method()->print_short_name(tty);2060tty->print(" ");2061}2062if (TimeOopMap) {2063_total_byte_count += method()->code_size();2064}2065#endif2066TraceTime t_single("oopmap time", TimeOopMap2);2067TraceTime t_all(NULL, &_total_oopmap_time, TimeOopMap);20682069// Initialize values2070_got_error = false;2071_conflict = false;2072_max_locals = method()->max_locals();2073_max_stack = method()->max_stack();2074_has_exceptions = (method()->has_exception_handler());2075_nof_refval_conflicts = 0;2076_init_vars = new GrowableArray<intptr_t>(5); // There are seldom more than 5 init_vars2077_report_result = false;2078_report_result_for_send = false;2079_new_var_map = NULL;2080_ret_adr_tos = new GrowableArray<intptr_t>(5); // 5 seems like a good number;2081_did_rewriting = false;2082_did_relocation = false;20832084if (TraceNewOopMapGeneration) {2085tty->print("Method name: %s\n", method()->name()->as_C_string());2086if (Verbose) {2087_method->print_codes();2088tty->print_cr("Exception table:");2089ExceptionTable excps(method());2090for(int i = 0; i < excps.length(); i ++) {2091tty->print_cr("[%d - %d] -> %d",2092excps.start_pc(i), excps.end_pc(i), excps.handler_pc(i));2093}2094}2095}20962097// if no code - do nothing2098// compiler needs info2099if (method()->code_size() == 0 || _max_locals + method()->max_stack() == 0) {2100fill_stackmap_prolog(0);2101fill_stackmap_epilog();2102return;2103}2104// Step 1: Compute all jump targets and their return value2105if (!_got_error)2106_rt.compute_ret_table(_method);21072108// Step 2: Find all basic blocks and count GC points2109if (!_got_error)2110mark_bbheaders_and_count_gc_points();21112112// Step 3: Calculate stack maps2113if (!_got_error)2114do_interpretation();21152116// Step 4:Return results2117if (!_got_error && report_results())2118report_result();21192120if (_got_error) {2121THROW_HANDLE(_exception);2122}2123}21242125// Error handling methods2126// These methods create an exception for the current thread which is thrown2127// at the bottom of the call stack, when it returns to compute_map(). The2128// _got_error flag controls execution. NOT TODO: The VM exception propagation2129// mechanism using TRAPS/CHECKs could be used here instead but it would need2130// to be added as a parameter to every function and checked for every call.2131// The tons of extra code it would generate didn't seem worth the change.2132//2133void GenerateOopMap::error_work(const char *format, va_list ap) {2134_got_error = true;2135char msg_buffer[512];2136os::vsnprintf(msg_buffer, sizeof(msg_buffer), format, ap);2137// Append method name2138char msg_buffer2[512];2139os::snprintf(msg_buffer2, sizeof(msg_buffer2), "%s in method %s", msg_buffer, method()->name()->as_C_string());2140_exception = Exceptions::new_exception(Thread::current(),2141vmSymbols::java_lang_LinkageError(), msg_buffer2);2142}21432144void GenerateOopMap::report_error(const char *format, ...) {2145va_list ap;2146va_start(ap, format);2147error_work(format, ap);2148}21492150void GenerateOopMap::verify_error(const char *format, ...) {2151// We do not distinguish between different types of errors for verification2152// errors. Let the verifier give a better message.2153const char *msg = "Illegal class file encountered. Try running with -Xverify:all";2154_got_error = true;2155// Append method name2156char msg_buffer2[512];2157os::snprintf(msg_buffer2, sizeof(msg_buffer2), "%s in method %s", msg,2158method()->name()->as_C_string());2159_exception = Exceptions::new_exception(Thread::current(),2160vmSymbols::java_lang_LinkageError(), msg_buffer2);2161}21622163//2164// Report result opcodes2165//2166void GenerateOopMap::report_result() {21672168if (TraceNewOopMapGeneration) tty->print_cr("Report result pass");21692170// We now want to report the result of the parse2171_report_result = true;21722173// Prolog code2174fill_stackmap_prolog(_gc_points);21752176// Mark everything changed, then do one interpretation pass.2177for (int i = 0; i<_bb_count; i++) {2178if (_basic_blocks[i].is_reachable()) {2179_basic_blocks[i].set_changed(true);2180interp_bb(&_basic_blocks[i]);2181}2182}21832184// Note: Since we are skipping dead-code when we are reporting results, then2185// the no. of encountered gc-points might be fewer than the previously number2186// we have counted. (dead-code is a pain - it should be removed before we get here)2187fill_stackmap_epilog();21882189// Report initvars2190fill_init_vars(_init_vars);21912192_report_result = false;2193}21942195void GenerateOopMap::result_for_basicblock(int bci) {2196if (TraceNewOopMapGeneration) tty->print_cr("Report result pass for basicblock");21972198// We now want to report the result of the parse2199_report_result = true;22002201// Find basicblock and report results2202BasicBlock* bb = get_basic_block_containing(bci);2203guarantee(bb != NULL, "no basic block for bci");2204assert(bb->is_reachable(), "getting result from unreachable basicblock");2205bb->set_changed(true);2206interp_bb(bb);2207}22082209//2210// Conflict handling code2211//22122213void GenerateOopMap::record_refval_conflict(int varNo) {2214assert(varNo>=0 && varNo< _max_locals, "index out of range");22152216if (TraceOopMapRewrites) {2217tty->print("### Conflict detected (local no: %d)\n", varNo);2218}22192220if (!_new_var_map) {2221_new_var_map = NEW_RESOURCE_ARRAY(int, _max_locals);2222for (int k = 0; k < _max_locals; k++) _new_var_map[k] = k;2223}22242225if ( _new_var_map[varNo] == varNo) {2226// Check if max. number of locals has been reached2227if (_max_locals + _nof_refval_conflicts >= MAX_LOCAL_VARS) {2228report_error("Rewriting exceeded local variable limit");2229return;2230}2231_new_var_map[varNo] = _max_locals + _nof_refval_conflicts;2232_nof_refval_conflicts++;2233}2234}22352236void GenerateOopMap::rewrite_refval_conflicts()2237{2238// We can get here two ways: Either a rewrite conflict was detected, or2239// an uninitialize reference was detected. In the second case, we do not2240// do any rewriting, we just want to recompute the reference set with the2241// new information22422243int nof_conflicts = 0; // Used for debugging only22442245if ( _nof_refval_conflicts == 0 )2246return;22472248// Check if rewrites are allowed in this parse.2249if (!allow_rewrites() && !IgnoreRewrites) {2250fatal("Rewriting method not allowed at this stage");2251}225222532254// This following flag is to tempoary supress rewrites. The locals that might conflict will2255// all be set to contain values. This is UNSAFE - however, until the rewriting has been completely2256// tested it is nice to have.2257if (IgnoreRewrites) {2258if (Verbose) {2259tty->print("rewrites suppressed for local no. ");2260for (int l = 0; l < _max_locals; l++) {2261if (_new_var_map[l] != l) {2262tty->print("%d ", l);2263vars()[l] = CellTypeState::value;2264}2265}2266tty->cr();2267}22682269// That was that...2270_new_var_map = NULL;2271_nof_refval_conflicts = 0;2272_conflict = false;22732274return;2275}22762277// Tracing flag2278_did_rewriting = true;22792280if (TraceOopMapRewrites) {2281tty->print_cr("ref/value conflict for method %s - bytecodes are getting rewritten", method()->name()->as_C_string());2282method()->print();2283method()->print_codes();2284}22852286assert(_new_var_map!=NULL, "nothing to rewrite");2287assert(_conflict==true, "We should not be here");22882289compute_ret_adr_at_TOS();2290if (!_got_error) {2291for (int k = 0; k < _max_locals && !_got_error; k++) {2292if (_new_var_map[k] != k) {2293if (TraceOopMapRewrites) {2294tty->print_cr("Rewriting: %d -> %d", k, _new_var_map[k]);2295}2296rewrite_refval_conflict(k, _new_var_map[k]);2297if (_got_error) return;2298nof_conflicts++;2299}2300}2301}23022303assert(nof_conflicts == _nof_refval_conflicts, "sanity check");23042305// Adjust the number of locals2306method()->set_max_locals(_max_locals+_nof_refval_conflicts);2307_max_locals += _nof_refval_conflicts;23082309// That was that...2310_new_var_map = NULL;2311_nof_refval_conflicts = 0;2312}23132314void GenerateOopMap::rewrite_refval_conflict(int from, int to) {2315bool startOver;2316do {2317// Make sure that the BytecodeStream is constructed in the loop, since2318// during rewriting a new method oop is going to be used, and the next time2319// around we want to use that.2320BytecodeStream bcs(_method);2321startOver = false;23222323while( !startOver && !_got_error &&2324// test bcs in case method changed and it became invalid2325bcs.next() >=0) {2326startOver = rewrite_refval_conflict_inst(&bcs, from, to);2327}2328} while (startOver && !_got_error);2329}23302331/* If the current instruction is one that uses local variable "from"2332in a ref way, change it to use "to". There's a subtle reason why we2333renumber the ref uses and not the non-ref uses: non-ref uses may be23342 slots wide (double, long) which would necessitate keeping track of2335whether we should add one or two variables to the method. If the change2336affected the width of some instruction, returns "TRUE"; otherwise, returns "FALSE".2337Another reason for moving ref's value is for solving (addr, ref) conflicts, which2338both uses aload/astore methods.2339*/2340bool GenerateOopMap::rewrite_refval_conflict_inst(BytecodeStream *itr, int from, int to) {2341Bytecodes::Code bc = itr->code();2342int index;2343int bci = itr->bci();23442345if (is_aload(itr, &index) && index == from) {2346if (TraceOopMapRewrites) {2347tty->print_cr("Rewriting aload at bci: %d", bci);2348}2349return rewrite_load_or_store(itr, Bytecodes::_aload, Bytecodes::_aload_0, to);2350}23512352if (is_astore(itr, &index) && index == from) {2353if (!stack_top_holds_ret_addr(bci)) {2354if (TraceOopMapRewrites) {2355tty->print_cr("Rewriting astore at bci: %d", bci);2356}2357return rewrite_load_or_store(itr, Bytecodes::_astore, Bytecodes::_astore_0, to);2358} else {2359if (TraceOopMapRewrites) {2360tty->print_cr("Supress rewriting of astore at bci: %d", bci);2361}2362}2363}23642365return false;2366}23672368// The argument to this method is:2369// bc : Current bytecode2370// bcN : either _aload or _astore2371// bc0 : either _aload_0 or _astore_02372bool GenerateOopMap::rewrite_load_or_store(BytecodeStream *bcs, Bytecodes::Code bcN, Bytecodes::Code bc0, unsigned int varNo) {2373assert(bcN == Bytecodes::_astore || bcN == Bytecodes::_aload, "wrong argument (bcN)");2374assert(bc0 == Bytecodes::_astore_0 || bc0 == Bytecodes::_aload_0, "wrong argument (bc0)");2375int ilen = Bytecodes::length_at(_method(), bcs->bcp());2376int newIlen;23772378if (ilen == 4) {2379// Original instruction was wide; keep it wide for simplicity2380newIlen = 4;2381} else if (varNo < 4)2382newIlen = 1;2383else if (varNo >= 256)2384newIlen = 4;2385else2386newIlen = 2;23872388// If we need to relocate in order to patch the byte, we2389// do the patching in a temp. buffer, that is passed to the reloc.2390// The patching of the bytecode stream is then done by the Relocator.2391// This is neccesary, since relocating the instruction at a certain bci, might2392// also relocate that instruction, e.g., if a _goto before it gets widen to a _goto_w.2393// Hence, we do not know which bci to patch after relocation.23942395assert(newIlen <= 4, "sanity check");2396u_char inst_buffer[4]; // Max. instruction size is 4.2397address bcp;23982399if (newIlen != ilen) {2400// Relocation needed do patching in temp. buffer2401bcp = (address)inst_buffer;2402} else {2403bcp = _method->bcp_from(bcs->bci());2404}24052406// Patch either directly in Method* or in temp. buffer2407if (newIlen == 1) {2408assert(varNo < 4, "varNo too large");2409*bcp = bc0 + varNo;2410} else if (newIlen == 2) {2411assert(varNo < 256, "2-byte index needed!");2412*(bcp + 0) = bcN;2413*(bcp + 1) = varNo;2414} else {2415assert(newIlen == 4, "Wrong instruction length");2416*(bcp + 0) = Bytecodes::_wide;2417*(bcp + 1) = bcN;2418Bytes::put_Java_u2(bcp+2, varNo);2419}24202421if (newIlen != ilen) {2422expand_current_instr(bcs->bci(), ilen, newIlen, inst_buffer);2423}242424252426return (newIlen != ilen);2427}24282429class RelocCallback : public RelocatorListener {2430private:2431GenerateOopMap* _gom;2432public:2433RelocCallback(GenerateOopMap* gom) { _gom = gom; };24342435// Callback method2436virtual void relocated(int bci, int delta, int new_code_length) {2437_gom->update_basic_blocks (bci, delta, new_code_length);2438_gom->update_ret_adr_at_TOS(bci, delta);2439_gom->_rt.update_ret_table (bci, delta);2440}2441};24422443// Returns true if expanding was succesful. Otherwise, reports an error and2444// returns false.2445void GenerateOopMap::expand_current_instr(int bci, int ilen, int newIlen, u_char inst_buffer[]) {2446Thread *THREAD = Thread::current(); // Could really have TRAPS argument.2447RelocCallback rcb(this);2448Relocator rc(_method, &rcb);2449methodHandle m= rc.insert_space_at(bci, newIlen, inst_buffer, THREAD);2450if (m.is_null() || HAS_PENDING_EXCEPTION) {2451report_error("could not rewrite method - exception occurred or bytecode buffer overflow");2452return;2453}24542455// Relocator returns a new method oop.2456_did_relocation = true;2457_method = m;2458}245924602461bool GenerateOopMap::is_astore(BytecodeStream *itr, int *index) {2462Bytecodes::Code bc = itr->code();2463switch(bc) {2464case Bytecodes::_astore_0:2465case Bytecodes::_astore_1:2466case Bytecodes::_astore_2:2467case Bytecodes::_astore_3:2468*index = bc - Bytecodes::_astore_0;2469return true;2470case Bytecodes::_astore:2471*index = itr->get_index();2472return true;2473}2474return false;2475}24762477bool GenerateOopMap::is_aload(BytecodeStream *itr, int *index) {2478Bytecodes::Code bc = itr->code();2479switch(bc) {2480case Bytecodes::_aload_0:2481case Bytecodes::_aload_1:2482case Bytecodes::_aload_2:2483case Bytecodes::_aload_3:2484*index = bc - Bytecodes::_aload_0;2485return true;24862487case Bytecodes::_aload:2488*index = itr->get_index();2489return true;2490}2491return false;2492}249324942495// Return true iff the top of the operand stack holds a return address at2496// the current instruction2497bool GenerateOopMap::stack_top_holds_ret_addr(int bci) {2498for(int i = 0; i < _ret_adr_tos->length(); i++) {2499if (_ret_adr_tos->at(i) == bci)2500return true;2501}25022503return false;2504}25052506void GenerateOopMap::compute_ret_adr_at_TOS() {2507assert(_ret_adr_tos != NULL, "must be initialized");2508_ret_adr_tos->clear();25092510for (int i = 0; i < bb_count(); i++) {2511BasicBlock* bb = &_basic_blocks[i];25122513// Make sure to only check basicblocks that are reachable2514if (bb->is_reachable()) {25152516// For each Basic block we check all instructions2517BytecodeStream bcs(_method);2518bcs.set_interval(bb->_bci, next_bb_start_pc(bb));25192520restore_state(bb);25212522while (bcs.next()>=0 && !_got_error) {2523// TDT: should this be is_good_address() ?2524if (_stack_top > 0 && stack()[_stack_top-1].is_address()) {2525_ret_adr_tos->append(bcs.bci());2526if (TraceNewOopMapGeneration) {2527tty->print_cr("Ret_adr TOS at bci: %d", bcs.bci());2528}2529}2530interp1(&bcs);2531}2532}2533}2534}25352536void GenerateOopMap::update_ret_adr_at_TOS(int bci, int delta) {2537for(int i = 0; i < _ret_adr_tos->length(); i++) {2538int v = _ret_adr_tos->at(i);2539if (v > bci) _ret_adr_tos->at_put(i, v + delta);2540}2541}25422543// ===================================================================25442545#ifndef PRODUCT2546int ResolveOopMapConflicts::_nof_invocations = 0;2547int ResolveOopMapConflicts::_nof_rewrites = 0;2548int ResolveOopMapConflicts::_nof_relocations = 0;2549#endif25502551methodHandle ResolveOopMapConflicts::do_potential_rewrite(TRAPS) {2552compute_map(CHECK_(methodHandle()));25532554#ifndef PRODUCT2555// Tracking and statistics2556if (PrintRewrites) {2557_nof_invocations++;2558if (did_rewriting()) {2559_nof_rewrites++;2560if (did_relocation()) _nof_relocations++;2561tty->print("Method was rewritten %s: ", (did_relocation()) ? "and relocated" : "");2562method()->print_value(); tty->cr();2563tty->print_cr("Cand.: %d rewrts: %d (%d%%) reloc.: %d (%d%%)",2564_nof_invocations,2565_nof_rewrites, (_nof_rewrites * 100) / _nof_invocations,2566_nof_relocations, (_nof_relocations * 100) / _nof_invocations);2567}2568}2569#endif2570return methodHandle(THREAD, method());2571}257225732574