Bug 831754 part 1 - Add patchable call instruction, ARM part. r=mjrosenb a=nonlibxul

This commit is contained in:
Jan de Mooij 2013-01-22 14:33:07 +01:00
parent 63b4e0b3f5
commit 1a46e13a3a
4 changed files with 85 additions and 1 deletions

View File

@ -181,6 +181,20 @@ InstLDR::asTHIS(Instruction &i)
return NULL;
}
InstNOP *
InstNOP::asTHIS(Instruction &i)
{
if (isTHIS(i))
return (InstNOP*) (&i);
return NULL;
}
bool
InstNOP::isTHIS(const Instruction &i)
{
return (i.encode() & 0x0fffffff) == NopInst;
}
bool
InstBranchReg::isTHIS(const Instruction &i)
{
@ -2471,6 +2485,31 @@ Assembler::ToggleToCmp(CodeLocationLabel inst_)
AutoFlushCache::updateTop((uintptr_t)ptr, 4);
}
void
Assembler::ToggleCall(CodeLocationLabel inst_, bool enabled)
{
Instruction *inst = (Instruction *)inst_.raw();
JS_ASSERT(inst->is<InstMovW>());
inst = inst->next();
JS_ASSERT(inst->is<InstMovT>());
inst = inst->next();
JS_ASSERT(inst->is<InstNOP>() || inst->is<InstBLXReg>());
if (enabled == inst->is<InstBLXReg>()) {
// Nothing to do.
return;
}
if (enabled)
*inst = InstBLXReg(ScratchRegister, Always);
else
*inst = InstNOP();
AutoFlushCache::updateTop(uintptr_t(inst), 4);
}
void
AutoFlushCache::update(uintptr_t newStart, size_t len)
{

View File

@ -1698,6 +1698,7 @@ class Assembler
static void ToggleToJmp(CodeLocationLabel inst_);
static void ToggleToCmp(CodeLocationLabel inst_);
static void ToggleCall(CodeLocationLabel inst_, bool enabled);
}; // Assembler
// An Instruction is a structure for both encoding and decoding any and all ARM instructions.
@ -1787,6 +1788,20 @@ class InstLDR : public InstDTR
};
JS_STATIC_ASSERT(sizeof(InstDTR) == sizeof(InstLDR));
class InstNOP : public Instruction
{
static const uint32_t NopInst = 0x0320f000;
public:
InstNOP()
: Instruction(NopInst, Assembler::Always)
{ }
static bool isTHIS(const Instruction &i);
static InstNOP *asTHIS(Instruction &i);
};
// Branching to a register, or calling a register
class InstBranchReg : public Instruction
{
@ -1798,7 +1813,7 @@ class InstBranchReg : public Instruction
};
static const uint32_t IsBRegMask = 0x0ffffff0;
InstBranchReg(BranchTag tag, Register rm, Assembler::Condition c)
: Instruction(tag | RM(rm), c)
: Instruction(tag | rm.code(), c)
{ }
public:
static bool isTHIS (const Instruction &i);
@ -1841,6 +1856,10 @@ class InstBXReg : public InstBranchReg
class InstBLXReg : public InstBranchReg
{
public:
InstBLXReg(Register reg, Assembler::Condition c)
: InstBranchReg(IsBLX, reg, c)
{ }
static bool isTHIS (const Instruction &i);
static InstBLXReg *asTHIS (const Instruction &i);
};

View File

@ -1136,6 +1136,12 @@ MacroAssemblerARM::ma_bl(Label *dest, Assembler::Condition c)
as_bl(dest, c);
}
void
MacroAssemblerARM::ma_blx(Register reg, Assembler::Condition c)
{
as_blx(reg, c);
}
// VFP/ALU
void
MacroAssemblerARM::ma_vadd(FloatRegister src1, FloatRegister src2, FloatRegister dst)
@ -3019,6 +3025,20 @@ MacroAssemblerARMCompat::toggledJump(Label *label)
return ret;
}
CodeOffsetLabel
MacroAssemblerARMCompat::toggledCall(IonCode *target, bool enabled)
{
CodeOffsetLabel offset(size());
BufferOffset bo = m_buffer.nextOffset();
addPendingJump(bo, target->raw(), Relocation::IONCODE);
ma_movPatchable(Imm32(uint32_t(target->raw())), ScratchRegister, Always, L_MOVWT);
if (enabled)
ma_blx(ScratchRegister);
else
ma_nop();
return offset;
}
void
MacroAssemblerARMCompat::round(FloatRegister input, Register output, Label *bail, FloatRegister tmp)
{

View File

@ -277,6 +277,8 @@ class MacroAssemblerARM : public Assembler
// except, possibly in the crazy bailout-table case.
void ma_bl(Label *dest, Condition c = Always);
void ma_blx(Register dest, Condition c = Always);
//VFP/ALU
void ma_vadd(FloatRegister src1, FloatRegister src2, FloatRegister dst);
void ma_vsub(FloatRegister src1, FloatRegister src2, FloatRegister dst);
@ -500,6 +502,10 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
CodeOffsetLabel toggledJump(Label *label);
// Emit a BLX or NOP instruction. ToggleCall can be used to patch
// this instruction.
CodeOffsetLabel toggledCall(IonCode *target, bool enabled);
CodeOffsetLabel pushWithPatch(ImmWord imm) {
CodeOffsetLabel label = currentOffset();
ma_movPatchable(Imm32(imm.value), ScratchRegister, Always, L_MOVWT);