Revision: 5866
Author: [email protected]
Date: Mon Nov 22 01:57:21 2010
Log: Force pretenuring of closures that are immediately assigned to
properties. For these closures we would like to be able to use
constant functions and for that we need the closures allocated in old
space.
Review URL: http://codereview.chromium.org/5220007
http://code.google.com/p/v8/source/detail?r=5866

Modified:
 /branches/bleeding_edge/src/arm/code-stubs-arm.cc
 /branches/bleeding_edge/src/arm/codegen-arm.cc
 /branches/bleeding_edge/src/arm/codegen-arm.h
 /branches/bleeding_edge/src/arm/full-codegen-arm.cc
 /branches/bleeding_edge/src/ast.h
 /branches/bleeding_edge/src/full-codegen.cc
 /branches/bleeding_edge/src/full-codegen.h
 /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc
 /branches/bleeding_edge/src/ia32/codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/codegen-ia32.h
 /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc
 /branches/bleeding_edge/src/parser.cc
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/runtime.h
 /branches/bleeding_edge/src/x64/code-stubs-x64.cc
 /branches/bleeding_edge/src/x64/codegen-x64.cc
 /branches/bleeding_edge/src/x64/codegen-x64.h
 /branches/bleeding_edge/src/x64/full-codegen-x64.cc

=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.cc Tue Oct 19 04:14:03 2010 +++ /branches/bleeding_edge/src/arm/code-stubs-arm.cc Mon Nov 22 01:57:21 2010
@@ -100,8 +100,9 @@

   // Create a new closure through the slower runtime call.
   __ bind(&gc);
-  __ Push(cp, r3);
-  __ TailCallRuntime(Runtime::kNewClosure, 2, 1);
+  __ LoadRoot(r4, Heap::kFalseValueRootIndex);
+  __ Push(cp, r3, r4);
+  __ TailCallRuntime(Runtime::kNewClosure, 3, 1);
 }


=======================================
--- /branches/bleeding_edge/src/arm/codegen-arm.cc      Fri Nov 19 01:25:46 2010
+++ /branches/bleeding_edge/src/arm/codegen-arm.cc      Mon Nov 22 01:57:21 2010
@@ -3103,10 +3103,13 @@


 void CodeGenerator::InstantiateFunction(
-    Handle<SharedFunctionInfo> function_info) {
+    Handle<SharedFunctionInfo> function_info,
+    bool pretenure) {
   // Use the fast case closure allocation code that allocates in new
   // space for nested functions that don't need literals cloning.
-  if (scope()->is_function_scope() && function_info->num_literals() == 0) {
+  if (scope()->is_function_scope() &&
+      function_info->num_literals() == 0 &&
+      !pretenure) {
     FastNewClosureStub stub;
     frame_->EmitPush(Operand(function_info));
     frame_->SpillAll();
@@ -3116,7 +3119,10 @@
     // Create a new closure.
     frame_->EmitPush(cp);
     frame_->EmitPush(Operand(function_info));
-    frame_->CallRuntime(Runtime::kNewClosure, 2);
+    frame_->EmitPush(Operand(pretenure
+                             ? Factory::true_value()
+                             : Factory::false_value()));
+    frame_->CallRuntime(Runtime::kNewClosure, 3);
     frame_->EmitPush(r0);
   }
 }
@@ -3136,7 +3142,7 @@
     ASSERT(frame_->height() == original_height);
     return;
   }
-  InstantiateFunction(function_info);
+  InstantiateFunction(function_info, node->pretenure());
   ASSERT_EQ(original_height + 1, frame_->height());
 }

@@ -3147,7 +3153,7 @@
   int original_height = frame_->height();
 #endif
   Comment cmnt(masm_, "[ SharedFunctionInfoLiteral");
-  InstantiateFunction(node->shared_function_info());
+  InstantiateFunction(node->shared_function_info(), false);
   ASSERT_EQ(original_height + 1, frame_->height());
 }

=======================================
--- /branches/bleeding_edge/src/arm/codegen-arm.h       Fri Nov 19 01:25:46 2010
+++ /branches/bleeding_edge/src/arm/codegen-arm.h       Mon Nov 22 01:57:21 2010
@@ -449,7 +449,8 @@
   void DeclareGlobals(Handle<FixedArray> pairs);

   // Instantiate the function based on the shared function info.
-  void InstantiateFunction(Handle<SharedFunctionInfo> function_info);
+  void InstantiateFunction(Handle<SharedFunctionInfo> function_info,
+                           bool pretenure);

   // Support for type checks.
   void GenerateIsSmi(ZoneList<Expression*>* args);
=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Fri Nov 19 01:25:46 2010 +++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Mon Nov 22 01:57:21 2010
@@ -860,18 +860,23 @@
 }


