Begin using the top-level code generator for code that is inside
authorkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 3 Nov 2009 14:48:59 +0000 (14:48 +0000)
committerkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 3 Nov 2009 14:48:59 +0000 (14:48 +0000)
directly-applied function literals that are themselves compiled with
the top-level code generator.

The choice is guarded by a test that the function is anonymous (thus
not expected to be recursive) and not in a loop.

A compilation hint is set in the shared function info and used to make
the choice.

Review URL: http://codereview.chromium.org/341081

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3206 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/arm/fast-codegen-arm.cc
src/ast.h
src/codegen.cc
src/compiler.cc
src/fast-codegen.cc
src/fast-codegen.h
src/ia32/fast-codegen-ia32.cc
src/objects-inl.h
src/objects.h
src/x64/fast-codegen-x64.cc

index f4d5bd11f966b0eab1e20459f9d7a1600cfd3e88..bd57fa01c75ecd8d571342d349263997cf751844 100644 (file)
@@ -92,7 +92,9 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) {
   }
 
   { Comment cmnt(masm_, "[ Body");
+    ASSERT(loop_depth() == 0);
     VisitStatements(fun->body());
+    ASSERT(loop_depth() == 0);
   }
 
   { Comment cmnt(masm_, "[ return <undefined>;");
@@ -323,7 +325,7 @@ void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
 
 
 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
-  Comment cmnt(masm_, "[ RegExp Literal");
+  Comment cmnt(masm_, "[ RegExpLiteral");
   Label done;
   // Registers will be used as follows:
   // r4 = JS function, literals array
@@ -818,8 +820,16 @@ void FastCodeGenerator::VisitCall(Call* expr) {
       EmitCallWithStub(expr);
     }
   } else {
-    // Call to some other function expression.
-    Visit(expr->expression());
+    // Call to some other expression.  If the expression is an anonymous
+    // function literal not called in a loop, mark it as one that should
+    // also use the fast code generator.
+    FunctionLiteral* lit = fun->AsFunctionLiteral();
+    if (lit != NULL &&
+        lit->name()->Equals(Heap::empty_string()) &&
+        loop_depth() == 0) {
+      lit->set_try_fast_codegen(true);
+    }
+    Visit(fun);
     // Load global receiver object.
     __ ldr(r1, CodeGenerator::GlobalObject());
     __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
@@ -890,7 +900,6 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
 
 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
   Comment cmnt(masm_, "[ UnaryOperation");
-
   switch (expr->op()) {
     case Token::VOID:
       Visit(expr->expression());
@@ -988,12 +997,12 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
 
 
 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
-  VariableProxy* v = expr->expression()->AsVariableProxy();
-  ASSERT(v->AsVariable() != NULL);
-  ASSERT(v->AsVariable()->is_global());
-
-  Visit(v);
+  Comment cmnt(masm_, "[ CountOperation");
+  VariableProxy* proxy = expr->expression()->AsVariableProxy();
+  ASSERT(proxy->AsVariable() != NULL);
+  ASSERT(proxy->AsVariable()->is_global());
 
+  Visit(proxy);
   __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS);
 
   switch (expr->context()) {
@@ -1020,7 +1029,7 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
     __ CallRuntime(Runtime::kNumberSub, 2);
   }
   // Call Store IC.
-  __ mov(r2, Operand(v->AsVariable()->name()));
+  __ mov(r2, Operand(proxy->AsVariable()->name()));
   __ ldr(ip, CodeGenerator::GlobalObject());
   __ push(ip);
   Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
@@ -1063,6 +1072,7 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
 
 
 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
+  Comment cmnt(masm_, "[ BinaryOperation");
   switch (expr->op()) {
     case Token::COMMA:
       ASSERT_EQ(Expression::kEffect, expr->left()->context());
@@ -1108,6 +1118,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
 
 
 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
+  Comment cmnt(masm_, "[ CompareOperation");
   ASSERT_EQ(Expression::kValue, expr->left()->context());
   ASSERT_EQ(Expression::kValue, expr->right()->context());
   Visit(expr->left());
index 590a3f8d369658e69d4284b03adb20f093f6d2c0..83f341c948b67dc868520ab31e7a21aff4b916f9 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -1302,7 +1302,8 @@ class FunctionLiteral: public Expression {
         is_expression_(is_expression),
         loop_nesting_(0),
         function_token_position_(RelocInfo::kNoPosition),
-        inferred_name_(Heap::empty_string()) {
+        inferred_name_(Heap::empty_string()),
+        try_fast_codegen_(false) {
 #ifdef DEBUG
     already_compiled_ = false;
 #endif
@@ -1345,6 +1346,9 @@ class FunctionLiteral: public Expression {
     inferred_name_ = inferred_name;
   }
 
+  bool try_fast_codegen() { return try_fast_codegen_; }
+  void set_try_fast_codegen(bool flag) { try_fast_codegen_ = flag; }
+
 #ifdef DEBUG
   void mark_as_compiled() {
     ASSERT(!already_compiled_);
@@ -1368,6 +1372,7 @@ class FunctionLiteral: public Expression {
   int loop_nesting_;
   int function_token_position_;
   Handle<String> inferred_name_;
+  bool try_fast_codegen_;
 #ifdef DEBUG
   bool already_compiled_;
 #endif
index 28c0ba5f9ef45e11616b6864cddf0e2659d7a8d9..57d5f51898fc9a5a156df37b523486719861c2fc 100644 (file)
@@ -271,6 +271,7 @@ void CodeGenerator::SetFunctionInfo(Handle<JSFunction> fun,
       lit->has_only_this_property_assignments(),
       lit->has_only_simple_this_property_assignments(),
       *lit->this_property_assignments());
+  fun->shared()->set_try_fast_codegen(lit->try_fast_codegen());
 }
 
 
index ba96542bfe180d7674f1d3df9355306766a4806b..d0a98f1d5a0eb34658e814899b6c2e40e1d1ceb3 100644 (file)
@@ -83,7 +83,8 @@ class CodeGenSelector: public AstVisitor {
 static Handle<Code> MakeCode(FunctionLiteral* literal,
                              Handle<Script> script,
                              Handle<Context> context,
-                             bool is_eval) {
+                             bool is_eval,
+                             Handle<SharedFunctionInfo> shared) {
   ASSERT(literal != NULL);
 
   // Rewrite the AST by introducing .result assignments where needed.
@@ -120,12 +121,21 @@ static Handle<Code> MakeCode(FunctionLiteral* literal,
 
   // Generate code and return it.
   if (FLAG_fast_compiler) {
-    CodeGenSelector selector;
-    CodeGenSelector::CodeGenTag code_gen = selector.Select(literal);
-    if (code_gen == CodeGenSelector::FAST) {
-      return FastCodeGenerator::MakeCode(literal, script, is_eval);
+    // If there is no shared function info, try the fast code
+    // generator for code in the global scope.  Otherwise obey the
+    // explicit hint in the shared function info.
+    if (shared.is_null() && !literal->scope()->is_global_scope()) {
+      if (FLAG_trace_bailout) PrintF("Non-global scope\n");
+    } else if (!shared.is_null() && !shared->try_fast_codegen()) {
+      if (FLAG_trace_bailout) PrintF("No hint to try fast\n");
+    } else {
+      CodeGenSelector selector;
+      CodeGenSelector::CodeGenTag code_gen = selector.Select(literal);
+      if (code_gen == CodeGenSelector::FAST) {
+        return FastCodeGenerator::MakeCode(literal, script, is_eval);
+      }
+      ASSERT(code_gen == CodeGenSelector::NORMAL);
     }
-    ASSERT(code_gen == CodeGenSelector::NORMAL);
   }
   return CodeGenerator::MakeCode(literal, script, is_eval);
 }
@@ -210,7 +220,8 @@ static Handle<JSFunction> MakeFunction(bool is_global,
   HistogramTimerScope timer(rate);
 
   // Compile the code.
-  Handle<Code> code = MakeCode(lit, script, context, is_eval);
+  Handle<Code> code = MakeCode(lit, script, context, is_eval,
+                               Handle<SharedFunctionInfo>::null());
 
   // Check for stack-overflow exceptions.
   if (code.is_null()) {
@@ -411,7 +422,8 @@ bool Compiler::CompileLazy(Handle<SharedFunctionInfo> shared,
   HistogramTimerScope timer(&Counters::compile_lazy);
 
   // Compile the code.
-  Handle<Code> code = MakeCode(lit, script, Handle<Context>::null(), false);
+  Handle<Code> code = MakeCode(lit, script, Handle<Context>::null(), false,
+                               shared);
 
   // Check for stack-overflow exception.
   if (code.is_null()) {
@@ -465,16 +477,17 @@ bool Compiler::CompileLazy(Handle<SharedFunctionInfo> shared,
 
 CodeGenSelector::CodeGenTag CodeGenSelector::Select(FunctionLiteral* fun) {
   Scope* scope = fun->scope();
-
-  if (!scope->is_global_scope()) {
-    if (FLAG_trace_bailout) PrintF("Non-global scope\n");
+  if (scope->num_heap_slots() != 0) {
+    if (FLAG_trace_bailout) PrintF("function has context slots\n");
+    return NORMAL;
+  }
+  if (scope->arguments() != NULL) {
+    if (FLAG_trace_bailout) PrintF("function uses 'arguments'\n");
     return NORMAL;
   }
-  ASSERT(scope->num_heap_slots() == 0);
-  ASSERT(scope->arguments() == NULL);
 
   has_supported_syntax_ = true;
-  VisitDeclarations(fun->scope()->declarations());
+  VisitDeclarations(scope->declarations());
   if (!has_supported_syntax_) return NORMAL;
 
   VisitStatements(fun->body());
index 3ea27825283cdcb0fe248fd381f028b33af471e6..983bcea529d3857f2f8a680237f106f67853bb2a 100644 (file)
@@ -75,6 +75,7 @@ int FastCodeGenerator::SlotOffset(Slot* slot) {
 
 void FastCodeGenerator::VisitDeclarations(
     ZoneList<Declaration*>* declarations) {
+  Comment cmnt(masm_, "[ Declarations");
   int length = declarations->length();
   int globals = 0;
   for (int i = 0; i < length; i++) {
@@ -289,6 +290,7 @@ void FastCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
 
 
 void FastCodeGenerator::VisitIfStatement(IfStatement* stmt) {
+  Comment cmnt(masm_, "[ IfStatement");
   // Expressions cannot recursively enter statements, there are no labels in
   // the state.
   ASSERT_EQ(NULL, true_label_);
@@ -350,9 +352,11 @@ void FastCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
 
 
 void FastCodeGenerator::VisitForStatement(ForStatement* stmt) {
+  Comment cmnt(masm_, "[ ForStatement");
   Label test, body, exit;
   if (stmt->init() != NULL) Visit(stmt->init());
 
+  increment_loop_depth();
   // Emit the test at the bottom of the loop (even if empty).
   __ jmp(&test);
   __ bind(&body);
@@ -377,6 +381,7 @@ void FastCodeGenerator::VisitForStatement(ForStatement* stmt) {
   }
 
   __ bind(&exit);
+  decrement_loop_depth();
 }
 
 
@@ -407,6 +412,7 @@ void FastCodeGenerator::VisitFunctionBoilerplateLiteral(
 
 
 void FastCodeGenerator::VisitConditional(Conditional* expr) {
+  Comment cmnt(masm_, "[ Conditional");
   ASSERT_EQ(Expression::kTest, expr->condition()->context());
   ASSERT_EQ(expr->context(), expr->then_expression()->context());
   ASSERT_EQ(expr->context(), expr->else_expression()->context());
@@ -447,6 +453,7 @@ void FastCodeGenerator::VisitSlot(Slot* expr) {
 
 
 void FastCodeGenerator::VisitLiteral(Literal* expr) {
+  Comment cmnt(masm_, "[ Literal");
   Move(expr->context(), expr);
 }
 
index 92af19ebd4f5902ecba8dc2b478b9d33c524ee4f..6a645fe38e89c55ab6282dddfce6637031ee5653 100644 (file)
@@ -43,6 +43,7 @@ class FastCodeGenerator: public AstVisitor {
         function_(NULL),
         script_(script),
         is_eval_(is_eval),
+        loop_depth_(0),
         true_label_(NULL),
         false_label_(NULL) {
   }
@@ -94,6 +95,13 @@ class FastCodeGenerator: public AstVisitor {
   void SetStatementPosition(Statement* stmt);
   void SetSourcePosition(int pos);
 
+  int loop_depth() { return loop_depth_; }
+  void increment_loop_depth() { loop_depth_++; }
+  void decrement_loop_depth() {
+    ASSERT(loop_depth_ > 0);
+    loop_depth_--;
+  }
+
   // AST node visit functions.
 #define DECLARE_VISIT(type) virtual void Visit##type(type* node);
   AST_NODE_LIST(DECLARE_VISIT)
@@ -107,6 +115,7 @@ class FastCodeGenerator: public AstVisitor {
   Handle<Script> script_;
   bool is_eval_;
   Label return_label_;
+  int loop_depth_;
 
   Label* true_label_;
   Label* false_label_;
index 02c19f67f587736c9ac50be297c8b40fe85f3906..12f90cd01c377dff993b3231642e48fbf3917e4f 100644 (file)
@@ -85,7 +85,9 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) {
   }
 
   { Comment cmnt(masm_, "[ Body");
+    ASSERT(loop_depth() == 0);
     VisitStatements(fun->body());
+    ASSERT(loop_depth() == 0);
   }
 
   { Comment cmnt(masm_, "[ return <undefined>;");
@@ -342,7 +344,7 @@ void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
 
 
 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
-  Comment cmnt(masm_, "[ RegExp Literal");
+  Comment cmnt(masm_, "[ RegExpLiteral");
   Label done;
   // Registers will be used as follows:
   // edi = JS function.
@@ -840,8 +842,16 @@ void FastCodeGenerator::VisitCall(Call* expr) {
       EmitCallWithStub(expr);
     }
   } else {
-    // Call to some other function expression.
-    Visit(expr->expression());
+    // Call to some other expression.  If the expression is an anonymous
+    // function literal not called in a loop, mark it as one that should
+    // also use the fast code generator.
+    FunctionLiteral* lit = fun->AsFunctionLiteral();
+    if (lit != NULL &&
+        lit->name()->Equals(Heap::empty_string()) &&
+        loop_depth() == 0) {
+      lit->set_try_fast_codegen(true);
+    }
+    Visit(fun);
     // Load global receiver object.
     __ mov(ebx, CodeGenerator::GlobalObject());
     __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
@@ -850,6 +860,7 @@ void FastCodeGenerator::VisitCall(Call* expr) {
   }
 }
 
+
 void FastCodeGenerator::VisitCallNew(CallNew* expr) {
   Comment cmnt(masm_, "[ CallNew");
   // According to ECMA-262, section 11.2.2, page 44, the function
@@ -910,7 +921,6 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
 
 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
   Comment cmnt(masm_, "[ UnaryOperation");
-
   switch (expr->op()) {
     case Token::VOID:
       Visit(expr->expression());
@@ -1003,12 +1013,12 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
 
 
 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
-  VariableProxy* v = expr->expression()->AsVariableProxy();
-  ASSERT(v->AsVariable() != NULL);
-  ASSERT(v->AsVariable()->is_global());
-
-  Visit(v);
+  Comment cmnt(masm_, "[ CountOperation");
+  VariableProxy* proxy = expr->expression()->AsVariableProxy();
+  ASSERT(proxy->AsVariable() != NULL);
+  ASSERT(proxy->AsVariable()->is_global());
 
+  Visit(proxy);
   __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION);
 
   switch (expr->context()) {
@@ -1034,7 +1044,7 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
     __ CallRuntime(Runtime::kNumberSub, 2);
   }
   // Call Store IC.
-  __ mov(ecx, v->AsVariable()->name());
+  __ mov(ecx, proxy->AsVariable()->name());
   __ push(CodeGenerator::GlobalObject());
   Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
   __ call(ic, RelocInfo::CODE_TARGET);
@@ -1076,6 +1086,7 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
 
 
 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
+  Comment cmnt(masm_, "[ BinaryOperation");
   switch (expr->op()) {
     case Token::COMMA:
       ASSERT_EQ(Expression::kEffect, expr->left()->context());
@@ -1120,6 +1131,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
 
 
 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
+  Comment cmnt(masm_, "[ CompareOperation");
   ASSERT_EQ(Expression::kValue, expr->left()->context());
   ASSERT_EQ(Expression::kValue, expr->right()->context());
   Visit(expr->left());
index 2350a35ba814f712a48c04b99ac0121207a9ede6..dca6fc8d3470626f014da025b460e8dd9b89d89d 100644 (file)
@@ -2538,7 +2538,10 @@ BOOL_GETTER(SharedFunctionInfo, compiler_hints,
 BOOL_GETTER(SharedFunctionInfo, compiler_hints,
             has_only_simple_this_property_assignments,
             kHasOnlySimpleThisPropertyAssignments)
-
+BOOL_ACCESSORS(SharedFunctionInfo,
+               compiler_hints,
+               try_fast_codegen,
+               kTryFastCodegen)
 
 INT_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
 INT_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
index 89cbd4463758e2e49c449c3d23ff1a1fe569b275..a8cbbfc4de6f45e4397a56c7ee75f922b2d96071 100644 (file)
@@ -3386,6 +3386,9 @@ class SharedFunctionInfo: public HeapObject {
   // this.x = y; where y is either a constant or refers to an argument.
   inline bool has_only_simple_this_property_assignments();
 
+  inline bool try_fast_codegen();
+  inline void set_try_fast_codegen(bool flag);
+
   // For functions which only contains this property assignments this provides
   // access to the names for the properties assigned.
   DECL_ACCESSORS(this_property_assignments, Object)
@@ -3466,6 +3469,7 @@ class SharedFunctionInfo: public HeapObject {
   // Bit positions in compiler_hints.
   static const int kHasOnlyThisPropertyAssignments = 0;
   static const int kHasOnlySimpleThisPropertyAssignments = 1;
+  static const int kTryFastCodegen = 2;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo);
 };
index bdf14a544f5a24f912ab8697a0e87a26d2c930bd..caa47367cc363ddcc6b08d36d2ca455cfb10d8d1 100644 (file)
@@ -84,7 +84,9 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) {
   }
 
   { Comment cmnt(masm_, "[ Body");
+    ASSERT(loop_depth() == 0);
     VisitStatements(fun->body());
+    ASSERT(loop_depth() == 0);
   }
 
   { Comment cmnt(masm_, "[ return <undefined>;");
@@ -360,7 +362,7 @@ void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
 
 
 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
-  Comment cmnt(masm_, "[ RegExp Literal");
+  Comment cmnt(masm_, "[ RegExpLiteral");
   Label done;
   // Registers will be used as follows:
   // rdi = JS function.
@@ -855,8 +857,16 @@ void FastCodeGenerator::VisitCall(Call* expr) {
       EmitCallWithStub(expr);
     }
   } else {
-    // Call to some other function expression.
-    Visit(expr->expression());
+    // Call to some other expression.  If the expression is an anonymous
+    // function literal not called in a loop, mark it as one that should
+    // also use the fast code generator.
+    FunctionLiteral* lit = fun->AsFunctionLiteral();
+    if (lit != NULL &&
+        lit->name()->Equals(Heap::empty_string()) &&
+        loop_depth() == 0) {
+      lit->set_try_fast_codegen(true);
+    }
+    Visit(fun);
     // Load global receiver object.
     __ movq(rbx, CodeGenerator::GlobalObject());
     __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset));
@@ -925,12 +935,12 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
 }
 
 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
-  VariableProxy* v = expr->expression()->AsVariableProxy();
-  ASSERT(v->AsVariable() != NULL);
-  ASSERT(v->AsVariable()->is_global());
-
-  Visit(v);
+  Comment cmnt(masm_, "[ CountOperation");
+  VariableProxy* proxy = expr->expression()->AsVariableProxy();
+  ASSERT(proxy->AsVariable() != NULL);
+  ASSERT(proxy->AsVariable()->is_global());
 
+  Visit(proxy);
   __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION);
 
   switch (expr->context()) {
@@ -956,7 +966,7 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
     __ CallRuntime(Runtime::kNumberSub, 2);
   }
   // Call Store IC.
-  __ Move(rcx, v->AsVariable()->name());
+  __ Move(rcx, proxy->AsVariable()->name());
   __ push(CodeGenerator::GlobalObject());
   Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
   __ call(ic, RelocInfo::CODE_TARGET);
@@ -999,7 +1009,6 @@ void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
 
 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
   Comment cmnt(masm_, "[ UnaryOperation");
-
   switch (expr->op()) {
     case Token::VOID:
       Visit(expr->expression());
@@ -1092,6 +1101,7 @@ void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
 
 
 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
+  Comment cmnt(masm_, "[ BinaryOperation");
   switch (expr->op()) {
     case Token::COMMA:
       ASSERT_EQ(Expression::kEffect, expr->left()->context());
@@ -1136,6 +1146,7 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
 
 
 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
+  Comment cmnt(masm_, "[ CompareOperation");
   ASSERT_EQ(Expression::kValue, expr->left()->context());
   ASSERT_EQ(Expression::kValue, expr->right()->context());
   Visit(expr->left());