nativeInst_sparc.cpp revision 1483
1483N/A * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 0N/A * published by the Free Software Foundation. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 0N/A * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 0N/A * CA 95054 USA or visit www.sun.com if you need additional information or 0N/A * have any questions. 0N/A#
include "incls/_precompiled.incl" 0N/A // Generate a the new sequence 0N/A // make sure code pattern is actually an instruction address 0N/A // Don't need to invalidate 2 words here, because 0N/A // the flush instruction operates on doublewords. 0N/A // Don't need to invalidate 2 words here in the 64-bit case, 0N/A // because the flush instruction operates on doublewords. 0N/A // The Intel code has this assertion for NativeCall::set_destination, 0N/A // NativeMovConstReg::set_data, NativeMovRegMem::set_offset, 0N/A // NativeJump::set_jump_destination, and NativePushImm32::set_data 0N/A //assert (Patching_lock->owned_by_self(), "must hold lock to patch instruction") 0N/A // make sure code pattern is actually a call instruction 0N/A// MT-safe patching of a call instruction (and following word). 0N/A// First patches the second word, and then atomicly replaces 0N/A// the first word with the first new instruction word. 0N/A// Other processors might briefly see the old first word 0N/A// followed by the new second word. This is OK if the old 0N/A// second word is harmless, and the new second word may be 0N/A// harmlessly executed in the delay slot of the call. 0N/A "must not interfere with original call");
0N/A // The set_long_at calls do the ICacheInvalidate so we just need to do them in reverse order 0N/A // NOTE: It is possible that another thread T will execute 0N/A // only the second patched word. 0N/A // In other words, since the original instruction is this 0N/A // call patching_stub; nop (NativeCall) 0N/A // and the new sequence from the buffer is this: 0N/A // sethi %hi(K), %r; add %r, %lo(K), %r (NativeMovConstReg) 0N/A // what T will execute is this: 0N/A // call patching_stub; add %r, %lo(K), %r 0N/A // thereby putting garbage into %r before calling the patching stub. 0N/A // This is OK, because the patching stub ignores the value of %r. 0N/A // Make sure the first-patched instruction, which may co-exist 0N/A // briefly with the call, will do something harmless. 0N/A "must not interfere with original call");
0N/A// Similar to replace_mt_safe, but just changes the destination. The 0N/A// important thing is that free-running threads are able to execute this 0N/A// call instruction at all times. Thus, the displacement field must be 0N/A// instruction-word-aligned. This is always true on SPARC. 0N/A// Used in the runtime linkage of calls; see class CompiledIC. 0N/A // set_destination uses set_long_at which does the ICache::invalidate 0N/A// Code for unit testing implementation of NativeCall class 0N/A// End code for unit testing implementation of NativeCall class 0N/A//------------------------------------------------------------------- 0N/A // Address materialized in the instruction stream, so nothing to do. 0N/A#
if 0
// What we'd do if we really did want to change the destination 0N/A // Generate the new sequence 0N/A // make sure code pattern is actually a jumpl_to instruction 0N/A// MT-safe patching of a far call. 0N/A// Code for unit testing implementation of NativeFarCall class 0N/A// End code for unit testing implementation of NativeFarCall class 0N/A//------------------------------------------------------------------- 0N/A // make sure code pattern is actually a "set_oop" synthetic instruction 0N/A // see MacroAssembler::set_oop() 0N/A // verify the pattern "sethi %hi22(imm), reg ; add reg, %lo10(imm), reg" 0N/A // also store the value into an oop_Relocation cell, if any 0N/A// Code for unit testing implementation of NativeMovConstReg class 0N/A// End code for unit testing implementation of NativeMovConstReg class 0N/A//------------------------------------------------------------------- 0N/A // Verify the pattern "sethi %hi22(imm), reg; nop; add reg, %lo10(imm), reg" 0N/A // The casual reader should note that on Sparc a nop is a special case if sethi 0N/A // in which the destination register is %g0. 0N/A // also store the value into an oop_Relocation cell, if any 0N/A// Code for unit testing implementation of NativeMovConstRegPatching class 0N/A// End code for unit testing implementation of NativeMovConstRegPatching class 0N/A//------------------------------------------------------------------- 0N/A // make sure code pattern is actually a "ld" or "st" of some sort. 0N/A// Code for unit testing implementation of NativeMovRegMem class 0N/A// End code for unit testing implementation of NativeMovRegMem class 0N/A//-------------------------------------------------------------------------------- 0N/A // make sure code pattern is actually a "ld" or "st" of some sort. 0N/A// Code for unit testing implementation of NativeMovRegMemPatching class 0N/A// End code for unit testing implementation of NativeMovRegMemPatching class 0N/A//-------------------------------------------------------------------------------- 0N/A // verify the pattern "sethi %hi22(imm), treg ; jmpl treg, %lo10(imm), lreg" 0N/A // In LP64, the jump instruction location varies for non relocatable 0N/A // jumps, for example is could be sethi, xor, jmp instead of the 0N/A // 7 instructions for sethi. So let's check sethi only. 0N/A// Code for unit testing implementation of NativeJump class 0N/A// End code for unit testing implementation of NativeJump class 0N/A// MT safe inserting of a jump over an unknown instruction sequence (used by nmethod::makeZombie) 0N/A// The problem: jump_to <dest> is a 3-word instruction (including its delay slot). 0N/A// Atomic write can be only with 1 word. 0N/A // Here's one way to do it: Pre-allocate a three-word jump sequence somewhere 0N/A // in the header of the nmethod, within a short branch's span of the patch point. 0N/A // Set up the jump sequence using NativeJump::insert, and then use an annulled 0N/A // unconditional branch at the target site (an atomic 1-word update). 0N/A // Limitations: You can only patch nmethods, with any given nmethod patched at 0N/A // most once, and the patch must be in the nmethod's header. 0N/A // It's messy, but you can ask the CodeCache for the nmethod containing the 0N/A // %%%%% For now, do something MT-stupid: 0N/A a->
ldsw(
G0, 0,
O7);
// "ld" must agree with code in the signal handler 0N/A a->
lduw(
G0, 0,
O7);
// "ld" must agree with code in the signal handler 0N/A// MT-safe patching of a jmp instruction (and following word). 0N/A// First patches the second word, and then atomicly replaces 0N/A// the first word with the first new instruction word. 0N/A// Other processors might briefly see the old first word 0N/A// followed by the new second word. This is OK if the old 0N/A// second word is harmless, and the new second word may be 0N/A// harmlessly executed in the delay slot of the call. 0N/A "must not interfere with original call");
0N/A // The set_long_at calls do the ICacheInvalidate so we just need to do them in reverse order 0N/A // NOTE: It is possible that another thread T will execute 0N/A // only the second patched word. 0N/A // In other words, since the original instruction is this 0N/A // jmp patching_stub; nop (NativeGeneralJump) 0N/A // and the new sequence from the buffer is this: 0N/A // sethi %hi(K), %r; add %r, %lo(K), %r (NativeMovConstReg) 0N/A // what T will execute is this: 0N/A // jmp patching_stub; add %r, %lo(K), %r 0N/A // thereby putting garbage into %r before calling the patching stub. 0N/A // This is OK, because the patching stub ignores the value of %r. 0N/A // Make sure the first-patched instruction, which may co-exist 0N/A // briefly with the call, will do something harmless. 0N/A "must not interfere with original call");