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
parent e8db709b
......@@ -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
......
......@@ -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;
......
......@@ -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());
}
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment