Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/cpu/ppc/vm/compiledIC_ppc.cpp
32285 views
/*1* Copyright (c) 1997, 2014, 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/nmethod.hpp"29#include "memory/resourceArea.hpp"30#include "runtime/mutexLocker.hpp"31#include "runtime/safepoint.hpp"32#ifdef COMPILER233#include "opto/matcher.hpp"34#endif3536// Release the CompiledICHolder* associated with this call site is there is one.37void CompiledIC::cleanup_call_site(virtual_call_Relocation* call_site) {38// This call site might have become stale so inspect it carefully.39NativeCall* call = nativeCall_at(call_site->addr());40if (is_icholder_entry(call->destination())) {41NativeMovConstReg* value = nativeMovConstReg_at(call_site->cached_value());42InlineCacheBuffer::queue_for_release((CompiledICHolder*)value->data());43}44}4546bool CompiledIC::is_icholder_call_site(virtual_call_Relocation* call_site) {47// This call site might have become stale so inspect it carefully.48NativeCall* call = nativeCall_at(call_site->addr());49return is_icholder_entry(call->destination());50}5152// ----------------------------------------------------------------------------5354// A PPC CompiledStaticCall looks like this:55//56// >>>> consts57//58// [call target1]59// [IC cache]60// [call target2]61//62// <<<< consts63// >>>> insts64//65// bl offset16 -+ -+ ??? // How many bits available?66// | |67// <<<< insts | |68// >>>> stubs | |69// | |- trampoline_stub_Reloc70// trampoline stub: | <-+71// r2 = toc |72// r2 = [r2 + offset] | // Load call target1 from const section73// mtctr r2 |74// bctr |- static_stub_Reloc75// comp_to_interp_stub: <---+76// r1 = toc77// ICreg = [r1 + IC_offset] // Load IC from const section78// r1 = [r1 + offset] // Load call target2 from const section79// mtctr r180// bctr81//82// <<<< stubs83//84// The call instruction in the code either85// - branches directly to a compiled method if offset encodable in instruction86// - branches to the trampoline stub if offset to compiled method not encodable87// - branches to the compiled_to_interp stub if target interpreted88//89// Further there are three relocations from the loads to the constants in90// the constant section.91//92// Usage of r1 and r2 in the stubs allows to distinguish them.9394const int IC_pos_in_java_to_interp_stub = 8;95#define __ _masm.96address CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf) {97#ifdef COMPILER298// Get the mark within main instrs section which is set to the address of the call.99address call_addr = cbuf.insts_mark();100101// Note that the code buffer's insts_mark is always relative to insts.102// That's why we must use the macroassembler to generate a stub.103MacroAssembler _masm(&cbuf);104105// Start the stub.106address stub = __ start_a_stub(CompiledStaticCall::to_interp_stub_size());107if (stub == NULL) {108return NULL; // CodeCache is full109}110111// For java_to_interp stubs we use R11_scratch1 as scratch register112// and in call trampoline stubs we use R12_scratch2. This way we113// can distinguish them (see is_NativeCallTrampolineStub_at()).114Register reg_scratch = R11_scratch1;115116// Create a static stub relocation which relates this stub117// with the call instruction at insts_call_instruction_offset in the118// instructions code-section.119__ relocate(static_stub_Relocation::spec(call_addr));120const int stub_start_offset = __ offset();121122// Now, create the stub's code:123// - load the TOC124// - load the inline cache oop from the constant pool125// - load the call target from the constant pool126// - call127__ calculate_address_from_global_toc(reg_scratch, __ method_toc());128AddressLiteral ic = __ allocate_metadata_address((Metadata *)NULL);129__ load_const_from_method_toc(as_Register(Matcher::inline_cache_reg_encode()), ic, reg_scratch);130131if (ReoptimizeCallSequences) {132__ b64_patchable((address)-1, relocInfo::none);133} else {134AddressLiteral a((address)-1);135__ load_const_from_method_toc(reg_scratch, a, reg_scratch);136__ mtctr(reg_scratch);137__ bctr();138}139140// FIXME: Assert that the stub can be identified and patched.141142// Java_to_interp_stub_size should be good.143assert((__ offset() - stub_start_offset) <= CompiledStaticCall::to_interp_stub_size(),144"should be good size");145assert(!is_NativeCallTrampolineStub_at(__ addr_at(stub_start_offset)),146"must not confuse java_to_interp with trampoline stubs");147148// End the stub.149__ end_a_stub();150return stub;151#else152ShouldNotReachHere();153#endif154}155#undef __156157// Size of java_to_interp stub, this doesn't need to be accurate but it must158// be larger or equal to the real size of the stub.159// Used for optimization in Compile::Shorten_branches.160int CompiledStaticCall::to_interp_stub_size() {161return 12 * BytesPerInstWord;162}163164// Relocation entries for call stub, compiled java to interpreter.165// Used for optimization in Compile::Shorten_branches.166int CompiledStaticCall::reloc_to_interp_stub() {167return 5;168}169170void CompiledStaticCall::set_to_interpreted(methodHandle callee, address entry) {171address stub = find_stub();172guarantee(stub != NULL, "stub not found");173174if (TraceICs) {175ResourceMark rm;176tty->print_cr("CompiledStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",177p2i(instruction_address()),178callee->name_and_sig_as_C_string());179}180181// Creation also verifies the object.182NativeMovConstReg* method_holder = nativeMovConstReg_at(stub + IC_pos_in_java_to_interp_stub);183NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());184185assert(method_holder->data() == 0 || method_holder->data() == (intptr_t)callee(),186"a) MT-unsafe modification of inline cache");187assert(jump->jump_destination() == (address)-1 || jump->jump_destination() == entry,188"b) MT-unsafe modification of inline cache");189190// Update stub.191method_holder->set_data((intptr_t)callee());192jump->set_jump_destination(entry);193194// Update jump to call.195set_destination_mt_safe(stub);196}197198void CompiledStaticCall::set_stub_to_clean(static_stub_Relocation* static_stub) {199assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "mt unsafe call");200// Reset stub.201address stub = static_stub->addr();202assert(stub != NULL, "stub not found");203// Creation also verifies the object.204NativeMovConstReg* method_holder = nativeMovConstReg_at(stub + IC_pos_in_java_to_interp_stub);205NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());206method_holder->set_data(0);207jump->set_jump_destination((address)-1);208}209210//-----------------------------------------------------------------------------211// Non-product mode code212#ifndef PRODUCT213214void CompiledStaticCall::verify() {215// Verify call.216NativeCall::verify();217if (os::is_MP()) {218verify_alignment();219}220221// Verify stub.222address stub = find_stub();223assert(stub != NULL, "no stub found for static call");224// Creation also verifies the object.225NativeMovConstReg* method_holder = nativeMovConstReg_at(stub + IC_pos_in_java_to_interp_stub);226NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());227228// Verify state.229assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted(), "sanity check");230}231232#endif // !PRODUCT233234235