MIPS: Fix deoptimization entry table when branch cannot reach.

This fixes failures when table has more than 8192 entries, and preserves
optimization to have 2 instructions per entry.

TEST=mozilla/regress-398085-01
BUG=
R=paul.lind@imgtec.com

Review URL: https://codereview.chromium.org/477623002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23131 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 5c7edb7e
...@@ -324,22 +324,59 @@ void Deoptimizer::TableEntryGenerator::GeneratePrologue() { ...@@ -324,22 +324,59 @@ void Deoptimizer::TableEntryGenerator::GeneratePrologue() {
// Create a sequence of deoptimization entries. // Create a sequence of deoptimization entries.
// Note that registers are still live when jumping to an entry. // Note that registers are still live when jumping to an entry.
Label table_start, done; Label table_start, done, done_special, trampoline_jump;
__ bind(&table_start); __ bind(&table_start);
for (int i = 0; i < count(); i++) { int kMaxEntriesBranchReach = (1 << (kImm16Bits - 2))/
Label start; (table_entry_size_ / Assembler::kInstrSize);
__ bind(&start);
DCHECK(is_int16(i)); if (count() <= kMaxEntriesBranchReach) {
__ Branch(USE_DELAY_SLOT, &done); // Expose delay slot. // Common case.
__ li(at, i); // In the delay slot. for (int i = 0; i < count(); i++) {
Label start;
DCHECK_EQ(table_entry_size_, masm()->SizeOfCodeGeneratedSince(&start)); __ bind(&start);
} DCHECK(is_int16(i));
__ Branch(USE_DELAY_SLOT, &done); // Expose delay slot.
__ li(at, i); // In the delay slot.
DCHECK_EQ(table_entry_size_, masm()->SizeOfCodeGeneratedSince(&start));
}
DCHECK_EQ(masm()->SizeOfCodeGeneratedSince(&table_start),
count() * table_entry_size_);
__ bind(&done);
__ Push(at);
} else {
// Uncommon case, the branch cannot reach.
// Create mini trampoline and adjust id constants to get proper value at
// the end of table.
for (int i = kMaxEntriesBranchReach; i > 1; i--) {
Label start;
__ bind(&start);
DCHECK(is_int16(i));
__ Branch(USE_DELAY_SLOT, &trampoline_jump); // Expose delay slot.
__ li(at, - i); // In the delay slot.
DCHECK_EQ(table_entry_size_, masm()->SizeOfCodeGeneratedSince(&start));
}
// Entry with id == kMaxEntriesBranchReach - 1.
__ bind(&trampoline_jump);
__ Branch(USE_DELAY_SLOT, &done_special);
__ li(at, -1);
for (int i = kMaxEntriesBranchReach ; i < count(); i++) {
Label start;
__ bind(&start);
DCHECK(is_int16(i));
__ Branch(USE_DELAY_SLOT, &done); // Expose delay slot.
__ li(at, i); // In the delay slot.
}
DCHECK_EQ(masm()->SizeOfCodeGeneratedSince(&table_start), DCHECK_EQ(masm()->SizeOfCodeGeneratedSince(&table_start),
count() * table_entry_size_); count() * table_entry_size_);
__ bind(&done); __ bind(&done_special);
__ Push(at); __ addiu(at, at, kMaxEntriesBranchReach);
__ bind(&done);
__ Push(at);
}
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment