From: sgjesse@chromium.org Date: Tue, 17 May 2011 10:52:51 +0000 (+0000) Subject: Optimise the deoptimisation check to improve performance on modern ARM cores. X-Git-Tag: upstream/4.7.83~19399 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9bddc8e0d8a16ac88b0183109a738ebe891bec6b;p=platform%2Fupstream%2Fv8.git 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 --- diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index 95ee13a..d6d1bc6 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -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(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); } } diff --git a/src/arm/lithium-codegen-arm.h b/src/arm/lithium-codegen-arm.h index c219a6b..99c5943 100644 --- a/src/arm/lithium-codegen-arm.h +++ b/src/arm/lithium-codegen-arm.h @@ -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 type, Handle 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* instructions_; ZoneList deoptimizations_; + ZoneList deopt_jump_table_; ZoneList > deoptimization_literals_; int inlined_function_count_; Scope* const scope_;