From 6dee88849a9b5203899ff96803b9282c3b8e1c88 Mon Sep 17 00:00:00 2001 From: "dusan.milosavljevic@imgtec.com" Date: Thu, 14 Aug 2014 15:23:01 +0000 Subject: [PATCH] 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 --- src/mips/deoptimizer-mips.cc | 63 ++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/src/mips/deoptimizer-mips.cc b/src/mips/deoptimizer-mips.cc index 1e88e62b21..2327dd25c3 100644 --- a/src/mips/deoptimizer-mips.cc +++ b/src/mips/deoptimizer-mips.cc @@ -324,22 +324,59 @@ void Deoptimizer::TableEntryGenerator::GeneratePrologue() { // Create a sequence of deoptimization entries. // 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); - for (int i = 0; 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. + int kMaxEntriesBranchReach = (1 << (kImm16Bits - 2))/ + (table_entry_size_ / Assembler::kInstrSize); - DCHECK_EQ(table_entry_size_, masm()->SizeOfCodeGeneratedSince(&start)); + if (count() <= kMaxEntriesBranchReach) { + // Common case. + for (int i = 0; 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(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), + count() * table_entry_size_); + __ bind(&done_special); + __ addiu(at, at, kMaxEntriesBranchReach); + __ bind(&done); + __ Push(at); } - - DCHECK_EQ(masm()->SizeOfCodeGeneratedSince(&table_start), - count() * table_entry_size_); - __ bind(&done); - __ Push(at); }