Reviewers: rossberg,

Description:
Fix to_boolean type feedback for unary and binary ops

BUG=

Please review this at https://codereview.chromium.org/17444011/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/arm/lithium-codegen-arm.cc
  M src/ast.h
  M src/ast.cc
  M src/hydrogen.cc
  M src/ia32/lithium-codegen-ia32.cc
  M src/typing.cc
  M src/x64/lithium-codegen-x64.cc


Index: src/arm/lithium-codegen-arm.cc
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index b9a3a0bfec6eab310f0634f80ba1af81a9e56410..04623c1ddaae5e9671f244a99927d21b2e1dcaa6 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -2313,7 +2313,11 @@ void LCodeGen::DoBranch(LBranch* instr) {
       if (!expected.IsGeneric()) {
         // We've seen something for the first time -> deopt.
         // This can only happen if we are not generic already.
-        DeoptimizeIf(al, instr->environment());
+        if (!info()->IsStub()) {
+          SoftDeoptimize(instr->environment());
+        } else {
+          DeoptimizeIf(al, instr->environment());
+        }
       }
     }
   }
Index: src/ast.cc
diff --git a/src/ast.cc b/src/ast.cc
index f2ec67f69b7efb899e937089759f2f5d6a6c9cb5..d2e823c34fa9d9cb9966cdfbde20dfd52d2b5cc7 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -428,7 +428,13 @@ void ForInStatement::RecordTypeFeedback(TypeFeedbackOracle* oracle) {


 void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) {
-  to_boolean_types_ = oracle->ToBooleanTypes(test_id());
+  to_boolean_types_ |= oracle->ToBooleanTypes(test_id());
+}
+
+
+void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle,
+    TypeFeedbackId origin) {
+  to_boolean_types_ |= oracle->ToBooleanTypes(origin);
 }


Index: src/ast.h
diff --git a/src/ast.h b/src/ast.h
index 249f7c0149be72cbfc7eb34da83e0b05c5511fb7..239d51083ff035bba5c1cea6842b2cd69b33e188 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -384,6 +384,8 @@ class Expression: public AstNode {

   // TODO(rossberg): this should move to its own AST node eventually.
   void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle);
+  void RecordToBooleanTypeFeedback(
+      TypeFeedbackOracle* oracle, TypeFeedbackId origin);
   byte to_boolean_types() const { return to_boolean_types_; }

   BailoutId id() const { return id_; }
@@ -393,12 +395,14 @@ class Expression: public AstNode {
   explicit Expression(Isolate* isolate)
       : upper_type_(Type::Any(), isolate),
         lower_type_(Type::None(), isolate),
+        to_boolean_types_(0),
         id_(GetNextId(isolate)),
-        test_id_(GetNextId(isolate)) {}
+        test_id_(GetNextId(isolate)) { }

  private:
   Handle<Type> upper_type_;
   Handle<Type> lower_type_;
+
   byte to_boolean_types_;

   const BailoutId id_;
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 33557a29f2e77314f0730606c1a0af671648984c..2e09660999d6f11242eecdb51a0cf010063a6d11 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -8160,17 +8160,19 @@ bool HOptimizedGraphBuilder::TryInline(CallKind call_kind,
     ClearInlinedTestContext();
     delete target_state;

+    TestContext* test_context = TestContext::cast(ast_context());
+
     // Forward to the real test context.
     if (if_true->HasPredecessor()) {
       entry->RegisterReturnTarget(if_true, zone());
       if_true->SetJoinId(ast_id);
- HBasicBlock* true_target = TestContext::cast(ast_context())->if_true();
+      HBasicBlock* true_target = test_context->if_true();
       if_true->Goto(true_target, function_state());
     }
     if (if_false->HasPredecessor()) {
       entry->RegisterReturnTarget(if_false, zone());
       if_false->SetJoinId(ast_id);
- HBasicBlock* false_target = TestContext::cast(ast_context())->if_false();
+      HBasicBlock* false_target = test_context->if_false();
       if_false->Goto(false_target, function_state());
     }
     set_current_block(NULL);
Index: src/ia32/lithium-codegen-ia32.cc
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index b67441f93797f4ba4f9daea1d052650cfd96a8ab..3e8b1aa4edc8b9dc67906f62f2a3fa30da987273 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -2240,7 +2240,11 @@ void LCodeGen::DoBranch(LBranch* instr) {
       if (!expected.IsGeneric()) {
         // We've seen something for the first time -> deopt.
         // This can only happen if we are not generic already.
-        DeoptimizeIf(no_condition, instr->environment());
+        if (!info()->IsStub()) {
+          SoftDeoptimize(instr->environment());
+        } else {
+          DeoptimizeIf(no_condition, instr->environment());
+        }
       }
     }
   }
Index: src/typing.cc
diff --git a/src/typing.cc b/src/typing.cc
index e890333d135e36750a546cc61eac25e78ee60005..295b9c370f65829fe0307933332ef9a0b7e41778 100644
--- a/src/typing.cc
+++ b/src/typing.cc
@@ -409,7 +409,7 @@ void AstTyper::VisitUnaryOperation(UnaryOperation* expr) {
   MergeLowerType(expr->expression(), op_type);
   if (expr->op() == Token::NOT) {
     // TODO(rossberg): only do in test or value context.
-    expr->expression()->RecordToBooleanTypeFeedback(oracle());
+ expr->RecordToBooleanTypeFeedback(oracle(), expr->expression()->test_id());
   }
 }

@@ -441,7 +441,8 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
   MergeLowerType(expr->right(), right_type);
   expr->set_fixed_right_arg(fixed_right_arg);
   if (expr->op() == Token::OR || expr->op() == Token::AND) {
-    expr->left()->RecordToBooleanTypeFeedback(oracle());
+    expr->RecordToBooleanTypeFeedback(oracle(), expr->left()->test_id());
+    expr->RecordToBooleanTypeFeedback(oracle(), expr->right()->test_id());
   }
 }

Index: src/x64/lithium-codegen-x64.cc
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 0ce44868a01343af268eb48b44b1961774467226..bb929e8b36599860beeb43214a06490c931961ce 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -2010,7 +2010,11 @@ void LCodeGen::DoBranch(LBranch* instr) {
       if (!expected.IsGeneric()) {
         // We've seen something for the first time -> deopt.
         // This can only happen if we are not generic already.
-        DeoptimizeIf(no_condition, instr->environment());
+        if (!info()->IsStub()) {
+          SoftDeoptimize(instr->environment());
+        } else {
+          DeoptimizeIf(no_condition, instr->environment());
+        }
       }
     }
   }


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to