00001 /* Copyright 1994, 1995 LongView Technologies L.L.C. $Revision: 1.50 $ */ 00002 /* Copyright (c) 2006, Sun Microsystems, Inc. 00003 All rights reserved. 00004 00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 00006 following conditions are met: 00007 00008 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 00009 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 00010 disclaimer in the documentation and/or other materials provided with the distribution. 00011 * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 00012 from this software without specific prior written permission. 00013 00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 00020 00021 00022 */ 00023 00024 // A frame represents a physical stack frame (an activation). Frames can be 00025 // C or Delta frames, and the Delta frames can be interpreted or compiled. 00026 // In contrast, vframes represent source-level activations, so that one (Delta) frame 00027 // can correspond to multiple deltaVFrames because of inlining. 00028 00029 // Layout of interpreter frame: 00030 // [locals + expr ] * <- sp 00031 // [old frame pointer ] <- fp 00032 // [return pc ] 00033 // [previous locals + expr] <- sender sp 00034 00035 // Layout of deoptimized frame: 00036 // [&unpack_unoptimized_frame ] // patched return address 00037 // [scrap area ] * <- sp 00038 // [sender sp ] 00039 // [frame array ] // objArrayOop holding the deoptimized frames 00040 // [old frame ] <- fp // old frame may skip real frames deoptimized away. 00041 // [return pc ] 00042 00043 const int frame_temp_offset = -3; // For interpreter frames only 00044 const int frame_hp_offset = -2; // For interpreter frames only 00045 const int frame_receiver_offset = -1; // For interpreter frames only 00046 const int frame_next_Delta_fp_offset = -1; // For entry frames only; see call_delta in interpreter_asm.asm 00047 const int frame_next_Delta_sp_offset = -2; // For entry frames only; see call_delta in interpreter_asm.asm 00048 const int frame_link_offset = 0; 00049 const int frame_return_addr_offset = 1; 00050 const int frame_arg_offset = 2; 00051 const int frame_sender_sp_offset = 2; 00052 00053 const int frame_real_sender_sp_offset = -2; // For deoptimized frames only 00054 const int frame_frame_array_offset = -1; // For deoptimized frames only 00055 00056 const int interpreted_frame_float_magic_offset = frame_temp_offset - 1; 00057 const int compiled_frame_magic_oop_offset = -1; 00058 const int minimum_size_for_deoptimized_frame = 4; 00059 00060 class frame : ValueObj { 00061 private: 00062 oop* _sp; // stack pointer 00063 int* _fp; // frame pointer 00064 char* _pc; // program counter 00065 00066 public: 00067 // Constructors 00068 frame() {} 00069 frame(oop* sp, int* fp, char* pc) { 00070 _sp = sp; _fp = fp; _pc = pc; 00071 } 00072 00073 frame(oop* sp, int* fp) { 00074 _sp = sp; 00075 _fp = fp; 00076 _pc = (char*) sp[-1]; 00077 } 00078 00079 // accessors for the instance variables 00080 oop* sp() const { return _sp; } 00081 int* fp() const { return _fp; } 00082 char* pc() const { return _pc; } 00083 00084 // patching operations 00085 void patch_pc(char* pc); // patch the return address of the frame below. 00086 void patch_fp(int* fp); // patch the link of the frame below. 00087 00088 int* addr_at(int index) const { return &fp()[index]; } 00089 int at(int index) const { return *addr_at(index); } 00090 00091 private: 00092 int** link_addr() const { return (int**) addr_at(frame_link_offset); } 00093 char** return_addr_addr() const { return (char**) addr_at(frame_return_addr_offset); } 00094 00095 // support for interpreter frames 00096 oop* receiver_addr() const { return (oop*) addr_at(frame_receiver_offset); } 00097 u_char** hp_addr() const { return (u_char**) addr_at(frame_hp_offset); } 00098 oop* arg_addr(int off) const { return (oop*) addr_at(frame_arg_offset + off); } 00099 00100 public: 00101 // returns the stack pointer of the calling frame 00102 oop* sender_sp() const { return (oop*) addr_at(frame_sender_sp_offset); } 00103 00104 // Link 00105 int* link() const { return *link_addr(); } 00106 void set_link(int* addr) { *link_addr() = addr; } 00107 00108 // Return address 00109 char* return_addr() const { return *return_addr_addr(); } 00110 void set_return_addr(char* addr) { *return_addr_addr() = addr; } 00111 00112 // Receiver 00113 oop receiver() const { return *receiver_addr(); } 00114 void set_receiver(oop recv) { *receiver_addr() = recv; } 00115 00116 // Temporaries 00117 oop temp(int offset) const { return *temp_addr(offset); } 00118 void set_temp(int offset, oop obj) { *temp_addr(offset) = obj; } 00119 oop* temp_addr(int offset) const { return (oop*) addr_at(frame_temp_offset - offset); } 00120 00121 // Arguments 00122 oop arg(int offset) const { return *arg_addr(offset); } 00123 void set_arg(int offset, oop obj) { *arg_addr(offset) = obj; } 00124 00125 // Expressions 00126 oop expr(int index) const { return ((oop*)sp())[index]; } 00127 00128 // Hybrid Code Pointer (interpreted frames only); corresponds to "current PC", not return address 00129 u_char* hp() const; 00130 void set_hp(u_char* hp); 00131 00132 // Returns the method for a valid hp() or NULL if frame not set up yet (interpreted frames only) 00133 // Used by the profiler which means we must check for 00134 // valid frame before using the hp value. 00135 methodOop method() const; 00136 00137 // compiled code (compiled frames only) 00138 nmethod* code() const; 00139 00140 private: 00141 // Float support 00142 inline bool has_interpreted_float_marker() const; 00143 bool oop_iterate_interpreted_float_frame(OopClosure* blk); 00144 bool follow_roots_interpreted_float_frame(); 00145 00146 inline bool has_compiled_float_marker() const; 00147 bool oop_iterate_compiled_float_frame(OopClosure* blk); 00148 bool follow_roots_compiled_float_frame(); 00149 public: 00150 00151 // Accessors for (deoptimized frames only) 00152 objArrayOop* frame_array_addr() const; 00153 oop** real_sender_sp_addr() const; 00154 00155 objArrayOop frame_array() const; 00156 void set_frame_array(objArrayOop a) { *frame_array_addr() = a; } 00157 00158 oop* real_sender_sp() const { return *real_sender_sp_addr(); } 00159 void set_real_sender_sp(oop* addr) { *real_sender_sp_addr() = addr; } 00160 00161 // returns the frame size in oops 00162 int frame_size() const { return sender_sp() - sp(); } 00163 00164 // returns the the sending frame 00165 frame sender() const; 00166 // returns the the sending Delta frame, skipping any intermediate C frames 00167 // NB: receiver must not be first frame 00168 frame delta_sender() const; 00169 00170 // tells whether there is another chunk of Delta stack above (entry frames only) 00171 bool has_next_Delta_fp() const; 00172 // returns the next C entry frame (entry frames only) 00173 int* next_Delta_fp() const; 00174 oop* next_Delta_sp() const; 00175 00176 bool is_first_frame() const; // oldest frame? (has no sender) 00177 bool is_first_delta_frame() const; // same for Delta frame 00178 00179 // testers 00180 bool is_interpreted_frame() const; 00181 bool is_compiled_frame() const; 00182 bool is_delta_frame() const { return is_interpreted_frame() || is_compiled_frame(); } 00183 00184 bool should_be_deoptimized() const; 00185 bool is_entry_frame() const; // Delta frame called from C? 00186 bool is_deoptimized_frame() const; 00187 00188 // inline caches 00189 IC_Iterator* sender_ic_iterator() const; // sending IC (NULL if entry frame or if a perform rather than a send) 00190 IC_Iterator* current_ic_iterator() const; // current IC (will break if not at a send or perform) 00191 InterpretedIC* current_interpretedIC() const; // current IC in this frame; NULL if !is_interpreted_frame 00192 CompiledIC* current_compiledIC() const; // current IC in this frame; NULL if !is_compiled_frame 00193 00194 // Iterators 00195 void oop_iterate(OopClosure* blk); 00196 void layout_iterate(FrameLayoutClosure* blk); 00197 00198 // For debugging 00199 private: 00200 char* print_name() const; 00201 00202 public: 00203 void verify() const; 00204 void print() const; 00205 00206 // Prints the frame in a format useful when debugging deoptimization. 00207 void print_for_deoptimization(outputStream* st); 00208 00209 // Garbage collection operations 00210 void follow_roots(); 00211 void convert_hcode_pointer(); 00212 void restore_hcode_pointer(); 00213 00214 // Returns the size of a number of interpreter frames in words. 00215 // This is used during deoptimization. 00216 static int interpreter_stack_size(int number_of_frames, int number_of_temporaries_and_locals) { 00217 return number_of_frames * interpreter_frame_size(0) 00218 + number_of_temporaries_and_locals; 00219 } 00220 00221 // Returns the word size of an interpreter frame 00222 static int interpreter_frame_size(int locals) { 00223 return frame_return_addr_offset - frame_temp_offset + locals; 00224 } 00225 };