1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
/*
* Copyright (c) 1997, 2018, 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.
*
*/
#ifndef CPU_X86_VM_FRAME_X86_HPP
#define CPU_X86_VM_FRAME_X86_HPP
#include "runtime/synchronizer.hpp"
// 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.
// A frame is comprised of {pc, fp, sp}
// ------------------------------ Asm interpreter ----------------------------------------
// Layout of asm interpreter frame:
// [expression stack ] * <- sp
// [monitors ] \
// ... | monitor block size
// [monitors ] /
// [monitor block size ]
// [byte code pointer ] = bcp() bcp_offset
// [pointer to locals ] = locals() locals_offset
// [constant pool cache ] = cache() cache_offset
// [methodData ] = mdp() mdx_offset
// [Method* ] = method() method_offset
// [last sp ] = last_sp() last_sp_offset
// [old stack pointer ] (sender_sp) sender_sp_offset
// [old frame pointer ] <- fp = link()
// [return pc ]
// [oop temp ] (only for native calls)
// [locals and parameters ]
// <- sender sp
// ------------------------------ Asm interpreter ----------------------------------------
public:
enum {
pc_return_offset = 0,
// All frames
link_offset = 0,
return_addr_offset = 1,
// non-interpreter frames
sender_sp_offset = 2,
// Interpreter frames
interpreter_frame_result_handler_offset = 3, // for native calls only
interpreter_frame_oop_temp_offset = 2, // for native calls only
interpreter_frame_sender_sp_offset = -1,
// outgoing sp before a call to an invoked method
interpreter_frame_last_sp_offset = interpreter_frame_sender_sp_offset - 1,
interpreter_frame_method_offset = interpreter_frame_last_sp_offset - 1,
interpreter_frame_mirror_offset = interpreter_frame_method_offset - 1,
interpreter_frame_mdp_offset = interpreter_frame_mirror_offset - 1,
interpreter_frame_cache_offset = interpreter_frame_mdp_offset - 1,
interpreter_frame_locals_offset = interpreter_frame_cache_offset - 1,
interpreter_frame_bcp_offset = interpreter_frame_locals_offset - 1,
interpreter_frame_initial_sp_offset = interpreter_frame_bcp_offset - 1,
interpreter_frame_monitor_block_top_offset = interpreter_frame_initial_sp_offset,
interpreter_frame_monitor_block_bottom_offset = interpreter_frame_initial_sp_offset,
// Entry frames
#ifdef AMD64
#ifdef _WIN64
entry_frame_after_call_words = 60,
entry_frame_call_wrapper_offset = 2,
arg_reg_save_area_bytes = 32 // Register argument save area
#else
entry_frame_after_call_words = 13,
entry_frame_call_wrapper_offset = -6,
arg_reg_save_area_bytes = 0
#endif // _WIN64
#else
entry_frame_call_wrapper_offset = 2
#endif // AMD64
};
intptr_t ptr_at(int offset) const {
return *ptr_at_addr(offset);
}
void ptr_at_put(int offset, intptr_t value) {
*ptr_at_addr(offset) = value;
}
private:
// an additional field beyond _sp and _pc:
intptr_t* _fp; // frame pointer
// The interpreter and adapters will extend the frame of the caller.
// Since oopMaps are based on the sp of the caller before extension
// we need to know that value. However in order to compute the address
// of the return address we need the real "raw" sp. Since sparc already
// uses sp() to mean "raw" sp and unextended_sp() to mean the caller's
// original sp we use that convention.
intptr_t* _unextended_sp;
void adjust_unextended_sp() NOT_DEBUG_RETURN;
intptr_t* ptr_at_addr(int offset) const {
return (intptr_t*) addr_at(offset);
}
#ifdef ASSERT
// Used in frame::sender_for_{interpreter,compiled}_frame
static void verify_deopt_original_pc(CompiledMethod* nm, intptr_t* unextended_sp);
#endif
public:
// Constructors
frame(intptr_t* sp, intptr_t* fp, address pc);
frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc);
frame(intptr_t* sp, intptr_t* fp);
void init(intptr_t* sp, intptr_t* fp, address pc);
// accessors for the instance variables
// Note: not necessarily the real 'frame pointer' (see real_fp)
intptr_t* fp() const { return _fp; }
inline address* sender_pc_addr() const;
// expression stack tos if we are nested in a java call
intptr_t* interpreter_frame_last_sp() const;
// helper to update a map with callee-saved RBP
static void update_map_with_saved_link(RegisterMap* map, intptr_t** link_addr);
// deoptimization support
void interpreter_frame_set_last_sp(intptr_t* sp);
static jint interpreter_frame_expression_stack_direction() { return -1; }
#endif // CPU_X86_VM_FRAME_X86_HPP
|