MIPS: Critical fix for label binding in RegExp engine when trampoline is emitted.
TEST=mjsunit/regress/regress-crbug-178790 BUG= Review URL: https://codereview.chromium.org/12939010 Patch from Dusan Milosavljevic <Dusan.Milosavljevic@rt-rk.com>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14013 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
fc856413fa
commit
d6ceb193fe
@ -490,7 +490,6 @@ bool Assembler::IsBranch(Instr instr) {
|
||||
uint32_t opcode = GetOpcodeField(instr);
|
||||
uint32_t rt_field = GetRtField(instr);
|
||||
uint32_t rs_field = GetRsField(instr);
|
||||
uint32_t label_constant = GetLabelConst(instr);
|
||||
// Checks if the instruction is a branch.
|
||||
return opcode == BEQ ||
|
||||
opcode == BNE ||
|
||||
@ -502,10 +501,13 @@ bool Assembler::IsBranch(Instr instr) {
|
||||
opcode == BGTZL ||
|
||||
(opcode == REGIMM && (rt_field == BLTZ || rt_field == BGEZ ||
|
||||
rt_field == BLTZAL || rt_field == BGEZAL)) ||
|
||||
(opcode == COP1 && rs_field == BC1) || // Coprocessor branch.
|
||||
label_constant == 0; // Emitted label const in reg-exp engine.
|
||||
(opcode == COP1 && rs_field == BC1); // Coprocessor branch.
|
||||
}
|
||||
|
||||
bool Assembler::IsEmittedConstant(Instr instr) {
|
||||
uint32_t label_constant = GetLabelConst(instr);
|
||||
return label_constant == 0; // Emitted label const in reg-exp engine.
|
||||
}
|
||||
|
||||
bool Assembler::IsBeq(Instr instr) {
|
||||
return GetOpcodeField(instr) == BEQ;
|
||||
@ -796,7 +798,7 @@ void Assembler::bind_to(Label* L, int pos) {
|
||||
}
|
||||
target_at_put(fixup_pos, pos);
|
||||
} else {
|
||||
ASSERT(IsJ(instr) || IsLui(instr));
|
||||
ASSERT(IsJ(instr) || IsLui(instr) || IsEmittedConstant(instr));
|
||||
target_at_put(fixup_pos, pos);
|
||||
}
|
||||
}
|
||||
|
@ -942,6 +942,7 @@ class Assembler : public AssemblerBase {
|
||||
static Instr SetAddImmediateOffset(Instr instr, int16_t offset);
|
||||
|
||||
static bool IsAndImmediate(Instr instr);
|
||||
static bool IsEmittedConstant(Instr instr);
|
||||
|
||||
void CheckTrampolinePool();
|
||||
|
||||
|
@ -1108,6 +1108,7 @@ void MacroAssembler::BranchF(Label* target,
|
||||
FPURegister cmp1,
|
||||
FPURegister cmp2,
|
||||
BranchDelaySlot bd) {
|
||||
BlockTrampolinePoolScope block_trampoline_pool(this);
|
||||
if (cc == al) {
|
||||
Branch(bd, target);
|
||||
return;
|
||||
@ -1700,6 +1701,7 @@ void MacroAssembler::BranchShort(int16_t offset, Condition cond, Register rs,
|
||||
if (rt.is_reg()) {
|
||||
// NOTE: 'at' can be clobbered by Branch but it is legal to use it as rs or
|
||||
// rt.
|
||||
BlockTrampolinePoolScope block_trampoline_pool(this);
|
||||
r2 = rt.rm_;
|
||||
switch (cond) {
|
||||
case cc_always:
|
||||
@ -1785,6 +1787,7 @@ void MacroAssembler::BranchShort(int16_t offset, Condition cond, Register rs,
|
||||
// Be careful to always use shifted_branch_offset only just before the
|
||||
// branch instruction, as the location will be remember for patching the
|
||||
// target.
|
||||
BlockTrampolinePoolScope block_trampoline_pool(this);
|
||||
switch (cond) {
|
||||
case cc_always:
|
||||
b(offset);
|
||||
@ -1929,6 +1932,7 @@ void MacroAssembler::BranchShort(Label* L, Condition cond, Register rs,
|
||||
Register r2 = no_reg;
|
||||
Register scratch = at;
|
||||
if (rt.is_reg()) {
|
||||
BlockTrampolinePoolScope block_trampoline_pool(this);
|
||||
r2 = rt.rm_;
|
||||
// Be careful to always use shifted_branch_offset only just before the
|
||||
// branch instruction, as the location will be remember for patching the
|
||||
@ -2035,6 +2039,7 @@ void MacroAssembler::BranchShort(Label* L, Condition cond, Register rs,
|
||||
// Be careful to always use shifted_branch_offset only just before the
|
||||
// branch instruction, as the location will be remember for patching the
|
||||
// target.
|
||||
BlockTrampolinePoolScope block_trampoline_pool(this);
|
||||
switch (cond) {
|
||||
case cc_always:
|
||||
offset = shifted_branch_offset(L, false);
|
||||
@ -2271,6 +2276,8 @@ void MacroAssembler::BranchAndLinkShort(int16_t offset, Condition cond,
|
||||
li(r2, rt);
|
||||
}
|
||||
|
||||
{
|
||||
BlockTrampolinePoolScope block_trampoline_pool(this);
|
||||
switch (cond) {
|
||||
case cc_always:
|
||||
bal(offset);
|
||||
@ -2333,6 +2340,7 @@ void MacroAssembler::BranchAndLinkShort(int16_t offset, Condition cond,
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
// Emit a nop in the branch delay slot if required.
|
||||
if (bdslot == PROTECT)
|
||||
nop();
|
||||
@ -2363,6 +2371,8 @@ void MacroAssembler::BranchAndLinkShort(Label* L, Condition cond, Register rs,
|
||||
li(r2, rt);
|
||||
}
|
||||
|
||||
{
|
||||
BlockTrampolinePoolScope block_trampoline_pool(this);
|
||||
switch (cond) {
|
||||
case cc_always:
|
||||
offset = shifted_branch_offset(L, false);
|
||||
@ -2436,7 +2446,7 @@ void MacroAssembler::BranchAndLinkShort(Label* L, Condition cond, Register rs,
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
}
|
||||
// Check that offset could actually hold on an int16_t.
|
||||
ASSERT(is_int16(offset));
|
||||
|
||||
|
@ -1005,6 +1005,7 @@ void RegExpMacroAssemblerMIPS::PushBacktrack(Label* label) {
|
||||
int target = label->pos();
|
||||
__ li(a0, Operand(target + Code::kHeaderSize - kHeapObjectTag));
|
||||
} else {
|
||||
Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
|
||||
Label after_constant;
|
||||
__ Branch(&after_constant);
|
||||
int offset = masm_->pc_offset();
|
||||
|
Loading…
Reference in New Issue
Block a user