In the toplevel code generator, support local context allocation
authorkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 5 Nov 2009 10:38:26 +0000 (10:38 +0000)
committerkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 5 Nov 2009 10:38:26 +0000 (10:38 +0000)
provided that none of the parameters need to be copied into the
context.

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

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

src/arm/fast-codegen-arm.cc
src/compiler.cc
src/ia32/fast-codegen-ia32.cc
src/x64/fast-codegen-x64.cc

index f7d369938e30174bff463c9e910e6f484f679dd7..249495a6650970026af87227dc1cc8d30a6c112a 100644 (file)
@@ -71,6 +71,24 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) {
     }
   }
 
+  // Possibly allocate a local context.
+  if (fun->scope()->num_heap_slots() > 0) {
+    Comment cmnt(masm_, "[ Allocate local context");
+    // Argument to NewContext is the function, still in r1.
+    __ push(r1);
+    __ CallRuntime(Runtime::kNewContext, 1);
+    // Context is returned in both r0 and cp.  It replaces the context
+    // passed to us.  It's saved in the stack and kept live in cp.
+    __ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+#ifdef DEBUG
+    // Assert we do not have to copy any parameters into the context.
+    for (int i = 0, len = fun->scope()->num_parameters(); i < len; i++) {
+      Slot* slot = fun->scope()->parameter(i)->slot();
+      ASSERT(slot != NULL && slot->type() != Slot::CONTEXT);
+    }
+#endif
+  }
+
   // Check the stack for overflow or break request.
   // Put the lr setup instruction in the delay slot.  The kInstrSize is
   // added to the implicit 8 byte offset that always applies to operations
index 69be4622115a07fa3e6230e4400149b611664d03..5a62b305e2cad2c7161bc77bee07284de1109532 100644 (file)
@@ -585,6 +585,21 @@ void Compiler::SetFunctionInfo(Handle<JSFunction> fun,
 
 CodeGenSelector::CodeGenTag CodeGenSelector::Select(FunctionLiteral* fun) {
   Scope* scope = fun->scope();
+
+  if (scope->num_heap_slots() > 0) {
+    // We support functions with a local context if they do not have
+    // parameters that need to be copied into the context.
+    for (int i = 0, len = scope->num_parameters(); i < len; i++) {
+      Slot* slot = scope->parameter(i)->slot();
+      if (slot != NULL && slot->type() == Slot::CONTEXT) {
+        if (FLAG_trace_bailout) {
+          PrintF("function has context-allocated parameters");
+        }
+        return NORMAL;
+      }
+    }
+  }
+
   if (scope->num_heap_slots() != 0) {
     if (FLAG_trace_bailout) PrintF("function has context slots\n");
     return NORMAL;
index 038bfd620de55536d5834cd77d0a00b9609300ec..6437fdfe3bf221bde84bd336a09e7e644c7a4deb 100644 (file)
@@ -67,6 +67,24 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) {
     }
   }
 
+  // Possibly allocate a local context.
+  if (fun->scope()->num_heap_slots() > 0) {
+    Comment cmnt(masm_, "[ Allocate local context");
+    // Argument to NewContext is the function, still in edi.
+    __ push(edi);
+    __ CallRuntime(Runtime::kNewContext, 1);
+    // Context is returned in both eax and esi.  It replaces the context
+    // passed to us.  It's saved in the stack and kept live in esi.
+    __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi);
+#ifdef DEBUG
+    // Assert we do not have to copy any parameters into the context.
+    for (int i = 0, len = fun->scope()->num_parameters(); i < len; i++) {
+      Slot* slot = fun->scope()->parameter(i)->slot();
+      ASSERT(slot != NULL && slot->type() != Slot::CONTEXT);
+    }
+#endif
+  }
+
   { Comment cmnt(masm_, "[ Declarations");
     VisitDeclarations(fun->scope()->declarations());
   }
index e68e5e4a70e476868a2132c75be56228b5b3b854..2be08710f0500407f4eda878a391dbc6fcb81f81 100644 (file)
@@ -67,6 +67,24 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) {
     }
   }
 
+  // Possibly allocate a local context.
+  if (fun->scope()->num_heap_slots() > 0) {
+    Comment cmnt(masm_, "[ Allocate local context");
+    // Argument to NewContext is the function, still in rdi.
+    __ push(rdi);
+    __ CallRuntime(Runtime::kNewContext, 1);
+    // Context is returned in both rax and rsi.  It replaces the context
+    // passed to us.  It's saved in the stack and kept live in rsi.
+    __ movq(Operand(rbp, StandardFrameConstants::kContextOffset), rsi);
+#ifdef DEBUG
+    // Assert we do not have to copy any parameters into the context.
+    for (int i = 0, len = fun->scope()->num_parameters(); i < len; i++) {
+      Slot* slot = fun->scope()->parameter(i)->slot();
+      ASSERT(slot != NULL && slot->type() != Slot::CONTEXT);
+    }
+#endif
+  }
+
   { Comment cmnt(masm_, "[ Stack check");
     Label ok;
     __ CompareRoot(rsp, Heap::kStackLimitRootIndex);