From 94c18b1cf8be72b4775efc0a64d87da056b8fdd9 Mon Sep 17 00:00:00 2001 From: "ricow@chromium.org" Date: Mon, 28 Feb 2011 13:57:42 +0000 Subject: [PATCH] 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 --- src/x64/lithium-codegen-x64.cc | 26 ++++++++++++++++++++++---- src/x64/lithium-codegen-x64.h | 11 +++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 90244f1c21..555908caf3 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -77,6 +77,7 @@ bool LCodeGen::GenerateCode() { return GeneratePrologue() && GenerateBody() && GenerateDeferredCode() && + GenerateJumpTable() && 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() { ASSERT(is_generating()); 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) { __ Jump(entry, RelocInfo::RUNTIME_ENTRY); } else { - NearLabel done; - __ j(NegateCondition(cc), &done); - __ Jump(entry, RelocInfo::RUNTIME_ENTRY); - __ bind(&done); + JumpTableEntry* jump_info = NULL; + // We often have several deopts to the same entry, reuse the last + // jump entry if this is the case. + 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_); } } diff --git a/src/x64/lithium-codegen-x64.h b/src/x64/lithium-codegen-x64.h index 1cac4e9df6..420556a585 100644 --- a/src/x64/lithium-codegen-x64.h +++ b/src/x64/lithium-codegen-x64.h @@ -53,6 +53,7 @@ class LCodeGen BASE_EMBEDDED { current_instruction_(-1), instructions_(chunk->instructions()), deoptimizations_(4), + jump_table_(4), deoptimization_literals_(8), inlined_function_count_(0), scope_(chunk->graph()->info()->scope()), @@ -147,6 +148,7 @@ class LCodeGen BASE_EMBEDDED { bool GeneratePrologue(); bool GenerateBody(); bool GenerateDeferredCode(); + bool GenerateJumpTable(); bool GenerateSafepointTable(); void CallCode(Handle code, @@ -234,6 +236,14 @@ class LCodeGen BASE_EMBEDDED { // Emits code for pushing a constant operand. void EmitPushConstantOperand(LOperand* operand); + struct JumpTableEntry { + inline JumpTableEntry(Address address) + : label_(), + address_(address) { } + Label label_; + Address address_; + }; + LChunk* const chunk_; MacroAssembler* const masm_; CompilationInfo* const info_; @@ -242,6 +252,7 @@ class LCodeGen BASE_EMBEDDED { int current_instruction_; const ZoneList* instructions_; ZoneList deoptimizations_; + ZoneList jump_table_; ZoneList > deoptimization_literals_; int inlined_function_count_; Scope* const scope_;