1 /*
2 * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
219 nc = nativeCall_at( cb.insts_begin() );
220 nc->print();
221
222 nc = nativeCall_overwriting_at( nc->next_instruction_address() );
223 for (idx = 0; idx < ARRAY_SIZE(offsets); idx++) {
224 nc->set_destination( cb.insts_begin() + offsets[idx] );
225 assert(nc->destination() == (cb.insts_begin() + offsets[idx]), "check unit test");
226 nc->print();
227 }
228
229 nc = nativeCall_before( cb.insts_begin() + 8 );
230 nc->print();
231
232 VM_Version::revert();
233 #endif
234 }
235 // End code for unit testing implementation of NativeCall class
236
237 //-------------------------------------------------------------------
238
239 #ifdef _LP64
240
241 void NativeFarCall::set_destination(address dest) {
242 // Address materialized in the instruction stream, so nothing to do.
243 return;
244 #if 0 // What we'd do if we really did want to change the destination
245 if (destination() == dest) {
246 return;
247 }
248 ResourceMark rm;
249 CodeBuffer buf(addr_at(0), instruction_size + 1);
250 MacroAssembler* _masm = new MacroAssembler(&buf);
251 // Generate the new sequence
252 AddressLiteral(dest);
253 _masm->jumpl_to(dest, O7, O7);
254 ICache::invalidate_range(addr_at(0), instruction_size );
255 #endif
256 }
257
258 void NativeFarCall::verify() {
259 // make sure code pattern is actually a jumpl_to instruction
260 assert((int)instruction_size == (int)NativeJump::instruction_size, "same as jump_to");
273 bool NativeFarCall::destination_is_compiled_verified_entry_point() {
274 nmethod* callee = CodeCache::find_nmethod(destination());
275 if (callee == NULL) {
276 return false;
277 } else {
278 return destination() == callee->verified_entry_point();
279 }
280 }
281
282 // MT-safe patching of a far call.
283 void NativeFarCall::replace_mt_safe(address instr_addr, address code_buffer) {
284 Unimplemented();
285 }
286
287 // Code for unit testing implementation of NativeFarCall class
288 void NativeFarCall::test() {
289 Unimplemented();
290 }
291 // End code for unit testing implementation of NativeFarCall class
292
293 #endif // _LP64
294
295 //-------------------------------------------------------------------
296
297
298 void NativeMovConstReg::verify() {
299 NativeInstruction::verify();
300 // make sure code pattern is actually a "set_metadata" synthetic instruction
301 // see MacroAssembler::set_oop()
302 int i0 = long_at(sethi_offset);
303 int i1 = long_at(add_offset);
304
305 // verify the pattern "sethi %hi22(imm), reg ; add reg, %lo10(imm), reg"
306 Register rd = inv_rd(i0);
307 #ifndef _LP64
308 if (!(is_op2(i0, Assembler::sethi_op2) && rd != G0 &&
309 is_op3(i1, Assembler::add_op3, Assembler::arith_op) &&
310 inv_immed(i1) && (unsigned)get_simm13(i1) < (1 << 10) &&
311 rd == inv_rs1(i1) && rd == inv_rd(i1))) {
312 fatal("not a set_metadata");
313 }
314 #else
315 if (!is_op2(i0, Assembler::sethi_op2) && rd != G0 ) {
316 fatal("not a set_metadata");
317 }
318 #endif
319 }
320
321
322 void NativeMovConstReg::print() {
323 tty->print_cr(INTPTR_FORMAT ": mov reg, " INTPTR_FORMAT, p2i(instruction_address()), data());
324 }
325
326
327 #ifdef _LP64
328 intptr_t NativeMovConstReg::data() const {
329 return data64(addr_at(sethi_offset), long_at(add_offset));
330 }
331 #else
332 intptr_t NativeMovConstReg::data() const {
333 return data32(long_at(sethi_offset), long_at(add_offset));
334 }
335 #endif
336
337
338 void NativeMovConstReg::set_data(intptr_t x) {
339 #ifdef _LP64
340 set_data64_sethi(addr_at(sethi_offset), x);
341 #else
342 set_long_at(sethi_offset, set_data32_sethi( long_at(sethi_offset), x));
343 #endif
344 set_long_at(add_offset, set_data32_simm13( long_at(add_offset), x));
345
346 // also store the value into an oop_Relocation cell, if any
347 CodeBlob* cb = CodeCache::find_blob(instruction_address());
348 nmethod* nm = cb ? cb->as_nmethod_or_null() : NULL;
349 if (nm != NULL) {
350 RelocIterator iter(nm, instruction_address(), next_instruction_address());
351 oop* oop_addr = NULL;
352 Metadata** metadata_addr = NULL;
353 while (iter.next()) {
354 if (iter.type() == relocInfo::oop_type) {
355 oop_Relocation *r = iter.oop_reloc();
356 if (oop_addr == NULL) {
357 oop_addr = r->oop_addr();
358 *oop_addr = cast_to_oop(x);
359 } else {
360 assert(oop_addr == r->oop_addr(), "must be only one set-oop here");
361 }
362 }
363 if (iter.type() == relocInfo::metadata_type) {
491 // The casual reader should note that on Sparc a nop is a special case if sethi
492 // in which the destination register is %g0.
493 Register rd0 = inv_rd(i0);
494 Register rd1 = inv_rd(i1);
495 if (!(is_op2(i0, Assembler::sethi_op2) && rd0 != G0 &&
496 is_op2(i1, Assembler::sethi_op2) && rd1 == G0 && // nop is a special case of sethi
497 is_op3(i2, Assembler::add_op3, Assembler::arith_op) &&
498 inv_immed(i2) && (unsigned)get_simm13(i2) < (1 << 10) &&
499 rd0 == inv_rs1(i2) && rd0 == inv_rd(i2))) {
500 fatal("not a set_metadata");
501 }
502 }
503
504
505 void NativeMovConstRegPatching::print() {
506 tty->print_cr(INTPTR_FORMAT ": mov reg, 0x%x", p2i(instruction_address()), data());
507 }
508
509
510 int NativeMovConstRegPatching::data() const {
511 #ifdef _LP64
512 return data64(addr_at(sethi_offset), long_at(add_offset));
513 #else
514 return data32(long_at(sethi_offset), long_at(add_offset));
515 #endif
516 }
517
518
519 void NativeMovConstRegPatching::set_data(int x) {
520 #ifdef _LP64
521 set_data64_sethi(addr_at(sethi_offset), x);
522 #else
523 set_long_at(sethi_offset, set_data32_sethi(long_at(sethi_offset), x));
524 #endif
525 set_long_at(add_offset, set_data32_simm13(long_at(add_offset), x));
526
527 // also store the value into an oop_Relocation cell, if any
528 CodeBlob* cb = CodeCache::find_blob(instruction_address());
529 nmethod* nm = cb ? cb->as_nmethod_or_null() : NULL;
530 if (nm != NULL) {
531 RelocIterator iter(nm, instruction_address(), next_instruction_address());
532 oop* oop_addr = NULL;
533 Metadata** metadata_addr = NULL;
534 while (iter.next()) {
535 if (iter.type() == relocInfo::oop_type) {
536 oop_Relocation *r = iter.oop_reloc();
537 if (oop_addr == NULL) {
538 oop_addr = r->oop_addr();
539 *oop_addr = cast_to_oop(x);
540 } else {
541 assert(oop_addr == r->oop_addr(), "must be only one set-oop here");
542 }
543 }
544 if (iter.type() == relocInfo::metadata_type) {
741 nm->print();
742 }
743
744 VM_Version::revert();
745 #endif // ASSERT
746 }
747
748 // End code for unit testing implementation of NativeMovRegMem class
749
750
751 //--------------------------------------------------------------------------------
752
753
754 void NativeJump::verify() {
755 NativeInstruction::verify();
756 int i0 = long_at(sethi_offset);
757 int i1 = long_at(jmpl_offset);
758 assert((int)jmpl_offset == (int)NativeMovConstReg::add_offset, "sethi size ok");
759 // verify the pattern "sethi %hi22(imm), treg ; jmpl treg, %lo10(imm), lreg"
760 Register rd = inv_rd(i0);
761 #ifndef _LP64
762 if (!(is_op2(i0, Assembler::sethi_op2) && rd != G0 &&
763 (is_op3(i1, Assembler::jmpl_op3, Assembler::arith_op)) &&
764 inv_immed(i1) && (unsigned)get_simm13(i1) < (1 << 10) &&
765 rd == inv_rs1(i1))) {
766 fatal("not a jump_to instruction");
767 }
768 #else
769 // In LP64, the jump instruction location varies for non relocatable
770 // jumps, for example is could be sethi, xor, jmp instead of the
771 // 7 instructions for sethi. So let's check sethi only.
772 if (!is_op2(i0, Assembler::sethi_op2) && rd != G0 ) {
773 fatal("not a jump_to instruction");
774 }
775 #endif
776 }
777
778
779 void NativeJump::print() {
780 tty->print_cr(INTPTR_FORMAT ": jmpl reg, " INTPTR_FORMAT, p2i(instruction_address()), p2i(jump_destination()));
781 }
782
783
784 // Code for unit testing implementation of NativeJump class
785 void NativeJump::test() {
786 #ifdef ASSERT
787 ResourceMark rm;
788 CodeBuffer cb("test", 100, 100);
789 MacroAssembler* a = new MacroAssembler(&cb);
790 NativeJump* nj;
791 uint idx;
792 int offsets[] = {
793 0x0,
794 0xffffffff,
795 0x7fffffff,
|
1 /*
2 * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
219 nc = nativeCall_at( cb.insts_begin() );
220 nc->print();
221
222 nc = nativeCall_overwriting_at( nc->next_instruction_address() );
223 for (idx = 0; idx < ARRAY_SIZE(offsets); idx++) {
224 nc->set_destination( cb.insts_begin() + offsets[idx] );
225 assert(nc->destination() == (cb.insts_begin() + offsets[idx]), "check unit test");
226 nc->print();
227 }
228
229 nc = nativeCall_before( cb.insts_begin() + 8 );
230 nc->print();
231
232 VM_Version::revert();
233 #endif
234 }
235 // End code for unit testing implementation of NativeCall class
236
237 //-------------------------------------------------------------------
238
239 void NativeFarCall::set_destination(address dest) {
240 // Address materialized in the instruction stream, so nothing to do.
241 return;
242 #if 0 // What we'd do if we really did want to change the destination
243 if (destination() == dest) {
244 return;
245 }
246 ResourceMark rm;
247 CodeBuffer buf(addr_at(0), instruction_size + 1);
248 MacroAssembler* _masm = new MacroAssembler(&buf);
249 // Generate the new sequence
250 AddressLiteral(dest);
251 _masm->jumpl_to(dest, O7, O7);
252 ICache::invalidate_range(addr_at(0), instruction_size );
253 #endif
254 }
255
256 void NativeFarCall::verify() {
257 // make sure code pattern is actually a jumpl_to instruction
258 assert((int)instruction_size == (int)NativeJump::instruction_size, "same as jump_to");
271 bool NativeFarCall::destination_is_compiled_verified_entry_point() {
272 nmethod* callee = CodeCache::find_nmethod(destination());
273 if (callee == NULL) {
274 return false;
275 } else {
276 return destination() == callee->verified_entry_point();
277 }
278 }
279
280 // MT-safe patching of a far call.
281 void NativeFarCall::replace_mt_safe(address instr_addr, address code_buffer) {
282 Unimplemented();
283 }
284
285 // Code for unit testing implementation of NativeFarCall class
286 void NativeFarCall::test() {
287 Unimplemented();
288 }
289 // End code for unit testing implementation of NativeFarCall class
290
291 //-------------------------------------------------------------------
292
293
294 void NativeMovConstReg::verify() {
295 NativeInstruction::verify();
296 // make sure code pattern is actually a "set_metadata" synthetic instruction
297 // see MacroAssembler::set_oop()
298 int i0 = long_at(sethi_offset);
299 int i1 = long_at(add_offset);
300
301 // verify the pattern "sethi %hi22(imm), reg ; add reg, %lo10(imm), reg"
302 Register rd = inv_rd(i0);
303 if (!is_op2(i0, Assembler::sethi_op2) && rd != G0 ) {
304 fatal("not a set_metadata");
305 }
306 }
307
308
309 void NativeMovConstReg::print() {
310 tty->print_cr(INTPTR_FORMAT ": mov reg, " INTPTR_FORMAT, p2i(instruction_address()), data());
311 }
312
313
314 intptr_t NativeMovConstReg::data() const {
315 return data64(addr_at(sethi_offset), long_at(add_offset));
316 }
317
318
319 void NativeMovConstReg::set_data(intptr_t x) {
320 set_data64_sethi(addr_at(sethi_offset), x);
321 set_long_at(add_offset, set_data32_simm13( long_at(add_offset), x));
322
323 // also store the value into an oop_Relocation cell, if any
324 CodeBlob* cb = CodeCache::find_blob(instruction_address());
325 nmethod* nm = cb ? cb->as_nmethod_or_null() : NULL;
326 if (nm != NULL) {
327 RelocIterator iter(nm, instruction_address(), next_instruction_address());
328 oop* oop_addr = NULL;
329 Metadata** metadata_addr = NULL;
330 while (iter.next()) {
331 if (iter.type() == relocInfo::oop_type) {
332 oop_Relocation *r = iter.oop_reloc();
333 if (oop_addr == NULL) {
334 oop_addr = r->oop_addr();
335 *oop_addr = cast_to_oop(x);
336 } else {
337 assert(oop_addr == r->oop_addr(), "must be only one set-oop here");
338 }
339 }
340 if (iter.type() == relocInfo::metadata_type) {
468 // The casual reader should note that on Sparc a nop is a special case if sethi
469 // in which the destination register is %g0.
470 Register rd0 = inv_rd(i0);
471 Register rd1 = inv_rd(i1);
472 if (!(is_op2(i0, Assembler::sethi_op2) && rd0 != G0 &&
473 is_op2(i1, Assembler::sethi_op2) && rd1 == G0 && // nop is a special case of sethi
474 is_op3(i2, Assembler::add_op3, Assembler::arith_op) &&
475 inv_immed(i2) && (unsigned)get_simm13(i2) < (1 << 10) &&
476 rd0 == inv_rs1(i2) && rd0 == inv_rd(i2))) {
477 fatal("not a set_metadata");
478 }
479 }
480
481
482 void NativeMovConstRegPatching::print() {
483 tty->print_cr(INTPTR_FORMAT ": mov reg, 0x%x", p2i(instruction_address()), data());
484 }
485
486
487 int NativeMovConstRegPatching::data() const {
488 return data64(addr_at(sethi_offset), long_at(add_offset));
489 }
490
491
492 void NativeMovConstRegPatching::set_data(int x) {
493 set_data64_sethi(addr_at(sethi_offset), x);
494 set_long_at(add_offset, set_data32_simm13(long_at(add_offset), x));
495
496 // also store the value into an oop_Relocation cell, if any
497 CodeBlob* cb = CodeCache::find_blob(instruction_address());
498 nmethod* nm = cb ? cb->as_nmethod_or_null() : NULL;
499 if (nm != NULL) {
500 RelocIterator iter(nm, instruction_address(), next_instruction_address());
501 oop* oop_addr = NULL;
502 Metadata** metadata_addr = NULL;
503 while (iter.next()) {
504 if (iter.type() == relocInfo::oop_type) {
505 oop_Relocation *r = iter.oop_reloc();
506 if (oop_addr == NULL) {
507 oop_addr = r->oop_addr();
508 *oop_addr = cast_to_oop(x);
509 } else {
510 assert(oop_addr == r->oop_addr(), "must be only one set-oop here");
511 }
512 }
513 if (iter.type() == relocInfo::metadata_type) {
710 nm->print();
711 }
712
713 VM_Version::revert();
714 #endif // ASSERT
715 }
716
717 // End code for unit testing implementation of NativeMovRegMem class
718
719
720 //--------------------------------------------------------------------------------
721
722
723 void NativeJump::verify() {
724 NativeInstruction::verify();
725 int i0 = long_at(sethi_offset);
726 int i1 = long_at(jmpl_offset);
727 assert((int)jmpl_offset == (int)NativeMovConstReg::add_offset, "sethi size ok");
728 // verify the pattern "sethi %hi22(imm), treg ; jmpl treg, %lo10(imm), lreg"
729 Register rd = inv_rd(i0);
730 // In LP64, the jump instruction location varies for non relocatable
731 // jumps, for example is could be sethi, xor, jmp instead of the
732 // 7 instructions for sethi. So let's check sethi only.
733 if (!is_op2(i0, Assembler::sethi_op2) && rd != G0 ) {
734 fatal("not a jump_to instruction");
735 }
736 }
737
738
739 void NativeJump::print() {
740 tty->print_cr(INTPTR_FORMAT ": jmpl reg, " INTPTR_FORMAT, p2i(instruction_address()), p2i(jump_destination()));
741 }
742
743
744 // Code for unit testing implementation of NativeJump class
745 void NativeJump::test() {
746 #ifdef ASSERT
747 ResourceMark rm;
748 CodeBuffer cb("test", 100, 100);
749 MacroAssembler* a = new MacroAssembler(&cb);
750 NativeJump* nj;
751 uint idx;
752 int offsets[] = {
753 0x0,
754 0xffffffff,
755 0x7fffffff,
|