/* * Copyright (c) 1997, 2022, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. *
*/
class CodeBlob; class CompiledMethod; class FrameValues; class InterpreterOopMap; class JavaCallWrapper; class Method; class methodHandle; class RegisterMap; 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 { private: // Instance variables: union {
intptr_t* _sp; // stack pointer (from Thread::last_Java_sp) int _offset_sp; // used by frames in stack chunks
};
address _pc; // program counter (the next instruction after the call) mutable CodeBlob* _cb; // CodeBlob that "owns" pc mutableconst ImmutableOopMap* _oop_map; // oop map, for compiled/stubs frames only enum deopt_state {
not_deoptimized,
is_deoptimized,
unknown
};
deopt_state _deopt_state;
// Do internal pointers in interpreter frames use absolute adddresses or relative (to fp)? // Frames in stack chunks are on the Java heap and use relative addressing; on the stack // they use absolute addressing bool _on_heap; // This frame represents a frame on the heap.
DEBUG_ONLY(int _frame_index;) // the frame index in a stack chunk; -1 when on a thread stack
// We use different assertions to allow for intermediate states (e.g. during thawing or relativizing the frame) void assert_on_heap() const { assert(is_heap_frame(), "Using offset with a non-chunk frame"); } void assert_offset() const { assert(_frame_index >= 0, "Using offset with a non-chunk frame"); assert_on_heap(); } void assert_absolute() const { assert(_frame_index == -1, "Using absolute addresses with a chunk frame"); }
public: // Constructors
frame();
explicit frame(bool dummy) {} // no initialization
explicit frame(intptr_t* sp);
#ifndef PRODUCT // This is a generic constructor which is only used by pns() in debug.cpp. // pns (i.e. print native stack) uses this constructor to create a starting // frame for stack walking. The implementation of this constructor is platform // dependent (i.e. SPARC doesn't need an 'fp' argument an will ignore it) but // we want to keep the signature generic because pns() is shared code.
frame(void* sp, void* fp, void* pc); #endif
// Accessors
// pc: Returns the pc at which this frame will continue normally. // It must point at the beginning of the next instruction to execute.
address pc() const { return _pc; }
// 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.
address raw_pc() const;
// 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.
// is this frame doing a call using the compiled calling convention? bool is_compiled_caller() const { return is_compiled_frame() || is_upcall_stub_frame();
}
// 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;
// the frame size in machine words inlineint frame_size() const;
// the size, in words, of stack-passed arguments inlineint compiled_frame_stack_argsize() const;
public: // Link (i.e., the pointer to the previous frame) // might crash if the frame has no parent
intptr_t* link() const;
// Link (i.e., the pointer to the previous frame) or null if the link cannot be accessed
intptr_t* link_or_null() const;
// Return address
address sender_pc() const;
// Support for deoptimization void deoptimize(JavaThread* thread);
// 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; void set_unextended_sp(intptr_t* value);
int offset_unextended_sp() const; void set_offset_unextended_sp(int value);
// returns the stack pointer of the calling frame
intptr_t* sender_sp() const;
// Returns the real 'frame pointer' for the current frame. // This is the value expected by the platform ABI when it defines a // frame pointer register. It may differ from the effective value of // the FP register when that register is used in the JVM for other // purposes (like compiled frames on some platforms). // On other platforms, it is defined so that the stack area used by // this frame goes from real_fp() to sp().
intptr_t* real_fp() const;
// Deoptimization info, if needed (platform dependent). // Stored in the initial_info field of the unroll info, to be used by // the platform dependent deoptimization blobs.
intptr_t *initial_deoptimization_info();
// method data pointer
address interpreter_frame_mdp() const; void interpreter_frame_set_mdp(address dp);
// Find receiver out of caller's (compiled) argument list
oop retrieve_receiver(RegisterMap *reg_map);
// Return the monitor owner and BasicLock for compiled synchronized // native methods. Used by JVMTI's GetLocalInstance method // (via VM_GetReceiver) to retrieve the receiver from a native wrapper frame.
BasicLock* get_native_monitor();
oop get_native_receiver();
// 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);
// template based interpreter deoptimization support void set_interpreter_frame_sender_sp(intptr_t* sender_sp); void interpreter_frame_set_monitor_end(BasicObjectLock* value);
// Address of the temp oop in the frame. Needed as GC root.
oop* interpreter_frame_temp_oop_addr() const;
// 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
// Return/result value from this interpreter 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.
BasicType interpreter_frame_result(oop* oop_result, jvalue* value_result);
// Add annotated descriptions of memory locations belonging to this frame to values void describe(FrameValues& values, int frame_no, const RegisterMap* reg_map=NULL);
// Conversion from a VMReg to physical stack location template <typename RegisterMapT>
address oopmapreg_to_location(VMReg reg, const RegisterMapT* reg_map) const; template <typename RegisterMapT>
oop* oopmapreg_to_oop_location(VMReg reg, const RegisterMapT* reg_map) const;
// RedefineClasses support for finding live interpreted methods on the stack void metadata_do(MetadataClosure* f) const;
// Verification void verify(const RegisterMap* map) const; staticbool verify_return_pc(address x); // Usage: // assert(frame::verify_return_pc(return_address), "must be a return pc");
#include CPU_HEADER(frame)
};
#ifndef PRODUCT // A simple class to describe a location on the stack class FrameValue { public:
intptr_t* location; char* description; int owner; int priority;
// A collection of described stack values that can print a symbolic // description of the stack memory. Interpreter frame values can be // in the caller frames so all the values are collected first and then // sorted before being printed. class FrameValues { private:
GrowableArray<FrameValue> _values;
staticint compare(FrameValue* a, FrameValue* b) { if (a->location == b->location) { return a->priority - b->priority;
} return a->location - b->location;
}
void print_on(outputStream* out, int min_index, int max_index, intptr_t* v0, intptr_t* v1, bool on_heap = false);
public: // Used by frame functions to describe locations. void describe(int owner, intptr_t* location, constchar* description, int priority = 0);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.