duke@435: /* xdono@631: * Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * duke@435: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, duke@435: * CA 95054 USA or visit www.sun.com if you need additional information or duke@435: * have any questions. duke@435: * duke@435: */ duke@435: duke@435: duke@435: class ciBlock; duke@435: duke@435: typedef short ciBlockIndex; duke@435: duke@435: class ciMethodBlocks : public ResourceObj { duke@435: private: duke@435: ciMethod *_method; duke@435: Arena *_arena; duke@435: GrowableArray *_blocks; duke@435: ciBlock **_bci_to_block; duke@435: int _num_blocks; duke@435: int _code_size; duke@435: duke@435: void do_analysis(); duke@435: public: duke@435: ciMethodBlocks(Arena *arena, ciMethod *meth); duke@435: duke@435: ciBlock *block_containing(int bci); duke@435: ciBlock *block(int index) { return _blocks->at(index); } duke@435: ciBlock *make_block_at(int bci); duke@435: ciBlock *split_block_at(int bci); duke@435: bool is_block_start(int bci); duke@435: int num_blocks() { return _num_blocks;} duke@435: void clear_processed(); duke@435: never@802: ciBlock *make_dummy_block(); // a block not associated with a bci never@802: duke@435: #ifndef PRODUCT duke@435: void dump(); duke@435: #endif duke@435: }; duke@435: duke@435: class ciBlock : public ResourceObj { duke@435: private: duke@435: int _idx; duke@435: int _start_bci; duke@435: int _limit_bci; duke@435: int _control_bci; duke@435: uint _flags; duke@435: int _ex_start_bci; duke@435: int _ex_limit_bci; duke@435: #ifndef PRODUCT duke@435: ciMethod *_method; duke@435: #endif duke@435: enum { duke@435: Processed = (1 << 0), duke@435: Handler = (1 << 1), duke@435: MayThrow = (1 << 2), duke@435: DoesJsr = (1 << 3), duke@435: DoesRet = (1 << 4), duke@435: RetTarget = (1 << 5), duke@435: HasHandler = (1 << 6) duke@435: }; duke@435: duke@435: duke@435: public: duke@435: enum { duke@435: fall_through_bci = -1 duke@435: }; duke@435: never@802: ciBlock(ciMethod *method, int index, int start_bci); duke@435: int start_bci() const { return _start_bci; } duke@435: int limit_bci() const { return _limit_bci; } duke@435: int control_bci() const { return _control_bci; } duke@435: int index() const { return _idx; } duke@435: void set_start_bci(int bci) { _start_bci = bci; } duke@435: void set_limit_bci(int bci) { _limit_bci = bci; } duke@435: void set_control_bci(int bci) { _control_bci = bci;} duke@435: void set_exception_range(int start_bci, int limit_bci); duke@435: int ex_start_bci() const { return _ex_start_bci; } duke@435: int ex_limit_bci() const { return _ex_limit_bci; } duke@435: bool contains(int bci) const { return start_bci() <= bci && bci < limit_bci(); } duke@435: duke@435: // flag handling duke@435: bool processed() const { return (_flags & Processed) != 0; } duke@435: bool is_handler() const { return (_flags & Handler) != 0; } duke@435: bool may_throw() const { return (_flags & MayThrow) != 0; } duke@435: bool does_jsr() const { return (_flags & DoesJsr) != 0; } duke@435: bool does_ret() const { return (_flags & DoesRet) != 0; } duke@435: bool has_handler() const { return (_flags & HasHandler) != 0; } duke@435: bool is_ret_target() const { return (_flags & RetTarget) != 0; } duke@435: void set_processed() { _flags |= Processed; } duke@435: void clear_processed() { _flags &= ~Processed; } duke@435: void set_handler() { _flags |= Handler; } duke@435: void set_may_throw() { _flags |= MayThrow; } duke@435: void set_does_jsr() { _flags |= DoesJsr; } duke@435: void clear_does_jsr() { _flags &= ~DoesJsr; } duke@435: void set_does_ret() { _flags |= DoesRet; } kvn@461: void clear_does_ret() { _flags &= ~DoesRet; } duke@435: void set_is_ret_target() { _flags |= RetTarget; } duke@435: void set_has_handler() { _flags |= HasHandler; } kvn@461: void clear_exception_handler() { _flags &= ~Handler; _ex_start_bci = -1; _ex_limit_bci = -1; } duke@435: #ifndef PRODUCT duke@435: ciMethod *method() const { return _method; } duke@435: void dump(); duke@435: void print_on(outputStream* st) const PRODUCT_RETURN; duke@435: #endif duke@435: };