/* Sun-$Revision: 23.5 $ */ /* Copyright 1992-9 Sun Microsystems, Inc. and Stanford University. See the LICENSE file for license information. */ # pragma interface // sparc frame layout: /* prev frame %fp-> ---------------------------------------------- %fp - offset: space for automatic arrays, aggregates, and addressable scalar automatics. (Self compiled frames alloc extras here for frame chains and currentPCs) ------------------------------- space dynamically allocated via alloca(), if any alloca()-> ---------------------------- space if needed for compiler temps and saved floating %sp + offset -point registers ---------------------------- %sp + offset outgoing params past the sixth, if any ----------------------------- %sp + offset 6 words into which callee may store reg args ----------------------------- %sp + offset one-word hidden param (addr where callee should store aggregate return value) ----------------------------- %sp + offset 16 words in which to save register window (in and locals) %sp-> ------------------------------------------------ next frame */ class sparc_fp; class sparc_sp; class frame; class sparc_fp { friend frame; friend FrameIterator; friend sparc_sp; sparc_fp() { ShouldNotCallThis(); } sparc_fp(sparc_fp &s) { ShouldNotCallThis(); } // coercions oop* as_oops() { return (oop*) this; } sparc_sp* as_callers_sp() { return (sparc_sp*)this; } // nmethod frame chain operations: // this is a word allocated by the Self compiler to allow // frames that use an nmethod to be linked frame** nmethod_frame_chain_addr() { return &((frame**) this)[nmethod_frame_chain_offset]; } char** currentPC_addr() { return &((char** ) this)[current_pc_offset]; } }; class Conversion; class Recompilation; class sparc_sp { friend sparc_fp; friend frame; friend FrameIterator; friend Conversion; // this is sparc-specific for now friend Recompilation; // this is sparc-specific for now sparc_sp() { ShouldNotCallThis(); } sparc_sp(sparc_sp &s) { ShouldNotCallThis(); } // coercions sparc_fp* as_callees_fp() { return (sparc_fp*)this; } frame* as_callers_frame() { return (frame*)this; } oop* as_oops() { return (oop*)this; } // what is stored here: // link is a low-level machine-dependent concept about how // frames are stiched together (senders are high-level) // could use location_addr but this is faster: sparc_fp** link_addr() { return &((sparc_fp**) this)[frame_offset]; } sparc_fp* link() { return *link_addr(); } void set_link(sparc_fp* x) { *link_addr() = x; } void adjust_link(int32 delta) { *(char**)link_addr() += delta; } // return address, no patch/real distinction here char** return_addr_addr() { return &((char**) this)[pc_offset]; } char* return_addr() { return *return_addr_addr(); } void set_return_addr(char* x) { *return_addr_addr() = x; } void** location_addr(Location r); public: sparc_sp* push_new_sp( char* pc, fint size_in_oops = 0, bool zapAlways = false); };