nativeInst_s390.cpp revision 12256:2844bdfd7a99
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
55void 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
69void 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}
91void NativeInstruction::print() const {
92  print(NULL);
93}
94
95// Hex-Dump of storage around current NativeInstruction. Also try disassembly.
96void 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
100void NativeInstruction::dump(const unsigned int range) const {
101  dump(range, NULL);
102}
103
104void NativeInstruction::dump() const {
105  dump(32, NULL);
106}
107
108void 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
120void 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
132void 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
150int NativeInstruction::illegal_instruction() {
151  return 0;
152}
153
154bool 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.
172bool 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
192bool 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
202void 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
211void NativeCall::verify() {
212  if (NativeCall::is_call_at(addr_at(0))) return;
213
214  fatal("this is not a `NativeCall' site");
215}
216
217address 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.
233void 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
250void NativeFarCall::verify() {
251  NativeInstruction::verify();
252  if (NativeFarCall::is_far_call_at(addr_at(0))) return;
253  fatal("not a NativeFarCall");
254}
255
256address NativeFarCall::destination() {
257  assert(MacroAssembler::is_call_far_patchable_at((address)this), "unexpected call type");
258  address ctable = NULL;
259  if (MacroAssembler::call_far_patchable_requires_alignment_nop((address)this)) {
260    return MacroAssembler::get_dest_of_call_far_patchable_at(((address)this)+MacroAssembler::nop_size(), ctable);
261  } else {
262    return MacroAssembler::get_dest_of_call_far_patchable_at((address)this, ctable);
263  }
264}
265
266
267// Handles both patterns of patchable far calls.
268void NativeFarCall::set_destination(address dest, int toc_offset) {
269  address inst_addr = (address)this;
270
271  // Set new destination (implementation of call may change here).
272  assert(MacroAssembler::is_call_far_patchable_at(inst_addr), "unexpected call type");
273
274  if (!MacroAssembler::is_call_far_patchable_pcrelative_at(inst_addr)) {
275    address ctable = CodeCache::find_blob(inst_addr)->ctable_begin();
276    // Need distance of TOC entry from current instruction.
277    toc_offset = (ctable + toc_offset) - inst_addr;
278    // Call is via constant table entry.
279    MacroAssembler::set_dest_of_call_far_patchable_at(inst_addr, dest, toc_offset);
280  } else {
281    // Here, we have a pc-relative call (brasl).
282    // Be aware: dest may have moved in this case, so really patch the displacement,
283    // when necessary!
284    // This while loop will also consume the nop which always preceeds a call_far_pcrelative.
285    // We need to revert this after the loop. Pc-relative calls are always assumed to have a leading nop.
286    unsigned int nop_sz    = MacroAssembler::nop_size();
287    unsigned int nop_bytes = 0;
288    while(MacroAssembler::is_z_nop(inst_addr+nop_bytes)) {
289      nop_bytes += nop_sz;
290    }
291    if (nop_bytes > 0) {
292      inst_addr += nop_bytes - nop_sz;
293    }
294
295    assert(MacroAssembler::is_call_far_pcrelative(inst_addr), "not a pc-relative call");
296    address target = MacroAssembler::get_target_addr_pcrel(inst_addr + nop_sz);
297    if (target != dest) {
298      NativeCall *call = nativeCall_at(inst_addr);
299      call->set_destination_mt_safe(dest);
300    }
301  }
302}
303
304//-------------------------------------
305//  N a t i v e M o v C o n s t R e g
306//-------------------------------------
307
308// Do not use an assertion here. Let clients decide whether they only
309// want this when assertions are enabled.
310void NativeMovConstReg::verify() {
311  address   loc = addr_at(0);
312
313  // This while loop will also consume the nop which always preceeds a
314  // call_far_pcrelative.  We need to revert this after the
315  // loop. Pc-relative calls are always assumed to have a leading nop.
316  unsigned int nop_sz    = MacroAssembler::nop_size();
317  unsigned int nop_bytes = 0;
318  while(MacroAssembler::is_z_nop(loc+nop_bytes)) {
319    nop_bytes += nop_sz;
320  }
321
322  if (nop_bytes > 0) {
323    if (MacroAssembler::is_call_far_pcrelative(loc+nop_bytes-nop_sz)) return;
324    loc += nop_bytes;
325  }
326
327  if (!MacroAssembler::is_load_const_from_toc(loc)            &&    // Load const from TOC.
328      !MacroAssembler::is_load_const(loc)                     &&    // Load const inline.
329      !MacroAssembler::is_load_narrow_oop(loc)                &&    // Load narrow oop.
330      !MacroAssembler::is_load_narrow_klass(loc)              &&    // Load narrow Klass ptr.
331      !MacroAssembler::is_compare_immediate_narrow_oop(loc)   &&    // Compare immediate narrow.
332      !MacroAssembler::is_compare_immediate_narrow_klass(loc) &&    // Compare immediate narrow.
333      !MacroAssembler::is_pcrelative_instruction(loc)) {            // Just to make it run.
334    tty->cr();
335    tty->print_cr("NativeMovConstReg::verify(): verifying addr %p(0x%x), %d leading nops", loc, *(uint*)loc, nop_bytes/nop_sz);
336    tty->cr();
337    ((NativeMovConstReg*)loc)->dump(64, "NativeMovConstReg::verify()");
338#ifdef LUCY_DBG
339    VM_Version::z_SIGSEGV();
340#endif
341    fatal("this is not a `NativeMovConstReg' site");
342  }
343}
344
345address NativeMovConstReg::next_instruction_address(int offset) const  {
346  address inst_addr = addr_at(offset);
347
348  // Load address (which is a constant) pc-relative.
349  if (MacroAssembler::is_load_addr_pcrel(inst_addr))                  { return addr_at(offset+MacroAssembler::load_addr_pcrel_size()); }
350
351  // Load constant from TOC.
352  if (MacroAssembler::is_load_const_from_toc(inst_addr))              { return addr_at(offset+MacroAssembler::load_const_from_toc_size()); }
353
354  // Load constant inline.
355  if (MacroAssembler::is_load_const(inst_addr))                       { return addr_at(offset+MacroAssembler::load_const_size()); }
356
357  // Load constant narrow inline.
358  if (MacroAssembler::is_load_narrow_oop(inst_addr))                  { return addr_at(offset+MacroAssembler::load_narrow_oop_size()); }
359  if (MacroAssembler::is_load_narrow_klass(inst_addr))                { return addr_at(offset+MacroAssembler::load_narrow_klass_size()); }
360
361  // Compare constant narrow inline.
362  if (MacroAssembler::is_compare_immediate_narrow_oop(inst_addr))     { return addr_at(offset+MacroAssembler::compare_immediate_narrow_oop_size()); }
363  if (MacroAssembler::is_compare_immediate_narrow_klass(inst_addr))   { return addr_at(offset+MacroAssembler::compare_immediate_narrow_klass_size()); }
364
365  if (MacroAssembler::is_call_far_patchable_pcrelative_at(inst_addr)) { return addr_at(offset+MacroAssembler::call_far_patchable_size()); }
366
367  if (MacroAssembler::is_pcrelative_instruction(inst_addr))           { return addr_at(offset+Assembler::instr_len(inst_addr)); }
368
369  ((NativeMovConstReg*)inst_addr)->dump(64, "NativeMovConstReg site is not recognized as such");
370#ifdef LUCY_DBG
371  VM_Version::z_SIGSEGV();
372#else
373  guarantee(false, "Not a NativeMovConstReg site");
374#endif
375  return NULL;
376}
377
378intptr_t NativeMovConstReg::data() const {
379  address loc = addr_at(0);
380  if (MacroAssembler::is_load_const(loc)) {
381    return MacroAssembler::get_const(loc);
382  } else if (MacroAssembler::is_load_narrow_oop(loc)              ||
383             MacroAssembler::is_compare_immediate_narrow_oop(loc) ||
384             MacroAssembler::is_load_narrow_klass(loc)            ||
385             MacroAssembler::is_compare_immediate_narrow_klass(loc)) {
386    ((NativeMovConstReg*)loc)->dump(32, "NativeMovConstReg::data(): cannot extract data from narrow ptr (oop or klass)");
387#ifdef LUCY_DBG
388    VM_Version::z_SIGSEGV();
389#else
390    ShouldNotReachHere();
391#endif
392    return *(intptr_t *)NULL;
393  } else {
394    // Otherwise, assume data resides in TOC. Is asserted in called method.
395    return MacroAssembler::get_const_from_toc(loc);
396  }
397}
398
399
400// Patch in a new constant.
401//
402// There are situations where we have multiple (hopefully two at most)
403// relocations connected to one instruction. Loading an oop from CP
404// using pcrelative addressing would one such example. Here we have an
405// oop relocation, modifying the oop itself, and an internal word relocation,
406// modifying the relative address.
407//
408// NativeMovConstReg::set_data is then called once for each relocation. To be
409// able to distinguish between the relocations, we use a rather dirty hack:
410//
411// All calls that deal with an internal word relocation to fix their relative
412// address are on a faked, odd instruction address. The instruction can be
413// found on the next lower, even address.
414//
415// All other calls are "normal", i.e. on even addresses.
416address NativeMovConstReg::set_data_plain(intptr_t src, CodeBlob *cb) {
417  unsigned long x = (unsigned long)src;
418  address loc = instruction_address();
419  address next_address;
420
421  if (MacroAssembler::is_load_addr_pcrel(loc)) {
422    MacroAssembler::patch_target_addr_pcrel(loc, (address)src);
423    ICache::invalidate_range(loc, MacroAssembler::load_addr_pcrel_size());
424    next_address = next_instruction_address();
425  } else if (MacroAssembler::is_load_const_from_toc(loc)) {  // Load constant from TOC.
426    MacroAssembler::set_const_in_toc(loc, src, cb);
427    next_address = next_instruction_address();
428  } else if (MacroAssembler::is_load_const(loc)) {
429    // Not mt safe, ok in methods like CodeBuffer::copy_code().
430    MacroAssembler::patch_const(loc, x);
431    ICache::invalidate_range(loc, MacroAssembler::load_const_size());
432    next_address = next_instruction_address();
433  }
434  // cOops
435  else if (MacroAssembler::is_load_narrow_oop(loc)) {
436    MacroAssembler::patch_load_narrow_oop(loc, (oop) (void*) x);
437    ICache::invalidate_range(loc, MacroAssembler::load_narrow_oop_size());
438    next_address = next_instruction_address();
439  }
440  // compressed klass ptrs
441  else if (MacroAssembler::is_load_narrow_klass(loc)) {
442    MacroAssembler::patch_load_narrow_klass(loc, (Klass*)x);
443    ICache::invalidate_range(loc, MacroAssembler::load_narrow_klass_size());
444    next_address = next_instruction_address();
445  }
446  // cOops
447  else if (MacroAssembler::is_compare_immediate_narrow_oop(loc)) {
448    MacroAssembler::patch_compare_immediate_narrow_oop(loc, (oop) (void*) x);
449    ICache::invalidate_range(loc, MacroAssembler::compare_immediate_narrow_oop_size());
450    next_address = next_instruction_address();
451  }
452  // compressed klass ptrs
453  else if (MacroAssembler::is_compare_immediate_narrow_klass(loc)) {
454    MacroAssembler::patch_compare_immediate_narrow_klass(loc, (Klass*)x);
455    ICache::invalidate_range(loc, MacroAssembler::compare_immediate_narrow_klass_size());
456    next_address = next_instruction_address();
457  }
458  else if (MacroAssembler::is_call_far_patchable_pcrelative_at(loc)) {
459    assert(ShortenBranches, "Wait a minute! A pc-relative call w/o ShortenBranches?");
460    // This NativeMovConstReg site does not need to be patched. It was
461    // patched when it was converted to a call_pcrelative site
462    // before. The value of the src argument is not related to the
463    // branch target.
464    next_address = next_instruction_address();
465  }
466
467  else {
468    tty->print_cr("WARNING: detected an unrecognized code pattern at loc = %p -> 0x%8.8x %8.8x",
469                  loc, *((unsigned int*)loc), *((unsigned int*)(loc+4)));
470    next_address = next_instruction_address(); // Failure should be handled in next_instruction_address().
471#ifdef LUCY_DBG
472    VM_Version::z_SIGSEGV();
473#endif
474  }
475
476  return next_address;
477}
478
479// Divided up in set_data_plain() which patches the instruction in the
480// code stream and set_data() which additionally patches the oop pool
481// if necessary.
482void NativeMovConstReg::set_data(intptr_t src) {
483  // Also store the value into an oop_Relocation cell, if any.
484  CodeBlob *cb = CodeCache::find_blob(instruction_address());
485  address next_address = set_data_plain(src, cb);
486
487  relocInfo::update_oop_pool(instruction_address(), next_address, (address)src, cb);
488}
489
490void NativeMovConstReg::set_narrow_oop(intptr_t data) {
491  const address start = addr_at(0);
492  int           range = 0;
493  if (MacroAssembler::is_load_narrow_oop(start)) {
494    range = MacroAssembler::patch_load_narrow_oop(start, cast_to_oop <intptr_t> (data));
495  } else if (MacroAssembler::is_compare_immediate_narrow_oop(start)) {
496    range = MacroAssembler::patch_compare_immediate_narrow_oop(start, cast_to_oop <intptr_t>(data));
497  } else {
498    fatal("this is not a `NativeMovConstReg::narrow_oop' site");
499  }
500  ICache::invalidate_range(start, range);
501}
502
503// Compressed klass ptrs. patch narrow klass constant.
504void NativeMovConstReg::set_narrow_klass(intptr_t data) {
505  const address start = addr_at(0);
506  int           range = 0;
507  if (MacroAssembler::is_load_narrow_klass(start)) {
508    range = MacroAssembler::patch_load_narrow_klass(start, (Klass*)data);
509  } else if (MacroAssembler::is_compare_immediate_narrow_klass(start)) {
510    range = MacroAssembler::patch_compare_immediate_narrow_klass(start, (Klass*)data);
511  } else {
512    fatal("this is not a `NativeMovConstReg::narrow_klass' site");
513  }
514  ICache::invalidate_range(start, range);
515}
516
517void NativeMovConstReg::set_pcrel_addr(intptr_t newTarget, CompiledMethod *passed_nm /* = NULL */, bool copy_back_to_oop_pool) {
518  address next_address;
519  address loc = addr_at(0);
520
521  if (MacroAssembler::is_load_addr_pcrel(loc)) {
522    address oldTarget = MacroAssembler::get_target_addr_pcrel(loc);
523    MacroAssembler::patch_target_addr_pcrel(loc, (address)newTarget);
524
525    ICache::invalidate_range(loc, MacroAssembler::load_addr_pcrel_size());
526    next_address = loc + MacroAssembler::load_addr_pcrel_size();
527  } else if (MacroAssembler::is_load_const_from_toc_pcrelative(loc) ) {  // Load constant from TOC.
528    address oldTarget = MacroAssembler::get_target_addr_pcrel(loc);
529    MacroAssembler::patch_target_addr_pcrel(loc, (address)newTarget);
530
531    ICache::invalidate_range(loc, MacroAssembler::load_const_from_toc_size());
532    next_address = loc + MacroAssembler::load_const_from_toc_size();
533  } else if (MacroAssembler::is_call_far_patchable_pcrelative_at(loc)) {
534    assert(ShortenBranches, "Wait a minute! A pc-relative call w/o ShortenBranches?");
535    next_address = next_instruction_address();
536  } else {
537    assert(false, "Not a NativeMovConstReg site for set_pcrel_addr");
538    next_address = next_instruction_address(); // Failure should be handled in next_instruction_address().
539  }
540
541  if (copy_back_to_oop_pool) {
542    if (relocInfo::update_oop_pool(instruction_address(), next_address, (address)newTarget, NULL)) {
543      ((NativeMovConstReg*)instruction_address())->dump(64, "NativeMovConstReg::set_pcrel_addr(): found oop reloc for pcrel_addr");
544#ifdef LUCY_DBG
545      VM_Version::z_SIGSEGV();
546#else
547      assert(false, "Ooooops: found oop reloc for pcrel_addr");
548#endif
549    }
550  }
551}
552
553void NativeMovConstReg::set_pcrel_data(intptr_t newData, CompiledMethod *passed_nm /* = NULL */, bool copy_back_to_oop_pool) {
554  address  next_address;
555  address  loc = addr_at(0);
556
557  if (MacroAssembler::is_load_const_from_toc(loc) ) {  // Load constant from TOC.
558    // Offset is +/- 2**32 -> use long.
559    long     offset  = MacroAssembler::get_load_const_from_toc_offset(loc);
560    address  target  = MacroAssembler::get_target_addr_pcrel(loc);
561    intptr_t oldData = *(intptr_t*)target;
562    if (oldData != newData) { // Update only if data changes. Prevents cache invalidation.
563      *(intptr_t *)(target) = newData;
564    }
565
566    // ICache::invalidate_range(target, sizeof(unsigned long));  // No ICache invalidate for CP data.
567    next_address = loc + MacroAssembler::load_const_from_toc_size();
568  } else if (MacroAssembler::is_call_far_pcrelative(loc)) {
569    ((NativeMovConstReg*)loc)->dump(64, "NativeMovConstReg::set_pcrel_data() has a problem: setting data for a pc-relative call?");
570#ifdef LUCY_DBG
571    VM_Version::z_SIGSEGV();
572#else
573    assert(false, "Ooooops: setting data for a pc-relative call");
574#endif
575    next_address = next_instruction_address();
576  } else {
577    assert(false, "Not a NativeMovConstReg site for set_pcrel_data");
578    next_address = next_instruction_address(); // Failure should be handled in next_instruction_address().
579  }
580
581  if (copy_back_to_oop_pool) {
582    if (relocInfo::update_oop_pool(instruction_address(), next_address, (address)newData, NULL)) {
583      ((NativeMovConstReg*)instruction_address())->dump(64, "NativeMovConstReg::set_pcrel_data(): found oop reloc for pcrel_data");
584#ifdef LUCY_DBG
585      VM_Version::z_SIGSEGV();
586#else
587      assert(false, "Ooooops: found oop reloc for pcrel_data");
588#endif
589    }
590  }
591}
592
593#ifdef COMPILER1
594//--------------------------------
595//  N a t i v e M o v R e g M e m
596//--------------------------------
597
598void NativeMovRegMem::verify() {
599  address l1 = addr_at(0);
600  address l2 = addr_at(MacroAssembler::load_const_size());
601
602  if (!MacroAssembler::is_load_const(l1)) {
603    tty->cr();
604    tty->print_cr("NativeMovRegMem::verify(): verifying addr " PTR_FORMAT, p2i(l1));
605    tty->cr();
606    ((NativeMovRegMem*)l1)->dump(64, "NativeMovConstReg::verify()");
607    fatal("this is not a `NativeMovRegMem' site");
608  }
609
610  unsigned long inst1;
611  Assembler::get_instruction(l2, &inst1);
612
613  if (!Assembler::is_z_lb(inst1)                         &&
614      !Assembler::is_z_llgh(inst1)                       &&
615      !Assembler::is_z_lh(inst1)                         &&
616      !Assembler::is_z_l(inst1)                          &&
617      !Assembler::is_z_llgf(inst1)                       &&
618      !Assembler::is_z_lg(inst1)                         &&
619      !Assembler::is_z_le(inst1)                         &&
620      !Assembler::is_z_ld(inst1)                         &&
621      !Assembler::is_z_stc(inst1)                        &&
622      !Assembler::is_z_sth(inst1)                        &&
623      !Assembler::is_z_st(inst1)                         &&
624      !(Assembler::is_z_lgr(inst1) && UseCompressedOops) &&
625      !Assembler::is_z_stg(inst1)                        &&
626      !Assembler::is_z_ste(inst1)                        &&
627      !Assembler::is_z_std(inst1)) {
628    tty->cr();
629    tty->print_cr("NativeMovRegMem::verify(): verifying addr " PTR_FORMAT
630                  ": wrong or missing load or store at " PTR_FORMAT, p2i(l1), p2i(l2));
631    tty->cr();
632    ((NativeMovRegMem*)l1)->dump(64, "NativeMovConstReg::verify()");
633    fatal("this is not a `NativeMovRegMem' site");
634  }
635}
636#endif // COMPILER1
637
638//-----------------------
639//  N a t i v e J u m p
640//-----------------------
641
642void NativeJump::verify() {
643  if (NativeJump::is_jump_at(addr_at(0))) return;
644  fatal("this is not a `NativeJump' site");
645}
646
647// Patch atomically with an illtrap.
648void NativeJump::patch_verified_entry(address entry, address verified_entry, address dest) {
649  ResourceMark rm;
650  int code_size = 2;
651  CodeBuffer cb(verified_entry, code_size + 1);
652  MacroAssembler* a = new MacroAssembler(&cb);
653#ifdef COMPILER2
654  assert(dest == SharedRuntime::get_handle_wrong_method_stub(), "expected fixed destination of patch");
655#endif
656  a->z_illtrap();
657  ICache::invalidate_range(verified_entry, code_size);
658}
659
660#undef LUCY_DBG
661
662//-------------------------------------
663//  N a t i v e G e n e r a l J u m p
664//-------------------------------------
665
666#ifndef PRODUCT
667void NativeGeneralJump::verify() {
668  unsigned long inst;
669  Assembler::get_instruction((address)this, &inst);
670  assert(MacroAssembler::is_branch_pcrelative_long(inst), "not a general jump instruction");
671}
672#endif
673
674void NativeGeneralJump::insert_unconditional(address code_pos, address entry) {
675  uint64_t instr = BRCL_ZOPC |
676                   Assembler::uimm4(Assembler::bcondAlways, 8, 48) |
677                   Assembler::simm32(RelAddr::pcrel_off32(entry, code_pos), 16, 48);
678  *(uint64_t*) code_pos = (instr << 16); // Must shift into big end, then the brcl will be written to code_pos.
679  ICache::invalidate_range(code_pos, instruction_size);
680}
681
682void NativeGeneralJump::replace_mt_safe(address instr_addr, address code_buffer) {
683  assert(((intptr_t)instr_addr & (BytesPerWord-1)) == 0, "requirement for mt safe patching");
684  // Bytes_after_jump cannot change, because we own the Patching_lock.
685  assert(Patching_lock->owned_by_self(), "must hold lock to patch instruction");
686  intptr_t bytes_after_jump = (*(intptr_t*)instr_addr)  & 0x000000000000ffffL; // 2 bytes after jump.
687  intptr_t load_const_bytes = (*(intptr_t*)code_buffer) & 0xffffffffffff0000L;
688  *(intptr_t*)instr_addr = load_const_bytes | bytes_after_jump;
689  ICache::invalidate_range(instr_addr, 6);
690}
691