1 /* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2016 SAP SE. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26 // Major contributions by JL, LS 27 28 #include "precompiled.hpp" 29 #include "asm/macroAssembler.inline.hpp" 30 #include "memory/resourceArea.hpp" 31 #include "nativeInst_s390.hpp" 32 #include "oops/oop.inline.hpp" 33 #include "runtime/handles.hpp" 34 #include "runtime/sharedRuntime.hpp" 35 #include "runtime/stubRoutines.hpp" 36 #include "utilities/ostream.hpp" 37 #ifdef COMPILER1 38 #include "c1/c1_Runtime1.hpp" 39 #endif 40 41 #define LUCY_DBG 42 43 //------------------------------------- 44 // N a t i v e I n s t r u c t i o n 45 //------------------------------------- 46 47 // Define this switch to prevent identity updates. 48 // In high-concurrency scenarios, it is beneficial to prevent 49 // identity updates. It has a positive effect on cache line steals. 50 // and invalidations. 51 // Test runs of JVM98, JVM2008, and JBB2005 show a very low frequency 52 // of identity updates. Detection is therefore disabled. 53 #undef SUPPRESS_IDENTITY_UPDATE 54 55 void NativeInstruction::verify() { 56 // Make sure code pattern is actually an instruction address. 57 // Do not allow: 58 // - NULL 59 // - any address in first page (0x0000 .. 0x0fff) 60 // - odd address (will cause a "specification exception") 61 address addr = addr_at(0); 62 if ((addr == 0) || (((unsigned long)addr & ~0x0fff) == 0) || ((intptr_t)addr & 1) != 0) { 63 tty->print_cr(INTPTR_FORMAT ": bad instruction address", p2i(addr)); 64 fatal("not an instruction address"); 65 } 66 } 67 68 // Print location and value (hex representation) of current NativeInstruction 69 void NativeInstruction::print(const char* msg) const { 70 int len = Assembler::instr_len(addr_at(0)); 71 if (msg == NULL) { // Output line without trailing blanks. 72 switch (len) { 73 case 2: tty->print_cr(INTPTR_FORMAT "(len=%d): %4.4x", p2i(addr_at(0)), len, halfword_at(0)); break; 74 case 4: tty->print_cr(INTPTR_FORMAT "(len=%d): %4.4x %4.4x", p2i(addr_at(0)), len, halfword_at(0), halfword_at(2)); break; 75 case 6: tty->print_cr(INTPTR_FORMAT "(len=%d): %4.4x %4.4x %4.4x", p2i(addr_at(0)), len, halfword_at(0), halfword_at(2), halfword_at(4)); break; 76 default: // Never reached. instr_len() always returns one of the above values. Keep the compiler happy. 77 ShouldNotReachHere(); 78 break; 79 } 80 } else { // Output line with filler blanks to have msg aligned. 81 switch (len) { 82 case 2: tty->print_cr(INTPTR_FORMAT "(len=%d): %4.4x %s", p2i(addr_at(0)), len, halfword_at(0), msg); break; 83 case 4: tty->print_cr(INTPTR_FORMAT "(len=%d): %4.4x %4.4x %s", p2i(addr_at(0)), len, halfword_at(0), halfword_at(2), msg); break; 84 case 6: tty->print_cr(INTPTR_FORMAT "(len=%d): %4.4x %4.4x %4.4x %s", p2i(addr_at(0)), len, halfword_at(0), halfword_at(2), halfword_at(4), msg); break; 85 default: // Never reached. instr_len() always returns one of the above values. Keep the compiler happy. 86 ShouldNotReachHere(); 87 break; 88 } 89 } 90 } 91 void NativeInstruction::print() const { 92 print(NULL); 93 } 94 95 // Hex-Dump of storage around current NativeInstruction. Also try disassembly. 96 void NativeInstruction::dump(const unsigned int range, const char* msg) const { 97 Assembler::dump_code_range(tty, addr_at(0), range, (msg == NULL) ? "":msg); 98 } 99 100 void NativeInstruction::dump(const unsigned int range) const { 101 dump(range, NULL); 102 } 103 104 void NativeInstruction::dump() const { 105 dump(32, NULL); 106 } 107 108 void NativeInstruction::set_halfword_at(int offset, short i) { 109 address addr = addr_at(offset); 110 #ifndef SUPPRESS_IDENTITY_UPDATE 111 *(short*)addr = i; 112 #else 113 if (*(short*)addr != i) { 114 *(short*)addr = i; 115 } 116 #endif 117 ICache::invalidate_word(addr); 118 } 119 120 void NativeInstruction::set_word_at(int offset, int i) { 121 address addr = addr_at(offset); 122 #ifndef SUPPRESS_IDENTITY_UPDATE 123 *(int*)addr = i; 124 #else 125 if (*(int*)addr != i) { 126 *(int*)addr = i; 127 } 128 #endif 129 ICache::invalidate_word(addr); 130 } 131 132 void NativeInstruction::set_jlong_at(int offset, jlong i) { 133 address addr = addr_at(offset); 134 #ifndef SUPPRESS_IDENTITY_UPDATE 135 *(jlong*)addr = i; 136 #else 137 if (*(jlong*)addr != i) { 138 *(jlong*)addr = i; 139 } 140 #endif 141 // Don't need to invalidate 2 words here, because 142 // the flush instruction operates on doublewords. 143 ICache::invalidate_word(addr); 144 } 145 146 #undef SUPPRESS_IDENTITY_UPDATE 147 148 //------------------------------------------------------------ 149 150 int NativeInstruction::illegal_instruction() { 151 return 0; 152 } 153 154 bool NativeInstruction::is_illegal() { 155 // An instruction with main opcode 0x00 (leftmost byte) is not a valid instruction 156 // (and will never be) and causes a SIGILL where the pc points to the next instruction. 157 // The caller of this method wants to know if such a situation exists at the current pc. 158 // 159 // The result of this method is unsharp with respect to the following facts: 160 // - Stepping backwards in the instruction stream is not possible on z/Architecture. 161 // - z/Architecture instructions are 2, 4, or 6 bytes in length. 162 // - The instruction length is coded in the leftmost two bits of the main opcode. 163 // - The result is exact if the caller knows by some other means that the 164 // instruction is of length 2. 165 // 166 // If this method returns false, then the 2-byte instruction at *-2 is not a 0x00 opcode. 167 // If this method returns true, then the 2-byte instruction at *-2 is a 0x00 opcode. 168 return halfword_at(-2) == illegal_instruction(); 169 } 170 171 // We use an illtrap for marking a method as not_entrant or zombie. 172 bool NativeInstruction::is_sigill_zombie_not_entrant() { 173 if (!is_illegal()) return false; // Just a quick path. 174 175 // One-sided error of is_illegal tolerable here 176 // (see implementation of is_illegal() for details). 177 178 CodeBlob* cb = CodeCache::find_blob_unsafe(addr_at(0)); 179 if (cb == NULL || !cb->is_nmethod()) { 180 return false; 181 } 182 183 nmethod *nm = (nmethod *)cb; 184 // This method is not_entrant or zombie if the illtrap instruction 185 // is located at the verified entry point. 186 // BE AWARE: the current pc (this) points to the instruction after the 187 // "illtrap" location. 188 address sig_addr = ((address) this) - 2; 189 return nm->verified_entry_point() == sig_addr; 190 } 191 192 bool NativeInstruction::is_jump() { 193 unsigned long inst; 194 Assembler::get_instruction((address)this, &inst); 195 return MacroAssembler::is_branch_pcrelative_long(inst); 196 } 197 198 //--------------------------------------------------- 199 // N a t i v e I l l e g a l I n s t r u c t i o n 200 //--------------------------------------------------- 201 202 void NativeIllegalInstruction::insert(address code_pos) { 203 NativeIllegalInstruction* nii = (NativeIllegalInstruction*) nativeInstruction_at(code_pos); 204 nii->set_halfword_at(0, illegal_instruction()); 205 } 206 207 //----------------------- 208 // N a t i v e C a l l 209 //----------------------- 210 211 void NativeCall::verify() { 212 if (NativeCall::is_call_at(addr_at(0))) return; 213 214 fatal("this is not a `NativeCall' site"); 215 } 216 217 address NativeCall::destination() const { 218 if (MacroAssembler::is_call_far_pcrelative(instruction_address())) { 219 address here = addr_at(MacroAssembler::nop_size()); 220 return MacroAssembler::get_target_addr_pcrel(here); 221 } 222 223 return (address)((NativeMovConstReg *)this)->data(); 224 } 225 226 // Similar to replace_mt_safe, but just changes the destination. The 227 // important thing is that free-running threads are able to execute this 228 // call instruction at all times. Thus, the displacement field must be 229 // 4-byte-aligned. We enforce this on z/Architecture by inserting a nop 230 // instruction in front of 'brasl' when needed. 231 // 232 // Used in the runtime linkage of calls; see class CompiledIC. 233 void NativeCall::set_destination_mt_safe(address dest) { 234 if (MacroAssembler::is_call_far_pcrelative(instruction_address())) { 235 address iaddr = addr_at(MacroAssembler::nop_size()); 236 // Ensure that patching is atomic hence mt safe. 237 assert(((long)addr_at(MacroAssembler::call_far_pcrelative_size()) & (call_far_pcrelative_displacement_alignment-1)) == 0, 238 "constant must be 4-byte aligned"); 239 set_word_at(MacroAssembler::call_far_pcrelative_size() - 4, Assembler::z_pcrel_off(dest, iaddr)); 240 } else { 241 assert(MacroAssembler::is_load_const_from_toc(instruction_address()), "unsupported instruction"); 242 nativeMovConstReg_at(instruction_address())->set_data(((intptr_t)dest)); 243 } 244 } 245 246 //----------------------------- 247 // N a t i v e F a r C a l l 248 //----------------------------- 249 250 void NativeFarCall::verify() { 251 NativeInstruction::verify(); 252 if (NativeFarCall::is_far_call_at(addr_at(0))) return; 253 fatal("not a NativeFarCall"); 254 } 255 256 address NativeFarCall::destination() { 257 assert(MacroAssembler::is_call_far_patchable_at((address)this), "unexpected call type"); 258 address ctable = NULL; 259 return MacroAssembler::get_dest_of_call_far_patchable_at((address)this, ctable); 260 } 261 262 263 // Handles both patterns of patchable far calls. 264 void NativeFarCall::set_destination(address dest, int toc_offset) { 265 address inst_addr = (address)this; 266 267 // Set new destination (implementation of call may change here). 268 assert(MacroAssembler::is_call_far_patchable_at(inst_addr), "unexpected call type"); 269 270 if (!MacroAssembler::is_call_far_patchable_pcrelative_at(inst_addr)) { 271 address ctable = CodeCache::find_blob(inst_addr)->ctable_begin(); 272 // Need distance of TOC entry from current instruction. 273 toc_offset = (ctable + toc_offset) - inst_addr; 274 // Call is via constant table entry. 275 MacroAssembler::set_dest_of_call_far_patchable_at(inst_addr, dest, toc_offset); 276 } else { 277 // Here, we have a pc-relative call (brasl). 278 // Be aware: dest may have moved in this case, so really patch the displacement, 279 // when necessary! 280 // This while loop will also consume the nop which always preceeds a call_far_pcrelative. 281 // We need to revert this after the loop. Pc-relative calls are always assumed to have a leading nop. 282 unsigned int nop_sz = MacroAssembler::nop_size(); 283 unsigned int nop_bytes = 0; 284 while(MacroAssembler::is_z_nop(inst_addr+nop_bytes)) { 285 nop_bytes += nop_sz; 286 } 287 if (nop_bytes > 0) { 288 inst_addr += nop_bytes - nop_sz; 289 } 290 291 assert(MacroAssembler::is_call_far_pcrelative(inst_addr), "not a pc-relative call"); 292 address target = MacroAssembler::get_target_addr_pcrel(inst_addr + nop_sz); 293 if (target != dest) { 294 NativeCall *call = nativeCall_at(inst_addr); 295 call->set_destination_mt_safe(dest); 296 } 297 } 298 } 299 300 //------------------------------------- 301 // N a t i v e M o v C o n s t R e g 302 //------------------------------------- 303 304 // Do not use an assertion here. Let clients decide whether they only 305 // want this when assertions are enabled. 306 void NativeMovConstReg::verify() { 307 address loc = addr_at(0); 308 309 // This while loop will also consume the nop which always preceeds a 310 // call_far_pcrelative. We need to revert this after the 311 // loop. Pc-relative calls are always assumed to have a leading nop. 312 unsigned int nop_sz = MacroAssembler::nop_size(); 313 unsigned int nop_bytes = 0; 314 while(MacroAssembler::is_z_nop(loc+nop_bytes)) { 315 nop_bytes += nop_sz; 316 } 317 318 if (nop_bytes > 0) { 319 if (MacroAssembler::is_call_far_pcrelative(loc+nop_bytes-nop_sz)) return; 320 loc += nop_bytes; 321 } 322 323 if (!MacroAssembler::is_load_const_from_toc(loc) && // Load const from TOC. 324 !MacroAssembler::is_load_const(loc) && // Load const inline. 325 !MacroAssembler::is_load_narrow_oop(loc) && // Load narrow oop. 326 !MacroAssembler::is_load_narrow_klass(loc) && // Load narrow Klass ptr. 327 !MacroAssembler::is_compare_immediate_narrow_oop(loc) && // Compare immediate narrow. 328 !MacroAssembler::is_compare_immediate_narrow_klass(loc) && // Compare immediate narrow. 329 !MacroAssembler::is_pcrelative_instruction(loc)) { // Just to make it run. 330 tty->cr(); 331 tty->print_cr("NativeMovConstReg::verify(): verifying addr %p(0x%x), %d leading nops", loc, *(uint*)loc, nop_bytes/nop_sz); 332 tty->cr(); 333 ((NativeMovConstReg*)loc)->dump(64, "NativeMovConstReg::verify()"); 334 #ifdef LUCY_DBG 335 VM_Version::z_SIGSEGV(); 336 #endif 337 fatal("this is not a `NativeMovConstReg' site"); 338 } 339 } 340 341 address NativeMovConstReg::next_instruction_address(int offset) const { 342 address inst_addr = addr_at(offset); 343 344 // Load address (which is a constant) pc-relative. 345 if (MacroAssembler::is_load_addr_pcrel(inst_addr)) { return addr_at(offset+MacroAssembler::load_addr_pcrel_size()); } 346 347 // Load constant from TOC. 348 if (MacroAssembler::is_load_const_from_toc(inst_addr)) { return addr_at(offset+MacroAssembler::load_const_from_toc_size()); } 349 350 // Load constant inline. 351 if (MacroAssembler::is_load_const(inst_addr)) { return addr_at(offset+MacroAssembler::load_const_size()); } 352 353 // Load constant narrow inline. 354 if (MacroAssembler::is_load_narrow_oop(inst_addr)) { return addr_at(offset+MacroAssembler::load_narrow_oop_size()); } 355 if (MacroAssembler::is_load_narrow_klass(inst_addr)) { return addr_at(offset+MacroAssembler::load_narrow_klass_size()); } 356 357 // Compare constant narrow inline. 358 if (MacroAssembler::is_compare_immediate_narrow_oop(inst_addr)) { return addr_at(offset+MacroAssembler::compare_immediate_narrow_oop_size()); } 359 if (MacroAssembler::is_compare_immediate_narrow_klass(inst_addr)) { return addr_at(offset+MacroAssembler::compare_immediate_narrow_klass_size()); } 360 361 if (MacroAssembler::is_call_far_patchable_pcrelative_at(inst_addr)) { return addr_at(offset+MacroAssembler::call_far_patchable_size()); } 362 363 if (MacroAssembler::is_pcrelative_instruction(inst_addr)) { return addr_at(offset+Assembler::instr_len(inst_addr)); } 364 365 ((NativeMovConstReg*)inst_addr)->dump(64, "NativeMovConstReg site is not recognized as such"); 366 #ifdef LUCY_DBG 367 VM_Version::z_SIGSEGV(); 368 #else 369 guarantee(false, "Not a NativeMovConstReg site"); 370 #endif 371 return NULL; 372 } 373 374 intptr_t NativeMovConstReg::data() const { 375 address loc = addr_at(0); 376 if (MacroAssembler::is_load_const(loc)) { 377 return MacroAssembler::get_const(loc); 378 } else if (MacroAssembler::is_load_narrow_oop(loc) || 379 MacroAssembler::is_compare_immediate_narrow_oop(loc) || 380 MacroAssembler::is_load_narrow_klass(loc) || 381 MacroAssembler::is_compare_immediate_narrow_klass(loc)) { 382 ((NativeMovConstReg*)loc)->dump(32, "NativeMovConstReg::data(): cannot extract data from narrow ptr (oop or klass)"); 383 #ifdef LUCY_DBG 384 VM_Version::z_SIGSEGV(); 385 #else 386 ShouldNotReachHere(); 387 #endif 388 return *(intptr_t *)NULL; 389 } else { 390 // Otherwise, assume data resides in TOC. Is asserted in called method. 391 return MacroAssembler::get_const_from_toc(loc); 392 } 393 } 394 395 396 // Patch in a new constant. 397 // 398 // There are situations where we have multiple (hopefully two at most) 399 // relocations connected to one instruction. Loading an oop from CP 400 // using pcrelative addressing would one such example. Here we have an 401 // oop relocation, modifying the oop itself, and an internal word relocation, 402 // modifying the relative address. 403 // 404 // NativeMovConstReg::set_data is then called once for each relocation. To be 405 // able to distinguish between the relocations, we use a rather dirty hack: 406 // 407 // All calls that deal with an internal word relocation to fix their relative 408 // address are on a faked, odd instruction address. The instruction can be 409 // found on the next lower, even address. 410 // 411 // All other calls are "normal", i.e. on even addresses. 412 address NativeMovConstReg::set_data_plain(intptr_t src, CodeBlob *cb) { 413 unsigned long x = (unsigned long)src; 414 address loc = instruction_address(); 415 address next_address; 416 417 if (MacroAssembler::is_load_addr_pcrel(loc)) { 418 MacroAssembler::patch_target_addr_pcrel(loc, (address)src); 419 ICache::invalidate_range(loc, MacroAssembler::load_addr_pcrel_size()); 420 next_address = next_instruction_address(); 421 } else if (MacroAssembler::is_load_const_from_toc(loc)) { // Load constant from TOC. 422 MacroAssembler::set_const_in_toc(loc, src, cb); 423 next_address = next_instruction_address(); 424 } else if (MacroAssembler::is_load_const(loc)) { 425 // Not mt safe, ok in methods like CodeBuffer::copy_code(). 426 MacroAssembler::patch_const(loc, x); 427 ICache::invalidate_range(loc, MacroAssembler::load_const_size()); 428 next_address = next_instruction_address(); 429 } 430 // cOops 431 else if (MacroAssembler::is_load_narrow_oop(loc)) { 432 MacroAssembler::patch_load_narrow_oop(loc, (oop) (void*) x); 433 ICache::invalidate_range(loc, MacroAssembler::load_narrow_oop_size()); 434 next_address = next_instruction_address(); 435 } 436 // compressed klass ptrs 437 else if (MacroAssembler::is_load_narrow_klass(loc)) { 438 MacroAssembler::patch_load_narrow_klass(loc, (Klass*)x); 439 ICache::invalidate_range(loc, MacroAssembler::load_narrow_klass_size()); 440 next_address = next_instruction_address(); 441 } 442 // cOops 443 else if (MacroAssembler::is_compare_immediate_narrow_oop(loc)) { 444 MacroAssembler::patch_compare_immediate_narrow_oop(loc, (oop) (void*) x); 445 ICache::invalidate_range(loc, MacroAssembler::compare_immediate_narrow_oop_size()); 446 next_address = next_instruction_address(); 447 } 448 // compressed klass ptrs 449 else if (MacroAssembler::is_compare_immediate_narrow_klass(loc)) { 450 MacroAssembler::patch_compare_immediate_narrow_klass(loc, (Klass*)x); 451 ICache::invalidate_range(loc, MacroAssembler::compare_immediate_narrow_klass_size()); 452 next_address = next_instruction_address(); 453 } 454 else if (MacroAssembler::is_call_far_patchable_pcrelative_at(loc)) { 455 assert(ShortenBranches, "Wait a minute! A pc-relative call w/o ShortenBranches?"); 456 // This NativeMovConstReg site does not need to be patched. It was 457 // patched when it was converted to a call_pcrelative site 458 // before. The value of the src argument is not related to the 459 // branch target. 460 next_address = next_instruction_address(); 461 } 462 463 else { 464 tty->print_cr("WARNING: detected an unrecognized code pattern at loc = %p -> 0x%8.8x %8.8x", 465 loc, *((unsigned int*)loc), *((unsigned int*)(loc+4))); 466 next_address = next_instruction_address(); // Failure should be handled in next_instruction_address(). 467 #ifdef LUCY_DBG 468 VM_Version::z_SIGSEGV(); 469 #endif 470 } 471 472 return next_address; 473 } 474 475 // Divided up in set_data_plain() which patches the instruction in the 476 // code stream and set_data() which additionally patches the oop pool 477 // if necessary. 478 void NativeMovConstReg::set_data(intptr_t src) { 479 // Also store the value into an oop_Relocation cell, if any. 480 CodeBlob *cb = CodeCache::find_blob(instruction_address()); 481 address next_address = set_data_plain(src, cb); 482 483 relocInfo::update_oop_pool(instruction_address(), next_address, (address)src, cb); 484 } 485 486 void NativeMovConstReg::set_narrow_oop(intptr_t data) { 487 const address start = addr_at(0); 488 int range = 0; 489 if (MacroAssembler::is_load_narrow_oop(start)) { 490 range = MacroAssembler::patch_load_narrow_oop(start, cast_to_oop <intptr_t> (data)); 491 } else if (MacroAssembler::is_compare_immediate_narrow_oop(start)) { 492 range = MacroAssembler::patch_compare_immediate_narrow_oop(start, cast_to_oop <intptr_t>(data)); 493 } else { 494 fatal("this is not a `NativeMovConstReg::narrow_oop' site"); 495 } 496 ICache::invalidate_range(start, range); 497 } 498 499 // Compressed klass ptrs. patch narrow klass constant. 500 void NativeMovConstReg::set_narrow_klass(intptr_t data) { 501 const address start = addr_at(0); 502 int range = 0; 503 if (MacroAssembler::is_load_narrow_klass(start)) { 504 range = MacroAssembler::patch_load_narrow_klass(start, (Klass*)data); 505 } else if (MacroAssembler::is_compare_immediate_narrow_klass(start)) { 506 range = MacroAssembler::patch_compare_immediate_narrow_klass(start, (Klass*)data); 507 } else { 508 fatal("this is not a `NativeMovConstReg::narrow_klass' site"); 509 } 510 ICache::invalidate_range(start, range); 511 } 512 513 void NativeMovConstReg::set_pcrel_addr(intptr_t newTarget, CompiledMethod *passed_nm /* = NULL */, bool copy_back_to_oop_pool) { 514 address next_address; 515 address loc = addr_at(0); 516 517 if (MacroAssembler::is_load_addr_pcrel(loc)) { 518 address oldTarget = MacroAssembler::get_target_addr_pcrel(loc); 519 MacroAssembler::patch_target_addr_pcrel(loc, (address)newTarget); 520 521 ICache::invalidate_range(loc, MacroAssembler::load_addr_pcrel_size()); 522 next_address = loc + MacroAssembler::load_addr_pcrel_size(); 523 } else if (MacroAssembler::is_load_const_from_toc_pcrelative(loc) ) { // Load constant from TOC. 524 address oldTarget = MacroAssembler::get_target_addr_pcrel(loc); 525 MacroAssembler::patch_target_addr_pcrel(loc, (address)newTarget); 526 527 ICache::invalidate_range(loc, MacroAssembler::load_const_from_toc_size()); 528 next_address = loc + MacroAssembler::load_const_from_toc_size(); 529 } else if (MacroAssembler::is_call_far_patchable_pcrelative_at(loc)) { 530 assert(ShortenBranches, "Wait a minute! A pc-relative call w/o ShortenBranches?"); 531 next_address = next_instruction_address(); 532 } else { 533 assert(false, "Not a NativeMovConstReg site for set_pcrel_addr"); 534 next_address = next_instruction_address(); // Failure should be handled in next_instruction_address(). 535 } 536 537 if (copy_back_to_oop_pool) { 538 if (relocInfo::update_oop_pool(instruction_address(), next_address, (address)newTarget, NULL)) { 539 ((NativeMovConstReg*)instruction_address())->dump(64, "NativeMovConstReg::set_pcrel_addr(): found oop reloc for pcrel_addr"); 540 #ifdef LUCY_DBG 541 VM_Version::z_SIGSEGV(); 542 #else 543 assert(false, "Ooooops: found oop reloc for pcrel_addr"); 544 #endif 545 } 546 } 547 } 548 549 void NativeMovConstReg::set_pcrel_data(intptr_t newData, CompiledMethod *passed_nm /* = NULL */, bool copy_back_to_oop_pool) { 550 address next_address; 551 address loc = addr_at(0); 552 553 if (MacroAssembler::is_load_const_from_toc(loc) ) { // Load constant from TOC. 554 // Offset is +/- 2**32 -> use long. 555 long offset = MacroAssembler::get_load_const_from_toc_offset(loc); 556 address target = MacroAssembler::get_target_addr_pcrel(loc); 557 intptr_t oldData = *(intptr_t*)target; 558 if (oldData != newData) { // Update only if data changes. Prevents cache invalidation. 559 *(intptr_t *)(target) = newData; 560 } 561 562 // ICache::invalidate_range(target, sizeof(unsigned long)); // No ICache invalidate for CP data. 563 next_address = loc + MacroAssembler::load_const_from_toc_size(); 564 } else if (MacroAssembler::is_call_far_pcrelative(loc)) { 565 ((NativeMovConstReg*)loc)->dump(64, "NativeMovConstReg::set_pcrel_data() has a problem: setting data for a pc-relative call?"); 566 #ifdef LUCY_DBG 567 VM_Version::z_SIGSEGV(); 568 #else 569 assert(false, "Ooooops: setting data for a pc-relative call"); 570 #endif 571 next_address = next_instruction_address(); 572 } else { 573 assert(false, "Not a NativeMovConstReg site for set_pcrel_data"); 574 next_address = next_instruction_address(); // Failure should be handled in next_instruction_address(). 575 } 576 577 if (copy_back_to_oop_pool) { 578 if (relocInfo::update_oop_pool(instruction_address(), next_address, (address)newData, NULL)) { 579 ((NativeMovConstReg*)instruction_address())->dump(64, "NativeMovConstReg::set_pcrel_data(): found oop reloc for pcrel_data"); 580 #ifdef LUCY_DBG 581 VM_Version::z_SIGSEGV(); 582 #else 583 assert(false, "Ooooops: found oop reloc for pcrel_data"); 584 #endif 585 } 586 } 587 } 588 589 #ifdef COMPILER1 590 //-------------------------------- 591 // N a t i v e M o v R e g M e m 592 //-------------------------------- 593 594 void NativeMovRegMem::verify() { 595 address l1 = addr_at(0); 596 address l2 = addr_at(MacroAssembler::load_const_size()); 597 598 if (!MacroAssembler::is_load_const(l1)) { 599 tty->cr(); 600 tty->print_cr("NativeMovRegMem::verify(): verifying addr " PTR_FORMAT, p2i(l1)); 601 tty->cr(); 602 ((NativeMovRegMem*)l1)->dump(64, "NativeMovConstReg::verify()"); 603 fatal("this is not a `NativeMovRegMem' site"); 604 } 605 606 unsigned long inst1; 607 Assembler::get_instruction(l2, &inst1); 608 609 if (!Assembler::is_z_lb(inst1) && 610 !Assembler::is_z_llgh(inst1) && 611 !Assembler::is_z_lh(inst1) && 612 !Assembler::is_z_l(inst1) && 613 !Assembler::is_z_llgf(inst1) && 614 !Assembler::is_z_lg(inst1) && 615 !Assembler::is_z_le(inst1) && 616 !Assembler::is_z_ld(inst1) && 617 !Assembler::is_z_stc(inst1) && 618 !Assembler::is_z_sth(inst1) && 619 !Assembler::is_z_st(inst1) && 620 !UseCompressedOops && 621 !Assembler::is_z_stg(inst1) && 622 !Assembler::is_z_ste(inst1) && 623 !Assembler::is_z_std(inst1)) { 624 tty->cr(); 625 tty->print_cr("NativeMovRegMem::verify(): verifying addr " PTR_FORMAT 626 ": wrong or missing load or store at " PTR_FORMAT, p2i(l1), p2i(l2)); 627 tty->cr(); 628 ((NativeMovRegMem*)l1)->dump(64, "NativeMovConstReg::verify()"); 629 fatal("this is not a `NativeMovRegMem' site"); 630 } 631 } 632 #endif // COMPILER1 633 634 //----------------------- 635 // N a t i v e J u m p 636 //----------------------- 637 638 void NativeJump::verify() { 639 if (NativeJump::is_jump_at(addr_at(0))) return; 640 fatal("this is not a `NativeJump' site"); 641 } 642 643 // Patch atomically with an illtrap. 644 void NativeJump::patch_verified_entry(address entry, address verified_entry, address dest) { 645 ResourceMark rm; 646 int code_size = 2; 647 CodeBuffer cb(verified_entry, code_size + 1); 648 MacroAssembler* a = new MacroAssembler(&cb); 649 #ifdef COMPILER2 650 assert(dest == SharedRuntime::get_handle_wrong_method_stub(), "expected fixed destination of patch"); 651 #endif 652 a->z_illtrap(); 653 ICache::invalidate_range(verified_entry, code_size); 654 } 655 656 #undef LUCY_DBG 657 658 //------------------------------------- 659 // N a t i v e G e n e r a l J u m p 660 //------------------------------------- 661 662 #ifndef PRODUCT 663 void NativeGeneralJump::verify() { 664 unsigned long inst; 665 Assembler::get_instruction((address)this, &inst); 666 assert(MacroAssembler::is_branch_pcrelative_long(inst), "not a general jump instruction"); 667 } 668 #endif 669 670 void NativeGeneralJump::insert_unconditional(address code_pos, address entry) { 671 uint64_t instr = BRCL_ZOPC | 672 Assembler::uimm4(Assembler::bcondAlways, 8, 48) | 673 Assembler::simm32(RelAddr::pcrel_off32(entry, code_pos), 16, 48); 674 *(uint64_t*) code_pos = (instr << 16); // Must shift into big end, then the brcl will be written to code_pos. 675 ICache::invalidate_range(code_pos, instruction_size); 676 } 677 678 void NativeGeneralJump::replace_mt_safe(address instr_addr, address code_buffer) { 679 assert(((intptr_t)instr_addr & (BytesPerWord-1)) == 0, "requirement for mt safe patching"); 680 // Bytes_after_jump cannot change, because we own the Patching_lock. 681 assert(Patching_lock->owned_by_self(), "must hold lock to patch instruction"); 682 intptr_t bytes_after_jump = (*(intptr_t*)instr_addr) & 0x000000000000ffffL; // 2 bytes after jump. 683 intptr_t load_const_bytes = (*(intptr_t*)code_buffer) & 0xffffffffffff0000L; 684 *(intptr_t*)instr_addr = load_const_bytes | bytes_after_jump; 685 ICache::invalidate_range(instr_addr, 6); 686 }