1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/cpu/x86/vm/nativeInst_x86.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,608 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "asm/macroAssembler.hpp" 1.30 +#include "memory/resourceArea.hpp" 1.31 +#include "nativeInst_x86.hpp" 1.32 +#include "oops/oop.inline.hpp" 1.33 +#include "runtime/handles.hpp" 1.34 +#include "runtime/sharedRuntime.hpp" 1.35 +#include "runtime/stubRoutines.hpp" 1.36 +#include "utilities/ostream.hpp" 1.37 +#ifdef COMPILER1 1.38 +#include "c1/c1_Runtime1.hpp" 1.39 +#endif 1.40 + 1.41 +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC 1.42 + 1.43 +void NativeInstruction::wrote(int offset) { 1.44 + ICache::invalidate_word(addr_at(offset)); 1.45 +} 1.46 + 1.47 + 1.48 +void NativeCall::verify() { 1.49 + // Make sure code pattern is actually a call imm32 instruction. 1.50 + int inst = ubyte_at(0); 1.51 + if (inst != instruction_code) { 1.52 + tty->print_cr("Addr: " INTPTR_FORMAT " Code: 0x%x", instruction_address(), 1.53 + inst); 1.54 + fatal("not a call disp32"); 1.55 + } 1.56 +} 1.57 + 1.58 +address NativeCall::destination() const { 1.59 + // Getting the destination of a call isn't safe because that call can 1.60 + // be getting patched while you're calling this. There's only special 1.61 + // places where this can be called but not automatically verifiable by 1.62 + // checking which locks are held. The solution is true atomic patching 1.63 + // on x86, nyi. 1.64 + return return_address() + displacement(); 1.65 +} 1.66 + 1.67 +void NativeCall::print() { 1.68 + tty->print_cr(PTR_FORMAT ": call " PTR_FORMAT, 1.69 + instruction_address(), destination()); 1.70 +} 1.71 + 1.72 +// Inserts a native call instruction at a given pc 1.73 +void NativeCall::insert(address code_pos, address entry) { 1.74 + intptr_t disp = (intptr_t)entry - ((intptr_t)code_pos + 1 + 4); 1.75 +#ifdef AMD64 1.76 + guarantee(disp == (intptr_t)(jint)disp, "must be 32-bit offset"); 1.77 +#endif // AMD64 1.78 + *code_pos = instruction_code; 1.79 + *((int32_t *)(code_pos+1)) = (int32_t) disp; 1.80 + ICache::invalidate_range(code_pos, instruction_size); 1.81 +} 1.82 + 1.83 +// MT-safe patching of a call instruction. 1.84 +// First patches first word of instruction to two jmp's that jmps to them 1.85 +// selfs (spinlock). Then patches the last byte, and then atomicly replaces 1.86 +// the jmp's with the first 4 byte of the new instruction. 1.87 +void NativeCall::replace_mt_safe(address instr_addr, address code_buffer) { 1.88 + assert(Patching_lock->is_locked() || 1.89 + SafepointSynchronize::is_at_safepoint(), "concurrent code patching"); 1.90 + assert (instr_addr != NULL, "illegal address for code patching"); 1.91 + 1.92 + NativeCall* n_call = nativeCall_at (instr_addr); // checking that it is a call 1.93 + if (os::is_MP()) { 1.94 + guarantee((intptr_t)instr_addr % BytesPerWord == 0, "must be aligned"); 1.95 + } 1.96 + 1.97 + // First patch dummy jmp in place 1.98 + unsigned char patch[4]; 1.99 + assert(sizeof(patch)==sizeof(jint), "sanity check"); 1.100 + patch[0] = 0xEB; // jmp rel8 1.101 + patch[1] = 0xFE; // jmp to self 1.102 + patch[2] = 0xEB; 1.103 + patch[3] = 0xFE; 1.104 + 1.105 + // First patch dummy jmp in place 1.106 + *(jint*)instr_addr = *(jint *)patch; 1.107 + 1.108 + // Invalidate. Opteron requires a flush after every write. 1.109 + n_call->wrote(0); 1.110 + 1.111 + // Patch 4th byte 1.112 + instr_addr[4] = code_buffer[4]; 1.113 + 1.114 + n_call->wrote(4); 1.115 + 1.116 + // Patch bytes 0-3 1.117 + *(jint*)instr_addr = *(jint *)code_buffer; 1.118 + 1.119 + n_call->wrote(0); 1.120 + 1.121 +#ifdef ASSERT 1.122 + // verify patching 1.123 + for ( int i = 0; i < instruction_size; i++) { 1.124 + address ptr = (address)((intptr_t)code_buffer + i); 1.125 + int a_byte = (*ptr) & 0xFF; 1.126 + assert(*((address)((intptr_t)instr_addr + i)) == a_byte, "mt safe patching failed"); 1.127 + } 1.128 +#endif 1.129 + 1.130 +} 1.131 + 1.132 + 1.133 +// Similar to replace_mt_safe, but just changes the destination. The 1.134 +// important thing is that free-running threads are able to execute this 1.135 +// call instruction at all times. If the displacement field is aligned 1.136 +// we can simply rely on atomicity of 32-bit writes to make sure other threads 1.137 +// will see no intermediate states. Otherwise, the first two bytes of the 1.138 +// call are guaranteed to be aligned, and can be atomically patched to a 1.139 +// self-loop to guard the instruction while we change the other bytes. 1.140 + 1.141 +// We cannot rely on locks here, since the free-running threads must run at 1.142 +// full speed. 1.143 +// 1.144 +// Used in the runtime linkage of calls; see class CompiledIC. 1.145 +// (Cf. 4506997 and 4479829, where threads witnessed garbage displacements.) 1.146 +void NativeCall::set_destination_mt_safe(address dest) { 1.147 + debug_only(verify()); 1.148 + // Make sure patching code is locked. No two threads can patch at the same 1.149 + // time but one may be executing this code. 1.150 + assert(Patching_lock->is_locked() || 1.151 + SafepointSynchronize::is_at_safepoint(), "concurrent code patching"); 1.152 + // Both C1 and C2 should now be generating code which aligns the patched address 1.153 + // to be within a single cache line except that C1 does not do the alignment on 1.154 + // uniprocessor systems. 1.155 + bool is_aligned = ((uintptr_t)displacement_address() + 0) / cache_line_size == 1.156 + ((uintptr_t)displacement_address() + 3) / cache_line_size; 1.157 + 1.158 + guarantee(!os::is_MP() || is_aligned, "destination must be aligned"); 1.159 + 1.160 + if (is_aligned) { 1.161 + // Simple case: The destination lies within a single cache line. 1.162 + set_destination(dest); 1.163 + } else if ((uintptr_t)instruction_address() / cache_line_size == 1.164 + ((uintptr_t)instruction_address()+1) / cache_line_size) { 1.165 + // Tricky case: The instruction prefix lies within a single cache line. 1.166 + intptr_t disp = dest - return_address(); 1.167 +#ifdef AMD64 1.168 + guarantee(disp == (intptr_t)(jint)disp, "must be 32-bit offset"); 1.169 +#endif // AMD64 1.170 + 1.171 + int call_opcode = instruction_address()[0]; 1.172 + 1.173 + // First patch dummy jump in place: 1.174 + { 1.175 + u_char patch_jump[2]; 1.176 + patch_jump[0] = 0xEB; // jmp rel8 1.177 + patch_jump[1] = 0xFE; // jmp to self 1.178 + 1.179 + assert(sizeof(patch_jump)==sizeof(short), "sanity check"); 1.180 + *(short*)instruction_address() = *(short*)patch_jump; 1.181 + } 1.182 + // Invalidate. Opteron requires a flush after every write. 1.183 + wrote(0); 1.184 + 1.185 + // (Note: We assume any reader which has already started to read 1.186 + // the unpatched call will completely read the whole unpatched call 1.187 + // without seeing the next writes we are about to make.) 1.188 + 1.189 + // Next, patch the last three bytes: 1.190 + u_char patch_disp[5]; 1.191 + patch_disp[0] = call_opcode; 1.192 + *(int32_t*)&patch_disp[1] = (int32_t)disp; 1.193 + assert(sizeof(patch_disp)==instruction_size, "sanity check"); 1.194 + for (int i = sizeof(short); i < instruction_size; i++) 1.195 + instruction_address()[i] = patch_disp[i]; 1.196 + 1.197 + // Invalidate. Opteron requires a flush after every write. 1.198 + wrote(sizeof(short)); 1.199 + 1.200 + // (Note: We assume that any reader which reads the opcode we are 1.201 + // about to repatch will also read the writes we just made.) 1.202 + 1.203 + // Finally, overwrite the jump: 1.204 + *(short*)instruction_address() = *(short*)patch_disp; 1.205 + // Invalidate. Opteron requires a flush after every write. 1.206 + wrote(0); 1.207 + 1.208 + debug_only(verify()); 1.209 + guarantee(destination() == dest, "patch succeeded"); 1.210 + } else { 1.211 + // Impossible: One or the other must be atomically writable. 1.212 + ShouldNotReachHere(); 1.213 + } 1.214 +} 1.215 + 1.216 + 1.217 +void NativeMovConstReg::verify() { 1.218 +#ifdef AMD64 1.219 + // make sure code pattern is actually a mov reg64, imm64 instruction 1.220 + if ((ubyte_at(0) != Assembler::REX_W && ubyte_at(0) != Assembler::REX_WB) || 1.221 + (ubyte_at(1) & (0xff ^ register_mask)) != 0xB8) { 1.222 + print(); 1.223 + fatal("not a REX.W[B] mov reg64, imm64"); 1.224 + } 1.225 +#else 1.226 + // make sure code pattern is actually a mov reg, imm32 instruction 1.227 + u_char test_byte = *(u_char*)instruction_address(); 1.228 + u_char test_byte_2 = test_byte & ( 0xff ^ register_mask); 1.229 + if (test_byte_2 != instruction_code) fatal("not a mov reg, imm32"); 1.230 +#endif // AMD64 1.231 +} 1.232 + 1.233 + 1.234 +void NativeMovConstReg::print() { 1.235 + tty->print_cr(PTR_FORMAT ": mov reg, " INTPTR_FORMAT, 1.236 + instruction_address(), data()); 1.237 +} 1.238 + 1.239 +//------------------------------------------------------------------- 1.240 + 1.241 +int NativeMovRegMem::instruction_start() const { 1.242 + int off = 0; 1.243 + u_char instr_0 = ubyte_at(off); 1.244 + 1.245 + // See comment in Assembler::locate_operand() about VEX prefixes. 1.246 + if (instr_0 == instruction_VEX_prefix_2bytes) { 1.247 + assert((UseAVX > 0), "shouldn't have VEX prefix"); 1.248 + NOT_LP64(assert((0xC0 & ubyte_at(1)) == 0xC0, "shouldn't have LDS and LES instructions")); 1.249 + return 2; 1.250 + } 1.251 + if (instr_0 == instruction_VEX_prefix_3bytes) { 1.252 + assert((UseAVX > 0), "shouldn't have VEX prefix"); 1.253 + NOT_LP64(assert((0xC0 & ubyte_at(1)) == 0xC0, "shouldn't have LDS and LES instructions")); 1.254 + return 3; 1.255 + } 1.256 + 1.257 + // First check to see if we have a (prefixed or not) xor 1.258 + if (instr_0 >= instruction_prefix_wide_lo && // 0x40 1.259 + instr_0 <= instruction_prefix_wide_hi) { // 0x4f 1.260 + off++; 1.261 + instr_0 = ubyte_at(off); 1.262 + } 1.263 + 1.264 + if (instr_0 == instruction_code_xor) { 1.265 + off += 2; 1.266 + instr_0 = ubyte_at(off); 1.267 + } 1.268 + 1.269 + // Now look for the real instruction and the many prefix/size specifiers. 1.270 + 1.271 + if (instr_0 == instruction_operandsize_prefix ) { // 0x66 1.272 + off++; // Not SSE instructions 1.273 + instr_0 = ubyte_at(off); 1.274 + } 1.275 + 1.276 + if ( instr_0 == instruction_code_xmm_ss_prefix || // 0xf3 1.277 + instr_0 == instruction_code_xmm_sd_prefix) { // 0xf2 1.278 + off++; 1.279 + instr_0 = ubyte_at(off); 1.280 + } 1.281 + 1.282 + if ( instr_0 >= instruction_prefix_wide_lo && // 0x40 1.283 + instr_0 <= instruction_prefix_wide_hi) { // 0x4f 1.284 + off++; 1.285 + instr_0 = ubyte_at(off); 1.286 + } 1.287 + 1.288 + 1.289 + if (instr_0 == instruction_extended_prefix ) { // 0x0f 1.290 + off++; 1.291 + } 1.292 + 1.293 + return off; 1.294 +} 1.295 + 1.296 +address NativeMovRegMem::instruction_address() const { 1.297 + return addr_at(instruction_start()); 1.298 +} 1.299 + 1.300 +address NativeMovRegMem::next_instruction_address() const { 1.301 + address ret = instruction_address() + instruction_size; 1.302 + u_char instr_0 = *(u_char*) instruction_address(); 1.303 + switch (instr_0) { 1.304 + case instruction_operandsize_prefix: 1.305 + 1.306 + fatal("should have skipped instruction_operandsize_prefix"); 1.307 + break; 1.308 + 1.309 + case instruction_extended_prefix: 1.310 + fatal("should have skipped instruction_extended_prefix"); 1.311 + break; 1.312 + 1.313 + case instruction_code_mem2reg_movslq: // 0x63 1.314 + case instruction_code_mem2reg_movzxb: // 0xB6 1.315 + case instruction_code_mem2reg_movsxb: // 0xBE 1.316 + case instruction_code_mem2reg_movzxw: // 0xB7 1.317 + case instruction_code_mem2reg_movsxw: // 0xBF 1.318 + case instruction_code_reg2mem: // 0x89 (q/l) 1.319 + case instruction_code_mem2reg: // 0x8B (q/l) 1.320 + case instruction_code_reg2memb: // 0x88 1.321 + case instruction_code_mem2regb: // 0x8a 1.322 + 1.323 + case instruction_code_float_s: // 0xd9 fld_s a 1.324 + case instruction_code_float_d: // 0xdd fld_d a 1.325 + 1.326 + case instruction_code_xmm_load: // 0x10 1.327 + case instruction_code_xmm_store: // 0x11 1.328 + case instruction_code_xmm_lpd: // 0x12 1.329 + { 1.330 + // If there is an SIB then instruction is longer than expected 1.331 + u_char mod_rm = *(u_char*)(instruction_address() + 1); 1.332 + if ((mod_rm & 7) == 0x4) { 1.333 + ret++; 1.334 + } 1.335 + } 1.336 + case instruction_code_xor: 1.337 + fatal("should have skipped xor lead in"); 1.338 + break; 1.339 + 1.340 + default: 1.341 + fatal("not a NativeMovRegMem"); 1.342 + } 1.343 + return ret; 1.344 + 1.345 +} 1.346 + 1.347 +int NativeMovRegMem::offset() const{ 1.348 + int off = data_offset + instruction_start(); 1.349 + u_char mod_rm = *(u_char*)(instruction_address() + 1); 1.350 + // nnnn(r12|rsp) isn't coded as simple mod/rm since that is 1.351 + // the encoding to use an SIB byte. Which will have the nnnn 1.352 + // field off by one byte 1.353 + if ((mod_rm & 7) == 0x4) { 1.354 + off++; 1.355 + } 1.356 + return int_at(off); 1.357 +} 1.358 + 1.359 +void NativeMovRegMem::set_offset(int x) { 1.360 + int off = data_offset + instruction_start(); 1.361 + u_char mod_rm = *(u_char*)(instruction_address() + 1); 1.362 + // nnnn(r12|rsp) isn't coded as simple mod/rm since that is 1.363 + // the encoding to use an SIB byte. Which will have the nnnn 1.364 + // field off by one byte 1.365 + if ((mod_rm & 7) == 0x4) { 1.366 + off++; 1.367 + } 1.368 + set_int_at(off, x); 1.369 +} 1.370 + 1.371 +void NativeMovRegMem::verify() { 1.372 + // make sure code pattern is actually a mov [reg+offset], reg instruction 1.373 + u_char test_byte = *(u_char*)instruction_address(); 1.374 + switch (test_byte) { 1.375 + case instruction_code_reg2memb: // 0x88 movb a, r 1.376 + case instruction_code_reg2mem: // 0x89 movl a, r (can be movq in 64bit) 1.377 + case instruction_code_mem2regb: // 0x8a movb r, a 1.378 + case instruction_code_mem2reg: // 0x8b movl r, a (can be movq in 64bit) 1.379 + break; 1.380 + 1.381 + case instruction_code_mem2reg_movslq: // 0x63 movsql r, a 1.382 + case instruction_code_mem2reg_movzxb: // 0xb6 movzbl r, a (movzxb) 1.383 + case instruction_code_mem2reg_movzxw: // 0xb7 movzwl r, a (movzxw) 1.384 + case instruction_code_mem2reg_movsxb: // 0xbe movsbl r, a (movsxb) 1.385 + case instruction_code_mem2reg_movsxw: // 0xbf movswl r, a (movsxw) 1.386 + break; 1.387 + 1.388 + case instruction_code_float_s: // 0xd9 fld_s a 1.389 + case instruction_code_float_d: // 0xdd fld_d a 1.390 + case instruction_code_xmm_load: // 0x10 movsd xmm, a 1.391 + case instruction_code_xmm_store: // 0x11 movsd a, xmm 1.392 + case instruction_code_xmm_lpd: // 0x12 movlpd xmm, a 1.393 + break; 1.394 + 1.395 + default: 1.396 + fatal ("not a mov [reg+offs], reg instruction"); 1.397 + } 1.398 +} 1.399 + 1.400 + 1.401 +void NativeMovRegMem::print() { 1.402 + tty->print_cr("0x%x: mov reg, [reg + %x]", instruction_address(), offset()); 1.403 +} 1.404 + 1.405 +//------------------------------------------------------------------- 1.406 + 1.407 +void NativeLoadAddress::verify() { 1.408 + // make sure code pattern is actually a mov [reg+offset], reg instruction 1.409 + u_char test_byte = *(u_char*)instruction_address(); 1.410 +#ifdef _LP64 1.411 + if ( (test_byte == instruction_prefix_wide || 1.412 + test_byte == instruction_prefix_wide_extended) ) { 1.413 + test_byte = *(u_char*)(instruction_address() + 1); 1.414 + } 1.415 +#endif // _LP64 1.416 + if ( ! ((test_byte == lea_instruction_code) 1.417 + LP64_ONLY(|| (test_byte == mov64_instruction_code) ))) { 1.418 + fatal ("not a lea reg, [reg+offs] instruction"); 1.419 + } 1.420 +} 1.421 + 1.422 + 1.423 +void NativeLoadAddress::print() { 1.424 + tty->print_cr("0x%x: lea [reg + %x], reg", instruction_address(), offset()); 1.425 +} 1.426 + 1.427 +//-------------------------------------------------------------------------------- 1.428 + 1.429 +void NativeJump::verify() { 1.430 + if (*(u_char*)instruction_address() != instruction_code) { 1.431 + fatal("not a jump instruction"); 1.432 + } 1.433 +} 1.434 + 1.435 + 1.436 +void NativeJump::insert(address code_pos, address entry) { 1.437 + intptr_t disp = (intptr_t)entry - ((intptr_t)code_pos + 1 + 4); 1.438 +#ifdef AMD64 1.439 + guarantee(disp == (intptr_t)(int32_t)disp, "must be 32-bit offset"); 1.440 +#endif // AMD64 1.441 + 1.442 + *code_pos = instruction_code; 1.443 + *((int32_t*)(code_pos + 1)) = (int32_t)disp; 1.444 + 1.445 + ICache::invalidate_range(code_pos, instruction_size); 1.446 +} 1.447 + 1.448 +void NativeJump::check_verified_entry_alignment(address entry, address verified_entry) { 1.449 + // Patching to not_entrant can happen while activations of the method are 1.450 + // in use. The patching in that instance must happen only when certain 1.451 + // alignment restrictions are true. These guarantees check those 1.452 + // conditions. 1.453 +#ifdef AMD64 1.454 + const int linesize = 64; 1.455 +#else 1.456 + const int linesize = 32; 1.457 +#endif // AMD64 1.458 + 1.459 + // Must be wordSize aligned 1.460 + guarantee(((uintptr_t) verified_entry & (wordSize -1)) == 0, 1.461 + "illegal address for code patching 2"); 1.462 + // First 5 bytes must be within the same cache line - 4827828 1.463 + guarantee((uintptr_t) verified_entry / linesize == 1.464 + ((uintptr_t) verified_entry + 4) / linesize, 1.465 + "illegal address for code patching 3"); 1.466 +} 1.467 + 1.468 + 1.469 +// MT safe inserting of a jump over an unknown instruction sequence (used by nmethod::makeZombie) 1.470 +// The problem: jmp <dest> is a 5-byte instruction. Atomical write can be only with 4 bytes. 1.471 +// First patches the first word atomically to be a jump to itself. 1.472 +// Then patches the last byte and then atomically patches the first word (4-bytes), 1.473 +// thus inserting the desired jump 1.474 +// This code is mt-safe with the following conditions: entry point is 4 byte aligned, 1.475 +// entry point is in same cache line as unverified entry point, and the instruction being 1.476 +// patched is >= 5 byte (size of patch). 1.477 +// 1.478 +// In C2 the 5+ byte sized instruction is enforced by code in MachPrologNode::emit. 1.479 +// In C1 the restriction is enforced by CodeEmitter::method_entry 1.480 +// 1.481 +void NativeJump::patch_verified_entry(address entry, address verified_entry, address dest) { 1.482 + // complete jump instruction (to be inserted) is in code_buffer; 1.483 + unsigned char code_buffer[5]; 1.484 + code_buffer[0] = instruction_code; 1.485 + intptr_t disp = (intptr_t)dest - ((intptr_t)verified_entry + 1 + 4); 1.486 +#ifdef AMD64 1.487 + guarantee(disp == (intptr_t)(int32_t)disp, "must be 32-bit offset"); 1.488 +#endif // AMD64 1.489 + *(int32_t*)(code_buffer + 1) = (int32_t)disp; 1.490 + 1.491 + check_verified_entry_alignment(entry, verified_entry); 1.492 + 1.493 + // Can't call nativeJump_at() because it's asserts jump exists 1.494 + NativeJump* n_jump = (NativeJump*) verified_entry; 1.495 + 1.496 + //First patch dummy jmp in place 1.497 + 1.498 + unsigned char patch[4]; 1.499 + assert(sizeof(patch)==sizeof(int32_t), "sanity check"); 1.500 + patch[0] = 0xEB; // jmp rel8 1.501 + patch[1] = 0xFE; // jmp to self 1.502 + patch[2] = 0xEB; 1.503 + patch[3] = 0xFE; 1.504 + 1.505 + // First patch dummy jmp in place 1.506 + *(int32_t*)verified_entry = *(int32_t *)patch; 1.507 + 1.508 + n_jump->wrote(0); 1.509 + 1.510 + // Patch 5th byte (from jump instruction) 1.511 + verified_entry[4] = code_buffer[4]; 1.512 + 1.513 + n_jump->wrote(4); 1.514 + 1.515 + // Patch bytes 0-3 (from jump instruction) 1.516 + *(int32_t*)verified_entry = *(int32_t *)code_buffer; 1.517 + // Invalidate. Opteron requires a flush after every write. 1.518 + n_jump->wrote(0); 1.519 + 1.520 +} 1.521 + 1.522 +void NativePopReg::insert(address code_pos, Register reg) { 1.523 + assert(reg->encoding() < 8, "no space for REX"); 1.524 + assert(NativePopReg::instruction_size == sizeof(char), "right address unit for update"); 1.525 + *code_pos = (u_char)(instruction_code | reg->encoding()); 1.526 + ICache::invalidate_range(code_pos, instruction_size); 1.527 +} 1.528 + 1.529 + 1.530 +void NativeIllegalInstruction::insert(address code_pos) { 1.531 + assert(NativeIllegalInstruction::instruction_size == sizeof(short), "right address unit for update"); 1.532 + *(short *)code_pos = instruction_code; 1.533 + ICache::invalidate_range(code_pos, instruction_size); 1.534 +} 1.535 + 1.536 +void NativeGeneralJump::verify() { 1.537 + assert(((NativeInstruction *)this)->is_jump() || 1.538 + ((NativeInstruction *)this)->is_cond_jump(), "not a general jump instruction"); 1.539 +} 1.540 + 1.541 + 1.542 +void NativeGeneralJump::insert_unconditional(address code_pos, address entry) { 1.543 + intptr_t disp = (intptr_t)entry - ((intptr_t)code_pos + 1 + 4); 1.544 +#ifdef AMD64 1.545 + guarantee(disp == (intptr_t)(int32_t)disp, "must be 32-bit offset"); 1.546 +#endif // AMD64 1.547 + 1.548 + *code_pos = unconditional_long_jump; 1.549 + *((int32_t *)(code_pos+1)) = (int32_t) disp; 1.550 + ICache::invalidate_range(code_pos, instruction_size); 1.551 +} 1.552 + 1.553 + 1.554 +// MT-safe patching of a long jump instruction. 1.555 +// First patches first word of instruction to two jmp's that jmps to them 1.556 +// selfs (spinlock). Then patches the last byte, and then atomicly replaces 1.557 +// the jmp's with the first 4 byte of the new instruction. 1.558 +void NativeGeneralJump::replace_mt_safe(address instr_addr, address code_buffer) { 1.559 + assert (instr_addr != NULL, "illegal address for code patching (4)"); 1.560 + NativeGeneralJump* n_jump = nativeGeneralJump_at (instr_addr); // checking that it is a jump 1.561 + 1.562 + // Temporary code 1.563 + unsigned char patch[4]; 1.564 + assert(sizeof(patch)==sizeof(int32_t), "sanity check"); 1.565 + patch[0] = 0xEB; // jmp rel8 1.566 + patch[1] = 0xFE; // jmp to self 1.567 + patch[2] = 0xEB; 1.568 + patch[3] = 0xFE; 1.569 + 1.570 + // First patch dummy jmp in place 1.571 + *(int32_t*)instr_addr = *(int32_t *)patch; 1.572 + n_jump->wrote(0); 1.573 + 1.574 + // Patch 4th byte 1.575 + instr_addr[4] = code_buffer[4]; 1.576 + 1.577 + n_jump->wrote(4); 1.578 + 1.579 + // Patch bytes 0-3 1.580 + *(jint*)instr_addr = *(jint *)code_buffer; 1.581 + 1.582 + n_jump->wrote(0); 1.583 + 1.584 +#ifdef ASSERT 1.585 + // verify patching 1.586 + for ( int i = 0; i < instruction_size; i++) { 1.587 + address ptr = (address)((intptr_t)code_buffer + i); 1.588 + int a_byte = (*ptr) & 0xFF; 1.589 + assert(*((address)((intptr_t)instr_addr + i)) == a_byte, "mt safe patching failed"); 1.590 + } 1.591 +#endif 1.592 + 1.593 +} 1.594 + 1.595 + 1.596 + 1.597 +address NativeGeneralJump::jump_destination() const { 1.598 + int op_code = ubyte_at(0); 1.599 + bool is_rel32off = (op_code == 0xE9 || op_code == 0x0F); 1.600 + int offset = (op_code == 0x0F) ? 2 : 1; 1.601 + int length = offset + ((is_rel32off) ? 4 : 1); 1.602 + 1.603 + if (is_rel32off) 1.604 + return addr_at(0) + length + int_at(offset); 1.605 + else 1.606 + return addr_at(0) + length + sbyte_at(offset); 1.607 +} 1.608 + 1.609 +bool NativeInstruction::is_dtrace_trap() { 1.610 + return (*(int32_t*)this & 0xff) == 0xcc; 1.611 +}