X64: Add a jumptable to for deoptimization checks on X64.

The current version includes an extra jump compared to IA32, because
we need to load the jump address into a register and do an indirect
jump, but in the normal case we just jump over this by negating the
deoptimization conditional.

Review URL: http://codereview.chromium.org/6596032

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6972 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
ricow@chromium.org 2011-02-28 13:57:42 +00:00
parent 7c561be519
commit 94c18b1cf8
2 changed files with 33 additions and 4 deletions

View File

@ -77,6 +77,7 @@ bool LCodeGen::GenerateCode() {
return GeneratePrologue() && return GeneratePrologue() &&
GenerateBody() && GenerateBody() &&
GenerateDeferredCode() && GenerateDeferredCode() &&
GenerateJumpTable() &&
GenerateSafepointTable(); GenerateSafepointTable();
} }
@ -240,6 +241,16 @@ LInstruction* LCodeGen::GetNextInstruction() {
} }
bool LCodeGen::GenerateJumpTable() {
for (int i = 0; i < jump_table_.length(); i++) {
JumpTableEntry* info = jump_table_[i];
__ bind(&(info->label_));
__ Jump(info->address_, RelocInfo::RUNTIME_ENTRY);
}
return !is_aborted();
}
bool LCodeGen::GenerateDeferredCode() { bool LCodeGen::GenerateDeferredCode() {
ASSERT(is_generating()); ASSERT(is_generating());
for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
@ -512,10 +523,17 @@ void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) {
if (cc == no_condition) { if (cc == no_condition) {
__ Jump(entry, RelocInfo::RUNTIME_ENTRY); __ Jump(entry, RelocInfo::RUNTIME_ENTRY);
} else { } else {
NearLabel done; JumpTableEntry* jump_info = NULL;
__ j(NegateCondition(cc), &done); // We often have several deopts to the same entry, reuse the last
__ Jump(entry, RelocInfo::RUNTIME_ENTRY); // jump entry if this is the case.
__ bind(&done); if (jump_table_.length() > 0 &&
jump_table_[jump_table_.length() - 1]->address_ == entry) {
jump_info = jump_table_[jump_table_.length() - 1];
} else {
jump_info = new JumpTableEntry(entry);
jump_table_.Add(jump_info);
}
__ j(cc, &jump_info->label_);
} }
} }

View File

@ -53,6 +53,7 @@ class LCodeGen BASE_EMBEDDED {
current_instruction_(-1), current_instruction_(-1),
instructions_(chunk->instructions()), instructions_(chunk->instructions()),
deoptimizations_(4), deoptimizations_(4),
jump_table_(4),
deoptimization_literals_(8), deoptimization_literals_(8),
inlined_function_count_(0), inlined_function_count_(0),
scope_(chunk->graph()->info()->scope()), scope_(chunk->graph()->info()->scope()),
@ -147,6 +148,7 @@ class LCodeGen BASE_EMBEDDED {
bool GeneratePrologue(); bool GeneratePrologue();
bool GenerateBody(); bool GenerateBody();
bool GenerateDeferredCode(); bool GenerateDeferredCode();
bool GenerateJumpTable();
bool GenerateSafepointTable(); bool GenerateSafepointTable();
void CallCode(Handle<Code> code, void CallCode(Handle<Code> code,
@ -234,6 +236,14 @@ class LCodeGen BASE_EMBEDDED {
// Emits code for pushing a constant operand. // Emits code for pushing a constant operand.
void EmitPushConstantOperand(LOperand* operand); void EmitPushConstantOperand(LOperand* operand);
struct JumpTableEntry {
inline JumpTableEntry(Address address)
: label_(),
address_(address) { }
Label label_;
Address address_;
};
LChunk* const chunk_; LChunk* const chunk_;
MacroAssembler* const masm_; MacroAssembler* const masm_;
CompilationInfo* const info_; CompilationInfo* const info_;
@ -242,6 +252,7 @@ class LCodeGen BASE_EMBEDDED {
int current_instruction_; int current_instruction_;
const ZoneList<LInstruction*>* instructions_; const ZoneList<LInstruction*>* instructions_;
ZoneList<LEnvironment*> deoptimizations_; ZoneList<LEnvironment*> deoptimizations_;
ZoneList<JumpTableEntry*> jump_table_;
ZoneList<Handle<Object> > deoptimization_literals_; ZoneList<Handle<Object> > deoptimization_literals_;
int inlined_function_count_; int inlined_function_count_;
Scope* const scope_; Scope* const scope_;