Path: blob/master/src/hotspot/share/c1/c1_FrameMap.hpp
40931 views
/*1* Copyright (c) 2000, 2020, 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_C1_C1_FRAMEMAP_HPP25#define SHARE_C1_C1_FRAMEMAP_HPP2627#include "asm/macroAssembler.hpp"28#include "c1/c1_Defs.hpp"29#include "c1/c1_LIR.hpp"30#include "code/vmreg.hpp"31#include "memory/allocation.hpp"32#include "runtime/frame.hpp"33#include "runtime/synchronizer.hpp"34#include "utilities/globalDefinitions.hpp"35#include "utilities/macros.hpp"3637class ciMethod;38class CallingConvention;3940//--------------------------------------------------------41// FrameMap42//--------------------------------------------------------4344// This class is responsible of mapping items (locals, monitors, spill45// slots and registers to their frame location46//47// The monitors are specified by a consecutive index, although each monitor entry48// occupies two words. The monitor_index is 0.._num_monitors49// The spill index is similar to local index; it is in range 0..(open)50//51// The CPU registers are mapped using a fixed table; register with number 052// is the most used one.535455// stack grow direction --> SP56// +----------+---+----------+-------+------------------------+-----+57// |arguments | x | monitors | spill | reserved argument area | ABI |58// +----------+---+----------+-------+------------------------+-----+59//60// x = ABI area (SPARC) or return adress and link (i486)61// ABI = ABI area (SPARC) or nothing (i486)626364class LIR_OprDesc;65typedef LIR_OprDesc* LIR_Opr;666768class FrameMap : public CompilationResourceObj {69public:70enum {71nof_cpu_regs = pd_nof_cpu_regs_frame_map,72nof_fpu_regs = pd_nof_fpu_regs_frame_map,7374nof_cpu_regs_reg_alloc = pd_nof_cpu_regs_reg_alloc,75nof_fpu_regs_reg_alloc = pd_nof_fpu_regs_reg_alloc,7677max_nof_caller_save_cpu_regs = pd_nof_caller_save_cpu_regs_frame_map,78nof_caller_save_fpu_regs = pd_nof_caller_save_fpu_regs_frame_map,7980spill_slot_size_in_bytes = 481};8283#include CPU_HEADER(c1_FrameMap)8485friend class LIR_OprDesc;8687private:88static bool _init_done;89static Register _cpu_rnr2reg [nof_cpu_regs];90static int _cpu_reg2rnr [nof_cpu_regs];9192static LIR_Opr _caller_save_cpu_regs [max_nof_caller_save_cpu_regs];93static LIR_Opr _caller_save_fpu_regs [nof_caller_save_fpu_regs];9495int _framesize;96int _argcount;97int _num_monitors;98int _num_spills;99int _reserved_argument_area_size;100int _oop_map_arg_count;101102CallingConvention* _incoming_arguments;103intArray* _argument_locations;104105void check_spill_index (int spill_index) const { assert(spill_index >= 0, "bad index"); }106void check_monitor_index (int monitor_index) const { assert(monitor_index >= 0 &&107monitor_index < _num_monitors, "bad index"); }108109static Register cpu_rnr2reg (int rnr) {110assert(_init_done, "tables not initialized");111debug_only(cpu_range_check(rnr);)112return _cpu_rnr2reg[rnr];113}114115static int cpu_reg2rnr (Register reg) {116assert(_init_done, "tables not initialized");117debug_only(cpu_range_check(reg->encoding());)118return _cpu_reg2rnr[reg->encoding()];119}120121static void map_register(int rnr, Register reg) {122debug_only(cpu_range_check(rnr);)123debug_only(cpu_range_check(reg->encoding());)124_cpu_rnr2reg[rnr] = reg;125_cpu_reg2rnr[reg->encoding()] = rnr;126}127128void update_reserved_argument_area_size (int size) {129assert(size >= 0, "check");130_reserved_argument_area_size = MAX2(_reserved_argument_area_size, size);131}132133protected:134#ifndef PRODUCT135static void cpu_range_check (int rnr) { assert(0 <= rnr && rnr < nof_cpu_regs, "cpu register number is too big"); }136static void fpu_range_check (int rnr) { assert(0 <= rnr && rnr < nof_fpu_regs, "fpu register number is too big"); }137#endif138139140ByteSize sp_offset_for_monitor_base(const int idx) const;141142Address make_new_address(ByteSize sp_offset) const;143144ByteSize sp_offset_for_slot(const int idx) const;145ByteSize sp_offset_for_double_slot(const int idx) const;146ByteSize sp_offset_for_spill(const int idx) const;147ByteSize sp_offset_for_monitor_lock(int monitor_index) const;148ByteSize sp_offset_for_monitor_object(int monitor_index) const;149150VMReg sp_offset2vmreg(ByteSize offset) const;151152// platform dependent hook used to check that frame is properly153// addressable on the platform. Used by arm, ppc to verify that all154// stack addresses are valid.155bool validate_frame();156157static LIR_Opr map_to_opr(BasicType type, VMRegPair* reg, bool incoming);158159public:160// Opr representing the stack_pointer on this platform161static LIR_Opr stack_pointer();162163// JSR 292164static LIR_Opr method_handle_invoke_SP_save_opr();165166static BasicTypeArray* signature_type_array_for(const ciMethod* method);167168// for outgoing calls, these also update the reserved area to169// include space for arguments and any ABI area.170CallingConvention* c_calling_convention(const BasicTypeArray* signature);171CallingConvention* java_calling_convention(const BasicTypeArray* signature, bool outgoing);172173// deopt support174ByteSize sp_offset_for_orig_pc() { return sp_offset_for_monitor_base(_num_monitors); }175176static LIR_Opr as_opr(Register r) {177return LIR_OprFact::single_cpu(cpu_reg2rnr(r));178}179static LIR_Opr as_oop_opr(Register r) {180return LIR_OprFact::single_cpu_oop(cpu_reg2rnr(r));181}182183static LIR_Opr as_metadata_opr(Register r) {184return LIR_OprFact::single_cpu_metadata(cpu_reg2rnr(r));185}186187static LIR_Opr as_address_opr(Register r) {188return LIR_OprFact::single_cpu_address(cpu_reg2rnr(r));189}190191FrameMap(ciMethod* method, int monitors, int reserved_argument_area_size);192bool finalize_frame(int nof_slots);193194int reserved_argument_area_size () const { return _reserved_argument_area_size; }195int framesize () const { assert(_framesize != -1, "hasn't been calculated"); return _framesize; }196ByteSize framesize_in_bytes () const { return in_ByteSize(framesize() * 4); }197int num_monitors () const { return _num_monitors; }198int num_spills () const { assert(_num_spills >= 0, "not set"); return _num_spills; }199int argcount () const { assert(_argcount >= 0, "not set"); return _argcount; }200201int oop_map_arg_count() const { return _oop_map_arg_count; }202203CallingConvention* incoming_arguments() const { return _incoming_arguments; }204205// convenience routines206Address address_for_slot(int index, int sp_adjust = 0) const {207return make_new_address(sp_offset_for_slot(index) + in_ByteSize(sp_adjust));208}209Address address_for_double_slot(int index, int sp_adjust = 0) const {210return make_new_address(sp_offset_for_double_slot(index) + in_ByteSize(sp_adjust));211}212Address address_for_monitor_lock(int monitor_index) const {213return make_new_address(sp_offset_for_monitor_lock(monitor_index));214}215Address address_for_monitor_object(int monitor_index) const {216return make_new_address(sp_offset_for_monitor_object(monitor_index));217}218219// Creates Location describing desired slot and returns it via pointer220// to Location object. Returns true if the stack frame offset was legal221// (as defined by Location::legal_offset_in_bytes()), false otherwise.222// Do not use the returned location if this returns false.223bool location_for_sp_offset(ByteSize byte_offset_from_sp,224Location::Type loc_type, Location* loc) const;225226bool location_for_monitor_lock (int monitor_index, Location* loc) const {227return location_for_sp_offset(sp_offset_for_monitor_lock(monitor_index), Location::normal, loc);228}229bool location_for_monitor_object(int monitor_index, Location* loc) const {230return location_for_sp_offset(sp_offset_for_monitor_object(monitor_index), Location::oop, loc);231}232bool locations_for_slot (int index, Location::Type loc_type,233Location* loc, Location* second = NULL) const;234235VMReg slot_regname(int index) const {236return sp_offset2vmreg(sp_offset_for_slot(index));237}238VMReg monitor_object_regname(int monitor_index) const {239return sp_offset2vmreg(sp_offset_for_monitor_object(monitor_index));240}241VMReg regname(LIR_Opr opr) const;242243static LIR_Opr caller_save_cpu_reg_at(int i) {244assert(i >= 0 && i < max_nof_caller_save_cpu_regs, "out of bounds");245return _caller_save_cpu_regs[i];246}247248static LIR_Opr caller_save_fpu_reg_at(int i) {249assert(i >= 0 && i < nof_caller_save_fpu_regs, "out of bounds");250return _caller_save_fpu_regs[i];251}252253static void initialize();254};255256// CallingConvention257//--------------------------------------------------------258259class CallingConvention: public ResourceObj {260private:261LIR_OprList* _args;262int _reserved_stack_slots;263264public:265CallingConvention (LIR_OprList* args, int reserved_stack_slots)266: _args(args)267, _reserved_stack_slots(reserved_stack_slots) {}268269LIR_OprList* args() { return _args; }270271LIR_Opr at(int i) const { return _args->at(i); }272int length() const { return _args->length(); }273274// Indicates number of real frame slots used by arguments passed on stack.275int reserved_stack_slots() const { return _reserved_stack_slots; }276277#ifndef PRODUCT278void print () const {279for (int i = 0; i < length(); i++) {280at(i)->print();281}282}283#endif // PRODUCT284};285286#endif // SHARE_C1_C1_FRAMEMAP_HPP287288289