Optimise the deoptimisation check to improve performance on modern ARM cores.
BUG=none TEST=none Review URL: http://codereview.chromium.org//7021007 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7909 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
17c4dc86f0
commit
9bddc8e0d8
@ -85,6 +85,7 @@ bool LCodeGen::GenerateCode() {
|
||||
return GeneratePrologue() &&
|
||||
GenerateBody() &&
|
||||
GenerateDeferredCode() &&
|
||||
GenerateDeoptJumpTable() &&
|
||||
GenerateSafepointTable();
|
||||
}
|
||||
|
||||
@ -249,13 +250,41 @@ bool LCodeGen::GenerateDeferredCode() {
|
||||
__ 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.
|
||||
if (!is_int24((masm()->pc_offset() / Assembler::kInstrSize) +
|
||||
deopt_jump_table_.length())) {
|
||||
Abort("Generated code is too large");
|
||||
}
|
||||
|
||||
__ 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 +624,18 @@ void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (FLAG_trap_on_deopt) __ stop("trap_on_deopt", cc);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,7 @@ class LCodeGen BASE_EMBEDDED {
|
||||
current_instruction_(-1),
|
||||
instructions_(chunk->instructions()),
|
||||
deoptimizations_(4),
|
||||
deopt_jump_table_(4),
|
||||
deoptimization_literals_(8),
|
||||
inlined_function_count_(0),
|
||||
scope_(info->scope()),
|
||||
@ -172,6 +173,7 @@ class LCodeGen BASE_EMBEDDED {
|
||||
bool GeneratePrologue();
|
||||
bool GenerateBody();
|
||||
bool GenerateDeferredCode();
|
||||
bool GenerateDeoptJumpTable();
|
||||
bool GenerateSafepointTable();
|
||||
|
||||
enum SafepointMode {
|
||||
@ -289,6 +291,14 @@ class LCodeGen BASE_EMBEDDED {
|
||||
Handle<Map> type,
|
||||
Handle<String> name);
|
||||
|
||||
struct JumpTableEntry {
|
||||
explicit inline JumpTableEntry(Address entry)
|
||||
: label(),
|
||||
address(entry) { }
|
||||
Label label;
|
||||
Address address;
|
||||
};
|
||||
|
||||
LChunk* const chunk_;
|
||||
MacroAssembler* const masm_;
|
||||
CompilationInfo* const info_;
|
||||
@ -297,6 +307,7 @@ class LCodeGen BASE_EMBEDDED {
|
||||
int current_instruction_;
|
||||
const ZoneList<LInstruction*>* instructions_;
|
||||
ZoneList<LEnvironment*> deoptimizations_;
|
||||
ZoneList<JumpTableEntry> deopt_jump_table_;
|
||||
ZoneList<Handle<Object> > deoptimization_literals_;
|
||||
int inlined_function_count_;
|
||||
Scope* const scope_;
|
||||
|
Loading…
Reference in New Issue
Block a user