From 3eb69a34fa7df88eb8623913e366386c6c0b4f7d Mon Sep 17 00:00:00 2001 From: "kmillikin@chromium.org" Date: Tue, 3 Nov 2009 14:48:59 +0000 Subject: [PATCH] Begin using the top-level code generator for code that is inside 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 | 31 +++++++++++++++++++++---------- src/ast.h | 7 ++++++- src/codegen.cc | 1 + src/compiler.cc | 41 +++++++++++++++++++++++++++-------------- src/fast-codegen.cc | 7 +++++++ src/fast-codegen.h | 9 +++++++++ src/ia32/fast-codegen-ia32.cc | 32 ++++++++++++++++++++++---------- src/objects-inl.h | 5 ++++- src/objects.h | 4 ++++ src/x64/fast-codegen-x64.cc | 31 +++++++++++++++++++++---------- 10 files changed, 122 insertions(+), 46 deletions(-) diff --git a/src/arm/fast-codegen-arm.cc b/src/arm/fast-codegen-arm.cc index f4d5bd1..bd57fa0 100644 --- a/src/arm/fast-codegen-arm.cc +++ b/src/arm/fast-codegen-arm.cc @@ -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 ;"); @@ -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 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()); diff --git a/src/ast.h b/src/ast.h index 590a3f8d..83f341c 100644 --- 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 inferred_name_; + bool try_fast_codegen_; #ifdef DEBUG bool already_compiled_; #endif diff --git a/src/codegen.cc b/src/codegen.cc index 28c0ba5..57d5f51 100644 --- a/src/codegen.cc +++ b/src/codegen.cc @@ -271,6 +271,7 @@ void CodeGenerator::SetFunctionInfo(Handle 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()); } diff --git a/src/compiler.cc b/src/compiler.cc index ba96542..d0a98f1 100644 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -83,7 +83,8 @@ class CodeGenSelector: public AstVisitor { static Handle MakeCode(FunctionLiteral* literal, Handle