Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/cpu/ppc/vm/nativeInst_ppc.hpp
32285 views
/*1* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.2* Copyright 2012, 2013 SAP AG. All rights reserved.3* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.4*5* This code is free software; you can redistribute it and/or modify it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*23*/2425#ifndef CPU_PPC_VM_NATIVEINST_PPC_HPP26#define CPU_PPC_VM_NATIVEINST_PPC_HPP2728#include "asm/assembler.hpp"29#include "asm/macroAssembler.hpp"30#include "memory/allocation.hpp"31#include "runtime/icache.hpp"32#include "runtime/os.hpp"33#include "utilities/top.hpp"3435// We have interfaces for the following instructions:36//37// - NativeInstruction38// - NativeCall39// - NativeFarCall40// - NativeMovConstReg41// - NativeJump42// - NativeIllegalInstruction43// - NativeConditionalFarBranch44// - NativeCallTrampolineStub4546// The base class for different kinds of native instruction abstractions.47// It provides the primitive operations to manipulate code relative to this.48class NativeInstruction VALUE_OBJ_CLASS_SPEC {49friend class Relocation;5051public:52bool is_sigtrap_ic_miss_check() {53assert(UseSIGTRAP, "precondition");54return MacroAssembler::is_trap_ic_miss_check(long_at(0));55}5657bool is_sigtrap_null_check() {58assert(UseSIGTRAP && TrapBasedNullChecks, "precondition");59return MacroAssembler::is_trap_null_check(long_at(0));60}6162// We use a special trap for marking a method as not_entrant or zombie63// iff UseSIGTRAP.64bool is_sigtrap_zombie_not_entrant() {65assert(UseSIGTRAP, "precondition");66return MacroAssembler::is_trap_zombie_not_entrant(long_at(0));67}6869// We use an illtrap for marking a method as not_entrant or zombie70// iff !UseSIGTRAP.71bool is_sigill_zombie_not_entrant() {72assert(!UseSIGTRAP, "precondition");73// Work around a C++ compiler bug which changes 'this'.74return NativeInstruction::is_sigill_zombie_not_entrant_at(addr_at(0));75}76static bool is_sigill_zombie_not_entrant_at(address addr);7778#ifdef COMPILER279// SIGTRAP-based implicit range checks80bool is_sigtrap_range_check() {81assert(UseSIGTRAP && TrapBasedRangeChecks, "precondition");82return MacroAssembler::is_trap_range_check(long_at(0));83}84#endif8586// 'should not reach here'.87bool is_sigtrap_should_not_reach_here() {88return MacroAssembler::is_trap_should_not_reach_here(long_at(0));89}9091bool is_safepoint_poll() {92// Is the current instruction a POTENTIAL read access to the polling page?93// The current arguments of the instruction are not checked!94return MacroAssembler::is_load_from_polling_page(long_at(0), NULL);95}9697bool is_memory_serialization(JavaThread *thread, void *ucontext) {98// Is the current instruction a write access of thread to the99// memory serialization page?100return MacroAssembler::is_memory_serialization(long_at(0), thread, ucontext);101}102103address get_stack_bang_address(void *ucontext) {104// If long_at(0) is not a stack bang, return 0. Otherwise, return105// banged address.106return MacroAssembler::get_stack_bang_address(long_at(0), ucontext);107}108109protected:110address addr_at(int offset) const { return address(this) + offset; }111int long_at(int offset) const { return *(int*)addr_at(offset); }112113public:114void verify() NOT_DEBUG_RETURN;115};116117inline NativeInstruction* nativeInstruction_at(address address) {118NativeInstruction* inst = (NativeInstruction*)address;119inst->verify();120return inst;121}122123// The NativeCall is an abstraction for accessing/manipulating call124// instructions. It is used to manipulate inline caches, primitive &125// dll calls, etc.126//127// Sparc distinguishes `NativeCall' and `NativeFarCall'. On PPC64,128// at present, we provide a single class `NativeCall' representing the129// sequence `load_const, mtctr, bctrl' or the sequence 'ld_from_toc,130// mtctr, bctrl'.131class NativeCall: public NativeInstruction {132public:133134enum ppc_specific_constants {135load_const_instruction_size = 28,136load_const_from_method_toc_instruction_size = 16,137instruction_size = 16 // Used in shared code for calls with reloc_info.138};139140static bool is_call_at(address a) {141return Assembler::is_bl(*(int*)(a));142}143144static bool is_call_before(address return_address) {145return NativeCall::is_call_at(return_address - 4);146}147148address instruction_address() const {149return addr_at(0);150}151152address next_instruction_address() const {153// We have only bl.154assert(MacroAssembler::is_bl(*(int*)instruction_address()), "Should be bl instruction!");155return addr_at(4);156}157158address return_address() const {159return next_instruction_address();160}161162address destination() const;163164// The parameter assert_lock disables the assertion during code generation.165void set_destination_mt_safe(address dest, bool assert_lock = true);166167address get_trampoline();168169void verify_alignment() {} // do nothing on ppc170void verify() NOT_DEBUG_RETURN;171};172173inline NativeCall* nativeCall_at(address instr) {174NativeCall* call = (NativeCall*)instr;175call->verify();176return call;177}178179inline NativeCall* nativeCall_before(address return_address) {180NativeCall* call = NULL;181if (MacroAssembler::is_bl(*(int*)(return_address - 4)))182call = (NativeCall*)(return_address - 4);183call->verify();184return call;185}186187// The NativeFarCall is an abstraction for accessing/manipulating native188// call-anywhere instructions.189// Used to call native methods which may be loaded anywhere in the address190// space, possibly out of reach of a call instruction.191class NativeFarCall: public NativeInstruction {192public:193// We use MacroAssembler::bl64_patchable() for implementing a194// call-anywhere instruction.195196// Checks whether instr points at a NativeFarCall instruction.197static bool is_far_call_at(address instr) {198return MacroAssembler::is_bl64_patchable_at(instr);199}200201// Does the NativeFarCall implementation use a pc-relative encoding202// of the call destination?203// Used when relocating code.204bool is_pcrelative() {205assert(MacroAssembler::is_bl64_patchable_at((address)this),206"unexpected call type");207return MacroAssembler::is_bl64_patchable_pcrelative_at((address)this);208}209210// Returns the NativeFarCall's destination.211address destination() const {212assert(MacroAssembler::is_bl64_patchable_at((address)this),213"unexpected call type");214return MacroAssembler::get_dest_of_bl64_patchable_at((address)this);215}216217// Sets the NativeCall's destination, not necessarily mt-safe.218// Used when relocating code.219void set_destination(address dest) {220// Set new destination (implementation of call may change here).221assert(MacroAssembler::is_bl64_patchable_at((address)this),222"unexpected call type");223MacroAssembler::set_dest_of_bl64_patchable_at((address)this, dest);224}225226void verify() NOT_DEBUG_RETURN;227};228229// Instantiates a NativeFarCall object starting at the given instruction230// address and returns the NativeFarCall object.231inline NativeFarCall* nativeFarCall_at(address instr) {232NativeFarCall* call = (NativeFarCall*)instr;233call->verify();234return call;235}236237// An interface for accessing/manipulating native set_oop imm, reg instructions.238// (used to manipulate inlined data references, etc.)239class NativeMovConstReg: public NativeInstruction {240public:241242enum ppc_specific_constants {243load_const_instruction_size = 20,244load_const_from_method_toc_instruction_size = 8,245instruction_size = 8 // Used in shared code for calls with reloc_info.246};247248address instruction_address() const {249return addr_at(0);250}251252address next_instruction_address() const;253254// (The [set_]data accessor respects oop_type relocs also.)255intptr_t data() const;256257// Patch the code stream.258address set_data_plain(intptr_t x, CodeBlob *code);259// Patch the code stream and oop pool.260void set_data(intptr_t x);261262// Patch narrow oop constants. Use this also for narrow klass.263void set_narrow_oop(narrowOop data, CodeBlob *code = NULL);264265void verify() NOT_DEBUG_RETURN;266};267268inline NativeMovConstReg* nativeMovConstReg_at(address address) {269NativeMovConstReg* test = (NativeMovConstReg*)address;270test->verify();271return test;272}273274// The NativeJump is an abstraction for accessing/manipulating native275// jump-anywhere instructions.276class NativeJump: public NativeInstruction {277public:278// We use MacroAssembler::b64_patchable() for implementing a279// jump-anywhere instruction.280281enum ppc_specific_constants {282instruction_size = MacroAssembler::b64_patchable_size283};284285// Checks whether instr points at a NativeJump instruction.286static bool is_jump_at(address instr) {287return MacroAssembler::is_b64_patchable_at(instr)288|| ( MacroAssembler::is_load_const_from_method_toc_at(instr)289&& Assembler::is_mtctr(*(int*)(instr + 2 * 4))290&& Assembler::is_bctr(*(int*)(instr + 3 * 4)));291}292293// Does the NativeJump implementation use a pc-relative encoding294// of the call destination?295// Used when relocating code or patching jumps.296bool is_pcrelative() {297return MacroAssembler::is_b64_patchable_pcrelative_at((address)this);298}299300// Returns the NativeJump's destination.301address jump_destination() const {302if (MacroAssembler::is_b64_patchable_at((address)this)) {303return MacroAssembler::get_dest_of_b64_patchable_at((address)this);304} else if (MacroAssembler::is_load_const_from_method_toc_at((address)this)305&& Assembler::is_mtctr(*(int*)((address)this + 2 * 4))306&& Assembler::is_bctr(*(int*)((address)this + 3 * 4))) {307return (address)((NativeMovConstReg *)this)->data();308} else {309ShouldNotReachHere();310return NULL;311}312}313314// Sets the NativeJump's destination, not necessarily mt-safe.315// Used when relocating code or patching jumps.316void set_jump_destination(address dest) {317// Set new destination (implementation of call may change here).318if (MacroAssembler::is_b64_patchable_at((address)this)) {319MacroAssembler::set_dest_of_b64_patchable_at((address)this, dest);320} else if (MacroAssembler::is_load_const_from_method_toc_at((address)this)321&& Assembler::is_mtctr(*(int*)((address)this + 2 * 4))322&& Assembler::is_bctr(*(int*)((address)this + 3 * 4))) {323((NativeMovConstReg *)this)->set_data((intptr_t)dest);324} else {325ShouldNotReachHere();326}327}328329// MT-safe insertion of native jump at verified method entry330static void patch_verified_entry(address entry, address verified_entry, address dest);331332void verify() NOT_DEBUG_RETURN;333334static void check_verified_entry_alignment(address entry, address verified_entry) {335// We just patch one instruction on ppc64, so the jump doesn't have to336// be aligned. Nothing to do here.337}338};339340// Instantiates a NativeJump object starting at the given instruction341// address and returns the NativeJump object.342inline NativeJump* nativeJump_at(address instr) {343NativeJump* call = (NativeJump*)instr;344call->verify();345return call;346}347348// NativeConditionalFarBranch is abstraction for accessing/manipulating349// conditional far branches.350class NativeConditionalFarBranch : public NativeInstruction {351public:352353static bool is_conditional_far_branch_at(address instr) {354return MacroAssembler::is_bc_far_at(instr);355}356357address branch_destination() const {358return MacroAssembler::get_dest_of_bc_far_at((address)this);359}360361void set_branch_destination(address dest) {362MacroAssembler::set_dest_of_bc_far_at((address)this, dest);363}364};365366inline NativeConditionalFarBranch* NativeConditionalFarBranch_at(address address) {367assert(NativeConditionalFarBranch::is_conditional_far_branch_at(address),368"must be a conditional far branch");369return (NativeConditionalFarBranch*)address;370}371372// Call trampoline stubs.373class NativeCallTrampolineStub : public NativeInstruction {374private:375376address encoded_destination_addr() const;377378public:379380address destination(nmethod *nm = NULL) const;381int destination_toc_offset() const;382383void set_destination(address new_destination);384};385386inline bool is_NativeCallTrampolineStub_at(address address) {387int first_instr = *(int*)address;388return Assembler::is_addis(first_instr) &&389(Register)(intptr_t)Assembler::inv_rt_field(first_instr) == R12_scratch2;390}391392inline NativeCallTrampolineStub* NativeCallTrampolineStub_at(address address) {393assert(is_NativeCallTrampolineStub_at(address), "no call trampoline found");394return (NativeCallTrampolineStub*)address;395}396397#endif // CPU_PPC_VM_NATIVEINST_PPC_HPP398399400