< prev index next > src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
Print this page
*/
#include "asm/assembler.hpp"
#include "asm/assembler.inline.hpp"
#include "ci/ciEnv.hpp"
+ #include "ci/ciUtilities.hpp"
#include "code/compiledIC.hpp"
#include "compiler/compileTask.hpp"
#include "compiler/disassembler.hpp"
#include "compiler/oopMap.hpp"
#include "gc/shared/barrierSet.hpp"
dest = (dest & 0xffffffffULL) | (uintptr_t(insn_addr) & 0xffff00000000ULL);
target = address(dest);
return 2;
}
virtual int immediate(address insn_addr, address &target) {
+ // Metadata pointers are either narrow (32 bits) or wide (48 bits).
+ // We encode narrow ones by setting the upper 16 bits in the first
+ // instruction.
+ if (Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010101) {
+ assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
+ narrowKlass nk = CompressedKlassPointers::encode((Klass*)target);
+ Instruction_aarch64::patch(insn_addr, 20, 5, nk >> 16);
+ Instruction_aarch64::patch(insn_addr+4, 20, 5, nk & 0xffff);
+ return 2;
+ }
assert(Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010100, "must be");
uint64_t dest = (uint64_t)target;
// Move wide constant
assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");
return 2;
}
}
virtual int immediate(address insn_addr, address &target) {
uint32_t *insns = (uint32_t *)insn_addr;
+ // Metadata pointers are either narrow (32 bits) or wide (48 bits).
+ // We encode narrow ones by setting the upper 16 bits in the first
+ // instruction.
+ if (Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010101) {
+ assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
+ narrowKlass nk = (narrowKlass)((uint32_t(Instruction_aarch64::extract(_insn, 20, 5)) << 16)
+ + uint32_t(Instruction_aarch64::extract(insns[1], 20, 5)));
+ target = (address)CompressedKlassPointers::decode(nk);
+ return 2;
+ }
assert(Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010100, "must be");
// Move wide constant: movz, movk, movk. See movptr().
assert(nativeInstruction_at(insns+1)->is_movk(), "wrong insns in patch");
assert(nativeInstruction_at(insns+2)->is_movk(), "wrong insns in patch");
target = address(uint64_t(Instruction_aarch64::extract(_insn, 20, 5))
}
void MacroAssembler::reinit_heapbase()
{
if (UseCompressedOops) {
! if (Universe::is_fully_initialized()) {
mov(rheapbase, CompressedOops::base());
} else {
lea(rheapbase, ExternalAddress(CompressedOops::base_addr()));
ldr(rheapbase, Address(rheapbase));
}
}
void MacroAssembler::reinit_heapbase()
{
if (UseCompressedOops) {
! if (Universe::is_fully_initialized() && !AOTCodeCache::is_on_for_dump()) {
mov(rheapbase, CompressedOops::base());
} else {
lea(rheapbase, ExternalAddress(CompressedOops::base_addr()));
ldr(rheapbase, Address(rheapbase));
}
CardTable::CardValue* byte_map_base =
((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base();
// Strictly speaking the byte_map_base isn't an address at all, and it might
// even be negative. It is thus materialised as a constant.
! mov(reg, (uint64_t)byte_map_base);
}
void MacroAssembler::build_frame(int framesize) {
assert(framesize >= 2 * wordSize, "framesize must include space for FP/LR");
assert(framesize % (2*wordSize) == 0, "must preserve 2*wordSize alignment");
CardTable::CardValue* byte_map_base =
((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base();
// Strictly speaking the byte_map_base isn't an address at all, and it might
// even be negative. It is thus materialised as a constant.
! #if INCLUDE_CDS
+ if (AOTCodeCache::is_on_for_dump()) {
+ // AOT code needs relocation info for card table base
+ lea(reg, ExternalAddress(reinterpret_cast<address>(byte_map_base)));
+ } else {
+ #endif
+ mov(reg, (uint64_t)byte_map_base);
+ #if INCLUDE_CDS
+ }
+ #endif
+ }
+
+ void MacroAssembler::load_aotrc_address(Register reg, address a) {
+ #if INCLUDE_CDS
+ assert(AOTRuntimeConstants::contains(a), "address out of range for data area");
+ if (AOTCodeCache::is_on_for_dump()) {
+ // all aotrc field addresses should be registered in the AOTCodeCache address table
+ lea(reg, ExternalAddress(a));
+ } else {
+ mov(reg, (uint64_t)a);
+ }
+ #else
+ ShouldNotReachHere();
+ #endif
}
void MacroAssembler::build_frame(int framesize) {
assert(framesize >= 2 * wordSize, "framesize must include space for FP/LR");
assert(framesize % (2*wordSize) == 0, "must preserve 2*wordSize alignment");
< prev index next >