Path: blob/master/src/hotspot/cpu/arm/abstractInterpreter_arm.cpp
40930 views
/*1* Copyright (c) 2008, 2017, 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 "asm/assembler.hpp"26#include "interpreter/bytecode.hpp"27#include "interpreter/interpreter.hpp"28#include "oops/constMethod.hpp"29#include "oops/klass.inline.hpp"30#include "oops/method.hpp"31#include "prims/methodHandles.hpp"32#include "runtime/handles.inline.hpp"33#include "runtime/frame.inline.hpp"34#include "runtime/synchronizer.hpp"35#include "utilities/align.hpp"36#include "utilities/macros.hpp"3738int AbstractInterpreter::BasicType_as_index(BasicType type) {39int i = 0;40switch (type) {41case T_VOID : i = 0; break;42case T_BOOLEAN: i = 1; break;43case T_CHAR : i = 2; break;44case T_BYTE : i = 3; break;45case T_SHORT : i = 4; break;46case T_INT : i = 5; break;47case T_OBJECT : // fall through48case T_ARRAY : i = 6; break;49case T_LONG : i = 7; break;50case T_FLOAT : i = 8; break;51case T_DOUBLE : i = 9; break;52default : ShouldNotReachHere();53}54assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, "index out of bounds");55return i;56}5758// How much stack a method activation needs in words.59int AbstractInterpreter::size_top_interpreter_activation(Method* method) {60const int stub_code = 12; // see generate_call_stub61// Save space for one monitor to get into the interpreted method in case62// the method is synchronized63int monitor_size = method->is_synchronized() ?641*frame::interpreter_frame_monitor_size() : 0;6566// total overhead size: monitor_size + (sender SP, thru expr stack bottom).67// be sure to change this if you add/subtract anything to/from the overhead area68const int overhead_size = monitor_size +69(frame::sender_sp_offset - frame::interpreter_frame_initial_sp_offset);70const int method_stack = (method->max_locals() + method->max_stack()) *71Interpreter::stackElementWords;72return overhead_size + method_stack + stub_code;73}7475// asm based interpreter deoptimization helpers76int AbstractInterpreter::size_activation(int max_stack,77int tempcount,78int extra_args,79int moncount,80int callee_param_count,81int callee_locals,82bool is_top_frame) {83// Note: This calculation must exactly parallel the frame setup84// in TemplateInterpreterGenerator::generate_fixed_frame.85// fixed size of an interpreter frame:86int overhead = frame::sender_sp_offset - frame::interpreter_frame_initial_sp_offset;8788// Our locals were accounted for by the caller (or last_frame_adjust on the transistion)89// Since the callee parameters already account for the callee's params we only need to account for90// the extra locals.9192int size = overhead +93((callee_locals - callee_param_count)*Interpreter::stackElementWords) +94(moncount*frame::interpreter_frame_monitor_size()) +95tempcount*Interpreter::stackElementWords + extra_args;969798return size;99}100101void AbstractInterpreter::layout_activation(Method* method,102int tempcount,103int popframe_extra_args,104int moncount,105int caller_actual_parameters,106int callee_param_count,107int callee_locals,108frame* caller,109frame* interpreter_frame,110bool is_top_frame,111bool is_bottom_frame) {112113// Set up the method, locals, and monitors.114// The frame interpreter_frame is guaranteed to be the right size,115// as determined by a previous call to the size_activation() method.116// It is also guaranteed to be walkable even though it is in a skeletal state117// NOTE: return size is in words not bytes118119// fixed size of an interpreter frame:120int max_locals = method->max_locals() * Interpreter::stackElementWords;121int extra_locals = (method->max_locals() - method->size_of_parameters()) * Interpreter::stackElementWords;122123#ifdef ASSERT124assert(caller->sp() == interpreter_frame->sender_sp(), "Frame not properly walkable");125#endif126127interpreter_frame->interpreter_frame_set_method(method);128// NOTE the difference in using sender_sp and interpreter_frame_sender_sp129// interpreter_frame_sender_sp is the original sp of the caller (the unextended_sp)130// and sender_sp is (fp + sender_sp_offset*wordSize)131132intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1;133134interpreter_frame->interpreter_frame_set_locals(locals);135BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin();136BasicObjectLock* monbot = montop - moncount;137interpreter_frame->interpreter_frame_set_monitor_end(monbot);138139// Set last_sp140intptr_t* stack_top = (intptr_t*) monbot -141tempcount*Interpreter::stackElementWords -142popframe_extra_args;143interpreter_frame->interpreter_frame_set_last_sp(stack_top);144145// All frames but the initial (oldest) interpreter frame we fill in have a146// value for sender_sp that allows walking the stack but isn't147// truly correct. Correct the value here.148149if (extra_locals != 0 &&150interpreter_frame->sender_sp() == interpreter_frame->interpreter_frame_sender_sp() ) {151interpreter_frame->set_interpreter_frame_sender_sp(caller->sp() + extra_locals);152}153154*interpreter_frame->interpreter_frame_cache_addr() =155method->constants()->cache();156*interpreter_frame->interpreter_frame_mirror_addr() =157method->method_holder()->java_mirror();158}159160161