Index: src/x64/codegen-x64.cc |
=================================================================== |
--- src/x64/codegen-x64.cc (revision 3788) |
+++ src/x64/codegen-x64.cc (working copy) |
@@ -246,14 +246,10 @@ |
// ----------------------------------------------------------------------------- |
// CodeGenerator implementation. |
-CodeGenerator::CodeGenerator(MacroAssembler* masm, |
- Handle<Script> script, |
- bool is_eval) |
- : is_eval_(is_eval), |
- script_(script), |
- deferred_(8), |
+CodeGenerator::CodeGenerator(MacroAssembler* masm) |
+ : deferred_(8), |
masm_(masm), |
- scope_(NULL), |
+ info_(NULL), |
frame_(NULL), |
allocator_(NULL), |
state_(NULL), |
@@ -263,6 +259,9 @@ |
} |
+Scope* CodeGenerator::scope() { return info_->function()->scope(); } |
+ |
+ |
void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
// Call the runtime to declare the globals. The inevitable call |
// will sync frame elements to memory anyway, so we do it eagerly to |
@@ -278,16 +277,12 @@ |
} |
-void CodeGenerator::Generate(FunctionLiteral* function, |
- Mode mode, |
- CompilationInfo* info) { |
+void CodeGenerator::Generate(CompilationInfo* info, Mode mode) { |
// Record the position for debugging purposes. |
- CodeForFunctionPosition(function); |
- ZoneList<Statement*>* body = function->body(); |
+ CodeForFunctionPosition(info->function()); |
// Initialize state. |
- ASSERT(scope_ == NULL); |
- scope_ = function->scope(); |
+ info_ = info; |
ASSERT(allocator_ == NULL); |
RegisterAllocator register_allocator(this); |
allocator_ = ®ister_allocator; |
@@ -302,7 +297,7 @@ |
#ifdef DEBUG |
if (strlen(FLAG_stop_at) > 0 && |
- function->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { |
+ info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { |
frame_->SpillAll(); |
__ int3(); |
} |
@@ -328,7 +323,7 @@ |
frame_->AllocateStackSlots(); |
// Allocate the local context if needed. |
- int heap_slots = scope_->num_heap_slots(); |
+ int heap_slots = scope()->num_heap_slots(); |
if (heap_slots > 0) { |
Comment cmnt(masm_, "[ allocate local context"); |
// Allocate local context. |
@@ -358,7 +353,6 @@ |
// 3) don't copy parameter operand code from SlotOperand! |
{ |
Comment cmnt2(masm_, "[ copy context parameters into .context"); |
- |
// Note that iteration order is relevant here! If we have the same |
// parameter twice (e.g., function (x, y, x)), and that parameter |
// needs to be copied into the context, it must be the last argument |
@@ -367,15 +361,15 @@ |
// order: such a parameter is copied repeatedly into the same |
// context location and thus the last value is what is seen inside |
// the function. |
- for (int i = 0; i < scope_->num_parameters(); i++) { |
- Variable* par = scope_->parameter(i); |
+ for (int i = 0; i < scope()->num_parameters(); i++) { |
+ Variable* par = scope()->parameter(i); |
Slot* slot = par->slot(); |
if (slot != NULL && slot->type() == Slot::CONTEXT) { |
// The use of SlotOperand below is safe in unspilled code |
// because the slot is guaranteed to be a context slot. |
// |
// There are no parameters in the global scope. |
- ASSERT(!scope_->is_global_scope()); |
+ ASSERT(!scope()->is_global_scope()); |
frame_->PushParameterAt(i); |
Result value = frame_->Pop(); |
value.ToRegister(); |
@@ -403,9 +397,9 @@ |
} |
// Initialize ThisFunction reference if present. |
- if (scope_->is_function_scope() && scope_->function() != NULL) { |
+ if (scope()->is_function_scope() && scope()->function() != NULL) { |
frame_->Push(Factory::the_hole_value()); |
- StoreToSlot(scope_->function()->slot(), NOT_CONST_INIT); |
+ StoreToSlot(scope()->function()->slot(), NOT_CONST_INIT); |
} |
} else { |
// When used as the secondary compiler for splitting, rbp, rsi, |
@@ -423,12 +417,12 @@ |
// Generate code to 'execute' declarations and initialize functions |
// (source elements). In case of an illegal redeclaration we need to |
// handle that instead of processing the declarations. |
- if (scope_->HasIllegalRedeclaration()) { |
+ if (scope()->HasIllegalRedeclaration()) { |
Comment cmnt(masm_, "[ illegal redeclarations"); |
- scope_->VisitIllegalRedeclaration(this); |
+ scope()->VisitIllegalRedeclaration(this); |
} else { |
Comment cmnt(masm_, "[ declarations"); |
- ProcessDeclarations(scope_->declarations()); |
+ ProcessDeclarations(scope()->declarations()); |
// Bail out if a stack-overflow exception occurred when processing |
// declarations. |
if (HasStackOverflow()) return; |
@@ -443,7 +437,7 @@ |
// Compile the body of the function in a vanilla state. Don't |
// bother compiling all the code if the scope has an illegal |
// redeclaration. |
- if (!scope_->HasIllegalRedeclaration()) { |
+ if (!scope()->HasIllegalRedeclaration()) { |
Comment cmnt(masm_, "[ function body"); |
#ifdef DEBUG |
bool is_builtin = Bootstrapper::IsActive(); |
@@ -454,14 +448,14 @@ |
// Ignore the return value. |
} |
#endif |
- VisitStatements(body); |
+ VisitStatements(info->function()->body()); |
// Handle the return from the function. |
if (has_valid_frame()) { |
// If there is a valid frame, control flow can fall off the end of |
// the body. In that case there is an implicit return statement. |
ASSERT(!function_return_is_shadowed_); |
- CodeForReturnPosition(function); |
+ CodeForReturnPosition(info->function()); |
frame_->PrepareForReturn(); |
Result undefined(Factory::undefined_value()); |
if (function_return_.is_bound()) { |
@@ -504,7 +498,6 @@ |
// There is no need to delete the register allocator, it is a |
// stack-allocated local. |
allocator_ = NULL; |
- scope_ = NULL; |
} |
void CodeGenerator::GenerateReturnSequence(Result* return_value) { |
@@ -527,7 +520,7 @@ |
// Leave the frame and return popping the arguments and the |
// receiver. |
frame_->Exit(); |
- masm_->ret((scope_->num_parameters() + 1) * kPointerSize); |
+ masm_->ret((scope()->num_parameters() + 1) * kPointerSize); |
#ifdef ENABLE_DEBUGGER_SUPPORT |
// Add padding that will be overwritten by a debugger breakpoint. |
// frame_->Exit() generates "movq rsp, rbp; pop rbp; ret k" |
@@ -695,7 +688,7 @@ |
// Load the receiver and the existing arguments object onto the |
// expression stack. Avoid allocating the arguments object here. |
Load(receiver); |
- LoadFromSlot(scope_->arguments()->var()->slot(), NOT_INSIDE_TYPEOF); |
+ LoadFromSlot(scope()->arguments()->var()->slot(), NOT_INSIDE_TYPEOF); |
// Emit the source position information after having loaded the |
// receiver and the arguments. |
@@ -773,8 +766,8 @@ |
__ j(equal, &adapted); |
// No arguments adaptor frame. Copy fixed number of arguments. |
- __ movq(rax, Immediate(scope_->num_parameters())); |
- for (int i = 0; i < scope_->num_parameters(); i++) { |
+ __ movq(rax, Immediate(scope()->num_parameters())); |
+ for (int i = 0; i < scope()->num_parameters(); i++) { |
__ push(frame_->ParameterAt(i)); |
} |
__ jmp(&invoke); |
@@ -2263,7 +2256,7 @@ |
// Build the function boilerplate and instantiate it. |
Handle<JSFunction> boilerplate = |
- Compiler::BuildBoilerplate(node, script_, this); |
+ Compiler::BuildBoilerplate(node, script(), this); |
// Check for stack-overflow exception. |
if (HasStackOverflow()) return; |
InstantiateBoilerplate(boilerplate); |
@@ -3610,7 +3603,7 @@ |
Load(args->at(0)); |
Result key = frame_->Pop(); |
// Explicitly create a constant result. |
- Result count(Handle<Smi>(Smi::FromInt(scope_->num_parameters()))); |
+ Result count(Handle<Smi>(Smi::FromInt(scope()->num_parameters()))); |
// Call the shared stub to get to arguments[key]. |
ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); |
Result result = frame_->CallStub(&stub, &key, &count); |
@@ -3719,7 +3712,7 @@ |
ASSERT(args->length() == 0); |
// ArgumentsAccessStub takes the parameter count as an input argument |
// in register eax. Create a constant result for it. |
- Result count(Handle<Smi>(Smi::FromInt(scope_->num_parameters()))); |
+ Result count(Handle<Smi>(Smi::FromInt(scope()->num_parameters()))); |
// Call the shared stub to get to the arguments.length. |
ArgumentsAccessStub stub(ArgumentsAccessStub::READ_LENGTH); |
Result result = frame_->CallStub(&stub, &count); |
@@ -4789,13 +4782,13 @@ |
} |
-ArgumentsAllocationMode CodeGenerator::ArgumentsMode() const { |
- if (scope_->arguments() == NULL) return NO_ARGUMENTS_ALLOCATION; |
- ASSERT(scope_->arguments_shadow() != NULL); |
+ArgumentsAllocationMode CodeGenerator::ArgumentsMode() { |
+ if (scope()->arguments() == NULL) return NO_ARGUMENTS_ALLOCATION; |
+ ASSERT(scope()->arguments_shadow() != NULL); |
// We don't want to do lazy arguments allocation for functions that |
// have heap-allocated contexts, because it interfers with the |
// uninitialized const tracking in the context objects. |
- return (scope_->num_heap_slots() > 0) |
+ return (scope()->num_heap_slots() > 0) |
? EAGER_ARGUMENTS_ALLOCATION |
: LAZY_ARGUMENTS_ALLOCATION; |
} |
@@ -4815,14 +4808,14 @@ |
ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); |
frame_->PushFunction(); |
frame_->PushReceiverSlotAddress(); |
- frame_->Push(Smi::FromInt(scope_->num_parameters())); |
+ frame_->Push(Smi::FromInt(scope()->num_parameters())); |
Result result = frame_->CallStub(&stub, 3); |
frame_->Push(&result); |
} |
- Variable* arguments = scope_->arguments()->var(); |
- Variable* shadow = scope_->arguments_shadow()->var(); |
+ Variable* arguments = scope()->arguments()->var(); |
+ Variable* shadow = scope()->arguments_shadow()->var(); |
ASSERT(arguments != NULL && arguments->slot() != NULL); |
ASSERT(shadow != NULL && shadow->slot() != NULL); |
JumpTarget done; |
@@ -4831,7 +4824,7 @@ |
// We have to skip storing into the arguments slot if it has |
// already been written to. This can happen if the a function |
// has a local variable named 'arguments'. |
- LoadFromSlot(scope_->arguments()->var()->slot(), NOT_INSIDE_TYPEOF); |
+ LoadFromSlot(scope()->arguments()->var()->slot(), NOT_INSIDE_TYPEOF); |
Result probe = frame_->Pop(); |
if (probe.is_constant()) { |
// We have to skip updating the arguments object if it has been |