Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/cpu/aarch32/vm/interp_masm_aarch32.cpp
32285 views
/*1* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2014, Red Hat Inc. All rights reserved.3* Copyright (c) 2015, Linaro Ltd. All rights reserved.4* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.5*6* This code is free software; you can redistribute it and/or modify it7* under the terms of the GNU General Public License version 2 only, as8* published by the Free Software Foundation.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*24*/2526#include "precompiled.hpp"27#include "interp_masm_aarch32.hpp"28#include "interpreter/interpreter.hpp"29#include "interpreter/interpreterRuntime.hpp"30#include "oops/arrayOop.hpp"31#include "oops/markOop.hpp"32#include "oops/methodData.hpp"33#include "oops/method.hpp"34#include "prims/jvmtiExport.hpp"35#include "prims/jvmtiRedefineClassesTrace.hpp"36#include "prims/jvmtiThreadState.hpp"37#include "runtime/basicLock.hpp"38#include "runtime/biasedLocking.hpp"39#include "runtime/sharedRuntime.hpp"40#include "runtime/thread.inline.hpp"41#include "vm_version_aarch32.hpp"42#include "register_aarch32.hpp"434445// Implementation of InterpreterMacroAssembler4647void InterpreterMacroAssembler::narrow(Register result) {48// Get method->_constMethod->_result_type49ldr(rscratch1, Address(rfp, frame::interpreter_frame_method_offset * wordSize));50ldr(rscratch1, Address(rscratch1, Method::const_offset()));51ldrb(rscratch1, Address(rscratch1, ConstMethod::result_type_offset()));5253Label done;5455// common case first5657cmp(rscratch1, T_INT);58b(done, Assembler::EQ);5960// mask integer result to narrower return type.61cmp(rscratch1, T_BOOLEAN);62andr(result, result, 0x1, Assembler::EQ);6364cmp(rscratch1, T_BYTE);65sxtb(result, result, Assembler::ror(), Assembler::EQ);6667cmp(rscratch1, T_CHAR);68uxth(result, result, Assembler::ror(), Assembler::EQ); // truncate upper 16 bits6970sxth(result, result, Assembler::ror(), Assembler::NE); // sign-extend short7172// Nothing to do for T_INT73bind(done);74}7576#ifndef CC_INTERP7778void InterpreterMacroAssembler::check_and_handle_popframe(Register java_thread) {79if (JvmtiExport::can_pop_frame()) {80Label L;81// Initiate popframe handling only if it is not already being82// processed. If the flag has the popframe_processing bit set, it83// means that this code is called *during* popframe handling - we84// don't want to reenter.85// This method is only called just after the call into the vm in86// call_VM_base, so the arg registers are available.87ldr(rscratch1, Address(rthread, JavaThread::popframe_condition_offset()));88tst(rscratch1, JavaThread::popframe_pending_bit);89b(L, Assembler::EQ);90tst(rscratch1, JavaThread::popframe_processing_bit);91b(L, Assembler::NE);92// Call Interpreter::remove_activation_preserving_args_entry() to get the93// address of the same-named entrypoint in the generated interpreter code.94call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_preserving_args_entry));95b(r0);96bind(L);97}98}99100101void InterpreterMacroAssembler::load_earlyret_value(TosState state) {102ldr(r2, Address(rthread, JavaThread::jvmti_thread_state_offset()));103const Address tos_addr(r2, JvmtiThreadState::earlyret_tos_offset());104const Address oop_addr(r2, JvmtiThreadState::earlyret_oop_offset());105const Address val_addr(r2, JvmtiThreadState::earlyret_value_offset());106switch (state) {107case atos: ldr(r0, oop_addr);108mov(rscratch1, 0);109str(rscratch1, oop_addr);110verify_oop(r0, state); break;111case dtos:112if(hasFPU()) {113vldr_f64(d0, val_addr); break;114}//fall through otherwise115case ltos: ldrd(r0, val_addr); break;116case ftos:117if(hasFPU()) {118vldr_f32(d0, val_addr); break;119} //fall through otherwise120case btos: // fall through121case ztos: // fall through122case ctos: // fall through123case stos: // fall through124case itos: ldr(r0, val_addr); break;125case vtos: /* nothing to do */ break;126default : ShouldNotReachHere();127}128// Clean up tos value in the thread object129mov(rscratch1, (int) ilgl);130str(rscratch1, tos_addr);131mov(rscratch1, 0);132str(rscratch1, val_addr);133}134135136void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread) {137if (JvmtiExport::can_force_early_return()) {138Label L;139ldr(rscratch1, Address(rthread, JavaThread::jvmti_thread_state_offset()));140cbz(rscratch1, L); // if (thread->jvmti_thread_state() == NULL) exit;141142// Initiate earlyret handling only if it is not already being processed.143// If the flag has the earlyret_processing bit set, it means that this code144// is called *during* earlyret handling - we don't want to reenter.145ldr(rscratch1, Address(rscratch1, JvmtiThreadState::earlyret_state_offset()));146cmp(rscratch1, JvmtiThreadState::earlyret_pending);147b(L, Assembler::NE);148149// Call Interpreter::remove_activation_early_entry() to get the address of the150// same-named entrypoint in the generated interpreter code.151ldr(rscratch1, Address(rthread, JavaThread::jvmti_thread_state_offset()));152ldr(rscratch1, Address(rscratch1, JvmtiThreadState::earlyret_tos_offset()));153call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_early_entry), rscratch1);154b(r0);155bind(L);156}157}158159void InterpreterMacroAssembler::get_unsigned_2_byte_index_at_bcp(160Register reg,161int bcp_offset) {162assert(bcp_offset >= 0, "bcp is still pointing to start of bytecode");163ldrh(reg, Address(rbcp, bcp_offset));164rev16(reg, reg);165}166167void InterpreterMacroAssembler::get_dispatch() {168mov(rdispatch, ExternalAddress((address)Interpreter::dispatch_table()));169}170171void InterpreterMacroAssembler::get_cache_index_at_bcp(Register index,172int bcp_offset,173size_t index_size) {174assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");175if (index_size == sizeof(u2)) {176load_unsigned_short(index, Address(rbcp, bcp_offset));177} else if (index_size == sizeof(u4)) {178// assert(EnableInvokeDynamic, "giant index used only for JSR 292");179ldr(index, Address(rbcp, bcp_offset));180// Check if the secondary index definition is still ~x, otherwise181// we have to change the following assembler code to calculate the182// plain index.183assert(ConstantPool::decode_invokedynamic_index(~123) == 123, "else change next line");184inv(index, index); // convert to plain index185} else if (index_size == sizeof(u1)) {186load_unsigned_byte(index, Address(rbcp, bcp_offset));187} else {188ShouldNotReachHere();189}190}191192// Return193// Rindex: index into constant pool194// Rcache: address of cache entry - ConstantPoolCache::base_offset()195//196// A caller must add ConstantPoolCache::base_offset() to Rcache to get197// the true address of the cache entry.198//199void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache,200Register index,201int bcp_offset,202size_t index_size) {203assert_different_registers(cache, index);204assert_different_registers(cache, rcpool);205get_cache_index_at_bcp(index, bcp_offset, index_size);206assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");207// convert from field index to ConstantPoolCacheEntry208// aarch32 already has the cache in rcpool so there is no need to209// install it in cache. instead we pre-add the indexed offset to210// rcpool and return it in cache. All clients of this method need to211// be modified accordingly.212add(cache, rcpool, index, lsl( exact_log2(4) + exact_log2(wordSize)));213}214215216void InterpreterMacroAssembler::get_cache_and_index_and_bytecode_at_bcp(Register cache,217Register index,218Register bytecode,219int byte_no,220int bcp_offset,221size_t index_size) {222get_cache_and_index_at_bcp(cache, index, bcp_offset, index_size);223// We use a 32-bit load here since the layout of 64-bit words on224// little-endian machines allow us that.225// n.b. unlike x86 cache alreeady includes the index offset226ldr(bytecode, Address(cache,227ConstantPoolCache::base_offset()228+ ConstantPoolCacheEntry::indices_offset()));229const int shift_count = (1 + byte_no) * BitsPerByte;230//ubfx(bytecode, bytecode, shift_count, BitsPerByte);231assert(shift_count >= 0 && shift_count <= 24 && 0 == (shift_count & 7), "Invalid shift count");232uxtb(bytecode, bytecode, ror(shift_count));233}234235void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,236Register tmp,237int bcp_offset,238size_t index_size) {239assert(cache != tmp, "must use different register");240get_cache_index_at_bcp(tmp, bcp_offset, index_size);241assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");242// convert from field index to ConstantPoolCacheEntry index243// and from word offset to byte offset244assert(exact_log2(in_bytes(ConstantPoolCacheEntry::size_in_bytes())) == 2 + LogBytesPerWord, "else change next line");245ldr(cache, Address(rfp, frame::interpreter_frame_cache_offset * wordSize));246// skip past the header247add(cache, cache, in_bytes(ConstantPoolCache::base_offset()));248add(cache, cache, tmp, lsl(2 + LogBytesPerWord)); // construct pointer to cache entry249}250251void InterpreterMacroAssembler::get_method_counters(Register method,252Register mcs, Label& skip) {253Label has_counters;254ldr(mcs, Address(method, Method::method_counters_offset()));255cbnz(mcs, has_counters);256call_VM(noreg, CAST_FROM_FN_PTR(address,257InterpreterRuntime::build_method_counters), method);258ldr(mcs, Address(method, Method::method_counters_offset()));259cbz(mcs, skip); // No MethodCounters allocated, OutOfMemory260bind(has_counters);261}262263// Load object from cpool->resolved_references(index)264void InterpreterMacroAssembler::load_resolved_reference_at_index(265Register result, Register index) {266assert_different_registers(result, index);267// convert from field index to resolved_references() index and from268// word index to byte offset. Since this is a java object, it can be compressed269Register tmp = index; // reuse270//lsl(tmp, tmp, LogBytesPerHeapOop);271//FIXME Rolled into add - does it work?272273get_constant_pool(result);274// load pointer for resolved_references[] objArray275ldr(result, Address(result, ConstantPool::resolved_references_offset_in_bytes()));276// JNIHandles::resolve(obj);277ldr(result, Address(result, 0));278// Add in the index279add(result, result, tmp, lsl(LogBytesPerHeapOop));280load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));281}282283// Generate a subtype check: branch to ok_is_subtype if sub_klass is a284// subtype of super_klass.285//286// Args:287// r0: superklass288// Rsub_klass: subklass289//290// Kills:291// r2, r5292void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass,293Label& ok_is_subtype) {294assert(Rsub_klass != r0, "r0 holds superklass");295assert(Rsub_klass != r2, "r2 holds 2ndary super array length");296assert(Rsub_klass != r14, "r14 holds 2ndary super array scan ptr");297298// Profile the not-null value's klass.299profile_typecheck(r2, Rsub_klass, r14); // blows r2300301// Do the check.302check_klass_subtype(Rsub_klass, r0, r2, ok_is_subtype); // blows r2303304// Profile the failure of the check.305profile_typecheck_failed(r2); // blows r2306}307308// Java Expression Stack309310void InterpreterMacroAssembler::pop_ptr(Register r) {311ldr(r, post(sp, wordSize));312}313314void InterpreterMacroAssembler::pop_i(Register r) {315ldr(r, post(sp, wordSize));316}317318void InterpreterMacroAssembler::pop_l(Register rLo, Register rHi) {319assert(rHi->encoding() == rLo->encoding() + 1, "must use two consecutive registers");320ldrd(rLo, post(sp, 2 * Interpreter::stackElementSize));321}322323void InterpreterMacroAssembler::push_ptr(Register r) {324str(r, pre(sp, -wordSize));325}326327void InterpreterMacroAssembler::push_i(Register r) {328str(r, pre(sp, -wordSize));329}330331void InterpreterMacroAssembler::push_l(Register rLo, Register rHi) {332assert(r2->encoding() == r1->encoding() + 1, "must use two consecutive registers");333strd(rLo, pre(sp, -2 * wordSize));334}335336void InterpreterMacroAssembler::pop_f(FloatRegister r) {337vldmia_f32(sp, FloatRegSet(r).bits());338}339340void InterpreterMacroAssembler::pop_d(FloatRegister r) {341assert(is_even(r->encoding()), "not double!");342vldmia_f64(sp, DoubleFloatRegSet(r).bits());343}344345void InterpreterMacroAssembler::push_f(FloatRegister r) {346vstmdb_f32(sp, FloatRegSet(r).bits());347}348349void InterpreterMacroAssembler::push_d(FloatRegister r) {350assert(is_even(r->encoding()), "not double!");351vstmdb_f64(sp, DoubleFloatRegSet(r).bits());352}353354void InterpreterMacroAssembler::pop(TosState state) {355switch (state) {356case atos: pop_ptr(); break;357case btos:358case ztos:359case ctos:360case stos:361case itos: pop_i(); break;362case ltos: pop_l(); break;363case ftos:364if(hasFPU()) {365pop_f();366} else {367pop_i();368}369break;370case dtos:371if(hasFPU()) {372pop_d();373} else {374pop_l();375}376break;377case vtos: /* nothing to do */ break;378default: ShouldNotReachHere();379}380verify_oop(r0, state);381}382383void InterpreterMacroAssembler::push(TosState state) {384verify_oop(r0, state);385switch (state) {386case atos: push_ptr(); break;387case btos:388case ztos:389case ctos:390case stos:391case itos: push_i(); break;392case ltos: push_l(); break;393case ftos:394if(hasFPU()) {395push_f();396} else {397push_i();398}399break;400case dtos:401if(hasFPU()) {402push_d();403} else {404push_l();405}406break;407case vtos: /* nothing to do */ break;408default : ShouldNotReachHere();409}410}411412// Helpers for swap and dup413void InterpreterMacroAssembler::load_ptr(int n, Register val) {414ldr(val, Address(sp, Interpreter::expr_offset_in_bytes(n)));415}416417void InterpreterMacroAssembler::store_ptr(int n, Register val) {418str(val, Address(sp, Interpreter::expr_offset_in_bytes(n)));419}420421422void InterpreterMacroAssembler::prepare_to_jump_from_interpreted() {423// set sender sp424mov(r4, sp);425// record last_sp426str(sp, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));427}428429void print_method_name(Method* m, char * msg) {430if(MacroAssembler::enable_debug) {431printf("%s", msg);432fflush(stdout);433m->print_short_name();434printf("\n");435fflush(stdout);436}437}438439// Jump to from_interpreted entry of a call unless single stepping is possible440// in this thread in which case we must call the i2i entry441void InterpreterMacroAssembler::jump_from_interpreted(Register method, Register temp) {442prepare_to_jump_from_interpreted();443444if (JvmtiExport::can_post_interpreter_events()) {445Label run_compiled_code;446// JVMTI events, such as single-stepping, are implemented partly by avoiding running447// compiled code in threads for which the event is enabled. Check here for448// interp_only_mode if these events CAN be enabled.449// interp_only is an int, on little endian it is sufficient to test the byte only450// Is a cmpl faster?451ldr(temp, Address(rthread, JavaThread::interp_only_mode_offset()));452cbz(temp, run_compiled_code);453ldr(temp, Address(method, Method::interpreter_entry_offset()));454b(temp);455bind(run_compiled_code);456}457458ldr(temp, Address(method, Method::from_interpreted_offset()));459b(temp);460}461462// The following two routines provide a hook so that an implementation463// can schedule the dispatch in two parts. amd64 does not do this.464void InterpreterMacroAssembler::dispatch_prolog(TosState state, int step) {465}466467void InterpreterMacroAssembler::dispatch_epilog(TosState state, int step) {468dispatch_next(state, step);469}470471void InterpreterMacroAssembler::dispatch_base(TosState state,472address* table,473bool verifyoop) {474if (VerifyActivationFrameSize) {475Unimplemented();476}477if (verifyoop) {478verify_oop(r0, state);479}480481/* Debugging code */482bytecode_seen(rscratch1, r3);483484/*{485Label skip;486487mov(r3, (address)&MacroAssembler::bytecodes_executed);488ldr(r2, r3);489add(r2, r2, 1);490str(r2, r3);491// Print out every 16384 (needs to be a power of two).492mov(r3, 16384 - 1);493tst(r2, r3);494b(skip, Assembler::NE);495reg_printf_important("Executed %d bytecodes.\n", r2);496bind(skip);497}*/498499500/*mov(r3, (address)&MacroAssembler::bytecodes_until_print);501ldr(r2, Address(r3));502cmp(r2, 0);503504sub(r2, r2, 1, Assembler::NE);505str(r2, Address(r3), Assembler::NE);506507mov(r2, 1, Assembler::EQ);508mov(r3, (address)&MacroAssembler::enable_debug, Assembler::EQ);509str(r2, Address(r3), Assembler::EQ);510511mov(r3, (address)&MacroAssembler::enable_method_debug, Assembler::EQ);512str(r2, Address(r3), Assembler::EQ);*/513514/*Label end;515cmp(r2, 0);516b(end, Assembler::NE);517stop("got to end of bytecodes");518bind(end);*/519520get_bytecode(r14, rscratch1);521reg_printf("Dispatching bytecode %s (%d) @ BCP = %p\n", r14, rscratch1, rbcp);522/* End debugging code */523524525if (table == Interpreter::dispatch_table(state)) {526add(rscratch2, rscratch1, Interpreter::distance_from_dispatch_table(state));527ldr(r15_pc, Address(rdispatch, rscratch2, lsl(2)));528} else {529mov(rscratch2, (address)table);530ldr(r15_pc, Address(rscratch2, rscratch1, lsl(2)));531}532}533534void InterpreterMacroAssembler::dispatch_only(TosState state) {535dispatch_base(state, Interpreter::dispatch_table(state));536}537538void InterpreterMacroAssembler::dispatch_only_normal(TosState state) {539dispatch_base(state, Interpreter::normal_table(state));540}541542void InterpreterMacroAssembler::dispatch_only_noverify(TosState state) {543dispatch_base(state, Interpreter::normal_table(state), false);544}545546547void InterpreterMacroAssembler::dispatch_next(TosState state, int step) {548// load next bytecode549ldrb(rscratch1, Address(pre(rbcp, step)));550dispatch_base(state, Interpreter::dispatch_table(state));551}552553void InterpreterMacroAssembler::dispatch_via(TosState state, address* table) {554// load current bytecode555ldrb(rscratch1, Address(rbcp, 0));556dispatch_base(state, table);557}558559// remove activation560//561// Unlock the receiver if this is a synchronized method.562// Unlock any Java monitors from syncronized blocks.563// Remove the activation from the stack.564//565// If there are locked Java monitors566// If throw_monitor_exception567// throws IllegalMonitorStateException568// Else if install_monitor_exception569// installs IllegalMonitorStateException570// Else571// no error processing572void InterpreterMacroAssembler::remove_activation(573TosState state,574bool throw_monitor_exception,575bool install_monitor_exception,576bool notify_jvmdi) {577// Note: Registers r3 xmm0 may be in use for the578// result check if synchronized method579Label unlocked, unlock, no_unlock;580581// get the value of _do_not_unlock_if_synchronized into r3582const Address do_not_unlock_if_synchronized(rthread,583in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()));584ldrb(r3, do_not_unlock_if_synchronized);585mov(rscratch1, 0);586strb(rscratch1, do_not_unlock_if_synchronized); // reset the flag587588// get method access flags589ldr(rscratch1, Address(rfp, frame::interpreter_frame_method_offset * wordSize));590ldr(r2, Address(rscratch1, Method::access_flags_offset()));591tst(r2, JVM_ACC_SYNCHRONIZED);592b(unlocked, Assembler::EQ);593594// Don't unlock anything if the _do_not_unlock_if_synchronized flag595// is set.596cbnz(r3, no_unlock);597598// unlock monitor599push(state); // save result600601// BasicObjectLock will be first in list, since this is a602// synchronized method. However, need to check that the object has603// not been unlocked by an explicit monitorexit bytecode.604const Address monitor(rfp, frame::interpreter_frame_initial_sp_offset *605wordSize - (int) sizeof(BasicObjectLock));606// We use c_rarg1 so that if we go slow path it will be the correct607// register for unlock_object to pass to VM directly608lea(c_rarg1, monitor); // address of first monitor609610ldr(r0, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes()));611cbnz(r0, unlock);612613pop(state);614if (throw_monitor_exception) {615// Entry already unlocked, need to throw exception616call_VM(noreg, CAST_FROM_FN_PTR(address,617InterpreterRuntime::throw_illegal_monitor_state_exception));618should_not_reach_here();619} else {620// Monitor already unlocked during a stack unroll. If requested,621// install an illegal_monitor_state_exception. Continue with622// stack unrolling.623if (install_monitor_exception) {624call_VM(noreg, CAST_FROM_FN_PTR(address,625InterpreterRuntime::new_illegal_monitor_state_exception));626}627b(unlocked);628}629630bind(unlock);631unlock_object(c_rarg1);632pop(state);633634// Check that for block-structured locking (i.e., that all locked635// objects has been unlocked)636bind(unlocked);637638// r0: Might contain return value639// FIXME r1 : Might contain the value too640641// Check that all monitors are unlocked642{643Label loop, exception, entry, restart;644const int entry_size = frame::interpreter_frame_monitor_size() * wordSize;645const Address monitor_block_top(646rfp, frame::interpreter_frame_monitor_block_top_offset * wordSize);647const Address monitor_block_bot(648rfp, frame::interpreter_frame_initial_sp_offset * wordSize);649650bind(restart);651// We can't use c_rarg1 as it might contain a result652ldr(c_rarg2, monitor_block_top); // points to current entry, starting653// with top-most entry654lea(r14, monitor_block_bot); // points to word before bottom of655// monitor block656b(entry);657658// Entry already locked, need to throw exception659bind(exception);660661if (throw_monitor_exception) {662// Throw exception663MacroAssembler::call_VM(noreg,664CAST_FROM_FN_PTR(address, InterpreterRuntime::665throw_illegal_monitor_state_exception));666should_not_reach_here();667} else {668// Stack unrolling. Unlock object and install illegal_monitor_exception.669// Unlock does not block, so don't have to worry about the frame.670// We don't have to preserve c_rarg1 since we are going to throw an exception.671672push(state);673mov(c_rarg1, c_rarg2);674unlock_object(c_rarg1);675pop(state);676677if (install_monitor_exception) {678call_VM(noreg, CAST_FROM_FN_PTR(address,679InterpreterRuntime::680new_illegal_monitor_state_exception));681}682683b(restart);684}685686bind(loop);687// check if current entry is used688ldr(rscratch1, Address(c_rarg2, BasicObjectLock::obj_offset_in_bytes()));689cbnz(rscratch1, exception);690691add(c_rarg2, c_rarg2, entry_size); // otherwise advance to next entry692bind(entry);693cmp(c_rarg2, r14); // check if bottom reached694b(loop, Assembler::NE); // if not at bottom then check this entry695}696697bind(no_unlock);698699// jvmti support700if (notify_jvmdi) {701notify_method_exit(state, NotifyJVMTI); // preserve TOSCA702} else {703notify_method_exit(state, SkipNotifyJVMTI); // preserve TOSCA704}705706// remove activation707// get sender sp708ldr(rscratch1,709Address(rfp, frame::interpreter_frame_sender_sp_offset * wordSize));710// remove frame anchor711leave();712// If we're returning to interpreted code we will shortly be713// adjusting SP to allow some space for ESP. If we're returning to714// compiled code the saved sender SP was saved in sender_sp, so this715// restores it.716//bic(sp, rscratch1, 0xf); changed to not drop it as this is the sp717mov(sp, rscratch1);718}719720#endif // C_INTERP721722// Lock object723//724// Args:725// c_rarg1: BasicObjectLock to be used for locking726//727// Kills:728// r0729// c_rarg0, c_rarg1, c_rarg2, c_rarg3, .. (param regs)730// rscratch1, rscratch2 (scratch regs)731void InterpreterMacroAssembler::lock_object(Register lock_reg)732{733reg_printf("LOCK:\n");734assert(lock_reg == c_rarg1, "The argument is only for looks. It must be c_rarg1");735if (UseHeavyMonitors) {736call_VM(noreg,737CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),738lock_reg);739} else {740Label done;741742const Register swap_reg = r0;743const Register obj_reg = c_rarg3; // Will contain the oop744745const int obj_offset = BasicObjectLock::obj_offset_in_bytes();746const int lock_offset = BasicObjectLock::lock_offset_in_bytes ();747const int mark_offset = lock_offset +748BasicLock::displaced_header_offset_in_bytes();749750Label slow_case;751752// Load object pointer into obj_reg %c_rarg3753ldr(obj_reg, Address(lock_reg, obj_offset));754755if (UseBiasedLocking) {756biased_locking_enter(lock_reg, obj_reg, swap_reg, rscratch2, false, done, &slow_case);757}758759// Load (object->mark() | 1) into swap_reg760ldr(rscratch1, Address(obj_reg, 0));761orr(swap_reg, rscratch1, 1);762763// Save (object->mark() | 1) into BasicLock's displaced header764str(swap_reg, Address(lock_reg, mark_offset));765766assert(lock_offset == 0,767"displached header must be first word in BasicObjectLock");768769Label fail;770if (PrintBiasedLockingStatistics) {771Label fast;772cmpxchgptr(swap_reg, lock_reg, obj_reg, rscratch1, fast, &fail);773bind(fast);774atomic_inc(Address((address)BiasedLocking::fast_path_entry_count_addr()),775rscratch2, rscratch1);776b(done);777bind(fail);778} else {779cmpxchgptr(swap_reg, lock_reg, obj_reg, rscratch1, done, /*fallthrough*/NULL);780}781782// Test if the oopMark is an obvious stack pointer, i.e.,783// 1) (mark & 7) == 0, and784// 2) rsp <= mark < mark + os::pagesize()785//786// These 3 tests can be done by evaluating the following787// expression: ((mark - rsp) & (7 - os::vm_page_size())),788// assuming both stack pointer and pagesize have their789// least significant 3 bits clear.790// NOTE: the oopMark is in swap_reg %r0 as the result of cmpxchg791// NOTE2: aarch32 does not like to subtract sp from rn so take a792// copy793794795//mov(rscratch1, sp);796//sub(swap_reg, swap_reg, rscratch1);797//ands(swap_reg, swap_reg, (unsigned long)(7 - os::vm_page_size()));798sub(swap_reg, swap_reg, sp);799mov(rscratch1, (os::vm_page_size() - 1) & ~0b11);800bics(swap_reg, swap_reg, rscratch1);801802// Save the test result, for recursive case, the result is zero803str(swap_reg, Address(lock_reg, mark_offset));804805if (PrintBiasedLockingStatistics) {806b(slow_case, Assembler::NE);807atomic_inc(Address((address)BiasedLocking::fast_path_entry_count_addr()),808rscratch2, rscratch1);809}810b(done, Assembler::EQ);811812bind(slow_case);813814// Call the runtime routine for slow case815call_VM(noreg,816CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),817lock_reg);818819bind(done);820}821}822823824// Unlocks an object. Used in monitorexit bytecode and825// remove_activation. Throws an IllegalMonitorException if object is826// not locked by current thread.827//828// Args:829// c_rarg1: BasicObjectLock for lock830//831// Kills:832// r0833// c_rarg0, c_rarg1, c_rarg2, c_rarg3, ... (param regs)834// rscratch1, rscratch2 (scratch regs)835void InterpreterMacroAssembler::unlock_object(Register lock_reg)836{837assert(lock_reg == c_rarg1, "The argument is only for looks. It must be rarg1");838839reg_printf("UNLOCK:\n");840if (UseHeavyMonitors) {841call_VM(noreg,842CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit),843lock_reg);844} else {845Label done;846847//create_breakpoint();848const Register swap_reg = c_rarg0;849const Register header_reg = c_rarg2; // Will contain the old oopMark850const Register obj_reg = c_rarg3; // Will contain the oop851852save_bcp(); // Save in case of exception853854// Convert from BasicObjectLock structure to object and BasicLock855// structure Store the BasicLock address into %r0856lea(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes()));857858// Load oop into obj_reg(%c_rarg3)859ldr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()));860861// Free entry862mov(rscratch2, 0);863str(rscratch2, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()));864865if (UseBiasedLocking) {866biased_locking_exit(obj_reg, header_reg, done);867}868869// Load the old header from BasicLock structure870ldr(header_reg, Address(swap_reg,871BasicLock::displaced_header_offset_in_bytes()));872873// Test for recursion874cbz(header_reg, done);875876// Atomic swap back the old header877cmpxchgptr(swap_reg, header_reg, obj_reg, rscratch1, done, /*fallthrough*/NULL);878879// Call the runtime routine for slow case.880str(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes())); // restore obj881call_VM(noreg,882CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit),883lock_reg);884885bind(done);886887restore_bcp();888}889}890891#ifndef CC_INTERP892893void InterpreterMacroAssembler::test_method_data_pointer(Register mdp,894Label& zero_continue) {895assert(ProfileInterpreter, "must be profiling interpreter");896ldr(mdp, Address(rfp, frame::interpreter_frame_mdx_offset * wordSize));897cbz(mdp, zero_continue);898}899900// Set the method data pointer for the current bcp.901void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() {902assert(ProfileInterpreter, "must be profiling interpreter");903Label set_mdp;904strd(r0, r1, Address(pre(sp, -2 * wordSize)));905906// Test MDO to avoid the call if it is NULL.907ldr(r0, Address(rmethod, in_bytes(Method::method_data_offset())));908cbz(r0, set_mdp);909call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), rmethod, rbcp);910// r0: mdi911// mdo is guaranteed to be non-zero here, we checked for it before the call.912ldr(r1, Address(rmethod, in_bytes(Method::method_data_offset())));913lea(r1, Address(r1, in_bytes(MethodData::data_offset())));914add(r0, r1, r0);915str(r0, Address(rfp, frame::interpreter_frame_mdx_offset * wordSize));916bind(set_mdp);917ldrd(r0, r1, Address(post(sp, 2 * wordSize)));918}919920void InterpreterMacroAssembler::verify_method_data_pointer() {921assert(ProfileInterpreter, "must be profiling interpreter");922#ifdef ASSERT923Label verify_continue;924strd(r0, r1, Address(pre(sp, -2 * wordSize)));925strd(r2, r3, Address(pre(sp, -2 * wordSize)));926test_method_data_pointer(r3, verify_continue); // If mdp is zero, continue927get_method(r1);928929// If the mdp is valid, it will point to a DataLayout header which is930// consistent with the bcp. The converse is highly probable also.931ldrsh(r2, Address(r3, in_bytes(DataLayout::bci_offset())));932ldr(rscratch1, Address(r1, Method::const_offset()));933add(r2, r2, rscratch1);934lea(r2, Address(r2, ConstMethod::codes_offset()));935cmp(r2, rbcp);936b(verify_continue, Assembler::EQ);937// r1: method938// rbcp: bcp // rbcp == 22939// r3: mdp940call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::verify_mdp),941r1, rbcp, r3);942bind(verify_continue);943ldrd(r2, r3, Address(post(sp, 2 * wordSize)));944ldrd(r0, r1, Address(post(sp, 2 * wordSize)));945#endif // ASSERT946}947948949void InterpreterMacroAssembler::set_mdp_data_at(Register mdp_in,950int constant,951Register value) {952assert(ProfileInterpreter, "must be profiling interpreter");953Address data(mdp_in, constant);954str(value, data);955}956957958void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in,959int constant,960bool decrement) {961increment_mdp_data_at(mdp_in, noreg, constant, decrement);962}963964void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in,965Register reg,966int constant,967bool decrement) {968assert(ProfileInterpreter, "must be profiling interpreter");969// %%% this does 64bit counters at best it is wasting space970// at worst it is a rare bug when counters overflow971972assert_different_registers(rscratch2, rscratch1, mdp_in, reg);973974Address addr1(mdp_in, constant);975Address addr2(rscratch2, reg, lsl(0));976Address &addr = addr1;977if (reg != noreg) {978lea(rscratch2, addr1);979addr = addr2;980}981982if (decrement) {983// Decrement the register. Set condition codes.984// Intel does this985// addptr(data, (int32_t) -DataLayout::counter_increment);986// If the decrement causes the counter to overflow, stay negative987// Label L;988// jcc(Assembler::negative, L);989// addptr(data, (int32_t) DataLayout::counter_increment);990// so we do this991ldr(rscratch1, addr);992subs(rscratch1, rscratch1, (unsigned)DataLayout::counter_increment);993Label L;994b(L, Assembler::LO); // skip store if counter underflow995str(rscratch1, addr);996bind(L);997} else {998assert(DataLayout::counter_increment == 1,999"flow-free idiom only works with 1");1000// Intel does this1001// Increment the register. Set carry flag.1002// addptr(data, DataLayout::counter_increment);1003// If the increment causes the counter to overflow, pull back by 1.1004// sbbptr(data, (int32_t)0);1005// so we do this1006ldr(rscratch1, addr);1007adds(rscratch1, rscratch1, DataLayout::counter_increment);1008Label L;1009b(L, Assembler::CS); // skip store if counter overflow1010str(rscratch1, addr);1011bind(L);1012}1013}10141015void InterpreterMacroAssembler::set_mdp_flag_at(Register mdp_in,1016int flag_byte_constant) {1017assert(ProfileInterpreter, "must be profiling interpreter");1018int header_offset = in_bytes(DataLayout::header_offset());1019int header_bits = DataLayout::flag_mask_to_header_mask(flag_byte_constant);1020// Set the flag1021ldr(rscratch1, Address(mdp_in, header_offset));1022orr(rscratch1, rscratch1, header_bits);1023str(rscratch1, Address(mdp_in, header_offset));1024}102510261027void InterpreterMacroAssembler::test_mdp_data_at(Register mdp_in,1028int offset,1029Register value,1030Register test_value_out,1031Label& not_equal_continue) {1032assert(ProfileInterpreter, "must be profiling interpreter");1033if (test_value_out == noreg) {1034ldr(rscratch1, Address(mdp_in, offset));1035cmp(value, rscratch1);1036} else {1037// Put the test value into a register, so caller can use it:1038ldr(test_value_out, Address(mdp_in, offset));1039cmp(value, test_value_out);1040}1041b(not_equal_continue, Assembler::NE);1042}104310441045void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in,1046int offset_of_disp) {1047assert(ProfileInterpreter, "must be profiling interpreter");1048ldr(rscratch1, Address(mdp_in, offset_of_disp));1049add(mdp_in, mdp_in, rscratch1);1050str(mdp_in, Address(rfp, frame::interpreter_frame_mdx_offset * wordSize));1051}105210531054void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in,1055Register reg,1056int offset_of_disp) {1057assert(ProfileInterpreter, "must be profiling interpreter");1058lea(rscratch1, Address(mdp_in, offset_of_disp));1059ldr(rscratch1, Address(rscratch1, reg, lsl()));1060add(mdp_in, mdp_in, rscratch1);1061str(mdp_in, Address(rfp, frame::interpreter_frame_mdx_offset * wordSize));1062}106310641065void InterpreterMacroAssembler::update_mdp_by_constant(Register mdp_in,1066int constant) {1067assert(ProfileInterpreter, "must be profiling interpreter");1068add(mdp_in, mdp_in, (unsigned) constant);1069str(mdp_in, Address(rfp, frame::interpreter_frame_mdx_offset * wordSize));1070}107110721073void InterpreterMacroAssembler::update_mdp_for_ret(Register return_bci) {1074assert(ProfileInterpreter, "must be profiling interpreter");1075// save/restore across call_VM1076mov(rscratch1, 0);1077strd(rscratch1, return_bci, Address(pre(sp, -2 * wordSize)));1078call_VM(noreg,1079CAST_FROM_FN_PTR(address, InterpreterRuntime::update_mdp_for_ret),1080return_bci);1081ldrd(rscratch1, return_bci, Address(post(sp, 2 * wordSize)));1082}108310841085void InterpreterMacroAssembler::profile_taken_branch(Register mdp,1086Register bumped_count) {1087if (ProfileInterpreter) {1088Label profile_continue;10891090// If no method data exists, go to profile_continue.1091// Otherwise, assign to mdp1092test_method_data_pointer(mdp, profile_continue);10931094// We are taking a branch. Increment the taken count.1095// We inline increment_mdp_data_at to return bumped_count in a register1096//increment_mdp_data_at(mdp, in_bytes(JumpData::taken_offset()));1097Address data(mdp, in_bytes(JumpData::taken_offset()));1098ldr(bumped_count, data);1099assert(DataLayout::counter_increment == 1,1100"flow-free idiom only works with 1");1101// Intel does this to catch overflow1102// addptr(bumped_count, DataLayout::counter_increment);1103// sbbptr(bumped_count, 0);1104// so we do this1105adds(bumped_count, bumped_count, DataLayout::counter_increment);1106Label L;1107b(L, Assembler::CS); // skip store if counter overflow1108str(bumped_count, data);1109bind(L);1110// The method data pointer needs to be updated to reflect the new target.1111update_mdp_by_offset(mdp, in_bytes(JumpData::displacement_offset()));1112bind(profile_continue);1113}1114}111511161117void InterpreterMacroAssembler::profile_not_taken_branch(Register mdp) {1118if (ProfileInterpreter) {1119Label profile_continue;11201121// If no method data exists, go to profile_continue.1122test_method_data_pointer(mdp, profile_continue);11231124// We are taking a branch. Increment the not taken count.1125increment_mdp_data_at(mdp, in_bytes(BranchData::not_taken_offset()));11261127// The method data pointer needs to be updated to correspond to1128// the next bytecode1129update_mdp_by_constant(mdp, in_bytes(BranchData::branch_data_size()));1130bind(profile_continue);1131}1132}113311341135void InterpreterMacroAssembler::profile_call(Register mdp) {1136if (ProfileInterpreter) {1137Label profile_continue;11381139// If no method data exists, go to profile_continue.1140test_method_data_pointer(mdp, profile_continue);11411142// We are making a call. Increment the count.1143increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));11441145// The method data pointer needs to be updated to reflect the new target.1146update_mdp_by_constant(mdp, in_bytes(CounterData::counter_data_size()));1147bind(profile_continue);1148}1149}11501151void InterpreterMacroAssembler::profile_final_call(Register mdp) {1152if (ProfileInterpreter) {1153Label profile_continue;11541155// If no method data exists, go to profile_continue.1156test_method_data_pointer(mdp, profile_continue);11571158// We are making a call. Increment the count.1159increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));11601161// The method data pointer needs to be updated to reflect the new target.1162update_mdp_by_constant(mdp,1163in_bytes(VirtualCallData::1164virtual_call_data_size()));1165bind(profile_continue);1166}1167}116811691170void InterpreterMacroAssembler::profile_virtual_call(Register receiver,1171Register mdp,1172Register reg2,1173bool receiver_can_be_null) {1174if (ProfileInterpreter) {1175Label profile_continue;11761177// If no method data exists, go to profile_continue.1178test_method_data_pointer(mdp, profile_continue);11791180Label skip_receiver_profile;1181if (receiver_can_be_null) {1182Label not_null;1183// We are making a call. Increment the count for null receiver.1184increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));1185b(skip_receiver_profile);1186bind(not_null);1187}11881189// Record the receiver type.1190record_klass_in_profile(receiver, mdp, reg2, true);1191bind(skip_receiver_profile);11921193// The method data pointer needs to be updated to reflect the new target.1194update_mdp_by_constant(mdp,1195in_bytes(VirtualCallData::1196virtual_call_data_size()));1197bind(profile_continue);1198}1199}12001201// This routine creates a state machine for updating the multi-row1202// type profile at a virtual call site (or other type-sensitive bytecode).1203// The machine visits each row (of receiver/count) until the receiver type1204// is found, or until it runs out of rows. At the same time, it remembers1205// the location of the first empty row. (An empty row records null for its1206// receiver, and can be allocated for a newly-observed receiver type.)1207// Because there are two degrees of freedom in the state, a simple linear1208// search will not work; it must be a decision tree. Hence this helper1209// function is recursive, to generate the required tree structured code.1210// It's the interpreter, so we are trading off code space for speed.1211// See below for example code.1212void InterpreterMacroAssembler::record_klass_in_profile_helper(1213Register receiver, Register mdp,1214Register reg2, int start_row,1215Label& done, bool is_virtual_call) {1216if (TypeProfileWidth == 0) {1217if (is_virtual_call) {1218increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));1219}1220return;1221}12221223int last_row = VirtualCallData::row_limit() - 1;1224assert(start_row <= last_row, "must be work left to do");1225// Test this row for both the receiver and for null.1226// Take any of three different outcomes:1227// 1. found receiver => increment count and goto done1228// 2. found null => keep looking for case 1, maybe allocate this cell1229// 3. found something else => keep looking for cases 1 and 21230// Case 3 is handled by a recursive call.1231for (int row = start_row; row <= last_row; row++) {1232Label next_test;1233bool test_for_null_also = (row == start_row);12341235// See if the receiver is receiver[n].1236int recvr_offset = in_bytes(VirtualCallData::receiver_offset(row));1237test_mdp_data_at(mdp, recvr_offset, receiver,1238(test_for_null_also ? reg2 : noreg),1239next_test);1240// (Reg2 now contains the receiver from the CallData.)12411242// The receiver is receiver[n]. Increment count[n].1243int count_offset = in_bytes(VirtualCallData::receiver_count_offset(row));1244increment_mdp_data_at(mdp, count_offset);1245b(done);1246bind(next_test);12471248if (test_for_null_also) {1249Label found_null;1250// Failed the equality check on receiver[n]... Test for null.1251if (start_row == last_row) {1252// The only thing left to do is handle the null case.1253if (is_virtual_call) {1254cbz(reg2, found_null);1255// Receiver did not match any saved receiver and there is no empty row for it.1256// Increment total counter to indicate polymorphic case.1257increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));1258b(done);1259bind(found_null);1260} else {1261cbz(reg2, done);1262}1263break;1264}1265// Since null is rare, make it be the branch-taken case.1266cbz(reg2,found_null);12671268// Put all the "Case 3" tests here.1269record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done, is_virtual_call);12701271// Found a null. Keep searching for a matching receiver,1272// but remember that this is an empty (unused) slot.1273bind(found_null);1274}1275}12761277// In the fall-through case, we found no matching receiver, but we1278// observed the receiver[start_row] is NULL.12791280// Fill in the receiver field and increment the count.1281int recvr_offset = in_bytes(VirtualCallData::receiver_offset(start_row));1282set_mdp_data_at(mdp, recvr_offset, receiver);1283int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row));1284mov(reg2, DataLayout::counter_increment);1285set_mdp_data_at(mdp, count_offset, reg2);1286if (start_row > 0) {1287b(done);1288}1289}12901291// Example state machine code for three profile rows:1292// // main copy of decision tree, rooted at row[1]1293// if (row[0].rec == rec) { row[0].incr(); goto done; }1294// if (row[0].rec != NULL) {1295// // inner copy of decision tree, rooted at row[1]1296// if (row[1].rec == rec) { row[1].incr(); goto done; }1297// if (row[1].rec != NULL) {1298// // degenerate decision tree, rooted at row[2]1299// if (row[2].rec == rec) { row[2].incr(); goto done; }1300// if (row[2].rec != NULL) { count.incr(); goto done; } // overflow1301// row[2].init(rec); goto done;1302// } else {1303// // remember row[1] is empty1304// if (row[2].rec == rec) { row[2].incr(); goto done; }1305// row[1].init(rec); goto done;1306// }1307// } else {1308// // remember row[0] is empty1309// if (row[1].rec == rec) { row[1].incr(); goto done; }1310// if (row[2].rec == rec) { row[2].incr(); goto done; }1311// row[0].init(rec); goto done;1312// }1313// done:13141315void InterpreterMacroAssembler::record_klass_in_profile(Register receiver,1316Register mdp, Register reg2,1317bool is_virtual_call) {1318assert(ProfileInterpreter, "must be profiling");1319Label done;13201321record_klass_in_profile_helper(receiver, mdp, reg2, 0, done, is_virtual_call);13221323bind (done);1324}13251326void InterpreterMacroAssembler::profile_ret(Register return_bci,1327Register mdp) {1328if (ProfileInterpreter) {1329Label profile_continue;1330uint row;13311332// If no method data exists, go to profile_continue.1333test_method_data_pointer(mdp, profile_continue);13341335// Update the total ret count.1336increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));13371338for (row = 0; row < RetData::row_limit(); row++) {1339Label next_test;13401341// See if return_bci is equal to bci[n]:1342test_mdp_data_at(mdp,1343in_bytes(RetData::bci_offset(row)),1344return_bci, noreg,1345next_test);13461347// return_bci is equal to bci[n]. Increment the count.1348increment_mdp_data_at(mdp, in_bytes(RetData::bci_count_offset(row)));13491350// The method data pointer needs to be updated to reflect the new target.1351update_mdp_by_offset(mdp,1352in_bytes(RetData::bci_displacement_offset(row)));1353b(profile_continue);1354bind(next_test);1355}13561357update_mdp_for_ret(return_bci);13581359bind(profile_continue);1360}1361}13621363void InterpreterMacroAssembler::profile_null_seen(Register mdp) {1364if (ProfileInterpreter) {1365Label profile_continue;13661367// If no method data exists, go to profile_continue.1368test_method_data_pointer(mdp, profile_continue);13691370set_mdp_flag_at(mdp, BitData::null_seen_byte_constant());13711372// The method data pointer needs to be updated.1373int mdp_delta = in_bytes(BitData::bit_data_size());1374if (TypeProfileCasts) {1375mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size());1376}1377update_mdp_by_constant(mdp, mdp_delta);13781379bind(profile_continue);1380}1381}13821383void InterpreterMacroAssembler::profile_typecheck_failed(Register mdp) {1384if (ProfileInterpreter && TypeProfileCasts) {1385Label profile_continue;13861387// If no method data exists, go to profile_continue.1388test_method_data_pointer(mdp, profile_continue);13891390int count_offset = in_bytes(CounterData::count_offset());1391// Back up the address, since we have already bumped the mdp.1392count_offset -= in_bytes(VirtualCallData::virtual_call_data_size());13931394// *Decrement* the counter. We expect to see zero or small negatives.1395increment_mdp_data_at(mdp, count_offset, true);13961397bind (profile_continue);1398}1399}14001401void InterpreterMacroAssembler::profile_typecheck(Register mdp, Register klass, Register reg2) {1402if (ProfileInterpreter) {1403Label profile_continue;14041405// If no method data exists, go to profile_continue.1406test_method_data_pointer(mdp, profile_continue);14071408// The method data pointer needs to be updated.1409int mdp_delta = in_bytes(BitData::bit_data_size());1410if (TypeProfileCasts) {1411mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size());14121413// Record the object type.1414record_klass_in_profile(klass, mdp, reg2, false);1415}1416update_mdp_by_constant(mdp, mdp_delta);14171418bind(profile_continue);1419}1420}14211422void InterpreterMacroAssembler::profile_switch_default(Register mdp) {1423if (ProfileInterpreter) {1424Label profile_continue;14251426// If no method data exists, go to profile_continue.1427test_method_data_pointer(mdp, profile_continue);14281429// Update the default case count1430increment_mdp_data_at(mdp,1431in_bytes(MultiBranchData::default_count_offset()));14321433// The method data pointer needs to be updated.1434update_mdp_by_offset(mdp,1435in_bytes(MultiBranchData::1436default_displacement_offset()));14371438bind(profile_continue);1439}1440}14411442void InterpreterMacroAssembler::profile_switch_case(Register index,1443Register mdp,1444Register reg2) {1445if (ProfileInterpreter) {1446Label profile_continue;14471448// If no method data exists, go to profile_continue.1449test_method_data_pointer(mdp, profile_continue);14501451// Build the base (index * per_case_size_in_bytes()) +1452// case_array_offset_in_bytes()1453mov(reg2, in_bytes(MultiBranchData::per_case_size()));1454mov(rscratch1, in_bytes(MultiBranchData::case_array_offset()));1455Assembler::mla(index, index, reg2, rscratch1);14561457// Update the case count1458increment_mdp_data_at(mdp,1459index,1460in_bytes(MultiBranchData::relative_count_offset()));14611462// The method data pointer needs to be updated.1463update_mdp_by_offset(mdp,1464index,1465in_bytes(MultiBranchData::1466relative_displacement_offset()));14671468bind(profile_continue);1469}1470}14711472void InterpreterMacroAssembler::verify_oop(Register reg, TosState state) {1473if (state == atos) {1474MacroAssembler::verify_oop(reg);1475}1476}14771478void InterpreterMacroAssembler::verify_FPU(int stack_depth, TosState state) { ; }1479#endif // !CC_INTERP148014811482void InterpreterMacroAssembler::notify_method_entry() {1483// Whenever JVMTI is interp_only_mode, method entry/exit events are sent to1484// track stack depth. If it is possible to enter interp_only_mode we add1485// the code to check if the event should be sent.1486if (JvmtiExport::can_post_interpreter_events()) {1487Label L;1488ldr(r3, Address(rthread, JavaThread::interp_only_mode_offset()));1489cbz(r3, L);1490call_VM(noreg, CAST_FROM_FN_PTR(address,1491InterpreterRuntime::post_method_entry));1492bind(L);1493}14941495#ifdef DTRACE_ENABLED1496{1497SkipIfEqual skip(this, &DTraceMethodProbes, false);1498get_method(c_rarg1);1499call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry),1500rthread, c_rarg1);1501}1502#endif15031504// RedefineClasses() tracing support for obsolete method entry1505if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {1506get_method(c_rarg1);1507call_VM_leaf(1508CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry),1509rthread, c_rarg1);1510}15111512}151315141515void InterpreterMacroAssembler::notify_method_exit(1516TosState state, NotifyMethodExitMode mode) {1517// Whenever JVMTI is interp_only_mode, method entry/exit events are sent to1518// track stack depth. If it is possible to enter interp_only_mode we add1519// the code to check if the event should be sent.1520if (mode == NotifyJVMTI && JvmtiExport::can_post_interpreter_events()) {1521Label L;1522// Note: frame::interpreter_frame_result has a dependency on how the1523// method result is saved across the call to post_method_exit. If this1524// is changed then the interpreter_frame_result implementation will1525// need to be updated too.15261527// For c++ interpreter the result is always stored at a known location in the frame1528// template interpreter will leave it on the top of the stack.1529NOT_CC_INTERP(push(state);)1530ldr(r3, Address(rthread, JavaThread::interp_only_mode_offset()));1531cbz(r3, L);1532call_VM(noreg,1533CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_exit));1534bind(L);1535NOT_CC_INTERP(pop(state));1536}15371538#ifdef DTRACE_ENABLED1539{1540SkipIfEqual skip(this, &DTraceMethodProbes, false);1541NOT_CC_INTERP(push(state));1542get_method(c_rarg1);1543call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit),1544rthread, c_rarg1);1545NOT_CC_INTERP(pop(state));1546}1547#endif1548}154915501551// Jump if ((*counter_addr += increment) & mask) satisfies the condition.1552void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr,1553int increment, int mask,1554Register scratch, Register scratch2, bool preloaded,1555Condition cond, Label* where) {1556if (!preloaded) {1557ldr(scratch, counter_addr);1558}1559add(scratch, scratch, increment);1560str(scratch, counter_addr);1561if (Assembler::is_valid_for_imm12(mask))1562ands(scratch, scratch, mask);1563else {1564mov(scratch2, mask);1565ands(scratch, scratch, scratch2);1566}1567b(*where, cond);1568}15691570void InterpreterMacroAssembler::call_VM_leaf_base(address entry_point,1571int number_of_arguments,1572Label *retaddr) {1573// interpreter specific1574//1575// Note: No need to save/restore rbcp & rlocals pointer since these1576// are callee saved registers and no blocking/ GC can happen1577// in leaf calls.1578#ifdef ASSERT1579{1580Label L;1581ldr(rscratch1, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));1582cbz(rscratch1, L);1583stop("InterpreterMacroAssembler::call_VM_leaf_base:"1584" last_sp != NULL");1585bind(L);1586}1587#endif /* ASSERT */1588// super call1589MacroAssembler::call_VM_leaf_base(entry_point, number_of_arguments, retaddr);1590}15911592void InterpreterMacroAssembler::call_VM_base(Register oop_result,1593Register java_thread,1594Register last_java_sp,1595address entry_point,1596int number_of_arguments,1597bool check_exceptions) {1598// interpreter specific1599//1600// Note: Could avoid restoring locals ptr (callee saved) - however doesn't1601// really make a difference for these runtime calls, since they are1602// slow anyway. Btw., bcp must be saved/restored since it may change1603// due to GC.1604// assert(java_thread == noreg , "not expecting a precomputed java thread");1605save_bcp();1606#ifdef ASSERT1607{1608Label L;1609ldr(rscratch1, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));1610cbz(rscratch1, L);1611stop("InterpreterMacroAssembler::call_VM_leaf_base:"1612" last_sp != NULL");1613bind(L);1614}1615#endif /* ASSERT */1616// super call1617MacroAssembler::call_VM_base(oop_result, noreg, last_java_sp,1618entry_point, number_of_arguments,1619check_exceptions);1620// interpreter specific1621restore_bcp();1622//restore_locals();1623}16241625void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) {1626Label update, next, none;16271628verify_oop(obj);16291630cbnz(obj, update);1631orptr(mdo_addr, TypeEntries::null_seen);1632b(next);16331634bind(update);1635load_klass(obj, obj);16361637ldr(rscratch1, mdo_addr);1638eor(obj, obj, rscratch1);1639bics(rscratch1, obj, ~TypeEntries::type_klass_mask);1640b(next, Assembler::EQ); // klass seen before, nothing to1641// do. The unknown bit may have been1642// set already but no need to check.16431644tst(obj, TypeEntries::type_unknown);1645b(next, Assembler::NE); // already unknown. Nothing to do anymore.16461647ldr(rscratch1, mdo_addr);1648cbz(rscratch1, none);1649cmp(rscratch1, TypeEntries::null_seen);1650b(none, Assembler::EQ);1651// There is a chance that the checks above (re-reading profiling1652// data from memory) fail if another thread has just set the1653// profiling to this obj's klass1654ldr(rscratch1, mdo_addr);1655eor(obj, obj, rscratch1);1656bics(rscratch1, obj, ~TypeEntries::type_klass_mask);1657b(next, Assembler::EQ);16581659// different than before. Cannot keep accurate profile.1660orptr(mdo_addr, TypeEntries::type_unknown);1661b(next);16621663bind(none);1664// first time here. Set profile type.1665str(obj, mdo_addr);16661667bind(next);1668}16691670void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual) {1671if (!ProfileInterpreter) {1672return;1673}16741675if (MethodData::profile_arguments() || MethodData::profile_return()) {1676Label profile_continue;16771678test_method_data_pointer(mdp, profile_continue);16791680int off_to_start = is_virtual ? in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size());16811682ldrb(rscratch1, Address(mdp, in_bytes(DataLayout::tag_offset()) - off_to_start));1683cmp(rscratch1, is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag);1684b(profile_continue, Assembler::NE);16851686if (MethodData::profile_arguments()) {1687Label done;1688int off_to_args = in_bytes(TypeEntriesAtCall::args_data_offset());1689add(mdp, mdp, off_to_args);16901691for (int i = 0; i < TypeProfileArgsLimit; i++) {1692if (i > 0 || MethodData::profile_return()) {1693// If return value type is profiled we may have no argument to profile1694ldr(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args));1695sub(tmp, tmp, i*TypeStackSlotEntries::per_arg_count());1696cmp(tmp, TypeStackSlotEntries::per_arg_count());1697b(done, Assembler::LT);1698}1699ldr(tmp, Address(callee, Method::const_offset()));1700load_unsigned_short(tmp, Address(tmp, ConstMethod::size_of_parameters_offset()));1701// stack offset o (zero based) from the start of the argument1702// list, for n arguments translates into offset n - o - 1 from1703// the end of the argument list1704ldr(rscratch1, Address(mdp, in_bytes(TypeEntriesAtCall::stack_slot_offset(i))-off_to_args));1705sub(tmp, tmp, rscratch1);1706sub(tmp, tmp, 1);1707Address arg_addr = argument_address(tmp);1708ldr(tmp, arg_addr);17091710Address mdo_arg_addr(mdp, in_bytes(TypeEntriesAtCall::argument_type_offset(i))-off_to_args);1711profile_obj_type(tmp, mdo_arg_addr);17121713int to_add = in_bytes(TypeStackSlotEntries::per_arg_size());1714add(mdp, mdp, to_add);1715off_to_args += to_add;1716}17171718if (MethodData::profile_return()) {1719ldr(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args));1720sub(tmp, tmp, TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count());1721}17221723bind(done);17241725if (MethodData::profile_return()) {1726// We're right after the type profile for the last1727// argument. tmp is the number of cells left in the1728// CallTypeData/VirtualCallTypeData to reach its end. Non null1729// if there's a return to profile.1730assert(ReturnTypeEntry::static_cell_count() < TypeStackSlotEntries::per_arg_count(), "can't move past ret type");1731add(mdp, mdp, tmp, lsl(exact_log2(DataLayout::cell_size)));1732}1733str(mdp, Address(rfp, frame::interpreter_frame_mdx_offset * wordSize));1734} else {1735assert(MethodData::profile_return(), "either profile call args or call ret");1736update_mdp_by_constant(mdp, in_bytes(TypeEntriesAtCall::return_only_size()));1737}17381739// mdp points right after the end of the1740// CallTypeData/VirtualCallTypeData, right after the cells for the1741// return value type if there's one17421743bind(profile_continue);1744}1745}17461747void InterpreterMacroAssembler::profile_return_type(Register mdp, Register ret, Register tmp) {1748assert_different_registers(mdp, ret, tmp, rbcp);1749if (ProfileInterpreter && MethodData::profile_return()) {1750Label profile_continue, done;17511752test_method_data_pointer(mdp, profile_continue);17531754if (MethodData::profile_return_jsr292_only()) {1755// If we don't profile all invoke bytecodes we must make sure1756// it's a bytecode we indeed profile. We can't go back to the1757// begining of the ProfileData we intend to update to check its1758// type because we're right after it and we don't known its1759// length1760Label do_profile;1761ldrb(rscratch1, Address(rbcp, 0));1762cmp(rscratch1, Bytecodes::_invokedynamic);1763b(do_profile, Assembler::EQ);1764cmp(rscratch1, Bytecodes::_invokehandle);1765b(do_profile, Assembler::EQ);1766get_method(tmp);1767ldrb(rscratch1, Address(tmp, Method::intrinsic_id_offset_in_bytes()));1768cmp(rscratch1, vmIntrinsics::_compiledLambdaForm);1769b(profile_continue, Assembler::NE);17701771bind(do_profile);1772}17731774Address mdo_ret_addr(mdp, -in_bytes(ReturnTypeEntry::size()));1775mov(tmp, ret);1776profile_obj_type(tmp, mdo_ret_addr);17771778bind(profile_continue);1779}1780}17811782void InterpreterMacroAssembler::profile_parameters_type(Register mdp, Register tmp1, Register tmp2) {1783if (ProfileInterpreter && MethodData::profile_parameters()) {1784Label profile_continue, done;17851786test_method_data_pointer(mdp, profile_continue);17871788// Load the offset of the area within the MDO used for1789// parameters. If it's negative we're not profiling any parameters1790ldr(tmp1, Address(mdp, in_bytes(MethodData::parameters_type_data_di_offset()) - in_bytes(MethodData::data_offset())));1791cmp(tmp1, 0u);1792b(profile_continue, Assembler::LT);17931794// Compute a pointer to the area for parameters from the offset1795// and move the pointer to the slot for the last1796// parameters. Collect profiling from last parameter down.1797// mdo start + parameters offset + array length - 11798add(mdp, mdp, tmp1);1799ldr(tmp1, Address(mdp, ArrayData::array_len_offset()));1800sub(tmp1, tmp1, TypeStackSlotEntries::per_arg_count());18011802Label loop;1803bind(loop);18041805int off_base = in_bytes(ParametersTypeData::stack_slot_offset(0));1806int type_base = in_bytes(ParametersTypeData::type_offset(0));1807int per_arg_scale = exact_log2(DataLayout::cell_size);1808add(rscratch1, mdp, off_base);1809add(rscratch2, mdp, type_base);18101811Address arg_off(rscratch1, tmp1, lsl(per_arg_scale));1812Address arg_type(rscratch2, tmp1, lsl(per_arg_scale));18131814// load offset on the stack from the slot for this parameter1815ldr(tmp2, arg_off);1816neg(tmp2, tmp2);1817// read the parameter from the local area1818ldr(tmp2, Address(rlocals, tmp2, lsl(Interpreter::logStackElementSize)));18191820// profile the parameter1821profile_obj_type(tmp2, arg_type);18221823// go to next parameter1824subs(tmp1, tmp1, TypeStackSlotEntries::per_arg_count());1825b(loop, Assembler::GE);18261827bind(profile_continue);1828}1829}183018311832