Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/c1/c1_FrameMap.hpp
32285 views
/*1* Copyright (c) 2000, 2013, 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_VM_C1_C1_FRAMEMAP_HPP25#define SHARE_VM_C1_C1_FRAMEMAP_HPP2627#include "asm/assembler.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"3536class ciMethod;37class CallingConvention;38class BasicTypeArray;39class BasicTypeList;4041//--------------------------------------------------------42// FrameMap43//--------------------------------------------------------4445// This class is responsible of mapping items (locals, monitors, spill46// slots and registers to their frame location47//48// The monitors are specified by a consecutive index, although each monitor entry49// occupies two words. The monitor_index is 0.._num_monitors50// The spill index is similar to local index; it is in range 0..(open)51//52// The CPU registers are mapped using a fixed table; register with number 053// is the most used one.545556// stack grow direction --> SP57// +----------+---+----------+-------+------------------------+-----+58// |arguments | x | monitors | spill | reserved argument area | ABI |59// +----------+---+----------+-------+------------------------+-----+60//61// x = ABI area (SPARC) or return adress and link (i486)62// ABI = ABI area (SPARC) or nothing (i486)636465class LIR_OprDesc;66typedef LIR_OprDesc* LIR_Opr;676869class FrameMap : public CompilationResourceObj {70public:71enum {72nof_cpu_regs = pd_nof_cpu_regs_frame_map,73nof_fpu_regs = pd_nof_fpu_regs_frame_map,7475nof_cpu_regs_reg_alloc = pd_nof_cpu_regs_reg_alloc,76nof_fpu_regs_reg_alloc = pd_nof_fpu_regs_reg_alloc,7778max_nof_caller_save_cpu_regs = pd_nof_caller_save_cpu_regs_frame_map,79nof_caller_save_fpu_regs = pd_nof_caller_save_fpu_regs_frame_map,8081spill_slot_size_in_bytes = 482};8384#ifdef TARGET_ARCH_x8685# include "c1_FrameMap_x86.hpp"86#endif87#ifdef TARGET_ARCH_aarch3288# include "c1_FrameMap_aarch32.hpp"89#endif90#ifdef TARGET_ARCH_aarch6491# include "c1_FrameMap_aarch64.hpp"92#endif93#ifdef TARGET_ARCH_sparc94# include "c1_FrameMap_sparc.hpp"95#endif96#ifdef TARGET_ARCH_arm97# include "c1_FrameMap_arm.hpp"98#endif99#ifdef TARGET_ARCH_ppc100# include "c1_FrameMap_ppc.hpp"101#endif102103104friend class LIR_OprDesc;105106private:107static bool _init_done;108static Register _cpu_rnr2reg [nof_cpu_regs];109static int _cpu_reg2rnr [nof_cpu_regs];110111static LIR_Opr _caller_save_cpu_regs [max_nof_caller_save_cpu_regs];112static LIR_Opr _caller_save_fpu_regs [nof_caller_save_fpu_regs];113114int _framesize;115int _argcount;116int _num_monitors;117int _num_spills;118int _reserved_argument_area_size;119int _oop_map_arg_count;120121CallingConvention* _incoming_arguments;122intArray* _argument_locations;123124void check_spill_index (int spill_index) const { assert(spill_index >= 0, "bad index"); }125void check_monitor_index (int monitor_index) const { assert(monitor_index >= 0 &&126monitor_index < _num_monitors, "bad index"); }127128static Register cpu_rnr2reg (int rnr) {129assert(_init_done, "tables not initialized");130debug_only(cpu_range_check(rnr);)131return _cpu_rnr2reg[rnr];132}133134static int cpu_reg2rnr (Register reg) {135assert(_init_done, "tables not initialized");136debug_only(cpu_range_check(reg->encoding());)137return _cpu_reg2rnr[reg->encoding()];138}139140static void map_register(int rnr, Register reg) {141debug_only(cpu_range_check(rnr);)142debug_only(cpu_range_check(reg->encoding());)143_cpu_rnr2reg[rnr] = reg;144_cpu_reg2rnr[reg->encoding()] = rnr;145}146147void update_reserved_argument_area_size (int size) {148assert(size >= 0, "check");149_reserved_argument_area_size = MAX2(_reserved_argument_area_size, size);150}151152protected:153#ifndef PRODUCT154static void cpu_range_check (int rnr) { assert(0 <= rnr && rnr < nof_cpu_regs, "cpu register number is too big"); }155static void fpu_range_check (int rnr) { assert(0 <= rnr && rnr < nof_fpu_regs, "fpu register number is too big"); }156#endif157158159ByteSize sp_offset_for_monitor_base(const int idx) const;160161Address make_new_address(ByteSize sp_offset) const;162163ByteSize sp_offset_for_slot(const int idx) const;164ByteSize sp_offset_for_double_slot(const int idx) const;165ByteSize sp_offset_for_spill(const int idx) const;166ByteSize sp_offset_for_monitor_lock(int monitor_index) const;167ByteSize sp_offset_for_monitor_object(int monitor_index) const;168169VMReg sp_offset2vmreg(ByteSize offset) const;170171// platform dependent hook used to check that frame is properly172// addressable on the platform. Used by sparc to verify that all173// stack addresses are expressable in a simm13.174bool validate_frame();175176static LIR_Opr map_to_opr(BasicType type, VMRegPair* reg, bool incoming);177178public:179// Opr representing the stack_pointer on this platform180static LIR_Opr stack_pointer();181182// JSR 292183static LIR_Opr method_handle_invoke_SP_save_opr();184185static BasicTypeArray* signature_type_array_for(const ciMethod* method);186187// for outgoing calls, these also update the reserved area to188// include space for arguments and any ABI area.189CallingConvention* c_calling_convention(const BasicTypeArray* signature);190CallingConvention* java_calling_convention(const BasicTypeArray* signature, bool outgoing);191192// deopt support193ByteSize sp_offset_for_orig_pc() { return sp_offset_for_monitor_base(_num_monitors); }194195static LIR_Opr as_opr(Register r) {196return LIR_OprFact::single_cpu(cpu_reg2rnr(r));197}198static LIR_Opr as_oop_opr(Register r) {199return LIR_OprFact::single_cpu_oop(cpu_reg2rnr(r));200}201202static LIR_Opr as_metadata_opr(Register r) {203return LIR_OprFact::single_cpu_metadata(cpu_reg2rnr(r));204}205206static LIR_Opr as_address_opr(Register r) {207return LIR_OprFact::single_cpu_address(cpu_reg2rnr(r));208}209210FrameMap(ciMethod* method, int monitors, int reserved_argument_area_size);211bool finalize_frame(int nof_slots);212213int reserved_argument_area_size () const { return _reserved_argument_area_size; }214int framesize () const { assert(_framesize != -1, "hasn't been calculated"); return _framesize; }215ByteSize framesize_in_bytes () const { return in_ByteSize(framesize() * 4); }216int num_monitors () const { return _num_monitors; }217int num_spills () const { assert(_num_spills >= 0, "not set"); return _num_spills; }218int argcount () const { assert(_argcount >= 0, "not set"); return _argcount; }219220int oop_map_arg_count() const { return _oop_map_arg_count; }221222CallingConvention* incoming_arguments() const { return _incoming_arguments; }223224// convenience routines225Address address_for_slot(int index, int sp_adjust = 0) const {226return make_new_address(sp_offset_for_slot(index) + in_ByteSize(sp_adjust));227}228Address address_for_double_slot(int index, int sp_adjust = 0) const {229return make_new_address(sp_offset_for_double_slot(index) + in_ByteSize(sp_adjust));230}231Address address_for_monitor_lock(int monitor_index) const {232return make_new_address(sp_offset_for_monitor_lock(monitor_index));233}234Address address_for_monitor_object(int monitor_index) const {235return make_new_address(sp_offset_for_monitor_object(monitor_index));236}237238// Creates Location describing desired slot and returns it via pointer239// to Location object. Returns true if the stack frame offset was legal240// (as defined by Location::legal_offset_in_bytes()), false otherwise.241// Do not use the returned location if this returns false.242bool location_for_sp_offset(ByteSize byte_offset_from_sp,243Location::Type loc_type, Location* loc) const;244245bool location_for_monitor_lock (int monitor_index, Location* loc) const {246return location_for_sp_offset(sp_offset_for_monitor_lock(monitor_index), Location::normal, loc);247}248bool location_for_monitor_object(int monitor_index, Location* loc) const {249return location_for_sp_offset(sp_offset_for_monitor_object(monitor_index), Location::oop, loc);250}251bool locations_for_slot (int index, Location::Type loc_type,252Location* loc, Location* second = NULL) const;253254VMReg slot_regname(int index) const {255return sp_offset2vmreg(sp_offset_for_slot(index));256}257VMReg monitor_object_regname(int monitor_index) const {258return sp_offset2vmreg(sp_offset_for_monitor_object(monitor_index));259}260VMReg regname(LIR_Opr opr) const;261262static LIR_Opr caller_save_cpu_reg_at(int i) {263assert(i >= 0 && i < max_nof_caller_save_cpu_regs, "out of bounds");264return _caller_save_cpu_regs[i];265}266267static LIR_Opr caller_save_fpu_reg_at(int i) {268assert(i >= 0 && i < nof_caller_save_fpu_regs, "out of bounds");269return _caller_save_fpu_regs[i];270}271272static void initialize();273};274275// CallingConvention276//--------------------------------------------------------277278class CallingConvention: public ResourceObj {279private:280LIR_OprList* _args;281int _reserved_stack_slots;282283public:284CallingConvention (LIR_OprList* args, int reserved_stack_slots)285: _args(args)286, _reserved_stack_slots(reserved_stack_slots) {}287288LIR_OprList* args() { return _args; }289290LIR_Opr at(int i) const { return _args->at(i); }291int length() const { return _args->length(); }292293// Indicates number of real frame slots used by arguments passed on stack.294int reserved_stack_slots() const { return _reserved_stack_slots; }295296#ifndef PRODUCT297void print () const {298for (int i = 0; i < length(); i++) {299at(i)->print();300}301}302#endif // PRODUCT303};304305#endif // SHARE_VM_C1_C1_FRAMEMAP_HPP306307308