Path: blob/master/src/hotspot/share/runtime/frame.hpp
40951 views
/*1* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_RUNTIME_FRAME_HPP25#define SHARE_RUNTIME_FRAME_HPP2627#include "code/vmregTypes.hpp"28#include "runtime/basicLock.hpp"29#include "runtime/monitorChunk.hpp"30#include "utilities/growableArray.hpp"31#include "utilities/macros.hpp"32#ifdef ZERO33# include "stack_zero.hpp"34#endif3536typedef class BytecodeInterpreter* interpreterState;3738class CodeBlob;39class CompiledMethod;40class FrameValues;41class vframeArray;42class JavaCallWrapper;43class Method;44class methodHandle;45class RegisterMap;4647enum class DerivedPointerIterationMode {48_with_table,49_directly,50_ignore51};5253// A frame represents a physical stack frame (an activation). Frames54// can be C or Java frames, and the Java frames can be interpreted or55// compiled. In contrast, vframes represent source-level activations,56// so that one physical frame can correspond to multiple source level57// frames because of inlining.5859class frame {60private:61// Instance variables:62intptr_t* _sp; // stack pointer (from Thread::last_Java_sp)63address _pc; // program counter (the next instruction after the call)6465CodeBlob* _cb; // CodeBlob that "owns" pc66enum deopt_state {67not_deoptimized,68is_deoptimized,69unknown70};7172deopt_state _deopt_state;7374public:75// Constructors76frame();7778#ifndef PRODUCT79// This is a generic constructor which is only used by pns() in debug.cpp.80// pns (i.e. print native stack) uses this constructor to create a starting81// frame for stack walking. The implementation of this constructor is platform82// dependent (i.e. SPARC doesn't need an 'fp' argument an will ignore it) but83// we want to keep the signature generic because pns() is shared code.84frame(void* sp, void* fp, void* pc);85#endif8687// Accessors8889// pc: Returns the pc at which this frame will continue normally.90// It must point at the beginning of the next instruction to execute.91address pc() const { return _pc; }9293// This returns the pc that if you were in the debugger you'd see. Not94// the idealized value in the frame object. This undoes the magic conversion95// that happens for deoptimized frames. In addition it makes the value the96// hardware would want to see in the native frame. The only user (at this point)97// is deoptimization. It likely no one else should ever use it.98address raw_pc() const;99100void set_pc( address newpc );101102intptr_t* sp() const { return _sp; }103void set_sp( intptr_t* newsp ) { _sp = newsp; }104105106CodeBlob* cb() const { return _cb; }107108// patching operations109void patch_pc(Thread* thread, address pc);110111// Every frame needs to return a unique id which distinguishes it from all other frames.112// For sparc and ia32 use sp. ia64 can have memory frames that are empty so multiple frames113// will have identical sp values. For ia64 the bsp (fp) value will serve. No real frame114// should have an id() of NULL so it is a distinguishing value for an unmatchable frame.115// We also have relationals which allow comparing a frame to anoth frame's id() allow116// us to distinguish younger (more recent activation) from older (less recent activations)117// A NULL id is only valid when comparing for equality.118119intptr_t* id(void) const;120bool is_younger(intptr_t* id) const;121bool is_older(intptr_t* id) const;122123// testers124125// Compares for strict equality. Rarely used or needed.126// It can return a different result than f1.id() == f2.id()127bool equal(frame other) const;128129// type testers130bool is_interpreted_frame() const;131bool is_java_frame() const;132bool is_entry_frame() const; // Java frame called from C?133bool is_stub_frame() const;134bool is_ignored_frame() const;135bool is_native_frame() const;136bool is_runtime_frame() const;137bool is_compiled_frame() const;138bool is_safepoint_blob_frame() const;139bool is_deoptimized_frame() const;140bool is_optimized_entry_frame() const;141142// testers143bool is_first_frame() const; // oldest frame? (has no sender)144bool is_first_java_frame() const; // same for Java frame145146bool is_interpreted_frame_valid(JavaThread* thread) const; // performs sanity checks on interpreted frames.147148// tells whether this frame is marked for deoptimization149bool should_be_deoptimized() const;150151// tells whether this frame can be deoptimized152bool can_be_deoptimized() const;153154// returns the frame size in stack slots155int frame_size(RegisterMap* map) const;156157// returns the sending frame158frame sender(RegisterMap* map) const;159160bool safe_for_sender(JavaThread *thread);161162// returns the sender, but skips conversion frames163frame real_sender(RegisterMap* map) const;164165// returns the the sending Java frame, skipping any intermediate C frames166// NB: receiver must not be first frame167frame java_sender() const;168169private:170// Helper methods for better factored code in frame::sender171frame sender_for_compiled_frame(RegisterMap* map) const;172frame sender_for_entry_frame(RegisterMap* map) const;173frame sender_for_interpreter_frame(RegisterMap* map) const;174frame sender_for_native_frame(RegisterMap* map) const;175frame sender_for_optimized_entry_frame(RegisterMap* map) const;176177bool is_entry_frame_valid(JavaThread* thread) const;178179// All frames:180181// A low-level interface for vframes:182183public:184185intptr_t* addr_at(int index) const { return &fp()[index]; }186intptr_t at(int index) const { return *addr_at(index); }187188// accessors for locals189oop obj_at(int offset) const { return *obj_at_addr(offset); }190void obj_at_put(int offset, oop value) { *obj_at_addr(offset) = value; }191192jint int_at(int offset) const { return *int_at_addr(offset); }193void int_at_put(int offset, jint value) { *int_at_addr(offset) = value; }194195oop* obj_at_addr(int offset) const { return (oop*) addr_at(offset); }196197oop* adjusted_obj_at_addr(Method* method, int index) { return obj_at_addr(adjust_offset(method, index)); }198199private:200jint* int_at_addr(int offset) const { return (jint*) addr_at(offset); }201202public:203// Link (i.e., the pointer to the previous frame)204intptr_t* link() const;205206// Return address207address sender_pc() const;208209// Support for deoptimization210void deoptimize(JavaThread* thread);211212// The frame's original SP, before any extension by an interpreted callee;213// used for packing debug info into vframeArray objects and vframeArray lookup.214intptr_t* unextended_sp() const;215216// returns the stack pointer of the calling frame217intptr_t* sender_sp() const;218219// Returns the real 'frame pointer' for the current frame.220// This is the value expected by the platform ABI when it defines a221// frame pointer register. It may differ from the effective value of222// the FP register when that register is used in the JVM for other223// purposes (like compiled frames on some platforms).224// On other platforms, it is defined so that the stack area used by225// this frame goes from real_fp() to sp().226intptr_t* real_fp() const;227228// Deoptimization info, if needed (platform dependent).229// Stored in the initial_info field of the unroll info, to be used by230// the platform dependent deoptimization blobs.231intptr_t *initial_deoptimization_info();232233// Interpreter frames:234235private:236intptr_t** interpreter_frame_locals_addr() const;237intptr_t* interpreter_frame_bcp_addr() const;238intptr_t* interpreter_frame_mdp_addr() const;239240public:241// Locals242243// The _at version returns a pointer because the address is used for GC.244intptr_t* interpreter_frame_local_at(int index) const;245246void interpreter_frame_set_locals(intptr_t* locs);247248// byte code index249jint interpreter_frame_bci() const;250251// byte code pointer252address interpreter_frame_bcp() const;253void interpreter_frame_set_bcp(address bcp);254255// method data pointer256address interpreter_frame_mdp() const;257void interpreter_frame_set_mdp(address dp);258259// Find receiver out of caller's (compiled) argument list260oop retrieve_receiver(RegisterMap *reg_map);261262// Return the monitor owner and BasicLock for compiled synchronized263// native methods so that biased locking can revoke the receiver's264// bias if necessary. This is also used by JVMTI's GetLocalInstance method265// (via VM_GetReceiver) to retrieve the receiver from a native wrapper frame.266BasicLock* get_native_monitor();267oop get_native_receiver();268269// Find receiver for an invoke when arguments are just pushed on stack (i.e., callee stack-frame is270// not setup)271oop interpreter_callee_receiver(Symbol* signature) { return *interpreter_callee_receiver_addr(signature); }272273274oop* interpreter_callee_receiver_addr(Symbol* signature);275276277// expression stack (may go up or down, direction == 1 or -1)278public:279intptr_t* interpreter_frame_expression_stack() const;280281// The _at version returns a pointer because the address is used for GC.282intptr_t* interpreter_frame_expression_stack_at(jint offset) const;283284// top of expression stack285intptr_t* interpreter_frame_tos_at(jint offset) const;286intptr_t* interpreter_frame_tos_address() const;287288289jint interpreter_frame_expression_stack_size() const;290291intptr_t* interpreter_frame_sender_sp() const;292293// template based interpreter deoptimization support294void set_interpreter_frame_sender_sp(intptr_t* sender_sp);295void interpreter_frame_set_monitor_end(BasicObjectLock* value);296297// Address of the temp oop in the frame. Needed as GC root.298oop* interpreter_frame_temp_oop_addr() const;299300// BasicObjectLocks:301//302// interpreter_frame_monitor_begin is higher in memory than interpreter_frame_monitor_end303// Interpreter_frame_monitor_begin points to one element beyond the oldest one,304// interpreter_frame_monitor_end points to the youngest one, or if there are none,305// it points to one beyond where the first element will be.306// interpreter_frame_monitor_size reports the allocation size of a monitor in the interpreter stack.307// this value is >= BasicObjectLock::size(), and may be rounded up308309BasicObjectLock* interpreter_frame_monitor_begin() const;310BasicObjectLock* interpreter_frame_monitor_end() const;311BasicObjectLock* next_monitor_in_interpreter_frame(BasicObjectLock* current) const;312BasicObjectLock* previous_monitor_in_interpreter_frame(BasicObjectLock* current) const;313static int interpreter_frame_monitor_size();314315void interpreter_frame_verify_monitor(BasicObjectLock* value) const;316317// Return/result value from this interpreter frame318// If the method return type is T_OBJECT or T_ARRAY populates oop_result319// For other (non-T_VOID) the appropriate field in the jvalue is populated320// with the result value.321// Should only be called when at method exit when the method is not322// exiting due to an exception.323BasicType interpreter_frame_result(oop* oop_result, jvalue* value_result);324325public:326// Method & constant pool cache327Method* interpreter_frame_method() const;328void interpreter_frame_set_method(Method* method);329Method** interpreter_frame_method_addr() const;330ConstantPoolCache** interpreter_frame_cache_addr() const;331oop* interpreter_frame_mirror_addr() const;332333void interpreter_frame_set_mirror(oop mirror);334335public:336// Entry frames337JavaCallWrapper* entry_frame_call_wrapper() const { return *entry_frame_call_wrapper_addr(); }338JavaCallWrapper* entry_frame_call_wrapper_if_safe(JavaThread* thread) const;339JavaCallWrapper** entry_frame_call_wrapper_addr() const;340intptr_t* entry_frame_argument_at(int offset) const;341342// tells whether there is another chunk of Delta stack above343bool entry_frame_is_first() const;344345// Safepoints346347public:348oop saved_oop_result(RegisterMap* map) const;349void set_saved_oop_result(RegisterMap* map, oop obj);350351// For debugging352private:353const char* print_name() const;354355void describe_pd(FrameValues& values, int frame_no);356357public:358void print_value() const { print_value_on(tty,NULL); }359void print_value_on(outputStream* st, JavaThread *thread) const;360void print_on(outputStream* st) const;361void interpreter_frame_print_on(outputStream* st) const;362void print_on_error(outputStream* st, char* buf, int buflen, bool verbose = false) const;363static void print_C_frame(outputStream* st, char* buf, int buflen, address pc);364365// Add annotated descriptions of memory locations belonging to this frame to values366void describe(FrameValues& values, int frame_no);367368// Conversion from a VMReg to physical stack location369address oopmapreg_to_location(VMReg reg, const RegisterMap* reg_map) const;370oop* oopmapreg_to_oop_location(VMReg reg, const RegisterMap* reg_map) const;371372// Oops-do's373void oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix, const RegisterMap* reg_map, OopClosure* f) const;374void oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool query_oop_map_cache = true) const;375376private:377void oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f) const;378379// Iteration of oops380void oops_do_internal(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* map,381bool use_interpreter_oop_map_cache, DerivedPointerIterationMode derived_mode) const;382void oops_entry_do(OopClosure* f, const RegisterMap* map) const;383void oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* map,384DerivedPointerIterationMode derived_mode) const;385int adjust_offset(Method* method, int index); // helper for above fn386public:387// Memory management388void oops_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* map,389DerivedPointerIterationMode derived_mode) const;390void oops_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* map) const;391void nmethods_do(CodeBlobClosure* cf) const;392393// RedefineClasses support for finding live interpreted methods on the stack394void metadata_do(MetadataClosure* f) const;395396// Verification397void verify(const RegisterMap* map) const;398static bool verify_return_pc(address x);399// Usage:400// assert(frame::verify_return_pc(return_address), "must be a return pc");401402NOT_PRODUCT(void pd_ps();) // platform dependent frame printing403404#include CPU_HEADER(frame)405406};407408#ifndef PRODUCT409// A simple class to describe a location on the stack410class FrameValue {411public:412intptr_t* location;413char* description;414int owner;415int priority;416417FrameValue() {418location = NULL;419description = NULL;420owner = -1;421priority = 0;422}423424};425426427// A collection of described stack values that can print a symbolic428// description of the stack memory. Interpreter frame values can be429// in the caller frames so all the values are collected first and then430// sorted before being printed.431class FrameValues {432private:433GrowableArray<FrameValue> _values;434435static int compare(FrameValue* a, FrameValue* b) {436if (a->location == b->location) {437return a->priority - b->priority;438}439return a->location - b->location;440}441442public:443// Used by frame functions to describe locations.444void describe(int owner, intptr_t* location, const char* description, int priority = 0);445446#ifdef ASSERT447void validate();448#endif449void print(JavaThread* thread) { print_on(thread, tty); }450void print_on(JavaThread* thread, outputStream* out);451};452453#endif454455456#endif // SHARE_RUNTIME_FRAME_HPP457458459