| 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
|
|
|