Index: src/arm/lithium-codegen-arm.cc |
=================================================================== |
--- src/arm/lithium-codegen-arm.cc (revision 7902) |
+++ src/arm/lithium-codegen-arm.cc (working copy) |
@@ -85,6 +85,7 @@ |
return GeneratePrologue() && |
GenerateBody() && |
GenerateDeferredCode() && |
+ GenerateDeoptJumpTable() && |
GenerateSafepointTable(); |
} |
@@ -249,13 +250,39 @@ |
__ jmp(code->exit()); |
} |
- // Force constant pool emission at the end of deferred code to make |
+ return !is_aborted(); |
+} |
+ |
+ |
+bool LCodeGen::GenerateDeoptJumpTable() { |
+ // Check that the jump table is accessible from everywhere in the function |
+ // code, ie that offsets to the table can be encoded in the 24bit signed |
+ // immediate of a branch instruction. |
+ // To simplify we consider the code size from the first instruction to the |
+ // end of the jump table. We also don't consider the pc load delta. |
+ // Each entry in the jump table generates only one instruction. |
Søren Thygesen Gjesse
2011/05/17 06:16:44
I have not been able to find anywhere where we ens
Alexandre
2011/05/17 08:10:32
Done: Changed the ASSERT to a test aborting the co
|
+ ASSERT(is_int24((masm()->pc_offset() / Assembler::kInstrSize) + |
+ deopt_jump_table_.length())); |
+ |
+ __ RecordComment("[ Deoptimisation jump table"); |
+ Label table_start; |
+ __ bind(&table_start); |
+ for (int i = 0; i < deopt_jump_table_.length(); i++) { |
+ __ bind(&deopt_jump_table_[i].label); |
+ __ mov(pc, Operand(reinterpret_cast<int32_t>(deopt_jump_table_[i].address), |
+ RelocInfo::RUNTIME_ENTRY)); |
+ } |
+ ASSERT(masm()->InstructionsGeneratedSince(&table_start) == |
+ deopt_jump_table_.length()); |
+ __ RecordComment("]"); |
+ |
+ // Force constant pool emission at the end of the jump table to make |
// sure that no constant pools are emitted after the official end of |
// the instruction sequence. |
masm()->CheckConstPool(true, false); |
- // Deferred code is the last part of the instruction sequence. Mark |
- // the generated code as done unless we bailed out. |
+ // The deoptimization jump table is the last part of the instruction |
+ // sequence. Mark the generated code as done unless we bailed out. |
if (!is_aborted()) status_ = DONE; |
return !is_aborted(); |
} |
@@ -595,19 +622,18 @@ |
return; |
} |
+ if (FLAG_trap_on_deopt) __ stop("trap_on_deopt"); |
Søren Thygesen Gjesse
2011/05/17 06:16:44
Shouldn't this stop still be conditional if cc is
Alexandre
2011/05/17 08:10:32
It should. Done.
On 2011/05/17 06:16:44, Søren Gj
Rodolph Perfetta
2011/05/17 10:16:29
Yes it should.
|
+ |
if (cc == al) { |
- if (FLAG_trap_on_deopt) __ stop("trap_on_deopt"); |
__ Jump(entry, RelocInfo::RUNTIME_ENTRY); |
} else { |
- if (FLAG_trap_on_deopt) { |
- Label done; |
- __ b(&done, NegateCondition(cc)); |
- __ stop("trap_on_deopt"); |
- __ Jump(entry, RelocInfo::RUNTIME_ENTRY); |
- __ bind(&done); |
- } else { |
- __ Jump(entry, RelocInfo::RUNTIME_ENTRY, cc); |
+ // We often have several deopts to the same entry, reuse the last |
+ // jump entry if this is the case. |
+ if (deopt_jump_table_.is_empty() || |
+ (deopt_jump_table_.last().address != entry)) { |
+ deopt_jump_table_.Add(JumpTableEntry(entry)); |
} |
+ __ b(cc, &deopt_jump_table_.last().label); |
} |
} |