-void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info) {
+void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
+                                       bool pretenure) {
   // Use the fast case closure allocation code that allocates in new
   // space for nested functions that don't need literals cloning.
-  if (scope()->is_function_scope() && info->num_literals() == 0) {
+  if (scope()->is_function_scope() &&
+      info->num_literals() == 0 &&
+      !pretenure) {
     FastNewClosureStub stub;
     __ mov(r0, Operand(info));
     __ push(r0);
     __ CallStub(&stub);
   } else {
     __ mov(r0, Operand(info));
-    __ Push(cp, r0);
-    __ CallRuntime(Runtime::kNewClosure, 2);
+    __ LoadRoot(r1, pretenure ? Heap::kTrueValueRootIndex
+                              : Heap::kFalseValueRootIndex);
+    __ Push(cp, r0, r1);
+    __ CallRuntime(Runtime::kNewClosure, 3);
   }
   context()->Plug(r0);
 }
=======================================
--- /branches/bleeding_edge/src/ast.h   Wed Oct 27 04:37:59 2010
+++ /branches/bleeding_edge/src/ast.h   Mon Nov 22 01:57:21 2010
@@ -1416,7 +1416,8 @@
         contains_loops_(contains_loops),
         function_token_position_(RelocInfo::kNoPosition),
         inferred_name_(Heap::empty_string()),
-        try_full_codegen_(false) {
+        try_full_codegen_(false),
+        pretenure_(false) {
 #ifdef DEBUG
     already_compiled_ = false;
 #endif
@@ -1458,6 +1459,9 @@

   bool try_full_codegen() { return try_full_codegen_; }
   void set_try_full_codegen(bool flag) { try_full_codegen_ = flag; }
+
+  bool pretenure() { return pretenure_; }
+  void set_pretenure(bool value) { pretenure_ = value; }

 #ifdef DEBUG
   void mark_as_compiled() {
@@ -1482,6 +1486,7 @@
   int function_token_position_;
   Handle<String> inferred_name_;
   bool try_full_codegen_;
+  bool pretenure_;
 #ifdef DEBUG
   bool already_compiled_;
 #endif
=======================================
--- /branches/bleeding_edge/src/full-codegen.cc Fri Nov 19 04:08:52 2010
+++ /branches/bleeding_edge/src/full-codegen.cc Mon Nov 22 01:57:21 2010
@@ -1168,14 +1168,14 @@
     SetStackOverflow();
     return;
   }
-  EmitNewClosure(function_info);
+  EmitNewClosure(function_info, expr->pretenure());
 }


 void FullCodeGenerator::VisitSharedFunctionInfoLiteral(
     SharedFunctionInfoLiteral* expr) {
   Comment cmnt(masm_, "[ SharedFunctionInfoLiteral");
-  EmitNewClosure(expr->shared_function_info());
+  EmitNewClosure(expr->shared_function_info(), false);
 }


=======================================
--- /branches/bleeding_edge/src/full-codegen.h  Wed Nov 10 09:00:20 2010
+++ /branches/bleeding_edge/src/full-codegen.h  Mon Nov 22 01:57:21 2010
@@ -348,7 +348,7 @@

   // Platform-specific support for allocating a new closure based on
   // the given function info.
-  void EmitNewClosure(Handle<SharedFunctionInfo> info);
+  void EmitNewClosure(Handle<SharedFunctionInfo> info, bool pretenure);

   // Platform-specific support for compiling assignments.

=======================================
--- /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Mon Nov 15 09:12:34 2010 +++ /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Mon Nov 22 01:57:21 2010
@@ -80,8 +80,9 @@
   __ pop(edx);
   __ push(esi);
   __ push(edx);
+  __ push(Immediate(Factory::false_value()));
   __ push(ecx);  // Restore return address.
-  __ TailCallRuntime(Runtime::kNewClosure, 2, 1);
+  __ TailCallRuntime(Runtime::kNewClosure, 3, 1);
 }


=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Fri Nov 19 01:25:46 2010 +++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Mon Nov 22 01:57:21 2010
@@ -4897,7 +4897,8 @@


 Result CodeGenerator::InstantiateFunction(
-    Handle<SharedFunctionInfo> function_info) {
+    Handle<SharedFunctionInfo> function_info,
+    bool pretenure) {
   // The inevitable call will sync frame elements to memory anyway, so
   // we do it eagerly to allow us to push the arguments directly into
   // place.
@@ -4905,7 +4906,9 @@

   // Use the fast case closure allocation code that allocates in new
   // space for nested functions that don't need literals cloning.
-  if (scope()->is_function_scope() && function_info->num_literals() == 0) {
+  if (scope()->is_function_scope() &&
+      function_info->num_literals() == 0 &&
+      !pretenure) {
     FastNewClosureStub stub;
     frame()->EmitPush(Immediate(function_info));
     return frame()->CallStub(&stub, 1);
@@ -4914,7 +4917,10 @@
     // shared function info.
     frame()->EmitPush(esi);
     frame()->EmitPush(Immediate(function_info));
-    return frame()->CallRuntime(Runtime::kNewClosure, 2);
+    frame()->EmitPush(Immediate(pretenure
+                                ? Factory::true_value()
+                                : Factory::false_value()));
+    return frame()->CallRuntime(Runtime::kNewClosure, 3);
   }
 }

@@ -4930,7 +4936,7 @@
     SetStackOverflow();
     return;
   }
-  Result result = InstantiateFunction(function_info);
+  Result result = InstantiateFunction(function_info, node->pretenure());
   frame()->Push(&result);
 }

