A64: Improve the deoptimization helpers to generate fewer instructions.
authoralexandre.rames@arm.com <alexandre.rames@arm.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 20 Feb 2014 16:40:53 +0000 (16:40 +0000)
committeralexandre.rames@arm.com <alexandre.rames@arm.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 20 Feb 2014 16:40:53 +0000 (16:40 +0000)
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
src/a64/lithium-codegen-a64.h

index c983ac8..6ee4675 100644 (file)
@@ -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<BranchType>(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);
 }
 
 
index 0061651..74dad62 100644 (file)
@@ -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);