Bug 1529559 - ARM64: PatchJump change the branching schema if the target is out of range. r=sstangl

Differential Revision: https://phabricator.services.mozilla.com/D23361

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Nicolas B. Pierron 2019-03-19 18:23:52 +00:00
parent 89daa23071
commit bf4b5b97d0
3 changed files with 18 additions and 5 deletions

View File

@ -356,7 +356,8 @@ size_t Assembler::addPatchableJump(BufferOffset src, RelocationKind reloc) {
return extendedTableIndex;
}
// PatchJump() is only used by the IonCacheIRCompiler.
// PatchJump() is only used by the IonCacheIRCompiler and patches code generated
// by jumpWithPatch.
//
// The CodeLocationJump is the jump to be patched.
// The code for the jump is emitted by jumpWithPatch().
@ -369,12 +370,18 @@ void PatchJump(CodeLocationJump& jump_, CodeLocationLabel label) {
Instruction* branch = (Instruction*)load->NextInstruction()->skipPool();
MOZ_ASSERT(branch->IsUncondB());
// FIXME: For the moment, just assume that the load isn't needed.
// FIXME: That assumption implies that the branch target is always in-range.
if (branch->IsTargetReachable((Instruction*)label.raw())) {
branch->SetImmPCOffsetTarget((Instruction*)label.raw());
} else {
MOZ_CRASH("PatchJump target not reachable");
// Set the literal read by the load instruction to the target.
load->SetLiteral64(uint64_t(label.raw()));
// Get the scratch register set by the load instruction.
vixl::Register loadTarget = vixl::Register(load->Rt(), 64);
// Overwrite the branch instruction to branch on the same register as the
// load instruction.
Assembler::br(branch, loadTarget);
MOZ_ASSERT(branch->IsBR());
MOZ_ASSERT(load->Rt() == branch->Rn());
}
}

View File

@ -1255,7 +1255,9 @@ class MacroAssemblerCompat : public vixl::MacroAssembler {
ARMBuffer::PoolEntry pe;
BufferOffset load_bo;
// FIXME: This load is currently unused.
// This no-op load exists for PatchJump(), in the case of a target outside
// the range of +/- 128 MB. If the load is used, then the branch here is
// overwritten with a `BR` from the loaded register.
load_bo = immPool64(scratch64, (uint64_t)label, &pe);
BufferOffset branch_bo = b(-1, LabelDoc());

View File

@ -462,6 +462,10 @@ class Instruction {
return literal;
}
void SetLiteral64(uint64_t literal) const {
memcpy(LiteralAddress<void*>(), &literal, sizeof(literal));
}
float LiteralFP32() const {
return rawbits_to_float(Literal32());
}