Path: blob/jdk8u272-b10-aarch32-20201026/hotspot/src/share/vm/c1/c1_FrameMap.cpp
83404 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#include "precompiled.hpp"25#include "c1/c1_FrameMap.hpp"26#include "c1/c1_LIR.hpp"27#include "runtime/sharedRuntime.hpp"28#ifdef TARGET_ARCH_x8629# include "vmreg_x86.inline.hpp"30#endif31#ifdef TARGET_ARCH_aarch6432# include "vmreg_aarch64.inline.hpp"33#endif34#ifdef TARGET_ARCH_sparc35# include "vmreg_sparc.inline.hpp"36#endif37#ifdef TARGET_ARCH_zero38# include "vmreg_zero.inline.hpp"39#endif40#ifdef TARGET_ARCH_arm41# include "vmreg_arm.inline.hpp"42#endif43#ifdef TARGET_ARCH_ppc44# include "vmreg_ppc.inline.hpp"45#endif46#ifdef TARGET_ARCH_aarch3247# include "vmreg_aarch32.inline.hpp"48#endif49505152//-----------------------------------------------------5354// Convert method signature into an array of BasicTypes for the arguments55BasicTypeArray* FrameMap::signature_type_array_for(const ciMethod* method) {56ciSignature* sig = method->signature();57BasicTypeList* sta = new BasicTypeList(method->arg_size());58// add receiver, if any59if (!method->is_static()) sta->append(T_OBJECT);60// add remaining arguments61for (int i = 0; i < sig->count(); i++) {62ciType* type = sig->type_at(i);63BasicType t = type->basic_type();64if (t == T_ARRAY) {65t = T_OBJECT;66}67sta->append(t);68}69// done70return sta;71}727374CallingConvention* FrameMap::java_calling_convention(const BasicTypeArray* signature, bool outgoing) {75// compute the size of the arguments first. The signature array76// that java_calling_convention takes includes a T_VOID after double77// work items but our signatures do not.78int i;79int sizeargs = 0;80for (i = 0; i < signature->length(); i++) {81sizeargs += type2size[signature->at(i)];82}8384BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sizeargs);85VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, sizeargs);86int sig_index = 0;87for (i = 0; i < sizeargs; i++, sig_index++) {88sig_bt[i] = signature->at(sig_index);89if (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) {90sig_bt[i + 1] = T_VOID;91i++;92}93}9495intptr_t out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs, outgoing);96LIR_OprList* args = new LIR_OprList(signature->length());97for (i = 0; i < sizeargs;) {98BasicType t = sig_bt[i];99assert(t != T_VOID, "should be skipping these");100LIR_Opr opr = map_to_opr(t, regs + i, outgoing);101args->append(opr);102if (opr->is_address()) {103LIR_Address* addr = opr->as_address_ptr();104assert(addr->disp() == (int)addr->disp(), "out of range value");105out_preserve = MAX2(out_preserve, (intptr_t)(addr->disp() - STACK_BIAS) / 4);106}107i += type2size[t];108}109assert(args->length() == signature->length(), "size mismatch");110out_preserve += SharedRuntime::out_preserve_stack_slots();111112if (outgoing) {113// update the space reserved for arguments.114update_reserved_argument_area_size(out_preserve * BytesPerWord);115}116return new CallingConvention(args, out_preserve);117}118119120CallingConvention* FrameMap::c_calling_convention(const BasicTypeArray* signature) {121// compute the size of the arguments first. The signature array122// that java_calling_convention takes includes a T_VOID after double123// work items but our signatures do not.124int i;125int sizeargs = 0;126for (i = 0; i < signature->length(); i++) {127sizeargs += type2size[signature->at(i)];128}129130BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sizeargs);131VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, sizeargs);132int sig_index = 0;133for (i = 0; i < sizeargs; i++, sig_index++) {134sig_bt[i] = signature->at(sig_index);135if (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) {136sig_bt[i + 1] = T_VOID;137i++;138}139}140141intptr_t out_preserve = SharedRuntime::c_calling_convention(sig_bt, regs, NULL, sizeargs);142LIR_OprList* args = new LIR_OprList(signature->length());143for (i = 0; i < sizeargs;) {144BasicType t = sig_bt[i];145assert(t != T_VOID, "should be skipping these");146147// C calls are always outgoing148bool outgoing = true;149LIR_Opr opr = map_to_opr(t, regs + i, outgoing);150// they might be of different types if for instance floating point151// values are passed in cpu registers, but the sizes must match.152assert(type2size[opr->type()] == type2size[t], "type mismatch");153args->append(opr);154if (opr->is_address()) {155LIR_Address* addr = opr->as_address_ptr();156out_preserve = MAX2(out_preserve, (intptr_t)(addr->disp() - STACK_BIAS) / 4);157}158i += type2size[t];159}160assert(args->length() == signature->length(), "size mismatch");161out_preserve += SharedRuntime::out_preserve_stack_slots();162update_reserved_argument_area_size(out_preserve * BytesPerWord);163return new CallingConvention(args, out_preserve);164}165166167//--------------------------------------------------------168// FrameMap169//--------------------------------------------------------170171bool FrameMap::_init_done = false;172Register FrameMap::_cpu_rnr2reg [FrameMap::nof_cpu_regs];173int FrameMap::_cpu_reg2rnr [FrameMap::nof_cpu_regs];174175176FrameMap::FrameMap(ciMethod* method, int monitors, int reserved_argument_area_size) {177assert(_init_done, "should already be completed");178179_framesize = -1;180_num_spills = -1;181182assert(monitors >= 0, "not set");183_num_monitors = monitors;184assert(reserved_argument_area_size >= 0, "not set");185_reserved_argument_area_size = MAX2(4, reserved_argument_area_size) * BytesPerWord;186187_argcount = method->arg_size();188_argument_locations = new intArray(_argcount, -1);189_incoming_arguments = java_calling_convention(signature_type_array_for(method), false);190_oop_map_arg_count = _incoming_arguments->reserved_stack_slots();191192int java_index = 0;193for (int i = 0; i < _incoming_arguments->length(); i++) {194LIR_Opr opr = _incoming_arguments->at(i);195if (opr->is_address()) {196LIR_Address* address = opr->as_address_ptr();197_argument_locations->at_put(java_index, address->disp() - STACK_BIAS);198_incoming_arguments->args()->at_put(i, LIR_OprFact::stack(java_index, as_BasicType(as_ValueType(address->type()))));199}200java_index += type2size[opr->type()];201}202203}204205206bool FrameMap::finalize_frame(int nof_slots) {207assert(nof_slots >= 0, "must be positive");208assert(_num_spills == -1, "can only be set once");209_num_spills = nof_slots;210assert(_framesize == -1, "should only be calculated once");211_framesize = round_to(in_bytes(sp_offset_for_monitor_base(0)) +212_num_monitors * sizeof(BasicObjectLock) +213sizeof(intptr_t) + // offset of deopt orig pc214frame_pad_in_bytes,215StackAlignmentInBytes) / 4;216int java_index = 0;217for (int i = 0; i < _incoming_arguments->length(); i++) {218LIR_Opr opr = _incoming_arguments->at(i);219if (opr->is_stack()) {220_argument_locations->at_put(java_index, in_bytes(framesize_in_bytes()) +221_argument_locations->at(java_index));222}223java_index += type2size[opr->type()];224}225// make sure it's expressible on the platform226return validate_frame();227}228229VMReg FrameMap::sp_offset2vmreg(ByteSize offset) const {230int offset_in_bytes = in_bytes(offset);231assert(offset_in_bytes % 4 == 0, "must be multiple of 4 bytes");232assert(offset_in_bytes / 4 < framesize() + oop_map_arg_count(), "out of range");233return VMRegImpl::stack2reg(offset_in_bytes / 4);234}235236237bool FrameMap::location_for_sp_offset(ByteSize byte_offset_from_sp,238Location::Type loc_type,239Location* loc) const {240int offset = in_bytes(byte_offset_from_sp);241assert(offset >= 0, "incorrect offset");242if (!Location::legal_offset_in_bytes(offset)) {243return false;244}245Location tmp_loc = Location::new_stk_loc(loc_type, offset);246*loc = tmp_loc;247return true;248}249250251bool FrameMap::locations_for_slot (int index, Location::Type loc_type,252Location* loc, Location* second) const {253ByteSize offset_from_sp = sp_offset_for_slot(index);254if (!location_for_sp_offset(offset_from_sp, loc_type, loc)) {255return false;256}257if (second != NULL) {258// two word item259offset_from_sp = offset_from_sp + in_ByteSize(4);260return location_for_sp_offset(offset_from_sp, loc_type, second);261}262return true;263}264265//////////////////////266// Public accessors //267//////////////////////268269270ByteSize FrameMap::sp_offset_for_slot(const int index) const {271if (index < argcount()) {272int offset = _argument_locations->at(index);273assert(offset != -1, "not a memory argument");274assert(offset >= framesize() * 4, "argument inside of frame");275return in_ByteSize(offset);276}277ByteSize offset = sp_offset_for_spill(index - argcount());278assert(in_bytes(offset) < framesize() * 4, "spill outside of frame");279return offset;280}281282283ByteSize FrameMap::sp_offset_for_double_slot(const int index) const {284ByteSize offset = sp_offset_for_slot(index);285if (index >= argcount()) {286assert(in_bytes(offset) + 4 < framesize() * 4, "spill outside of frame");287}288return offset;289}290291292ByteSize FrameMap::sp_offset_for_spill(const int index) const {293assert(index >= 0 && index < _num_spills, "out of range");294int offset = round_to(first_available_sp_in_frame + _reserved_argument_area_size, sizeof(double)) +295index * spill_slot_size_in_bytes;296return in_ByteSize(offset);297}298299ByteSize FrameMap::sp_offset_for_monitor_base(const int index) const {300int end_of_spills = round_to(first_available_sp_in_frame + _reserved_argument_area_size, sizeof(double)) +301_num_spills * spill_slot_size_in_bytes;302int offset = (int) round_to(end_of_spills, HeapWordSize) + index * sizeof(BasicObjectLock);303return in_ByteSize(offset);304}305306ByteSize FrameMap::sp_offset_for_monitor_lock(int index) const {307check_monitor_index(index);308return sp_offset_for_monitor_base(index) + in_ByteSize(BasicObjectLock::lock_offset_in_bytes());;309}310311ByteSize FrameMap::sp_offset_for_monitor_object(int index) const {312check_monitor_index(index);313return sp_offset_for_monitor_base(index) + in_ByteSize(BasicObjectLock::obj_offset_in_bytes());314}315316317// For OopMaps, map a local variable or spill index to an VMReg.318// This is the offset from sp() in the frame of the slot for the index,319// skewed by SharedInfo::stack0 to indicate a stack location (vs.a register.)320//321// C ABI size +322// framesize + framesize +323// stack0 stack0 stack0 0 <- VMReg->value()324// | | | <registers> |325// ..........|..............|..............|.............|326// 0 1 2 3 | <C ABI area> | 4 5 6 ...... | <- local indices327// ^ ^ sp()328// | |329// arguments non-argument locals330331332VMReg FrameMap::regname(LIR_Opr opr) const {333if (opr->is_single_cpu()) {334assert(!opr->is_virtual(), "should not see virtual registers here");335return opr->as_register()->as_VMReg();336} else if (opr->is_single_stack()) {337return sp_offset2vmreg(sp_offset_for_slot(opr->single_stack_ix()));338} else if (opr->is_address()) {339LIR_Address* addr = opr->as_address_ptr();340assert(addr->base() == stack_pointer(), "sp based addressing only");341return sp_offset2vmreg(in_ByteSize(addr->index()->as_jint()));342}343ShouldNotReachHere();344return VMRegImpl::Bad();345}346347348349350// ------------ extra spill slots ---------------351352353