@@ -4939,7 +4945,7 @@
     SharedFunctionInfoLiteral* node) {
   ASSERT(!in_safe_int32_mode());
   Comment cmnt(masm_, "[ SharedFunctionInfoLiteral");
-  Result result = InstantiateFunction(node->shared_function_info());
+  Result result = InstantiateFunction(node->shared_function_info(), false);
   frame()->Push(&result);
 }

=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.h     Fri Nov 19 01:25:46 2010
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.h     Mon Nov 22 01:57:21 2010
@@ -625,7 +625,8 @@
   void DeclareGlobals(Handle<FixedArray> pairs);

   // Instantiate the function based on the shared function info.
-  Result InstantiateFunction(Handle<SharedFunctionInfo> function_info);
+  Result InstantiateFunction(Handle<SharedFunctionInfo> function_info,
+                             bool pretenure);

   // Support for types.
   void GenerateIsSmi(ZoneList<Expression*>* args);
=======================================
--- /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Fri Nov 19 01:25:46 2010 +++ /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Mon Nov 22 01:57:21 2010
@@ -880,17 +880,23 @@
 }


-void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info) {
+void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
+                                       bool pretenure) {
   // Use the fast case closure allocation code that allocates in new
   // space for nested functions that don't need literals cloning.
-  if (scope()->is_function_scope() && info->num_literals() == 0) {
+  if (scope()->is_function_scope() &&
+      info->num_literals() == 0 &&
+      !pretenure) {
     FastNewClosureStub stub;
     __ push(Immediate(info));
     __ CallStub(&stub);
   } else {
     __ push(esi);
     __ push(Immediate(info));
-    __ CallRuntime(Runtime::kNewClosure, 2);
+    __ push(Immediate(pretenure
+                      ? Factory::true_value()
+                      : Factory::false_value()));
+    __ CallRuntime(Runtime::kNewClosure, 3);
   }
   context()->Plug(eax);
 }
=======================================
--- /branches/bleeding_edge/src/parser.cc       Fri Nov 19 01:02:59 2010
+++ /branches/bleeding_edge/src/parser.cc       Mon Nov 22 01:57:21 2010
@@ -2275,6 +2275,12 @@
       property->obj()->AsVariableProxy()->is_this()) {
     temp_scope_->AddProperty();
   }
+
+  // If we assign a function literal to a property we pretenure the
+  // literal so it can be added as a constant function property.
+  if (property != NULL && right->AsFunctionLiteral() != NULL) {
+    right->AsFunctionLiteral()->set_pretenure(true);
+  }

   if (fni_ != NULL) {
     // Check if the right hand side is a call to avoid inferring a
=======================================
--- /branches/bleeding_edge/src/runtime.cc      Wed Nov 10 04:34:28 2010
+++ /branches/bleeding_edge/src/runtime.cc      Mon Nov 22 01:57:21 2010
@@ -6341,15 +6341,20 @@

 static MaybeObject* Runtime_NewClosure(Arguments args) {
   HandleScope scope;
-  ASSERT(args.length() == 2);
+  ASSERT(args.length() == 3);
   CONVERT_ARG_CHECKED(Context, context, 0);
   CONVERT_ARG_CHECKED(SharedFunctionInfo, shared, 1);
-
-  PretenureFlag pretenure = (context->global_context() == *context)
-      ? TENURED       // Allocate global closures in old space.
-      : NOT_TENURED;  // Allocate local closures in new space.
+  CONVERT_BOOLEAN_CHECKED(pretenure, args[2]);
+
+  // Allocate global closures in old space and allocate local closures
+  // in new space. Additionally pretenure closures that are assigned
+  // directly to properties.
+  pretenure = pretenure || (context->global_context() == *context);
+  PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED;
   Handle<JSFunction> result =
- Factory::NewFunctionFromSharedFunctionInfo(shared, context, pretenure);
+      Factory::NewFunctionFromSharedFunctionInfo(shared,
+                                                 context,
+                                                 pretenure_flag);
   return *result;
 }

=======================================
--- /branches/bleeding_edge/src/runtime.h       Fri Nov 19 01:25:46 2010
+++ /branches/bleeding_edge/src/runtime.h       Mon Nov 22 01:57:21 2010
@@ -262,7 +262,7 @@
   F(CreateCatchExtensionObject, 2, 1) \
   \
   /* Statements */ \
-  F(NewClosure, 2, 1) \
+  F(NewClosure, 3, 1) \
   F(NewObject, 1, 1) \
   F(NewObjectFromBound, 2, 1) \
   F(FinalizeInstanceSize, 1, 1) \
=======================================
--- /branches/bleeding_edge/src/x64/code-stubs-x64.cc Wed Nov 17 02:44:16 2010 +++ /branches/bleeding_edge/src/x64/code-stubs-x64.cc Mon Nov 22 01:57:21 2010
@@ -80,8 +80,9 @@
   __ pop(rdx);
   __ push(rsi);
   __ push(rdx);
+  __ Push(Factory::false_value());
   __ push(rcx);  // Restore return address.
-  __ TailCallRuntime(Runtime::kNewClosure, 2, 1);
+  __ TailCallRuntime(Runtime::kNewClosure, 3, 1);
 }


