From efd20687c9e3d921463138e6ab528120eecbac09 Mon Sep 17 00:00:00 2001 From: "kmillikin@chromium.org" Date: Thu, 5 Nov 2009 10:38:26 +0000 Subject: [PATCH] In the toplevel code generator, support local context allocation 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 | 18 ++++++++++++++++++ src/compiler.cc | 15 +++++++++++++++ src/ia32/fast-codegen-ia32.cc | 18 ++++++++++++++++++ src/x64/fast-codegen-x64.cc | 18 ++++++++++++++++++ 4 files changed, 69 insertions(+) diff --git a/src/arm/fast-codegen-arm.cc b/src/arm/fast-codegen-arm.cc index f7d369938..249495a66 100644 --- a/src/arm/fast-codegen-arm.cc +++ b/src/arm/fast-codegen-arm.cc @@ -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 diff --git a/src/compiler.cc b/src/compiler.cc index 69be46221..5a62b305e 100644 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -585,6 +585,21 @@ void Compiler::SetFunctionInfo(Handle 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; diff --git a/src/ia32/fast-codegen-ia32.cc b/src/ia32/fast-codegen-ia32.cc index 038bfd620..6437fdfe3 100644 --- a/src/ia32/fast-codegen-ia32.cc +++ b/src/ia32/fast-codegen-ia32.cc @@ -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()); } diff --git a/src/x64/fast-codegen-x64.cc b/src/x64/fast-codegen-x64.cc index e68e5e4a7..2be08710f 100644 --- a/src/x64/fast-codegen-x64.cc +++ b/src/x64/fast-codegen-x64.cc @@ -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); -- 2.34.1