Reviewers: William Hesse,

Description:
Revert r6194: Clean up code for type feedback a bit.

This causes a big performance regression. I'll investigate.


Please review this at http://codereview.chromium.org/6172001/

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

Affected files:
  M     src/ast.h
  M     src/ast.cc
  M     src/hydrogen.cc
  M     src/type-info.h
  M     src/type-info.cc


Index: src/ast.cc
===================================================================
--- src/ast.cc  (revision 6216)
+++ src/ast.cc  (working copy)
@@ -649,11 +649,19 @@
 }


+void BinaryOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
+  TypeInfo left = oracle->BinaryType(this, TypeFeedbackOracle::LEFT);
+  TypeInfo right = oracle->BinaryType(this, TypeFeedbackOracle::RIGHT);
+  is_smi_only_ = left.IsSmi() && right.IsSmi();
+}
+
+
 void CompareOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
-  TypeInfo info = oracle->CompareType(this);
-  if (info.IsSmi()) {
+  TypeInfo left = oracle->CompareType(this, TypeFeedbackOracle::LEFT);
+  TypeInfo right = oracle->CompareType(this, TypeFeedbackOracle::RIGHT);
+  if (left.IsSmi() && right.IsSmi()) {
     compare_type_ = SMI_ONLY;
-  } else if (info.IsNonPrimitive()) {
+  } else if (left.IsNonPrimitive() && right.IsNonPrimitive()) {
     compare_type_ = OBJECT_ONLY;
   } else {
     ASSERT(compare_type_ == NONE);
Index: src/ast.h
===================================================================
--- src/ast.h   (revision 6216)
+++ src/ast.h   (working copy)
@@ -1392,7 +1392,7 @@
                   Expression* left,
                   Expression* right,
                   int pos)
-      : op_(op), left_(left), right_(right), pos_(pos) {
+ : op_(op), left_(left), right_(right), pos_(pos), is_smi_only_(false) {
     ASSERT(Token::IsBinaryOp(op));
     right_id_ = (op == Token::AND || op == Token::OR)
         ? static_cast<int>(GetNextId())
@@ -1413,6 +1413,10 @@
   Expression* right() const { return right_; }
   int position() const { return pos_; }

+  // Type feedback information.
+  void RecordTypeFeedback(TypeFeedbackOracle* oracle);
+  bool IsSmiOnly() const { return is_smi_only_; }
+
   // Bailout support.
   int RightId() const { return right_id_; }

@@ -1421,6 +1425,7 @@
   Expression* left_;
   Expression* right_;
   int pos_;
+  bool is_smi_only_;
   // The short-circuit logical operations have an AST ID for their
   // right-hand subexpression.
   int right_id_;
Index: src/hydrogen.cc
===================================================================
--- src/hydrogen.cc     (revision 6216)
+++ src/hydrogen.cc     (working copy)
@@ -3366,6 +3366,7 @@
   // We have a second position recorded in the FullCodeGenerator to have
   // type feedback for the binary operation.
   BinaryOperation* operation = expr->binary_operation();
+  operation->RecordTypeFeedback(oracle());

   if (var != NULL) {
     if (!var->is_global() && !var->IsStackAllocated()) {
@@ -4730,7 +4731,7 @@
     default:
       UNREACHABLE();
   }
-  TypeInfo info = oracle()->BinaryType(expr);
+  TypeInfo info = oracle()->BinaryType(expr, TypeFeedbackOracle::RESULT);
   // If we hit an uninitialized binary op stub we will get type info
   // for a smi operation. If one of the operands is a constant string
   // do not generate code assuming it is a smi operation.
@@ -4875,7 +4876,7 @@
   HValue* left = Pop();
   Token::Value op = expr->op();

-  TypeInfo info = oracle()->CompareType(expr);
+  TypeInfo info = oracle()->CompareType(expr, TypeFeedbackOracle::RESULT);
   HInstruction* instr = NULL;
   if (op == Token::INSTANCEOF) {
     // Check to see if the rhs of the instanceof is a global function not
Index: src/type-info.cc
===================================================================
--- src/type-info.cc    (revision 6216)
+++ src/type-info.cc    (working copy)
@@ -132,7 +132,7 @@
 }


-TypeInfo TypeFeedbackOracle::CompareType(CompareOperation* expr) {
+TypeInfo TypeFeedbackOracle::CompareType(CompareOperation* expr, Side side) {
   Handle<Object> object = GetElement(map_, expr->position());
   TypeInfo unknown = TypeInfo::Unknown();
   if (!object->IsCode()) return unknown;
@@ -159,12 +159,27 @@
 }


-TypeInfo TypeFeedbackOracle::BinaryType(BinaryOperation* expr) {
+TypeInfo TypeFeedbackOracle::BinaryType(BinaryOperation* expr, Side side) {
   Handle<Object> object = GetElement(map_, expr->position());
   TypeInfo unknown = TypeInfo::Unknown();
   if (!object->IsCode()) return unknown;
   Handle<Code> code = Handle<Code>::cast(object);
-  if (code->is_type_recording_binary_op_stub()) {
+  if (code->is_binary_op_stub()) {
+    BinaryOpIC::TypeInfo type = static_cast<BinaryOpIC::TypeInfo>(
+        code->binary_op_type());
+    switch (type) {
+      case BinaryOpIC::UNINIT_OR_SMI:
+        return TypeInfo::Smi();
+      case BinaryOpIC::DEFAULT:
+        return (expr->op() == Token::DIV || expr->op() == Token::MUL)
+            ? TypeInfo::Double()
+            : TypeInfo::Integer32();
+      case BinaryOpIC::HEAP_NUMBERS:
+        return TypeInfo::Double();
+      default:
+        return unknown;
+    }
+  } else if (code->is_type_recording_binary_op_stub()) {
     TRBinaryOpIC::TypeInfo type = static_cast<TRBinaryOpIC::TypeInfo>(
         code->type_recording_binary_op_type());
TRBinaryOpIC::TypeInfo result_type = static_cast<TRBinaryOpIC::TypeInfo>(
@@ -276,7 +291,8 @@
     int position = source_positions[i];
     InlineCacheState state = target->ic_state();
     Code::Kind kind = target->kind();
-    if (kind == Code::TYPE_RECORDING_BINARY_OP_IC ||
+    if (kind == Code::BINARY_OP_IC ||
+        kind == Code::TYPE_RECORDING_BINARY_OP_IC ||
         kind == Code::COMPARE_IC) {
       // TODO(kasperl): Avoid having multiple ICs with the same
       // position by making sure that we have position information
@@ -316,17 +332,19 @@
       if (target->is_inline_cache_stub()) {
         InlineCacheState state = target->ic_state();
         Code::Kind kind = target->kind();
-        if (kind == Code::TYPE_RECORDING_BINARY_OP_IC &&
- target->type_recording_binary_op_type() == TRBinaryOpIC::GENERIC) {
-          continue;
-        } else if (kind == Code::COMPARE_IC &&
-                   target->compare_state() == CompareIC::GENERIC) {
-          continue;
-        } else if (kind == Code::CALL_IC && state == MONOMORPHIC &&
-                   target->check_type() != RECEIVER_MAP_CHECK) {
-          continue;
-        } else if (state != MONOMORPHIC && state != MEGAMORPHIC) {
-          continue;
+        if (kind == Code::BINARY_OP_IC) {
+          if (target->binary_op_type() == BinaryOpIC::GENERIC) continue;
+        } else if (kind == Code::TYPE_RECORDING_BINARY_OP_IC) {
+          if (target->type_recording_binary_op_type() ==
+              TRBinaryOpIC::GENERIC) {
+            continue;
+          }
+        } else if (kind == Code::COMPARE_IC) {
+          if (target->compare_state() == CompareIC::GENERIC) continue;
+        } else {
+          if (kind == Code::CALL_IC && state == MONOMORPHIC &&
+              target->check_type() != RECEIVER_MAP_CHECK) continue;
+          if (state != MONOMORPHIC && state != MEGAMORPHIC) continue;
         }
         code_positions->Add(
             static_cast<int>(info->pc() - code->instruction_start()));
Index: src/type-info.h
===================================================================
--- src/type-info.h     (revision 6216)
+++ src/type-info.h     (working copy)
@@ -230,6 +230,12 @@

 class TypeFeedbackOracle BASE_EMBEDDED {
  public:
+  enum Side {
+    LEFT,
+    RIGHT,
+    RESULT
+  };
+
   explicit TypeFeedbackOracle(Handle<Code> code);

   bool LoadIsMonomorphic(Property* expr);
@@ -247,8 +253,8 @@
   bool LoadIsBuiltin(Property* expr, Builtins::Name id);

   // Get type information for arithmetic operations and compares.
-  TypeInfo BinaryType(BinaryOperation* expr);
-  TypeInfo CompareType(CompareOperation* expr);
+  TypeInfo BinaryType(BinaryOperation* expr, Side side);
+  TypeInfo CompareType(CompareOperation* expr, Side side);
   TypeInfo SwitchType(CaseClause* clause);

  private:


--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev

Reply via email to