Mercurial > hg > truffle
diff src/share/vm/code/exceptionHandlerTable.hpp @ 0:a61af66fc99e jdk7-b24
Initial load
author | duke |
---|---|
date | Sat, 01 Dec 2007 00:00:00 +0000 |
parents | |
children | c18cbe5936b8 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/code/exceptionHandlerTable.hpp Sat Dec 01 00:00:00 2007 +0000 @@ -0,0 +1,156 @@ +/* + * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +// A HandlerTableEntry describes an individual entry of a subtable +// of ExceptionHandlerTable. An entry consists of a pair(bci, pco), +// where bci is the exception handler bci, and pco is the pc offset +// relative to the nmethod code start for the compiled exception +// handler corresponding to the (interpreted) exception handler +// starting at bci. +// +// The first HandlerTableEntry of each subtable holds the length +// and catch_pco for the subtable (the length is the number of +// subtable entries w/o header). + +class HandlerTableEntry { + private: + int _bci; + int _pco; + int _scope_depth; + + public: + HandlerTableEntry(int bci, int pco, int scope_depth) { + assert( 0 <= pco, "pco must be positive"); + assert( 0 <= scope_depth, "scope_depth must be positive"); + _bci = bci; + _pco = pco; + _scope_depth = scope_depth; + } + + int len() const { return _bci; } // for entry at subtable begin + int bci() const { return _bci; } + int pco() const { return _pco; } + int scope_depth() const { return _scope_depth; } +}; + + +// An ExceptionHandlerTable is an abstraction over a list of subtables +// of exception handlers for CatchNodes. Each subtable has a one-entry +// header holding length and catch_pco of the subtable, followed +// by 'length' entries for each exception handler that can be reached +// from the corresponding CatchNode. The catch_pco is the pc offset of +// the CatchNode in the corresponding nmethod. Empty subtables are dis- +// carded. +// +// Structure of the table: +// +// table = { subtable }. +// subtable = header entry { entry }. +// header = a pair (number of subtable entries, catch pc offset, [unused]) +// entry = a pair (handler bci, handler pc offset, scope depth) +// +// An ExceptionHandlerTable can be created from scratch, in which case +// it is possible to add subtables. It can also be created from an +// nmethod (for lookup purposes) in which case the table cannot be +// modified. + +class nmethod; +class ExceptionHandlerTable VALUE_OBJ_CLASS_SPEC { + private: + HandlerTableEntry* _table; // the table + int _length; // the current length of the table + int _size; // the number of allocated entries + ReallocMark _nesting; // assertion check for reallocations + + // add the entry & grow the table if needed + void add_entry(HandlerTableEntry entry); + HandlerTableEntry* subtable_for(int catch_pco) const; + + public: + // (compile-time) construction within compiler + ExceptionHandlerTable(int initial_size = 8); + + // (run-time) construction from nmethod + ExceptionHandlerTable(const nmethod* nm); + + // (compile-time) add entries + void add_subtable( + int catch_pco, // the pc offset for the CatchNode + GrowableArray<intptr_t>* handler_bcis, // the exception handler entry point bcis + GrowableArray<intptr_t>* scope_depths_from_top_scope, + // if representing exception handlers in multiple + // inlined scopes, indicates which scope relative to + // the youngest/innermost one in which we are performing + // the lookup; zero (or null GrowableArray) indicates + // innermost scope + GrowableArray<intptr_t>* handler_pcos // pc offsets for the compiled handlers + ); + + // nmethod support + int size_in_bytes() const { return round_to(_length * sizeof(HandlerTableEntry), oopSize); } + void copy_to(nmethod* nm); + + // lookup + HandlerTableEntry* entry_for(int catch_pco, int handler_bci, int scope_depth) const; + + // debugging + void print_subtable(HandlerTableEntry* t) const; + void print() const; + void print_subtable_for(int catch_pco) const; +}; + + +// ---------------------------------------------------------------------------- +// Implicit null exception tables. Maps an exception PC offset to a +// continuation PC offset. During construction it's a variable sized +// array with a max size and current length. When stored inside an +// nmethod a zero length table takes no space. This is detected by +// nul_chk_table_size() == 0. Otherwise the table has a length word +// followed by pairs of <excp-offset, const-offset>. + +// Use 32-bit representation for offsets +typedef uint implicit_null_entry; + +class ImplicitExceptionTable VALUE_OBJ_CLASS_SPEC { + uint _size; + uint _len; + implicit_null_entry *_data; + implicit_null_entry *adr( uint idx ) const { return &_data[2*idx]; } + ReallocMark _nesting; // assertion check for reallocations +public: + ImplicitExceptionTable( ) : _data(0), _size(0), _len(0) { } + // (run-time) construction from nmethod + ImplicitExceptionTable( const nmethod *nm ); + + void set_size( uint size ); + void append( uint exec_off, uint cont_off ); + uint at( uint exec_off ) const; + + uint len() const { return _len; } + int size_in_bytes() const { return len() == 0 ? 0 : ((2 * len() + 1) * sizeof(implicit_null_entry)); } + + void copy_to(nmethod* nm); + void print(address base) const; + void verify(nmethod *nm) const; +};