Revision: 3998
Author: [email protected]
Date: Tue Mar  2 06:00:59 2010
Log: Add syntax checker for side-effect-free expressions to AstOptimizer in rewriter.cc. Add bit fields for syntax checker results to Expression in ast.h.
Review URL: http://codereview.chromium.org/660372
http://code.google.com/p/v8/source/detail?r=3998

Modified:
 /branches/bleeding_edge/src/ast.h
 /branches/bleeding_edge/src/rewriter.cc

=======================================
--- /branches/bleeding_edge/src/ast.h   Tue Mar  2 03:58:10 2010
+++ /branches/bleeding_edge/src/ast.h   Tue Mar  2 06:00:59 2010
@@ -183,7 +183,11 @@

   static const int kNoLabel = -1;

-  Expression() : num_(kNoLabel), def_(NULL), defined_vars_(NULL) {}
+  Expression()
+      : bitfields_(0),
+        num_(kNoLabel),
+        def_(NULL),
+        defined_vars_(NULL) {}

   virtual Expression* AsExpression()  { return this; }

@@ -224,12 +228,67 @@
   void set_defined_vars(ZoneList<DefinitionInfo*>* defined_vars) {
     defined_vars_ = defined_vars;
   }
+
+  // AST analysis results
+
+  // True if the expression rooted at this node can be compiled by the
+  // side-effect free compiler.
+ bool side_effect_free() { return SideEffectFreeField::decode(bitfields_); }
+  void set_side_effect_free(bool is_side_effect_free) {
+    bitfields_ = (bitfields_ & ~SideEffectFreeField::mask()) |
+                 SideEffectFreeField::encode(is_side_effect_free);
+  }
+
+  // The number of unary and binary operations contained in the expression
+  // rooted at this node.  Valid only if side_effect_free() is true.
+  int expression_size() { return ExpressionSizeField::decode(bitfields_); }
+  void set_expression_size(int expression_size) {
+    bitfields_ = (bitfields_ & ~ExpressionSizeField::mask()) |
+ ExpressionSizeField::encode(Min(expression_size, ExpressionSizeMax));
+  }
+
+  // The number of expression stack slots needed to compute the expression
+  // rooted at this node.  Does not count the slot needed by the value
+  // computed by this expression. Valid only if side_effect_free() is true.
+  int stack_height() { return StackHeightField::decode(bitfields_); }
+  void set_stack_height(int stack_height) {
+    bitfields_ &= ~StackHeightField::mask();
+    bitfields_ |=
+        StackHeightField::encode(Min(stack_height, StackHeightMax));
+  }

  private:
+  uint32_t bitfields_;
   StaticType type_;
+
   int num_;
   DefinitionInfo* def_;
   ZoneList<DefinitionInfo*>* defined_vars_;
+
+  static const int SideEffectFreeFieldStart = 0;
+  static const int SideEffectFreeFieldLength = 1;
+  class SideEffectFreeField: public BitField<bool,
+                                             SideEffectFreeFieldStart,
+                                             SideEffectFreeFieldLength> {
+  };
+
+  static const int ExpressionSizeFieldStart =
+      SideEffectFreeFieldStart + SideEffectFreeFieldLength;
+  static const int ExpressionSizeFieldLength = 5;
+ static const int ExpressionSizeMax = (1 << ExpressionSizeFieldLength) - 1;
+  class ExpressionSizeField: public BitField<int,
+                                             ExpressionSizeFieldStart,
+                                             ExpressionSizeFieldLength> {
+  };
+
+  static const int StackHeightFieldStart =
+      ExpressionSizeFieldStart + ExpressionSizeFieldLength;
+  static const int StackHeightFieldLength = 5;
+  static const int StackHeightMax = (1 << StackHeightFieldLength) - 1;
+  class StackHeightField: public BitField<int,
+                                          StackHeightFieldStart,
+                                          StackHeightFieldLength> {
+  };
 };


=======================================
--- /branches/bleeding_edge/src/rewriter.cc     Wed Dec 16 22:21:50 2009
+++ /branches/bleeding_edge/src/rewriter.cc     Tue Mar  2 06:00:59 2010
@@ -244,6 +244,14 @@
         !Heap::result_symbol()->Equals(*var->name())) {
       func_name_inferrer_.PushName(var->name());
     }
+
+    if (var->slot() != NULL) {
+      Slot* slot = var->slot();
+      node->set_side_effect_free(
+          (slot->type() == Slot::LOCAL  && !slot->is_arguments()) ||
+          slot->type() == Slot::PARAMETER));
+      // stack_height and expression_size remain 0.
+    }
   }
 }

@@ -252,11 +260,16 @@
   Handle<Object> literal = node->handle();
   if (literal->IsSmi()) {
     node->type()->SetAsLikelySmi();
+    node->set_side_effect_free(true);
+    // stack_height and expression_size remain 0.
   } else if (literal->IsString()) {
     Handle<String> lit_str(Handle<String>::cast(literal));
     if (!Heap::prototype_symbol()->Equals(*lit_str)) {
       func_name_inferrer_.PushName(lit_str);
     }
+  } else if (literal->IsHeapNumber()) {
+    node->set_side_effect_free(true);
+    // stack_height and expression_size remain 0.
   }
 }

@@ -414,6 +427,23 @@

 void AstOptimizer::VisitUnaryOperation(UnaryOperation* node) {
   Visit(node->expression());
+  switch (node->op()) {
+    case Token::ADD:
+    case Token::SUB:
+      node->set_side_effect_free(node->expression()->side_effect_free());
+      node->set_expression_size(node->expression()->expression_size() + 1);
+      node->set_stack_height(node->expression()->stack_height());
+      break;
+    case Token::DELETE:
+    case Token::TYPEOF:
+    case Token::VOID:
+    case Token::BIT_NOT:
+    case Token::NOT:
+      break;
+    default:
+      UNREACHABLE();
+      break;
+  }
 }


@@ -483,6 +513,33 @@
       }
     }
   }
+  switch (node->op()) {
+    case Token::COMMA:
+    case Token::OR:
+    case Token::AND:
+    case Token::BIT_OR:
+    case Token::BIT_XOR:
+    case Token::BIT_AND:
+    case Token::SHL:
+    case Token::SAR:
+    case Token::SHR:
+    case Token::MOD:
+      break;
+    case Token::ADD:
+    case Token::SUB:
+    case Token::MUL:
+    case Token::DIV:
+      node->set_side_effect_free(node->left()->side_effect_free() &&
+                                 node->right()->side_effect_free());
+      node->set_expression_size(node->left()->expression_size() +
+                                node->right()->expression_size() + 1);
+      node->set_stack_height(Max(node->left()->stack_height(),
+                                 node->right()->stack_height() + 1));
+      break;
+    default:
+      UNREACHABLE();
+      break;
+  }
 }


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to