=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.cc      Fri Nov 19 01:25:46 2010
+++ /branches/bleeding_edge/src/x64/codegen-x64.cc      Mon Nov 22 01:57:21 2010
@@ -4244,7 +4244,8 @@


 void CodeGenerator::InstantiateFunction(
-    Handle<SharedFunctionInfo> function_info) {
+    Handle<SharedFunctionInfo> function_info,
+    bool pretenure) {
   // The inevitable call will sync frame elements to memory anyway, so
   // we do it eagerly to allow us to push the arguments directly into
   // place.
@@ -4252,7 +4253,9 @@

   // Use the fast case closure allocation code that allocates in new
   // space for nested functions that don't need literals cloning.
-  if (scope()->is_function_scope() && function_info->num_literals() == 0) {
+  if (scope()->is_function_scope() &&
+      function_info->num_literals() == 0 &&
+      !pretenure) {
     FastNewClosureStub stub;
     frame_->Push(function_info);
     Result answer = frame_->CallStub(&stub, 1);
@@ -4262,7 +4265,10 @@
     // shared function info.
     frame_->EmitPush(rsi);
     frame_->EmitPush(function_info);
-    Result result = frame_->CallRuntime(Runtime::kNewClosure, 2);
+    frame_->EmitPush(pretenure
+                     ? Factory::true_value()
+                     : Factory::false_value());
+    Result result = frame_->CallRuntime(Runtime::kNewClosure, 3);
     frame_->Push(&result);
   }
 }
@@ -4279,14 +4285,14 @@
     SetStackOverflow();
     return;
   }
-  InstantiateFunction(function_info);
+  InstantiateFunction(function_info, node->pretenure());
 }


 void CodeGenerator::VisitSharedFunctionInfoLiteral(
     SharedFunctionInfoLiteral* node) {
   Comment cmnt(masm_, "[ SharedFunctionInfoLiteral");
-  InstantiateFunction(node->shared_function_info());
+  InstantiateFunction(node->shared_function_info(), false);
 }


=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.h       Fri Nov 19 01:25:46 2010
+++ /branches/bleeding_edge/src/x64/codegen-x64.h       Mon Nov 22 01:57:21 2010
@@ -585,7 +585,8 @@
   void DeclareGlobals(Handle<FixedArray> pairs);

   // Instantiate the function based on the shared function info.
-  void InstantiateFunction(Handle<SharedFunctionInfo> function_info);
+  void InstantiateFunction(Handle<SharedFunctionInfo> function_info,
+                           bool pretenure);

   // Support for type checks.
   void GenerateIsSmi(ZoneList<Expression*>* args);
=======================================
--- /branches/bleeding_edge/src/x64/full-codegen-x64.cc Fri Nov 19 01:25:46 2010 +++ /branches/bleeding_edge/src/x64/full-codegen-x64.cc Mon Nov 22 01:57:21 2010
@@ -837,17 +837,21 @@
 }


-void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info) {
+void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
+                                       bool pretenure) {
   // Use the fast case closure allocation code that allocates in new
   // space for nested functions that don't need literals cloning.
-  if (scope()->is_function_scope() && info->num_literals() == 0) {
+  if (scope()->is_function_scope() &&
+      info->num_literals() == 0 &&
+      !pretenure) {
     FastNewClosureStub stub;
     __ Push(info);
     __ CallStub(&stub);
   } else {
     __ push(rsi);
     __ Push(info);
-    __ CallRuntime(Runtime::kNewClosure, 2);
+    __ Push(pretenure ? Factory::true_value() : Factory::false_value());
+    __ CallRuntime(Runtime::kNewClosure, 3);
   }
   context()->Plug(rax);
 }

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

Reply via email to