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 
verify()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
print(const char * msg) const69 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 }
print() const91 void NativeInstruction::print() const {
92   print(NULL);
93 }
94 
95 // Hex-Dump of storage around current NativeInstruction. Also try disassembly.
dump(const unsigned int range,const char * msg) const96 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 
dump(const unsigned int range) const100 void NativeInstruction::dump(const unsigned int range) const {
101   dump(range, NULL);
102 }
103 
dump() const104 void NativeInstruction::dump() const {
105   dump(32, NULL);
106 }
107 
set_halfword_at(int offset,short i)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 
set_word_at(int offset,int i)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 
set_jlong_at(int offset,jlong i)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 
illegal_instruction()150 int NativeInstruction::illegal_instruction() {
151   return 0;
152 }
153 
is_illegal()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.
is_sigill_zombie_not_entrant()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 
is_jump()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 
insert(address code_pos)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 
verify()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 
destination() const217 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.
set_destination_mt_safe(address dest)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 
verify()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 
destination()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.
set_destination(address dest,int toc_offset)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.
verify()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 
next_instruction_address(int offset) const341 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 
data() const374 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.
set_data_plain(intptr_t src,CodeBlob * cb)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.
set_data(intptr_t data,relocInfo::relocType expected_type)478 void NativeMovConstReg::set_data(intptr_t data, relocInfo::relocType expected_type) {
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(data, cb);
482 
483   // 'RelocIterator' requires an nmethod
484   nmethod* nm = cb ? cb->as_nmethod_or_null() : NULL;
485   if (nm != NULL) {
486     RelocIterator iter(nm, instruction_address(), next_address);
487     oop* oop_addr = NULL;
488     Metadata** metadata_addr = NULL;
489     while (iter.next()) {
490       if (iter.type() == relocInfo::oop_type) {
491         oop_Relocation *r = iter.oop_reloc();
492         if (oop_addr == NULL) {
493           oop_addr = r->oop_addr();
494           *oop_addr = cast_to_oop(data);
495         } else {
496           assert(oop_addr == r->oop_addr(), "must be only one set-oop here");
497         }
498       }
499       if (iter.type() == relocInfo::metadata_type) {
500         metadata_Relocation *r = iter.metadata_reloc();
501         if (metadata_addr == NULL) {
502           metadata_addr = r->metadata_addr();
503           *metadata_addr = (Metadata*)data;
504         } else {
505           assert(metadata_addr == r->metadata_addr(), "must be only one set-metadata here");
506         }
507       }
508     }
509     assert(expected_type == relocInfo::none ||
510           (expected_type == relocInfo::metadata_type && metadata_addr != NULL) ||
511           (expected_type == relocInfo::oop_type && oop_addr != NULL),
512           "%s relocation not found", expected_type == relocInfo::oop_type ? "oop" : "metadata");
513   }
514 }
515 
set_narrow_oop(intptr_t data)516 void NativeMovConstReg::set_narrow_oop(intptr_t data) {
517   const address start = addr_at(0);
518   int           range = 0;
519   if (MacroAssembler::is_load_narrow_oop(start)) {
520     range = MacroAssembler::patch_load_narrow_oop(start, cast_to_oop <intptr_t> (data));
521   } else if (MacroAssembler::is_compare_immediate_narrow_oop(start)) {
522     range = MacroAssembler::patch_compare_immediate_narrow_oop(start, cast_to_oop <intptr_t>(data));
523   } else {
524     fatal("this is not a `NativeMovConstReg::narrow_oop' site");
525   }
526   ICache::invalidate_range(start, range);
527 }
528 
529 // Compressed klass ptrs. patch narrow klass constant.
set_narrow_klass(intptr_t data)530 void NativeMovConstReg::set_narrow_klass(intptr_t data) {
531   const address start = addr_at(0);
532   int           range = 0;
533   if (MacroAssembler::is_load_narrow_klass(start)) {
534     range = MacroAssembler::patch_load_narrow_klass(start, (Klass*)data);
535   } else if (MacroAssembler::is_compare_immediate_narrow_klass(start)) {
536     range = MacroAssembler::patch_compare_immediate_narrow_klass(start, (Klass*)data);
537   } else {
538     fatal("this is not a `NativeMovConstReg::narrow_klass' site");
539   }
540   ICache::invalidate_range(start, range);
541 }
542 
set_pcrel_addr(intptr_t newTarget,CompiledMethod * passed_nm)543 void NativeMovConstReg::set_pcrel_addr(intptr_t newTarget, CompiledMethod *passed_nm /* = NULL */) {
544   address next_address;
545   address loc = addr_at(0);
546 
547   if (MacroAssembler::is_load_addr_pcrel(loc)) {
548     address oldTarget = MacroAssembler::get_target_addr_pcrel(loc);
549     MacroAssembler::patch_target_addr_pcrel(loc, (address)newTarget);
550 
551     ICache::invalidate_range(loc, MacroAssembler::load_addr_pcrel_size());
552     next_address = loc + MacroAssembler::load_addr_pcrel_size();
553   } else if (MacroAssembler::is_load_const_from_toc_pcrelative(loc) ) {  // Load constant from TOC.
554     address oldTarget = MacroAssembler::get_target_addr_pcrel(loc);
555     MacroAssembler::patch_target_addr_pcrel(loc, (address)newTarget);
556 
557     ICache::invalidate_range(loc, MacroAssembler::load_const_from_toc_size());
558     next_address = loc + MacroAssembler::load_const_from_toc_size();
559   } else if (MacroAssembler::is_call_far_patchable_pcrelative_at(loc)) {
560     assert(ShortenBranches, "Wait a minute! A pc-relative call w/o ShortenBranches?");
561     next_address = next_instruction_address();
562   } else {
563     assert(false, "Not a NativeMovConstReg site for set_pcrel_addr");
564     next_address = next_instruction_address(); // Failure should be handled in next_instruction_address().
565   }
566 }
567 
set_pcrel_data(intptr_t newData,CompiledMethod * passed_nm)568 void NativeMovConstReg::set_pcrel_data(intptr_t newData, CompiledMethod *passed_nm /* = NULL */) {
569   address  next_address;
570   address  loc = addr_at(0);
571 
572   if (MacroAssembler::is_load_const_from_toc(loc) ) {  // Load constant from TOC.
573     // Offset is +/- 2**32 -> use long.
574     long     offset  = MacroAssembler::get_load_const_from_toc_offset(loc);
575     address  target  = MacroAssembler::get_target_addr_pcrel(loc);
576     intptr_t oldData = *(intptr_t*)target;
577     if (oldData != newData) { // Update only if data changes. Prevents cache invalidation.
578       *(intptr_t *)(target) = newData;
579     }
580 
581     // ICache::invalidate_range(target, sizeof(unsigned long));  // No ICache invalidate for CP data.
582     next_address = loc + MacroAssembler::load_const_from_toc_size();
583   } else if (MacroAssembler::is_call_far_pcrelative(loc)) {
584     ((NativeMovConstReg*)loc)->dump(64, "NativeMovConstReg::set_pcrel_data() has a problem: setting data for a pc-relative call?");
585 #ifdef LUCY_DBG
586     VM_Version::z_SIGSEGV();
587 #else
588     assert(false, "Ooooops: setting data for a pc-relative call");
589 #endif
590     next_address = next_instruction_address();
591   } else {
592     assert(false, "Not a NativeMovConstReg site for set_pcrel_data");
593     next_address = next_instruction_address(); // Failure should be handled in next_instruction_address().
594   }
595 }
596 
597 #ifdef COMPILER1
598 //--------------------------------
599 //  N a t i v e M o v R e g M e m
600 //--------------------------------
601 
verify()602 void NativeMovRegMem::verify() {
603   address l1 = addr_at(0);
604 
605   if (!MacroAssembler::is_load_const(l1)) {
606     tty->cr();
607     tty->print_cr("NativeMovRegMem::verify(): verifying addr " PTR_FORMAT, p2i(l1));
608     tty->cr();
609     ((NativeMovRegMem*)l1)->dump(64, "NativeMovConstReg::verify()");
610     fatal("this is not a `NativeMovRegMem' site");
611   }
612 }
613 #endif // COMPILER1
614 
615 //-----------------------
616 //  N a t i v e J u m p
617 //-----------------------
618 
verify()619 void NativeJump::verify() {
620   if (NativeJump::is_jump_at(addr_at(0))) return;
621   fatal("this is not a `NativeJump' site");
622 }
623 
624 // Patch atomically with an illtrap.
patch_verified_entry(address entry,address verified_entry,address dest)625 void NativeJump::patch_verified_entry(address entry, address verified_entry, address dest) {
626   ResourceMark rm;
627   int code_size = 2;
628   CodeBuffer cb(verified_entry, code_size + 1);
629   MacroAssembler* a = new MacroAssembler(&cb);
630 #ifdef COMPILER2
631   assert(dest == SharedRuntime::get_handle_wrong_method_stub(), "expected fixed destination of patch");
632 #endif
633   a->z_illtrap();
634   ICache::invalidate_range(verified_entry, code_size);
635 }
636 
637 #undef LUCY_DBG
638 
639 //-------------------------------------
640 //  N a t i v e G e n e r a l J u m p
641 //-------------------------------------
642 
643 #ifndef PRODUCT
verify()644 void NativeGeneralJump::verify() {
645   unsigned long inst;
646   Assembler::get_instruction((address)this, &inst);
647   assert(MacroAssembler::is_branch_pcrelative_long(inst), "not a general jump instruction");
648 }
649 #endif
650 
insert_unconditional(address code_pos,address entry)651 void NativeGeneralJump::insert_unconditional(address code_pos, address entry) {
652   uint64_t instr = BRCL_ZOPC |
653                    Assembler::uimm4(Assembler::bcondAlways, 8, 48) |
654                    Assembler::simm32(RelAddr::pcrel_off32(entry, code_pos), 16, 48);
655   *(uint64_t*) code_pos = (instr << 16); // Must shift into big end, then the brcl will be written to code_pos.
656   ICache::invalidate_range(code_pos, instruction_size);
657 }
658 
replace_mt_safe(address instr_addr,address code_buffer)659 void NativeGeneralJump::replace_mt_safe(address instr_addr, address code_buffer) {
660   assert(((intptr_t)instr_addr & (BytesPerWord-1)) == 0, "requirement for mt safe patching");
661   // Bytes_after_jump cannot change, because we own the Patching_lock.
662   assert(Patching_lock->owned_by_self(), "must hold lock to patch instruction");
663   intptr_t bytes_after_jump = (*(intptr_t*)instr_addr)  & 0x000000000000ffffL; // 2 bytes after jump.
664   intptr_t load_const_bytes = (*(intptr_t*)code_buffer) & 0xffffffffffff0000L;
665   *(intptr_t*)instr_addr = load_const_bytes | bytes_after_jump;
666   ICache::invalidate_range(instr_addr, 6);
667 }
668