< prev index next >

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp

Print this page

   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 #include "asm/assembler.hpp"
  27 #include "asm/assembler.inline.hpp"
  28 #include "ci/ciEnv.hpp"

  29 #include "code/compiledIC.hpp"
  30 #include "compiler/compileTask.hpp"
  31 #include "compiler/disassembler.hpp"
  32 #include "compiler/oopMap.hpp"
  33 #include "gc/shared/barrierSet.hpp"
  34 #include "gc/shared/barrierSetAssembler.hpp"
  35 #include "gc/shared/cardTableBarrierSet.hpp"
  36 #include "gc/shared/cardTable.hpp"
  37 #include "gc/shared/collectedHeap.hpp"
  38 #include "gc/shared/tlab_globals.hpp"
  39 #include "interpreter/bytecodeHistogram.hpp"
  40 #include "interpreter/interpreter.hpp"
  41 #include "interpreter/interpreterRuntime.hpp"
  42 #include "jvm.h"
  43 #include "memory/resourceArea.hpp"
  44 #include "memory/universe.hpp"
  45 #include "nativeInst_aarch64.hpp"
  46 #include "oops/accessDecorators.hpp"
  47 #include "oops/compressedKlass.inline.hpp"
  48 #include "oops/compressedOops.inline.hpp"

 331     uint32_t insn2 = insn_at(insn_addr, 1);
 332     uint32_t size = Instruction_aarch64::extract(insn2, 31, 30);
 333     Instruction_aarch64::patch(insn_addr + sizeof (uint32_t), 21, 10, offset_lo >> size);
 334     guarantee(((dest >> size) << size) == dest, "misaligned target");
 335     return 2;
 336   }
 337   static int adrpAdd_impl(address insn_addr, address &target) {
 338     uintptr_t dest = (uintptr_t)target;
 339     int offset_lo = dest & 0xfff;
 340     Instruction_aarch64::patch(insn_addr + sizeof (uint32_t), 21, 10, offset_lo);
 341     return 2;
 342   }
 343   static int adrpMovk_impl(address insn_addr, address &target) {
 344     uintptr_t dest = uintptr_t(target);
 345     Instruction_aarch64::patch(insn_addr + sizeof (uint32_t), 20, 5, (uintptr_t)target >> 32);
 346     dest = (dest & 0xffffffffULL) | (uintptr_t(insn_addr) & 0xffff00000000ULL);
 347     target = address(dest);
 348     return 2;
 349   }
 350   virtual int immediate(address insn_addr, address &target) {










 351     assert(Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010100, "must be");
 352     uint64_t dest = (uint64_t)target;
 353     // Move wide constant
 354     assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
 355     assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");
 356     Instruction_aarch64::patch(insn_addr, 20, 5, dest & 0xffff);
 357     Instruction_aarch64::patch(insn_addr+4, 20, 5, (dest >>= 16) & 0xffff);
 358     Instruction_aarch64::patch(insn_addr+8, 20, 5, (dest >>= 16) & 0xffff);
 359     return 3;
 360   }
 361   virtual void verify(address insn_addr, address &target) {
 362 #ifdef ASSERT
 363     address address_is = MacroAssembler::target_addr_for_insn(insn_addr);
 364     if (!(address_is == target)) {
 365       tty->print_cr("%p at %p should be %p", address_is, insn_addr, target);
 366       disnm((intptr_t)insn_addr);
 367       assert(address_is == target, "should be");
 368     }
 369 #endif
 370   }

 461     uint32_t insn2 = insn_at(insn_addr, 1);
 462     uint64_t dest = uint64_t(target);
 463     dest = (dest & 0xffff0000ffffffff) |
 464       ((uint64_t)Instruction_aarch64::extract(insn2, 20, 5) << 32);
 465     target = address(dest);
 466 
 467     // We know the destination 4k page. Maybe we have a third
 468     // instruction.
 469     uint32_t insn = insn_at(insn_addr, 0);
 470     uint32_t insn3 = insn_at(insn_addr, 2);
 471     ptrdiff_t byte_offset;
 472     if (offset_for(insn, insn3, byte_offset)) {
 473       target += byte_offset;
 474       return 3;
 475     } else {
 476       return 2;
 477     }
 478   }
 479   virtual int immediate(address insn_addr, address &target) {
 480     uint32_t *insns = (uint32_t *)insn_addr;










 481     assert(Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010100, "must be");
 482     // Move wide constant: movz, movk, movk.  See movptr().
 483     assert(nativeInstruction_at(insns+1)->is_movk(), "wrong insns in patch");
 484     assert(nativeInstruction_at(insns+2)->is_movk(), "wrong insns in patch");
 485     target = address(uint64_t(Instruction_aarch64::extract(_insn, 20, 5))
 486                  + (uint64_t(Instruction_aarch64::extract(insns[1], 20, 5)) << 16)
 487                  + (uint64_t(Instruction_aarch64::extract(insns[2], 20, 5)) << 32));
 488     assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
 489     assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");
 490     return 3;
 491   }
 492   virtual void verify(address insn_addr, address &target) {
 493   }
 494 };
 495 
 496 address MacroAssembler::target_addr_for_insn(address insn_addr, uint32_t insn) {
 497   AArch64Decoder decoder(insn_addr, insn);
 498   address target;
 499   decoder.run(insn_addr, target);
 500   return target;

3324 
3325 void MacroAssembler::sub(Register Rd, Register Rn, RegisterOrConstant decrement) {
3326   if (decrement.is_register()) {
3327     sub(Rd, Rn, decrement.as_register());
3328   } else {
3329     sub(Rd, Rn, decrement.as_constant());
3330   }
3331 }
3332 
3333 void MacroAssembler::subw(Register Rd, Register Rn, RegisterOrConstant decrement) {
3334   if (decrement.is_register()) {
3335     subw(Rd, Rn, decrement.as_register());
3336   } else {
3337     subw(Rd, Rn, decrement.as_constant());
3338   }
3339 }
3340 
3341 void MacroAssembler::reinit_heapbase()
3342 {
3343   if (UseCompressedOops) {
3344     if (Universe::is_fully_initialized()) {
3345       mov(rheapbase, CompressedOops::base());
3346     } else {
3347       lea(rheapbase, ExternalAddress(CompressedOops::base_addr()));
3348       ldr(rheapbase, Address(rheapbase));
3349     }
3350   }
3351 }
3352 
3353 // this simulates the behaviour of the x86 cmpxchg instruction using a
3354 // load linked/store conditional pair. we use the acquire/release
3355 // versions of these instructions so that we flush pending writes as
3356 // per Java semantics.
3357 
3358 // n.b the x86 version assumes the old value to be compared against is
3359 // in rax and updates rax with the value located in memory if the
3360 // cmpxchg fails. we supply a register for the old value explicitly
3361 
3362 // the aarch64 load linked/store conditional instructions do not
3363 // accept an offset. so, unlike x86, we must provide a plain register
3364 // to identify the memory word to be compared/exchanged rather than a

5094 void MacroAssembler::load_mirror(Register dst, Register method, Register tmp1, Register tmp2) {
5095   const int mirror_offset = in_bytes(Klass::java_mirror_offset());
5096   ldr(dst, Address(rmethod, Method::const_offset()));
5097   ldr(dst, Address(dst, ConstMethod::constants_offset()));
5098   ldr(dst, Address(dst, ConstantPool::pool_holder_offset()));
5099   ldr(dst, Address(dst, mirror_offset));
5100   resolve_oop_handle(dst, tmp1, tmp2);
5101 }
5102 
5103 void MacroAssembler::cmp_klass(Register obj, Register klass, Register tmp) {
5104   assert_different_registers(obj, klass, tmp);
5105   if (UseCompressedClassPointers) {
5106     if (UseCompactObjectHeaders) {
5107       load_narrow_klass_compact(tmp, obj);
5108     } else {
5109       ldrw(tmp, Address(obj, oopDesc::klass_offset_in_bytes()));
5110     }
5111     if (CompressedKlassPointers::base() == nullptr) {
5112       cmp(klass, tmp, LSL, CompressedKlassPointers::shift());
5113       return;
5114     } else if (((uint64_t)CompressedKlassPointers::base() & 0xffffffff) == 0

5115                && CompressedKlassPointers::shift() == 0) {
5116       // Only the bottom 32 bits matter
5117       cmpw(klass, tmp);
5118       return;
5119     }
5120     decode_klass_not_null(tmp);
5121   } else {
5122     ldr(tmp, Address(obj, oopDesc::klass_offset_in_bytes()));
5123   }
5124   cmp(klass, tmp);
5125 }
5126 
5127 void MacroAssembler::cmp_klasses_from_objects(Register obj1, Register obj2, Register tmp1, Register tmp2) {
5128   if (UseCompactObjectHeaders) {
5129     load_narrow_klass_compact(tmp1, obj1);
5130     load_narrow_klass_compact(tmp2,  obj2);
5131     cmpw(tmp1, tmp2);
5132   } else if (UseCompressedClassPointers) {
5133     ldrw(tmp1, Address(obj1, oopDesc::klass_offset_in_bytes()));
5134     ldrw(tmp2, Address(obj2, oopDesc::klass_offset_in_bytes()));

5353   if (dst != src) {
5354     // we can load the base into dst, subtract it formthe src and shift down
5355     lea(dst, ExternalAddress(CompressedKlassPointers::base_addr()));
5356     ldr(dst, dst);
5357     sub(dst, src, dst);
5358     lsr(dst, dst, shift);
5359   } else {
5360     // we need an extra register in order to load the coop base
5361     Register tmp = pick_different_tmp(dst, src);
5362     RegSet regs = RegSet::of(tmp);
5363     push(regs, sp);
5364     lea(tmp, ExternalAddress(CompressedKlassPointers::base_addr()));
5365     ldr(tmp, tmp);
5366     sub(dst, src, tmp);
5367     lsr(dst, dst, shift);
5368     pop(regs, sp);
5369   }
5370 }
5371 
5372 void MacroAssembler::encode_klass_not_null(Register dst, Register src) {
5373   if (AOTCodeCache::is_on_for_dump()) {
5374     encode_klass_not_null_for_aot(dst, src);
5375     return;
5376   }
5377 
5378   switch (klass_decode_mode()) {
5379   case KlassDecodeZero:
5380     if (CompressedKlassPointers::shift() != 0) {
5381       lsr(dst, src, CompressedKlassPointers::shift());
5382     } else {
5383       if (dst != src) mov(dst, src);
5384     }
5385     break;
5386 
5387   case KlassDecodeXor:
5388     if (CompressedKlassPointers::shift() != 0) {
5389       eor(dst, src, (uint64_t)CompressedKlassPointers::base());
5390       lsr(dst, dst, CompressedKlassPointers::shift());
5391     } else {
5392       eor(dst, src, (uint64_t)CompressedKlassPointers::base());
5393     }

5419   if (dst != src) {
5420     // we can load the base into dst then add the offset with a suitable shift
5421     lea(dst, ExternalAddress(CompressedKlassPointers::base_addr()));
5422     ldr(dst, dst);
5423     add(dst, dst, src, LSL,  shift);
5424   } else {
5425     // we need an extra register in order to load the coop base
5426     Register tmp = pick_different_tmp(dst, src);
5427     RegSet regs = RegSet::of(tmp);
5428     push(regs, sp);
5429     lea(tmp, ExternalAddress(CompressedKlassPointers::base_addr()));
5430     ldr(tmp, tmp);
5431     add(dst, tmp,  src, LSL,  shift);
5432     pop(regs, sp);
5433   }
5434 }
5435 
5436 void  MacroAssembler::decode_klass_not_null(Register dst, Register src) {
5437   assert (UseCompressedClassPointers, "should only be used for compressed headers");
5438 
5439   if (AOTCodeCache::is_on_for_dump()) {
5440     decode_klass_not_null_for_aot(dst, src);
5441     return;
5442   }
5443 
5444   switch (klass_decode_mode()) {
5445   case KlassDecodeZero:
5446     if (CompressedKlassPointers::shift() != 0) {
5447       lsl(dst, src, CompressedKlassPointers::shift());
5448     } else {
5449       if (dst != src) mov(dst, src);
5450     }
5451     break;
5452 
5453   case KlassDecodeXor:
5454     if (CompressedKlassPointers::shift() != 0) {
5455       lsl(dst, src, CompressedKlassPointers::shift());
5456       eor(dst, dst, (uint64_t)CompressedKlassPointers::base());
5457     } else {
5458       eor(dst, src, (uint64_t)CompressedKlassPointers::base());
5459     }

5753   // the code cache so that if it is relocated we know it will still reach
5754   if (offset_high >= -(1<<20) && offset_low < (1<<20)) {
5755     _adrp(reg1, dest.target());
5756   } else {
5757     uint64_t target = (uint64_t)dest.target();
5758     uint64_t adrp_target
5759       = (target & 0xffffffffULL) | ((uint64_t)pc() & 0xffff00000000ULL);
5760 
5761     _adrp(reg1, (address)adrp_target);
5762     movk(reg1, target >> 32, 32);
5763   }
5764   byte_offset = (uint64_t)dest.target() & 0xfff;
5765 }
5766 
5767 void MacroAssembler::load_byte_map_base(Register reg) {
5768   CardTable::CardValue* byte_map_base =
5769     ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base();
5770 
5771   // Strictly speaking the byte_map_base isn't an address at all, and it might
5772   // even be negative. It is thus materialised as a constant.
5773   mov(reg, (uint64_t)byte_map_base);























5774 }
5775 
5776 void MacroAssembler::build_frame(int framesize) {
5777   assert(framesize >= 2 * wordSize, "framesize must include space for FP/LR");
5778   assert(framesize % (2*wordSize) == 0, "must preserve 2*wordSize alignment");
5779   protect_return_address();
5780   if (framesize < ((1 << 9) + 2 * wordSize)) {
5781     sub(sp, sp, framesize);
5782     stp(rfp, lr, Address(sp, framesize - 2 * wordSize));
5783     if (PreserveFramePointer) add(rfp, sp, framesize - 2 * wordSize);
5784   } else {
5785     stp(rfp, lr, Address(pre(sp, -2 * wordSize)));
5786     if (PreserveFramePointer) mov(rfp, sp);
5787     if (framesize < ((1 << 12) + 2 * wordSize))
5788       sub(sp, sp, framesize - 2 * wordSize);
5789     else {
5790       mov(rscratch1, framesize - 2 * wordSize);
5791       sub(sp, sp, rscratch1);
5792     }
5793   }

   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 #include "asm/assembler.hpp"
  27 #include "asm/assembler.inline.hpp"
  28 #include "ci/ciEnv.hpp"
  29 #include "ci/ciUtilities.hpp"
  30 #include "code/compiledIC.hpp"
  31 #include "compiler/compileTask.hpp"
  32 #include "compiler/disassembler.hpp"
  33 #include "compiler/oopMap.hpp"
  34 #include "gc/shared/barrierSet.hpp"
  35 #include "gc/shared/barrierSetAssembler.hpp"
  36 #include "gc/shared/cardTableBarrierSet.hpp"
  37 #include "gc/shared/cardTable.hpp"
  38 #include "gc/shared/collectedHeap.hpp"
  39 #include "gc/shared/tlab_globals.hpp"
  40 #include "interpreter/bytecodeHistogram.hpp"
  41 #include "interpreter/interpreter.hpp"
  42 #include "interpreter/interpreterRuntime.hpp"
  43 #include "jvm.h"
  44 #include "memory/resourceArea.hpp"
  45 #include "memory/universe.hpp"
  46 #include "nativeInst_aarch64.hpp"
  47 #include "oops/accessDecorators.hpp"
  48 #include "oops/compressedKlass.inline.hpp"
  49 #include "oops/compressedOops.inline.hpp"

 332     uint32_t insn2 = insn_at(insn_addr, 1);
 333     uint32_t size = Instruction_aarch64::extract(insn2, 31, 30);
 334     Instruction_aarch64::patch(insn_addr + sizeof (uint32_t), 21, 10, offset_lo >> size);
 335     guarantee(((dest >> size) << size) == dest, "misaligned target");
 336     return 2;
 337   }
 338   static int adrpAdd_impl(address insn_addr, address &target) {
 339     uintptr_t dest = (uintptr_t)target;
 340     int offset_lo = dest & 0xfff;
 341     Instruction_aarch64::patch(insn_addr + sizeof (uint32_t), 21, 10, offset_lo);
 342     return 2;
 343   }
 344   static int adrpMovk_impl(address insn_addr, address &target) {
 345     uintptr_t dest = uintptr_t(target);
 346     Instruction_aarch64::patch(insn_addr + sizeof (uint32_t), 20, 5, (uintptr_t)target >> 32);
 347     dest = (dest & 0xffffffffULL) | (uintptr_t(insn_addr) & 0xffff00000000ULL);
 348     target = address(dest);
 349     return 2;
 350   }
 351   virtual int immediate(address insn_addr, address &target) {
 352     // Metadata pointers are either narrow (32 bits) or wide (48 bits).
 353     // We encode narrow ones by setting the upper 16 bits in the first
 354     // instruction.
 355     if (Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010101) {
 356       assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
 357       narrowKlass nk = CompressedKlassPointers::encode((Klass*)target);
 358       Instruction_aarch64::patch(insn_addr, 20, 5, nk >> 16);
 359       Instruction_aarch64::patch(insn_addr+4, 20, 5, nk & 0xffff);
 360       return 2;
 361     }
 362     assert(Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010100, "must be");
 363     uint64_t dest = (uint64_t)target;
 364     // Move wide constant
 365     assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
 366     assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");
 367     Instruction_aarch64::patch(insn_addr, 20, 5, dest & 0xffff);
 368     Instruction_aarch64::patch(insn_addr+4, 20, 5, (dest >>= 16) & 0xffff);
 369     Instruction_aarch64::patch(insn_addr+8, 20, 5, (dest >>= 16) & 0xffff);
 370     return 3;
 371   }
 372   virtual void verify(address insn_addr, address &target) {
 373 #ifdef ASSERT
 374     address address_is = MacroAssembler::target_addr_for_insn(insn_addr);
 375     if (!(address_is == target)) {
 376       tty->print_cr("%p at %p should be %p", address_is, insn_addr, target);
 377       disnm((intptr_t)insn_addr);
 378       assert(address_is == target, "should be");
 379     }
 380 #endif
 381   }

 472     uint32_t insn2 = insn_at(insn_addr, 1);
 473     uint64_t dest = uint64_t(target);
 474     dest = (dest & 0xffff0000ffffffff) |
 475       ((uint64_t)Instruction_aarch64::extract(insn2, 20, 5) << 32);
 476     target = address(dest);
 477 
 478     // We know the destination 4k page. Maybe we have a third
 479     // instruction.
 480     uint32_t insn = insn_at(insn_addr, 0);
 481     uint32_t insn3 = insn_at(insn_addr, 2);
 482     ptrdiff_t byte_offset;
 483     if (offset_for(insn, insn3, byte_offset)) {
 484       target += byte_offset;
 485       return 3;
 486     } else {
 487       return 2;
 488     }
 489   }
 490   virtual int immediate(address insn_addr, address &target) {
 491     uint32_t *insns = (uint32_t *)insn_addr;
 492     // Metadata pointers are either narrow (32 bits) or wide (48 bits).
 493     // We encode narrow ones by setting the upper 16 bits in the first
 494     // instruction.
 495     if (Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010101) {
 496       assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
 497       narrowKlass nk = (narrowKlass)((uint32_t(Instruction_aarch64::extract(_insn, 20, 5)) << 16)
 498                                    +  uint32_t(Instruction_aarch64::extract(insns[1], 20, 5)));
 499       target = (address)CompressedKlassPointers::decode(nk);
 500       return 2;
 501     }
 502     assert(Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010100, "must be");
 503     // Move wide constant: movz, movk, movk.  See movptr().
 504     assert(nativeInstruction_at(insns+1)->is_movk(), "wrong insns in patch");
 505     assert(nativeInstruction_at(insns+2)->is_movk(), "wrong insns in patch");
 506     target = address(uint64_t(Instruction_aarch64::extract(_insn, 20, 5))
 507                  + (uint64_t(Instruction_aarch64::extract(insns[1], 20, 5)) << 16)
 508                  + (uint64_t(Instruction_aarch64::extract(insns[2], 20, 5)) << 32));
 509     assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
 510     assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");
 511     return 3;
 512   }
 513   virtual void verify(address insn_addr, address &target) {
 514   }
 515 };
 516 
 517 address MacroAssembler::target_addr_for_insn(address insn_addr, uint32_t insn) {
 518   AArch64Decoder decoder(insn_addr, insn);
 519   address target;
 520   decoder.run(insn_addr, target);
 521   return target;

3345 
3346 void MacroAssembler::sub(Register Rd, Register Rn, RegisterOrConstant decrement) {
3347   if (decrement.is_register()) {
3348     sub(Rd, Rn, decrement.as_register());
3349   } else {
3350     sub(Rd, Rn, decrement.as_constant());
3351   }
3352 }
3353 
3354 void MacroAssembler::subw(Register Rd, Register Rn, RegisterOrConstant decrement) {
3355   if (decrement.is_register()) {
3356     subw(Rd, Rn, decrement.as_register());
3357   } else {
3358     subw(Rd, Rn, decrement.as_constant());
3359   }
3360 }
3361 
3362 void MacroAssembler::reinit_heapbase()
3363 {
3364   if (UseCompressedOops) {
3365     if (Universe::is_fully_initialized() && !AOTCodeCache::is_on_for_dump()) {
3366       mov(rheapbase, CompressedOops::base());
3367     } else {
3368       lea(rheapbase, ExternalAddress(CompressedOops::base_addr()));
3369       ldr(rheapbase, Address(rheapbase));
3370     }
3371   }
3372 }
3373 
3374 // this simulates the behaviour of the x86 cmpxchg instruction using a
3375 // load linked/store conditional pair. we use the acquire/release
3376 // versions of these instructions so that we flush pending writes as
3377 // per Java semantics.
3378 
3379 // n.b the x86 version assumes the old value to be compared against is
3380 // in rax and updates rax with the value located in memory if the
3381 // cmpxchg fails. we supply a register for the old value explicitly
3382 
3383 // the aarch64 load linked/store conditional instructions do not
3384 // accept an offset. so, unlike x86, we must provide a plain register
3385 // to identify the memory word to be compared/exchanged rather than a

5115 void MacroAssembler::load_mirror(Register dst, Register method, Register tmp1, Register tmp2) {
5116   const int mirror_offset = in_bytes(Klass::java_mirror_offset());
5117   ldr(dst, Address(rmethod, Method::const_offset()));
5118   ldr(dst, Address(dst, ConstMethod::constants_offset()));
5119   ldr(dst, Address(dst, ConstantPool::pool_holder_offset()));
5120   ldr(dst, Address(dst, mirror_offset));
5121   resolve_oop_handle(dst, tmp1, tmp2);
5122 }
5123 
5124 void MacroAssembler::cmp_klass(Register obj, Register klass, Register tmp) {
5125   assert_different_registers(obj, klass, tmp);
5126   if (UseCompressedClassPointers) {
5127     if (UseCompactObjectHeaders) {
5128       load_narrow_klass_compact(tmp, obj);
5129     } else {
5130       ldrw(tmp, Address(obj, oopDesc::klass_offset_in_bytes()));
5131     }
5132     if (CompressedKlassPointers::base() == nullptr) {
5133       cmp(klass, tmp, LSL, CompressedKlassPointers::shift());
5134       return;
5135     } else if (!AOTCodeCache::is_on_for_dump() &&
5136                ((uint64_t)CompressedKlassPointers::base() & 0xffffffff) == 0
5137                && CompressedKlassPointers::shift() == 0) {
5138       // Only the bottom 32 bits matter
5139       cmpw(klass, tmp);
5140       return;
5141     }
5142     decode_klass_not_null(tmp);
5143   } else {
5144     ldr(tmp, Address(obj, oopDesc::klass_offset_in_bytes()));
5145   }
5146   cmp(klass, tmp);
5147 }
5148 
5149 void MacroAssembler::cmp_klasses_from_objects(Register obj1, Register obj2, Register tmp1, Register tmp2) {
5150   if (UseCompactObjectHeaders) {
5151     load_narrow_klass_compact(tmp1, obj1);
5152     load_narrow_klass_compact(tmp2,  obj2);
5153     cmpw(tmp1, tmp2);
5154   } else if (UseCompressedClassPointers) {
5155     ldrw(tmp1, Address(obj1, oopDesc::klass_offset_in_bytes()));
5156     ldrw(tmp2, Address(obj2, oopDesc::klass_offset_in_bytes()));

5375   if (dst != src) {
5376     // we can load the base into dst, subtract it formthe src and shift down
5377     lea(dst, ExternalAddress(CompressedKlassPointers::base_addr()));
5378     ldr(dst, dst);
5379     sub(dst, src, dst);
5380     lsr(dst, dst, shift);
5381   } else {
5382     // we need an extra register in order to load the coop base
5383     Register tmp = pick_different_tmp(dst, src);
5384     RegSet regs = RegSet::of(tmp);
5385     push(regs, sp);
5386     lea(tmp, ExternalAddress(CompressedKlassPointers::base_addr()));
5387     ldr(tmp, tmp);
5388     sub(dst, src, tmp);
5389     lsr(dst, dst, shift);
5390     pop(regs, sp);
5391   }
5392 }
5393 
5394 void MacroAssembler::encode_klass_not_null(Register dst, Register src) {
5395   if (CompressedKlassPointers::base() != nullptr && AOTCodeCache::is_on_for_dump()) {
5396     encode_klass_not_null_for_aot(dst, src);
5397     return;
5398   }
5399 
5400   switch (klass_decode_mode()) {
5401   case KlassDecodeZero:
5402     if (CompressedKlassPointers::shift() != 0) {
5403       lsr(dst, src, CompressedKlassPointers::shift());
5404     } else {
5405       if (dst != src) mov(dst, src);
5406     }
5407     break;
5408 
5409   case KlassDecodeXor:
5410     if (CompressedKlassPointers::shift() != 0) {
5411       eor(dst, src, (uint64_t)CompressedKlassPointers::base());
5412       lsr(dst, dst, CompressedKlassPointers::shift());
5413     } else {
5414       eor(dst, src, (uint64_t)CompressedKlassPointers::base());
5415     }

5441   if (dst != src) {
5442     // we can load the base into dst then add the offset with a suitable shift
5443     lea(dst, ExternalAddress(CompressedKlassPointers::base_addr()));
5444     ldr(dst, dst);
5445     add(dst, dst, src, LSL,  shift);
5446   } else {
5447     // we need an extra register in order to load the coop base
5448     Register tmp = pick_different_tmp(dst, src);
5449     RegSet regs = RegSet::of(tmp);
5450     push(regs, sp);
5451     lea(tmp, ExternalAddress(CompressedKlassPointers::base_addr()));
5452     ldr(tmp, tmp);
5453     add(dst, tmp,  src, LSL,  shift);
5454     pop(regs, sp);
5455   }
5456 }
5457 
5458 void  MacroAssembler::decode_klass_not_null(Register dst, Register src) {
5459   assert (UseCompressedClassPointers, "should only be used for compressed headers");
5460 
5461   if (CompressedKlassPointers::base() != nullptr && AOTCodeCache::is_on_for_dump()) {
5462     decode_klass_not_null_for_aot(dst, src);
5463     return;
5464   }
5465 
5466   switch (klass_decode_mode()) {
5467   case KlassDecodeZero:
5468     if (CompressedKlassPointers::shift() != 0) {
5469       lsl(dst, src, CompressedKlassPointers::shift());
5470     } else {
5471       if (dst != src) mov(dst, src);
5472     }
5473     break;
5474 
5475   case KlassDecodeXor:
5476     if (CompressedKlassPointers::shift() != 0) {
5477       lsl(dst, src, CompressedKlassPointers::shift());
5478       eor(dst, dst, (uint64_t)CompressedKlassPointers::base());
5479     } else {
5480       eor(dst, src, (uint64_t)CompressedKlassPointers::base());
5481     }

5775   // the code cache so that if it is relocated we know it will still reach
5776   if (offset_high >= -(1<<20) && offset_low < (1<<20)) {
5777     _adrp(reg1, dest.target());
5778   } else {
5779     uint64_t target = (uint64_t)dest.target();
5780     uint64_t adrp_target
5781       = (target & 0xffffffffULL) | ((uint64_t)pc() & 0xffff00000000ULL);
5782 
5783     _adrp(reg1, (address)adrp_target);
5784     movk(reg1, target >> 32, 32);
5785   }
5786   byte_offset = (uint64_t)dest.target() & 0xfff;
5787 }
5788 
5789 void MacroAssembler::load_byte_map_base(Register reg) {
5790   CardTable::CardValue* byte_map_base =
5791     ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base();
5792 
5793   // Strictly speaking the byte_map_base isn't an address at all, and it might
5794   // even be negative. It is thus materialised as a constant.
5795 #if INCLUDE_CDS
5796   if (AOTCodeCache::is_on_for_dump()) {
5797     // AOT code needs relocation info for card table base
5798     lea(reg, ExternalAddress(reinterpret_cast<address>(byte_map_base)));
5799   } else {
5800 #endif
5801     mov(reg, (uint64_t)byte_map_base);
5802 #if INCLUDE_CDS
5803   }
5804 #endif
5805 }
5806 
5807 void MacroAssembler::load_aotrc_address(Register reg, address a) {
5808 #if INCLUDE_CDS
5809   assert(AOTRuntimeConstants::contains(a), "address out of range for data area");
5810   if (AOTCodeCache::is_on_for_dump()) {
5811     // all aotrc field addresses should be registered in the AOTCodeCache address table
5812     lea(reg, ExternalAddress(a));
5813   } else {
5814     mov(reg, (uint64_t)a);
5815   }
5816 #else
5817   ShouldNotReachHere();
5818 #endif
5819 }
5820 
5821 void MacroAssembler::build_frame(int framesize) {
5822   assert(framesize >= 2 * wordSize, "framesize must include space for FP/LR");
5823   assert(framesize % (2*wordSize) == 0, "must preserve 2*wordSize alignment");
5824   protect_return_address();
5825   if (framesize < ((1 << 9) + 2 * wordSize)) {
5826     sub(sp, sp, framesize);
5827     stp(rfp, lr, Address(sp, framesize - 2 * wordSize));
5828     if (PreserveFramePointer) add(rfp, sp, framesize - 2 * wordSize);
5829   } else {
5830     stp(rfp, lr, Address(pre(sp, -2 * wordSize)));
5831     if (PreserveFramePointer) mov(rfp, sp);
5832     if (framesize < ((1 << 12) + 2 * wordSize))
5833       sub(sp, sp, framesize - 2 * wordSize);
5834     else {
5835       mov(rscratch1, framesize - 2 * wordSize);
5836       sub(sp, sp, rscratch1);
5837     }
5838   }
< prev index next >