summaryrefslogtreecommitdiff
path: root/deps/v8/src/arm/assembler-arm-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/arm/assembler-arm-inl.h')
-rw-r--r--deps/v8/src/arm/assembler-arm-inl.h64
1 files changed, 40 insertions, 24 deletions
diff --git a/deps/v8/src/arm/assembler-arm-inl.h b/deps/v8/src/arm/assembler-arm-inl.h
index 4c4eb00ec2..a432e44814 100644
--- a/deps/v8/src/arm/assembler-arm-inl.h
+++ b/deps/v8/src/arm/assembler-arm-inl.h
@@ -60,14 +60,17 @@ void RelocInfo::apply(intptr_t delta) {
// absolute code pointer inside code object moves with the code object.
int32_t* p = reinterpret_cast<int32_t*>(pc_);
*p += delta; // relocate entry
+ } else if (RelocInfo::IsRelativeCodeTarget(rmode_)) {
+ Instruction* branch = Instruction::At(pc_);
+ int32_t branch_offset = branch->GetBranchOffset() + delta;
+ branch->SetBranchOffset(branch_offset);
}
- // We do not use pc relative addressing on ARM, so there is
- // nothing else to do.
}
Address RelocInfo::target_address() {
- DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) || IsWasmCall(rmode_));
+ DCHECK(IsCodeTargetMode(rmode_) || IsRuntimeEntry(rmode_) ||
+ IsWasmCall(rmode_));
return Assembler::target_address_at(pc_, constant_pool_);
}
@@ -101,12 +104,15 @@ HeapObject* RelocInfo::target_object() {
}
Handle<HeapObject> RelocInfo::target_object_handle(Assembler* origin) {
- DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
- return Handle<HeapObject>(reinterpret_cast<HeapObject**>(
- Assembler::target_address_at(pc_, constant_pool_)));
+ if (IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT) {
+ return Handle<HeapObject>(reinterpret_cast<HeapObject**>(
+ Assembler::target_address_at(pc_, constant_pool_)));
+ }
+ DCHECK(IsRelativeCodeTarget(rmode_));
+ return origin->relative_code_target_object_handle_at(pc_);
}
-void RelocInfo::set_target_object(HeapObject* target,
+void RelocInfo::set_target_object(Heap* heap, HeapObject* target,
WriteBarrierMode write_barrier_mode,
ICacheFlushMode icache_flush_mode) {
DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
@@ -114,9 +120,8 @@ void RelocInfo::set_target_object(HeapObject* target,
reinterpret_cast<Address>(target),
icache_flush_mode);
if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != nullptr) {
- host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(host(), this,
- target);
- host()->GetHeap()->RecordWriteIntoCode(host(), this, target);
+ heap->incremental_marking()->RecordWriteIntoCode(host(), this, target);
+ heap->RecordWriteIntoCode(host(), this, target);
}
}
@@ -144,13 +149,6 @@ Address RelocInfo::target_internal_reference_address() {
return pc_;
}
-void RelocInfo::set_wasm_code_table_entry(Address target,
- ICacheFlushMode icache_flush_mode) {
- DCHECK(rmode_ == RelocInfo::WASM_CODE_TABLE_ENTRY);
- Assembler::set_target_address_at(pc_, constant_pool_, target,
- icache_flush_mode);
-}
-
Address RelocInfo::target_runtime_entry(Assembler* origin) {
DCHECK(IsRuntimeEntry(rmode_));
return target_address();
@@ -180,12 +178,19 @@ void RelocInfo::WipeOut() {
}
}
+Handle<Code> Assembler::relative_code_target_object_handle_at(
+ Address pc) const {
+ Instruction* branch = Instruction::At(pc);
+ int code_target_index = branch->GetBranchOffset() / Instruction::kInstrSize;
+ return GetCodeTarget(code_target_index);
+}
+
template <typename ObjectVisitor>
void RelocInfo::Visit(ObjectVisitor* visitor) {
RelocInfo::Mode mode = rmode();
if (mode == RelocInfo::EMBEDDED_OBJECT) {
visitor->VisitEmbeddedPointer(host(), this);
- } else if (RelocInfo::IsCodeTarget(mode)) {
+ } else if (RelocInfo::IsCodeTargetMode(mode)) {
visitor->VisitCodeTarget(host(), this);
} else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
visitor->VisitExternalReference(host(), this);
@@ -317,7 +322,7 @@ Address Assembler::constant_pool_entry_address(Address pc,
Address constant_pool) {
DCHECK(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc)));
Instr instr = Memory::int32_at(pc);
- return pc + GetLdrRegisterImmediateOffset(instr) + kPcLoadDelta;
+ return pc + GetLdrRegisterImmediateOffset(instr) + Instruction::kPcLoadDelta;
}
@@ -325,7 +330,7 @@ Address Assembler::target_address_at(Address pc, Address constant_pool) {
if (is_constant_pool_load(pc)) {
// This is a constant pool lookup. Return the value in the constant pool.
return Memory::Address_at(constant_pool_entry_address(pc, constant_pool));
- } else if (CpuFeatures::IsSupported(ARMv7)) {
+ } else if (CpuFeatures::IsSupported(ARMv7) && IsMovW(Memory::int32_at(pc))) {
// This is an movw / movt immediate load. Return the immediate.
DCHECK(IsMovW(Memory::int32_at(pc)) &&
IsMovT(Memory::int32_at(pc + kInstrSize)));
@@ -333,7 +338,7 @@ Address Assembler::target_address_at(Address pc, Address constant_pool) {
Instruction* movt_instr = Instruction::At(pc + kInstrSize);
return static_cast<Address>((movt_instr->ImmedMovwMovtValue() << 16) |
movw_instr->ImmedMovwMovtValue());
- } else {
+ } else if (IsMovImmed(Memory::int32_at(pc))) {
// This is an mov / orr immediate load. Return the immediate.
DCHECK(IsMovImmed(Memory::int32_at(pc)) &&
IsOrrImmed(Memory::int32_at(pc + kInstrSize)) &&
@@ -347,6 +352,10 @@ Address Assembler::target_address_at(Address pc, Address constant_pool) {
DecodeShiftImm(mov_instr) | DecodeShiftImm(orr_instr_1) |
DecodeShiftImm(orr_instr_2) | DecodeShiftImm(orr_instr_3));
return ret;
+ } else {
+ Instruction* branch = Instruction::At(pc);
+ int32_t delta = branch->GetBranchOffset();
+ return pc + delta + Instruction::kPcLoadDelta;
}
}
@@ -364,7 +373,7 @@ void Assembler::set_target_address_at(Address pc, Address constant_pool,
// ldr ip, [pp, #...]
// since the instruction accessing this address in the constant pool remains
// unchanged.
- } else if (CpuFeatures::IsSupported(ARMv7)) {
+ } else if (CpuFeatures::IsSupported(ARMv7) && IsMovW(Memory::int32_at(pc))) {
// This is an movw / movt immediate load. Patch the immediate embedded in
// the instructions.
DCHECK(IsMovW(Memory::int32_at(pc)));
@@ -378,7 +387,7 @@ void Assembler::set_target_address_at(Address pc, Address constant_pool,
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc, 2 * kInstrSize);
}
- } else {
+ } else if (IsMovImmed(Memory::int32_at(pc))) {
// This is an mov / orr immediate load. Patch the immediate embedded in
// the instructions.
DCHECK(IsMovImmed(Memory::int32_at(pc)) &&
@@ -386,7 +395,7 @@ void Assembler::set_target_address_at(Address pc, Address constant_pool,
IsOrrImmed(Memory::int32_at(pc + 2 * kInstrSize)) &&
IsOrrImmed(Memory::int32_at(pc + 3 * kInstrSize)));
uint32_t* instr_ptr = reinterpret_cast<uint32_t*>(pc);
- uint32_t immediate = reinterpret_cast<uint32_t>(target);
+ uint32_t immediate = static_cast<uint32_t>(target);
instr_ptr[0] = PatchShiftImm(instr_ptr[0], immediate & kImm8Mask);
instr_ptr[1] = PatchShiftImm(instr_ptr[1], immediate & (kImm8Mask << 8));
instr_ptr[2] = PatchShiftImm(instr_ptr[2], immediate & (kImm8Mask << 16));
@@ -398,6 +407,13 @@ void Assembler::set_target_address_at(Address pc, Address constant_pool,
if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
Assembler::FlushICache(pc, 4 * kInstrSize);
}
+ } else {
+ intptr_t branch_offset = target - pc - Instruction::kPcLoadDelta;
+ Instruction* branch = Instruction::At(pc);
+ branch->SetBranchOffset(branch_offset);
+ if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
+ Assembler::FlushICache(pc, kInstrSize);
+ }
}
}