frame.hpp revision 2062
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_RUNTIME_FRAME_HPP
#define SHARE_VM_RUNTIME_FRAME_HPP
#include "asm/assembler.hpp"
#include "oops/methodOop.hpp"
#include "runtime/basicLock.hpp"
#include "runtime/monitorChunk.hpp"
#include "runtime/registerMap.hpp"
#ifdef COMPILER2
#ifdef TARGET_ARCH_MODEL_x86_32
# include "adfiles/adGlobals_x86_32.hpp"
#endif
#ifdef TARGET_ARCH_MODEL_x86_64
# include "adfiles/adGlobals_x86_64.hpp"
#endif
#ifdef TARGET_ARCH_MODEL_sparc
# include "adfiles/adGlobals_sparc.hpp"
#endif
#ifdef TARGET_ARCH_MODEL_zero
# include "adfiles/adGlobals_zero.hpp"
#endif
#endif
#ifdef ZERO
#ifdef TARGET_ARCH_zero
# include "stack_zero.hpp"
#endif
#endif
typedef class BytecodeInterpreter* interpreterState;
class CodeBlob;
class vframeArray;
// A frame represents a physical stack frame (an activation). Frames
// can be C or Java frames, and the Java frames can be interpreted or
// compiled. In contrast, vframes represent source-level activations,
// so that one physical frame can correspond to multiple source level
// frames because of inlining.
class frame VALUE_OBJ_CLASS_SPEC {
private:
// Instance variables:
enum deopt_state {
};
public:
// Constructors
frame();
// Accessors
// pc: Returns the pc at which this frame will continue normally.
// It must point at the beginning of the next instruction to execute.
// This returns the pc that if you were in the debugger you'd see. Not
// the idealized value in the frame object. This undoes the magic conversion
// that happens for deoptimized frames. In addition it makes the value the
// hardware would want to see in the native frame. The only user (at this point)
// is deoptimization. It likely no one else should ever use it.
// patching operations
// Every frame needs to return a unique id which distinguishes it from all other frames.
// For sparc and ia32 use sp. ia64 can have memory frames that are empty so multiple frames
// will have identical sp values. For ia64 the bsp (fp) value will serve. No real frame
// should have an id() of NULL so it is a distinguishing value for an unmatchable frame.
// We also have relationals which allow comparing a frame to anoth frame's id() allow
// us to distinguish younger (more recent activation) from older (less recent activations)
// A NULL id is only valid when comparing for equality.
// testers
// Compares for strict equality. Rarely used or needed.
// It can return a different result than f1.id() == f2.id()
// type testers
bool is_interpreted_frame() const;
bool is_java_frame() const;
bool is_entry_frame() const; // Java frame called from C?
bool is_native_frame() const;
bool is_runtime_frame() const;
bool is_compiled_frame() const;
bool is_safepoint_blob_frame() const;
bool is_deoptimized_frame() const;
// testers
bool is_first_frame() const; // oldest frame? (has no sender)
bool is_first_java_frame() const; // same for Java frame
bool is_interpreted_frame_valid(JavaThread* thread) const; // performs sanity checks on interpreted frames.
// tells whether this frame is marked for deoptimization
bool should_be_deoptimized() const;
// tells whether this frame can be deoptimized
bool can_be_deoptimized() const;
// returns the frame size in stack slots
// returns the sending frame
// for Profiling - acting on another frame. walks sender frames
// if valid.
// returns the sender, but skips conversion frames
// returns the the sending Java frame, skipping any intermediate C frames
// NB: receiver must not be first frame
frame java_sender() const;
private:
// Helper methods for better factored code in frame::sender
// All frames:
// A low-level interface for vframes:
public:
// accessors for locals
oop* adjusted_obj_at_addr(methodOop method, int index) { return obj_at_addr(adjust_offset(method, index)); }
private:
public:
// Link (i.e., the pointer to the previous frame)
// Return address
// Support for deoptimization
// The frame's original SP, before any extension by an interpreted callee;
// used for packing debug info into vframeArray objects and vframeArray lookup.
intptr_t* unextended_sp() const;
// returns the stack pointer of the calling frame
// Interpreter frames:
private:
intptr_t** interpreter_frame_locals_addr() const;
intptr_t* interpreter_frame_bcx_addr() const;
intptr_t* interpreter_frame_mdx_addr() const;
public:
// Locals
// The _at version returns a pointer because the address is used for GC.
// byte code index
jint interpreter_frame_bci() const;
// byte code pointer
address interpreter_frame_bcp() const;
// Only use this if you know what you are doing.
// method data pointer
address interpreter_frame_mdp() const;
// Find receiver out of caller's (compiled) argument list
// Return the monitor owner and BasicLock for compiled synchronized
// native methods so that biased locking can revoke the receiver's
// bias if necessary. This is also used by JVMTI's GetLocalInstance method
// (via VM_GetReceiver) to retrieve the receiver from a native wrapper frame.
// Find receiver for an invoke when arguments are just pushed on stack (i.e., callee stack-frame is
// not setup)
oop interpreter_callee_receiver(Symbol* signature) { return *interpreter_callee_receiver_addr(signature); }
// expression stack (may go up or down, direction == 1 or -1)
public:
intptr_t* interpreter_frame_expression_stack() const;
// The _at version returns a pointer because the address is used for GC.
// top of expression stack
intptr_t* interpreter_frame_tos_address() const;
intptr_t* interpreter_frame_sender_sp() const;
#ifndef CC_INTERP
// template based interpreter deoptimization support
#endif // CC_INTERP
// BasicObjectLocks:
//
// interpreter_frame_monitor_begin is higher in memory than interpreter_frame_monitor_end
// Interpreter_frame_monitor_begin points to one element beyond the oldest one,
// interpreter_frame_monitor_end points to the youngest one, or if there are none,
// it points to one beyond where the first element will be.
// interpreter_frame_monitor_size reports the allocation size of a monitor in the interpreter stack.
// this value is >= BasicObjectLock::size(), and may be rounded up
BasicObjectLock* interpreter_frame_monitor_end() const;
static int interpreter_frame_monitor_size();
// Tells whether the current interpreter_frame frame pointer
// corresponds to the old compiled/deoptimized fp
// The receiver used to be a top level frame
// If the method return type is T_OBJECT or T_ARRAY populates oop_result
// For other (non-T_VOID) the appropriate field in the jvalue is populated
// with the result value.
// Should only be called when at method exit when the method is not
// exiting due to an exception.
public:
// Method & constant pool cache
methodOop interpreter_frame_method() const;
methodOop* interpreter_frame_method_addr() const;
#ifdef PPC
oop* interpreter_frame_mirror_addr() const;
#endif
public:
// Entry frames
JavaCallWrapper* entry_frame_call_wrapper() const;
// tells whether there is another chunk of Delta stack above
bool entry_frame_is_first() const;
// Compiled frames:
public:
// Given the index of a local, and the number of argument words
// in this stack frame, tell which word of the stack frame to find
// while other locals are stored below it.
// Since monitors (BasicLock blocks) are also assigned indexes,
// but may have different storage requirements, their presence
// can also affect the calculation of offsets.
static int local_offset_for_compiler(int local_index, int nof_args, int max_nof_locals, int max_nof_monitors);
// Given the index of a monitor, etc., tell which word of the
// stack frame contains the start of the BasicLock block.
// Note that the local index by convention is the __higher__
// of the two indexes allocated to the block.
static int monitor_offset_for_compiler(int local_index, int nof_args, int max_nof_locals, int max_nof_monitors);
// Tell the smallest value that local_offset_for_compiler will attain.
// This is used to help determine how much stack frame to allocate.
// Tells if this register must be spilled during a call.
// On Intel, all registers are smashed by calls.
// Safepoints
public:
// For debugging
private:
const char* print_name() const;
public:
// Conversion from an VMReg to physical stack location
// Oops-do's
void oops_compiled_arguments_do(Symbol* signature, bool has_receiver, const RegisterMap* reg_map, OopClosure* f);
private:
// Iteration of oops
void oops_do_internal(OopClosure* f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache);
public:
// Memory management
void oops_do(OopClosure* f, CodeBlobClosure* cf, RegisterMap* map) { oops_do_internal(f, cf, map, true); }
void gc_prologue();
void gc_epilogue();
void pd_gc_epilog();
# ifdef ENABLE_ZAP_DEAD_LOCALS
private:
class CheckValueClosure: public OopClosure {
public:
};
static CheckValueClosure _check_value;
class CheckOopClosure: public OopClosure {
public:
};
static CheckOopClosure _check_oop;
class ZapDeadClosure: public OopClosure {
public:
};
static ZapDeadClosure _zap_dead;
public:
// Zapping
# endif
// Verification
static bool verify_return_pc(address x);
// Usage:
// assert(frame::verify_return_pc(return_address), "must be a return pc");
int pd_oop_map_offset_adjustment() const;
#ifdef TARGET_ARCH_x86
# include "frame_x86.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "frame_sparc.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "frame_zero.hpp"
#endif
};
//
// StackFrameStream iterates through the frames of a thread starting from
// top most frame. It automatically takes care of updating the location of
// all (callee-saved) registers. Notice: If a thread is stopped at
// a safepoint, all registers are saved, not only the callee-saved ones.
//
// Use:
//
// for(StackFrameStream fst(thread); !fst.is_done(); fst.next()) {
// ...
// }
//
class StackFrameStream : public StackObj {
private:
bool _is_done;
public:
// Iteration
// Query
};
#endif // SHARE_VM_RUNTIME_FRAME_HPP