Path: blob/master/src/hotspot/cpu/arm/compiledIC_arm.cpp
40930 views
/*1* Copyright (c) 1997, 2021, 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/macroAssembler.inline.hpp"26#include "code/compiledIC.hpp"27#include "code/icBuffer.hpp"28#include "code/nativeInst.hpp"29#include "code/nmethod.hpp"30#include "memory/resourceArea.hpp"31#include "runtime/mutexLocker.hpp"32#include "runtime/safepoint.hpp"3334// ----------------------------------------------------------------------------35#if COMPILER2_OR_JVMCI36#define __ _masm.37// emit call stub, compiled java to interpreter38address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark) {39// Stub is fixed up when the corresponding call is converted from calling40// compiled code to calling interpreted code.41// set (empty), R942// b -14344if (mark == NULL) {45mark = cbuf.insts_mark(); // get mark within main instrs section46}4748MacroAssembler _masm(&cbuf);4950address base = __ start_a_stub(to_interp_stub_size());51if (base == NULL) {52return NULL; // CodeBuffer::expand failed53}5455// static stub relocation stores the instruction address of the call56__ relocate(static_stub_Relocation::spec(mark));5758InlinedMetadata object_literal(NULL);59// single instruction, see NativeMovConstReg::next_instruction_address() in60// CompiledStaticCall::set_to_interpreted()61__ ldr_literal(Rmethod, object_literal);6263__ set_inst_mark(); // Who uses this?6465bool near_range = __ cache_fully_reachable();66InlinedAddress dest((address)-1);67address branch_site = __ pc();68if (near_range) {69__ b(branch_site); // special NativeJump -1 destination70} else {71// Can't trash LR, FP, or argument registers72__ indirect_jump(dest, Rtemp);73}74__ bind_literal(object_literal); // includes spec_for_immediate reloc75if (!near_range) {76__ bind_literal(dest); // special NativeJump -1 destination77}7879assert(__ pc() - base <= to_interp_stub_size(), "wrong stub size");8081// Update current stubs pointer and restore code_end.82__ end_a_stub();83return base;84}85#undef __8687// Relocation entries for call stub, compiled java to interpreter.88int CompiledStaticCall::reloc_to_interp_stub() {89return 10; // 4 in emit_to_interp_stub + 1 in Java_Static_Call90}91#endif // COMPILER2_OR_JVMCI9293int CompiledStaticCall::to_trampoline_stub_size() {94// ARM doesn't use trampolines.95return 0;96}9798// size of C2 call stub, compiled java to interpretor99int CompiledStaticCall::to_interp_stub_size() {100return 8 * NativeInstruction::instruction_size;101}102103void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, address entry) {104address stub = find_stub();105guarantee(stub != NULL, "stub not found");106107if (TraceICs) {108ResourceMark rm;109tty->print_cr("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",110p2i(instruction_address()),111callee->name_and_sig_as_C_string());112}113114// Creation also verifies the object.115NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);116NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());117verify_mt_safe(callee, entry, method_holder, jump);118119// Update stub.120method_holder->set_data((intptr_t)callee());121jump->set_jump_destination(entry);122123ICache::invalidate_range(stub, to_interp_stub_size());124125// Update jump to call.126set_destination_mt_safe(stub);127}128129void CompiledDirectStaticCall::set_stub_to_clean(static_stub_Relocation* static_stub) {130// Reset stub.131address stub = static_stub->addr();132assert(stub != NULL, "stub not found");133assert(CompiledICLocker::is_safe(stub), "mt unsafe call");134// Creation also verifies the object.135NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);136NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());137method_holder->set_data(0);138jump->set_jump_destination((address)-1);139}140141//-----------------------------------------------------------------------------142// Non-product mode code143#ifndef PRODUCT144145void CompiledDirectStaticCall::verify() {146// Verify call.147_call->verify();148_call->verify_alignment();149150// Verify stub.151address stub = find_stub();152assert(stub != NULL, "no stub found for static call");153// Creation also verifies the object.154NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);155NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());156157// Verify state.158assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted(), "sanity check");159}160161#endif // !PRODUCT162163164