From a4f065822766b30e0ad105a9c4386e565e5226d0 Mon Sep 17 00:00:00 2001 From: "alexandre.rames@arm.com" Date: Thu, 20 Feb 2014 16:40:53 +0000 Subject: [PATCH] A64: Improve the deoptimization helpers to generate fewer instructions. R=jochen@chromium.org Review URL: https://codereview.chromium.org/166343004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19516 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/a64/lithium-codegen-a64.cc | 93 ++++++++++++++---------------------------- src/a64/lithium-codegen-a64.h | 8 ++-- 2 files changed, 35 insertions(+), 66 deletions(-) diff --git a/src/a64/lithium-codegen-a64.cc b/src/a64/lithium-codegen-a64.cc index c983ac8..6ee4675 100644 --- a/src/a64/lithium-codegen-a64.cc +++ b/src/a64/lithium-codegen-a64.cc @@ -960,22 +960,26 @@ void LCodeGen::PopulateDeoptimizationLiteralsWithInlinedFunctions() { } -Deoptimizer::BailoutType LCodeGen::DeoptimizeHeader( +void LCodeGen::DeoptimizeBranch( LEnvironment* environment, + BranchType branch_type, Register reg, int bit, Deoptimizer::BailoutType* override_bailout_type) { RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); + Deoptimizer::BailoutType bailout_type = + info()->IsStub() ? Deoptimizer::LAZY : Deoptimizer::EAGER; + + if (override_bailout_type != NULL) { + bailout_type = *override_bailout_type; + } + ASSERT(environment->HasBeenRegistered()); ASSERT(info()->IsOptimizing() || info()->IsStub()); int id = environment->deoptimization_index(); - Deoptimizer::BailoutType bailout_type = - info()->IsStub() ? Deoptimizer::LAZY : Deoptimizer::EAGER; - if (override_bailout_type) bailout_type = *override_bailout_type; Address entry = Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); if (entry == NULL) { Abort(kBailoutWasNotPrepared); - return bailout_type; } if (FLAG_deopt_every_n_times != 0 && !info()->IsStub()) { @@ -1001,26 +1005,20 @@ Deoptimizer::BailoutType LCodeGen::DeoptimizeHeader( __ Pop(x0, x1, x2); } - return bailout_type; -} - - -void LCodeGen::Deoptimize(LEnvironment* environment, - Deoptimizer::BailoutType bailout_type) { - ASSERT(environment->HasBeenRegistered()); - ASSERT(info()->IsOptimizing() || info()->IsStub()); - int id = environment->deoptimization_index(); - Address entry = - Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); - if (info()->ShouldTrapOnDeopt()) { + Label dont_trap; + __ B(&dont_trap, InvertBranchType(branch_type), reg, bit); __ Debug("trap_on_deopt", __LINE__, BREAK); + __ Bind(&dont_trap); } ASSERT(info()->IsStub() || frame_is_built_); // Go through jump table if we need to build frame, or restore caller doubles. if (frame_is_built_ && !info()->saves_caller_doubles()) { + Label dont_deopt; + __ B(&dont_deopt, InvertBranchType(branch_type), reg, bit); __ Call(entry, RelocInfo::RUNTIME_ENTRY); + __ Bind(&dont_deopt); } else { // We often have several deopts to the same entry, reuse the last // jump entry if this is the case. @@ -1033,82 +1031,58 @@ void LCodeGen::Deoptimize(LEnvironment* environment, !frame_is_built_); deopt_jump_table_.Add(table_entry, zone()); } - __ B(&deopt_jump_table_.last().label); + __ B(&deopt_jump_table_.last().label, + branch_type, reg, bit); } } -void LCodeGen::Deoptimize(LEnvironment* environment) { - Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment, NULL); - Deoptimize(environment, bailout_type); +void LCodeGen::Deoptimize(LEnvironment* environment, + Deoptimizer::BailoutType* override_bailout_type) { + DeoptimizeBranch(environment, always, NoReg, -1, override_bailout_type); } void LCodeGen::DeoptimizeIf(Condition cond, LEnvironment* environment) { - Label dont_deopt; - Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment, NULL); - __ B(InvertCondition(cond), &dont_deopt); - Deoptimize(environment, bailout_type); - __ Bind(&dont_deopt); + DeoptimizeBranch(environment, static_cast(cond)); } void LCodeGen::DeoptimizeIfZero(Register rt, LEnvironment* environment) { - Label dont_deopt; - Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment, NULL); - __ Cbnz(rt, &dont_deopt); - Deoptimize(environment, bailout_type); - __ Bind(&dont_deopt); + DeoptimizeBranch(environment, reg_zero, rt); } void LCodeGen::DeoptimizeIfNegative(Register rt, LEnvironment* environment) { - Label dont_deopt; - Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment, NULL); - __ Tbz(rt, rt.Is64Bits() ? kXSignBit : kWSignBit, &dont_deopt); - Deoptimize(environment, bailout_type); - __ Bind(&dont_deopt); + int sign_bit = rt.Is64Bits() ? kXSignBit : kWSignBit; + DeoptimizeBranch(environment, reg_bit_set, rt, sign_bit); } void LCodeGen::DeoptimizeIfSmi(Register rt, LEnvironment* environment) { - Label dont_deopt; - Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment, NULL); - __ JumpIfNotSmi(rt, &dont_deopt); - Deoptimize(environment, bailout_type); - __ Bind(&dont_deopt); + DeoptimizeBranch(environment, reg_bit_clear, rt, MaskToBit(kSmiTagMask)); } void LCodeGen::DeoptimizeIfNotSmi(Register rt, LEnvironment* environment) { - Label dont_deopt; - Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment, NULL); - __ JumpIfSmi(rt, &dont_deopt); - Deoptimize(environment, bailout_type); - __ Bind(&dont_deopt); + DeoptimizeBranch(environment, reg_bit_set, rt, MaskToBit(kSmiTagMask)); } void LCodeGen::DeoptimizeIfRoot(Register rt, Heap::RootListIndex index, LEnvironment* environment) { - Label dont_deopt; - Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment, NULL); - __ JumpIfNotRoot(rt, index, &dont_deopt); - Deoptimize(environment, bailout_type); - __ Bind(&dont_deopt); + __ CompareRoot(rt, index); + DeoptimizeIf(eq, environment); } void LCodeGen::DeoptimizeIfNotRoot(Register rt, Heap::RootListIndex index, LEnvironment* environment) { - Label dont_deopt; - Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment, NULL); - __ JumpIfRoot(rt, index, &dont_deopt); - Deoptimize(environment, bailout_type); - __ Bind(&dont_deopt); + __ CompareRoot(rt, index); + DeoptimizeIf(ne, environment); } @@ -2135,9 +2109,6 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) { void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { if (!instr->hydrogen()->value()->IsHeapObject()) { - // TODO(all): Depending of how we chose to implement the deopt, if we could - // guarantee that we have a deopt handler reachable by a tbz instruction, - // we could use tbz here and produce less code to support this instruction. DeoptimizeIfSmi(ToRegister(instr->value()), instr->environment()); } } @@ -2146,7 +2117,6 @@ void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { void LCodeGen::DoCheckSmi(LCheckSmi* instr) { Register value = ToRegister(instr->value()); ASSERT(!instr->result() || ToRegister(instr->result()).Is(value)); - // TODO(all): See DoCheckNonSmi for comments on use of tbz. DeoptimizeIfNotSmi(value, instr->environment()); } @@ -2586,8 +2556,7 @@ void LCodeGen::DoDeoptimize(LDeoptimize* instr) { } Comment(";;; deoptimize: %s", instr->hydrogen()->reason()); - DeoptimizeHeader(instr->environment(), &type); - Deoptimize(instr->environment(), type); + Deoptimize(instr->environment(), &type); } diff --git a/src/a64/lithium-codegen-a64.h b/src/a64/lithium-codegen-a64.h index 0061651..74dad62 100644 --- a/src/a64/lithium-codegen-a64.h +++ b/src/a64/lithium-codegen-a64.h @@ -218,12 +218,12 @@ class LCodeGen: public LCodeGenBase { Register temp, LOperand* index, String::Encoding encoding); - Deoptimizer::BailoutType DeoptimizeHeader( + void DeoptimizeBranch( LEnvironment* environment, - Deoptimizer::BailoutType* override_bailout_type); - void Deoptimize(LEnvironment* environment); + BranchType branch_type, Register reg = NoReg, int bit = -1, + Deoptimizer::BailoutType* override_bailout_type = NULL); void Deoptimize(LEnvironment* environment, - Deoptimizer::BailoutType bailout_type); + Deoptimizer::BailoutType* override_bailout_type = NULL); void DeoptimizeIf(Condition cc, LEnvironment* environment); void DeoptimizeIfZero(Register rt, LEnvironment* environment); void DeoptimizeIfNegative(Register rt, LEnvironment* environment); -- 2.7.4