From 3e936b547a6a9bb60331dc72c3ab9a0700284548 Mon Sep 17 00:00:00 2001 From: "ager@chromium.org" Date: Fri, 13 Aug 2010 09:07:09 +0000 Subject: [PATCH] Remove experimental fast-codegen. We are no longer working on this approach. Review URL: http://codereview.chromium.org/3152016 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5259 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/SConscript | 7 - src/arm/codegen-arm.cc | 145 +++-- src/arm/fast-codegen-arm.cc | 241 --------- src/arm/full-codegen-arm.cc | 156 +++--- src/compiler.cc | 26 +- src/compiler.h | 53 -- src/fast-codegen.cc | 746 -------------------------- src/fast-codegen.h | 161 ------ src/flag-definitions.h | 3 - src/full-codegen.cc | 2 +- src/full-codegen.h | 7 +- src/ia32/codegen-ia32.cc | 165 +++--- src/ia32/fast-codegen-ia32.cc | 954 --------------------------------- src/ia32/fast-codegen-ia32.h | 155 ------ src/ia32/full-codegen-ia32.cc | 154 +++--- src/x64/codegen-x64.cc | 164 +++--- src/x64/fast-codegen-x64.cc | 250 --------- src/x64/full-codegen-x64.cc | 160 +++--- tools/gyp/v8.gyp | 7 - tools/v8.xcodeproj/project.pbxproj | 16 - tools/visual_studio/v8_base.vcproj | 12 - tools/visual_studio/v8_base_arm.vcproj | 12 - tools/visual_studio/v8_base_x64.vcproj | 12 - 23 files changed, 452 insertions(+), 3156 deletions(-) delete mode 100644 src/arm/fast-codegen-arm.cc delete mode 100644 src/fast-codegen.cc delete mode 100644 src/fast-codegen.h delete mode 100644 src/ia32/fast-codegen-ia32.cc delete mode 100644 src/ia32/fast-codegen-ia32.h delete mode 100644 src/x64/fast-codegen-x64.cc diff --git a/src/SConscript b/src/SConscript index 536f76b..e6b4e38 100755 --- a/src/SConscript +++ b/src/SConscript @@ -118,7 +118,6 @@ SOURCES = { zone.cc """), 'arch:arm': Split(""" - fast-codegen.cc jump-target-light.cc virtual-frame-light.cc arm/builtins-arm.cc @@ -127,7 +126,6 @@ SOURCES = { arm/cpu-arm.cc arm/debug-arm.cc arm/disasm-arm.cc - arm/fast-codegen-arm.cc arm/frames-arm.cc arm/full-codegen-arm.cc arm/ic-arm.cc @@ -140,7 +138,6 @@ SOURCES = { arm/assembler-arm.cc """), 'arch:mips': Split(""" - fast-codegen.cc mips/assembler-mips.cc mips/builtins-mips.cc mips/codegen-mips.cc @@ -148,7 +145,6 @@ SOURCES = { mips/cpu-mips.cc mips/debug-mips.cc mips/disasm-mips.cc - mips/fast-codegen-mips.cc mips/full-codegen-mips.cc mips/frames-mips.cc mips/ic-mips.cc @@ -167,7 +163,6 @@ SOURCES = { ia32/cpu-ia32.cc ia32/debug-ia32.cc ia32/disasm-ia32.cc - ia32/fast-codegen-ia32.cc ia32/frames-ia32.cc ia32/full-codegen-ia32.cc ia32/ic-ia32.cc @@ -179,7 +174,6 @@ SOURCES = { ia32/virtual-frame-ia32.cc """), 'arch:x64': Split(""" - fast-codegen.cc jump-target-heavy.cc virtual-frame-heavy.cc x64/assembler-x64.cc @@ -188,7 +182,6 @@ SOURCES = { x64/cpu-x64.cc x64/debug-x64.cc x64/disasm-x64.cc - x64/fast-codegen-x64.cc x64/frames-x64.cc x64/full-codegen-x64.cc x64/ic-x64.cc diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc index 660a7ba..a7e4c04 100644 --- a/src/arm/codegen-arm.cc +++ b/src/arm/codegen-arm.cc @@ -217,93 +217,80 @@ void CodeGenerator::Generate(CompilationInfo* info) { } #endif - if (info->mode() == CompilationInfo::PRIMARY) { - frame_->Enter(); - // tos: code slot - - // Allocate space for locals and initialize them. This also checks - // for stack overflow. - frame_->AllocateStackSlots(); - - frame_->AssertIsSpilled(); - int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; - if (heap_slots > 0) { - // Allocate local context. - // Get outer context and create a new context based on it. - __ ldr(r0, frame_->Function()); - frame_->EmitPush(r0); - if (heap_slots <= FastNewContextStub::kMaximumSlots) { - FastNewContextStub stub(heap_slots); - frame_->CallStub(&stub, 1); - } else { - frame_->CallRuntime(Runtime::kNewContext, 1); - } + frame_->Enter(); + // tos: code slot + + // Allocate space for locals and initialize them. This also checks + // for stack overflow. + frame_->AllocateStackSlots(); + + frame_->AssertIsSpilled(); + int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; + if (heap_slots > 0) { + // Allocate local context. + // Get outer context and create a new context based on it. + __ ldr(r0, frame_->Function()); + frame_->EmitPush(r0); + if (heap_slots <= FastNewContextStub::kMaximumSlots) { + FastNewContextStub stub(heap_slots); + frame_->CallStub(&stub, 1); + } else { + frame_->CallRuntime(Runtime::kNewContext, 1); + } #ifdef DEBUG - JumpTarget verified_true; - __ cmp(r0, cp); - verified_true.Branch(eq); - __ stop("NewContext: r0 is expected to be the same as cp"); - verified_true.Bind(); + JumpTarget verified_true; + __ cmp(r0, cp); + verified_true.Branch(eq); + __ stop("NewContext: r0 is expected to be the same as cp"); + verified_true.Bind(); #endif - // Update context local. - __ str(cp, frame_->Context()); - } + // Update context local. + __ str(cp, frame_->Context()); + } - // TODO(1241774): Improve this code: - // 1) only needed if we have a context - // 2) no need to recompute context ptr every single time - // 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 - // passed to the parameter that needs to be copied. This is a rare - // case so we don't check for it, instead we rely on the copying - // order: such a parameter is copied repeatedly into the same - // context location and thus the last value is what is seen inside - // the function. - frame_->AssertIsSpilled(); - 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) { - ASSERT(!scope()->is_global_scope()); // No params in global scope. - __ ldr(r1, frame_->ParameterAt(i)); - // Loads r2 with context; used below in RecordWrite. - __ str(r1, SlotOperand(slot, r2)); - // Load the offset into r3. - int slot_offset = - FixedArray::kHeaderSize + slot->index() * kPointerSize; - __ RecordWrite(r2, Operand(slot_offset), r3, r1); - } + // TODO(1241774): Improve this code: + // 1) only needed if we have a context + // 2) no need to recompute context ptr every single time + // 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 + // passed to the parameter that needs to be copied. This is a rare + // case so we don't check for it, instead we rely on the copying + // order: such a parameter is copied repeatedly into the same + // context location and thus the last value is what is seen inside + // the function. + frame_->AssertIsSpilled(); + 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) { + ASSERT(!scope()->is_global_scope()); // No params in global scope. + __ ldr(r1, frame_->ParameterAt(i)); + // Loads r2 with context; used below in RecordWrite. + __ str(r1, SlotOperand(slot, r2)); + // Load the offset into r3. + int slot_offset = + FixedArray::kHeaderSize + slot->index() * kPointerSize; + __ RecordWrite(r2, Operand(slot_offset), r3, r1); } } + } - // Store the arguments object. This must happen after context - // initialization because the arguments object may be stored in - // the context. - if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) { - StoreArgumentsObject(true); - } + // Store the arguments object. This must happen after context + // initialization because the arguments object may be stored in + // the context. + if (ArgumentsMode() != NO_ARGUMENTS_ALLOCATION) { + StoreArgumentsObject(true); + } - // Initialize ThisFunction reference if present. - if (scope()->is_function_scope() && scope()->function() != NULL) { - frame_->EmitPushRoot(Heap::kTheHoleValueRootIndex); - StoreToSlot(scope()->function()->slot(), NOT_CONST_INIT); - } - } else { - // When used as the secondary compiler for splitting, r1, cp, - // fp, and lr have been pushed on the stack. Adjust the virtual - // frame to match this state. - frame_->Adjust(4); - - // Bind all the bailout labels to the beginning of the function. - List* bailouts = info->bailouts(); - for (int i = 0; i < bailouts->length(); i++) { - __ bind(bailouts->at(i)->label()); - } + // Initialize ThisFunction reference if present. + if (scope()->is_function_scope() && scope()->function() != NULL) { + frame_->EmitPushRoot(Heap::kTheHoleValueRootIndex); + StoreToSlot(scope()->function()->slot(), NOT_CONST_INIT); } // Initialize the function return target after the locals are set diff --git a/src/arm/fast-codegen-arm.cc b/src/arm/fast-codegen-arm.cc deleted file mode 100644 index 36ac2aa..0000000 --- a/src/arm/fast-codegen-arm.cc +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright 2010 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "v8.h" - -#if defined(V8_TARGET_ARCH_ARM) - -#include "codegen-inl.h" -#include "fast-codegen.h" -#include "scopes.h" - -namespace v8 { -namespace internal { - -#define __ ACCESS_MASM(masm()) - -Register FastCodeGenerator::accumulator0() { return r0; } -Register FastCodeGenerator::accumulator1() { return r1; } -Register FastCodeGenerator::scratch0() { return r3; } -Register FastCodeGenerator::scratch1() { return r4; } -Register FastCodeGenerator::scratch2() { return r5; } -Register FastCodeGenerator::receiver_reg() { return r2; } -Register FastCodeGenerator::context_reg() { return cp; } - - -void FastCodeGenerator::EmitLoadReceiver() { - // Offset 2 is due to return address and saved frame pointer. - int index = 2 + scope()->num_parameters(); - __ ldr(receiver_reg(), MemOperand(sp, index * kPointerSize)); -} - - -void FastCodeGenerator::EmitGlobalVariableLoad(Handle cell) { - ASSERT(!destination().is(no_reg)); - ASSERT(cell->IsJSGlobalPropertyCell()); - - __ mov(destination(), Operand(cell)); - __ ldr(destination(), - FieldMemOperand(destination(), JSGlobalPropertyCell::kValueOffset)); - if (FLAG_debug_code) { - __ mov(ip, Operand(Factory::the_hole_value())); - __ cmp(destination(), ip); - __ Check(ne, "DontDelete cells can't contain the hole"); - } - - // The loaded value is not known to be a smi. - clear_as_smi(destination()); -} - - -void FastCodeGenerator::EmitThisPropertyStore(Handle name) { - LookupResult lookup; - info()->receiver()->Lookup(*name, &lookup); - - ASSERT(lookup.holder() == *info()->receiver()); - ASSERT(lookup.type() == FIELD); - Handle map(Handle::cast(info()->receiver())->map()); - int index = lookup.GetFieldIndex() - map->inobject_properties(); - int offset = index * kPointerSize; - - // We will emit the write barrier unless the stored value is statically - // known to be a smi. - bool needs_write_barrier = !is_smi(accumulator0()); - - // Negative offsets are inobject properties. - if (offset < 0) { - offset += map->instance_size(); - __ str(accumulator0(), FieldMemOperand(receiver_reg(), offset)); - if (needs_write_barrier) { - // Preserve receiver from write barrier. - __ mov(scratch0(), receiver_reg()); - } - } else { - offset += FixedArray::kHeaderSize; - __ ldr(scratch0(), - FieldMemOperand(receiver_reg(), JSObject::kPropertiesOffset)); - __ str(accumulator0(), FieldMemOperand(scratch0(), offset)); - } - - if (needs_write_barrier) { - __ RecordWrite(scratch0(), Operand(offset), scratch1(), scratch2()); - } - - if (destination().is(accumulator1())) { - __ mov(accumulator1(), accumulator0()); - if (is_smi(accumulator0())) { - set_as_smi(accumulator1()); - } else { - clear_as_smi(accumulator1()); - } - } -} - - -void FastCodeGenerator::EmitThisPropertyLoad(Handle name) { - ASSERT(!destination().is(no_reg)); - LookupResult lookup; - info()->receiver()->Lookup(*name, &lookup); - - ASSERT(lookup.holder() == *info()->receiver()); - ASSERT(lookup.type() == FIELD); - Handle map(Handle::cast(info()->receiver())->map()); - int index = lookup.GetFieldIndex() - map->inobject_properties(); - int offset = index * kPointerSize; - - // Perform the load. Negative offsets are inobject properties. - if (offset < 0) { - offset += map->instance_size(); - __ ldr(destination(), FieldMemOperand(receiver_reg(), offset)); - } else { - offset += FixedArray::kHeaderSize; - __ ldr(scratch0(), - FieldMemOperand(receiver_reg(), JSObject::kPropertiesOffset)); - __ ldr(destination(), FieldMemOperand(scratch0(), offset)); - } - - // The loaded value is not known to be a smi. - clear_as_smi(destination()); -} - - -void FastCodeGenerator::EmitBitOr() { - if (is_smi(accumulator0()) && is_smi(accumulator1())) { - // If both operands are known to be a smi then there is no need to check - // the operands or result. There is no need to perform the operation in - // an effect context. - if (!destination().is(no_reg)) { - __ orr(destination(), accumulator1(), Operand(accumulator0())); - } - } else { - // Left is in accumulator1, right in accumulator0. - if (destination().is(accumulator0())) { - __ mov(scratch0(), accumulator0()); - __ orr(destination(), accumulator1(), Operand(accumulator1())); - Label* bailout = - info()->AddBailout(accumulator1(), scratch0()); // Left, right. - __ BranchOnNotSmi(destination(), bailout); - } else if (destination().is(accumulator1())) { - __ mov(scratch0(), accumulator1()); - __ orr(destination(), accumulator1(), Operand(accumulator0())); - Label* bailout = info()->AddBailout(scratch0(), accumulator0()); - __ BranchOnNotSmi(destination(), bailout); - } else { - ASSERT(destination().is(no_reg)); - __ orr(scratch0(), accumulator1(), Operand(accumulator0())); - Label* bailout = info()->AddBailout(accumulator1(), accumulator0()); - __ BranchOnNotSmi(scratch0(), bailout); - } - } - - // If we didn't bailout, the result (in fact, both inputs too) is known to - // be a smi. - set_as_smi(accumulator0()); - set_as_smi(accumulator1()); -} - - -void FastCodeGenerator::Generate(CompilationInfo* compilation_info) { - ASSERT(info_ == NULL); - info_ = compilation_info; - Comment cmnt(masm_, "[ function compiled by fast code generator"); - - // Save the caller's frame pointer and set up our own. - Comment prologue_cmnt(masm(), ";; Prologue"); - __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit()); - __ add(fp, sp, Operand(2 * kPointerSize)); - // Note that we keep a live register reference to cp (context) at - // this point. - - Label* bailout_to_beginning = info()->AddBailout(); - // Receiver (this) is allocated to a fixed register. - if (info()->has_this_properties()) { - Comment cmnt(masm(), ";; MapCheck(this)"); - if (FLAG_print_ir) { - PrintF("MapCheck(this)\n"); - } - ASSERT(info()->has_receiver() && info()->receiver()->IsHeapObject()); - Handle object = Handle::cast(info()->receiver()); - Handle map(object->map()); - EmitLoadReceiver(); - __ CheckMap(receiver_reg(), scratch0(), map, bailout_to_beginning, false); - } - - // If there is a global variable access check if the global object is the - // same as at lazy-compilation time. - if (info()->has_globals()) { - Comment cmnt(masm(), ";; MapCheck(GLOBAL)"); - if (FLAG_print_ir) { - PrintF("MapCheck(GLOBAL)\n"); - } - ASSERT(info()->has_global_object()); - Handle map(info()->global_object()->map()); - __ ldr(scratch0(), CodeGenerator::GlobalObject()); - __ CheckMap(scratch0(), scratch1(), map, bailout_to_beginning, true); - } - - VisitStatements(function()->body()); - - Comment return_cmnt(masm(), ";; Return()"); - if (FLAG_print_ir) { - PrintF("Return()\n"); - } - __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); - __ mov(sp, fp); - __ ldm(ia_w, sp, fp.bit() | lr.bit()); - int32_t sp_delta = (scope()->num_parameters() + 1) * kPointerSize; - __ add(sp, sp, Operand(sp_delta)); - __ Jump(lr); -} - - -#undef __ - - -} } // namespace v8::internal - -#endif // V8_TARGET_ARCH_ARM diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index f967a00..b58a4a5 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -55,99 +55,97 @@ namespace internal { // // The function builds a JS frame. Please see JavaScriptFrameConstants in // frames-arm.h for its layout. -void FullCodeGenerator::Generate(CompilationInfo* info, Mode mode) { +void FullCodeGenerator::Generate(CompilationInfo* info) { ASSERT(info_ == NULL); info_ = info; SetFunctionPosition(function()); Comment cmnt(masm_, "[ function compiled by full code generator"); - if (mode == PRIMARY) { - int locals_count = scope()->num_stack_slots(); + int locals_count = scope()->num_stack_slots(); - __ Push(lr, fp, cp, r1); - if (locals_count > 0) { - // Load undefined value here, so the value is ready for the loop - // below. - __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); - } - // Adjust fp to point to caller's fp. - __ add(fp, sp, Operand(2 * kPointerSize)); + __ Push(lr, fp, cp, r1); + if (locals_count > 0) { + // Load undefined value here, so the value is ready for the loop + // below. + __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); + } + // Adjust fp to point to caller's fp. + __ add(fp, sp, Operand(2 * kPointerSize)); - { Comment cmnt(masm_, "[ Allocate locals"); - for (int i = 0; i < locals_count; i++) { - __ push(ip); - } + { Comment cmnt(masm_, "[ Allocate locals"); + for (int i = 0; i < locals_count; i++) { + __ push(ip); } + } - bool function_in_register = true; + bool function_in_register = true; - // Possibly allocate a local context. - int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; - if (heap_slots > 0) { - Comment cmnt(masm_, "[ Allocate local context"); - // Argument to NewContext is the function, which is in r1. - __ push(r1); - if (heap_slots <= FastNewContextStub::kMaximumSlots) { - FastNewContextStub stub(heap_slots); - __ CallStub(&stub); - } else { - __ CallRuntime(Runtime::kNewContext, 1); - } - function_in_register = false; - // 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)); - // Copy any necessary parameters into the context. - int num_parameters = scope()->num_parameters(); - for (int i = 0; i < num_parameters; i++) { - Slot* slot = scope()->parameter(i)->slot(); - if (slot != NULL && slot->type() == Slot::CONTEXT) { - int parameter_offset = StandardFrameConstants::kCallerSPOffset + - (num_parameters - 1 - i) * kPointerSize; - // Load parameter from stack. - __ ldr(r0, MemOperand(fp, parameter_offset)); - // Store it in the context. - __ mov(r1, Operand(Context::SlotOffset(slot->index()))); - __ str(r0, MemOperand(cp, r1)); - // Update the write barrier. This clobbers all involved - // registers, so we have to use two more registers to avoid - // clobbering cp. - __ mov(r2, Operand(cp)); - __ RecordWrite(r2, Operand(r1), r3, r0); - } + // Possibly allocate a local context. + int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; + if (heap_slots > 0) { + Comment cmnt(masm_, "[ Allocate local context"); + // Argument to NewContext is the function, which is in r1. + __ push(r1); + if (heap_slots <= FastNewContextStub::kMaximumSlots) { + FastNewContextStub stub(heap_slots); + __ CallStub(&stub); + } else { + __ CallRuntime(Runtime::kNewContext, 1); + } + function_in_register = false; + // 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)); + // Copy any necessary parameters into the context. + int num_parameters = scope()->num_parameters(); + for (int i = 0; i < num_parameters; i++) { + Slot* slot = scope()->parameter(i)->slot(); + if (slot != NULL && slot->type() == Slot::CONTEXT) { + int parameter_offset = StandardFrameConstants::kCallerSPOffset + + (num_parameters - 1 - i) * kPointerSize; + // Load parameter from stack. + __ ldr(r0, MemOperand(fp, parameter_offset)); + // Store it in the context. + __ mov(r1, Operand(Context::SlotOffset(slot->index()))); + __ str(r0, MemOperand(cp, r1)); + // Update the write barrier. This clobbers all involved + // registers, so we have to use two more registers to avoid + // clobbering cp. + __ mov(r2, Operand(cp)); + __ RecordWrite(r2, Operand(r1), r3, r0); } } + } - Variable* arguments = scope()->arguments()->AsVariable(); - if (arguments != NULL) { - // Function uses arguments object. - Comment cmnt(masm_, "[ Allocate arguments object"); - if (!function_in_register) { - // Load this again, if it's used by the local context below. - __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); - } else { - __ mov(r3, r1); - } - // Receiver is just before the parameters on the caller's stack. - int offset = scope()->num_parameters() * kPointerSize; - __ add(r2, fp, - Operand(StandardFrameConstants::kCallerSPOffset + offset)); - __ mov(r1, Operand(Smi::FromInt(scope()->num_parameters()))); - __ Push(r3, r2, r1); - - // Arguments to ArgumentsAccessStub: - // function, receiver address, parameter count. - // The stub will rewrite receiever and parameter count if the previous - // stack frame was an arguments adapter frame. - ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); - __ CallStub(&stub); - // Duplicate the value; move-to-slot operation might clobber registers. - __ mov(r3, r0); - Move(arguments->slot(), r0, r1, r2); - Slot* dot_arguments_slot = - scope()->arguments_shadow()->AsVariable()->slot(); - Move(dot_arguments_slot, r3, r1, r2); + Variable* arguments = scope()->arguments()->AsVariable(); + if (arguments != NULL) { + // Function uses arguments object. + Comment cmnt(masm_, "[ Allocate arguments object"); + if (!function_in_register) { + // Load this again, if it's used by the local context below. + __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); + } else { + __ mov(r3, r1); } + // Receiver is just before the parameters on the caller's stack. + int offset = scope()->num_parameters() * kPointerSize; + __ add(r2, fp, + Operand(StandardFrameConstants::kCallerSPOffset + offset)); + __ mov(r1, Operand(Smi::FromInt(scope()->num_parameters()))); + __ Push(r3, r2, r1); + + // Arguments to ArgumentsAccessStub: + // function, receiver address, parameter count. + // The stub will rewrite receiever and parameter count if the previous + // stack frame was an arguments adapter frame. + ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); + __ CallStub(&stub); + // Duplicate the value; move-to-slot operation might clobber registers. + __ mov(r3, r0); + Move(arguments->slot(), r0, r1, r2); + Slot* dot_arguments_slot = + scope()->arguments_shadow()->AsVariable()->slot(); + Move(dot_arguments_slot, r3, r1, r2); } { Comment cmnt(masm_, "[ Declarations"); diff --git a/src/compiler.cc b/src/compiler.cc index ffee28f..9f0162e 100755 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -33,7 +33,6 @@ #include "compiler.h" #include "data-flow.h" #include "debug.h" -#include "fast-codegen.h" #include "flow-graph.h" #include "full-codegen.h" #include "liveedit.h" @@ -120,14 +119,9 @@ static Handle MakeCode(Handle context, CompilationInfo* info) { // // --full-compiler enables the dedicated backend for code we expect to be // run once - // --fast-compiler enables a speculative optimizing backend (for - // non-run-once code) // // The normal choice of backend can be overridden with the flags - // --always-full-compiler and --always-fast-compiler, which are mutually - // incompatible. - CHECK(!FLAG_always_full_compiler || !FLAG_always_fast_compiler); - + // --always-full-compiler. Handle shared = info->shared_info(); bool is_run_once = (shared.is_null()) ? info->scope()->is_global_scope() @@ -141,13 +135,6 @@ static Handle MakeCode(Handle context, CompilationInfo* info) { if (checker.has_supported_syntax()) { return FullCodeGenerator::MakeCode(info); } - } else if (FLAG_always_fast_compiler || - (FLAG_fast_compiler && !is_run_once)) { - FastCodeGenSyntaxChecker checker; - checker.Check(info); - if (checker.has_supported_syntax()) { - return FastCodeGenerator::MakeCode(info); - } } return CodeGenerator::MakeCode(info); @@ -528,7 +515,6 @@ Handle Compiler::BuildFunctionInfo(FunctionLiteral* literal, // the static helper function MakeCode. CompilationInfo info(literal, script, false); - CHECK(!FLAG_always_full_compiler || !FLAG_always_fast_compiler); bool is_run_once = literal->try_full_codegen(); bool is_compiled = false; @@ -542,16 +528,6 @@ Handle Compiler::BuildFunctionInfo(FunctionLiteral* literal, code = FullCodeGenerator::MakeCode(&info); is_compiled = true; } - } else if (FLAG_always_fast_compiler || - (FLAG_fast_compiler && !is_run_once)) { - // Since we are not lazily compiling we do not have a receiver to - // specialize for. - FastCodeGenSyntaxChecker checker; - checker.Check(&info); - if (checker.has_supported_syntax()) { - code = FastCodeGenerator::MakeCode(&info); - is_compiled = true; - } } if (!is_compiled) { diff --git a/src/compiler.h b/src/compiler.h index ade21f5..ed26603 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -41,37 +41,6 @@ namespace internal { // is constructed based on the resources available at compile-time. class CompilationInfo BASE_EMBEDDED { public: - // Compilation mode. Either the compiler is used as the primary - // compiler and needs to setup everything or the compiler is used as - // the secondary compiler for split compilation and has to handle - // bailouts. - enum Mode { - PRIMARY, - SECONDARY - }; - - // A description of the compilation state at a bailout to the secondary - // code generator. - // - // The state is currently simple: there are no parameters or local - // variables to worry about ('this' can be found in the stack frame). - // There are at most two live values. - // - // There is a label that should be bound to the beginning of the bailout - // stub code. - class Bailout : public ZoneObject { - public: - Bailout(Register left, Register right) : left_(left), right_(right) {} - - Label* label() { return &label_; } - - private: - Register left_; - Register right_; - Label label_; - }; - - // Lazy compilation of a JSFunction. CompilationInfo(Handle closure, int loop_nesting, @@ -145,12 +114,6 @@ class CompilationInfo BASE_EMBEDDED { int loop_nesting() { return loop_nesting_; } bool has_receiver() { return !receiver_.is_null(); } Handle receiver() { return receiver_; } - List* bailouts() { return &bailouts_; } - - // Accessors for mutable fields (possibly set by analysis passes) with - // default values given by Initialize. - Mode mode() { return mode_; } - void set_mode(Mode mode) { mode_ = mode; } bool has_this_properties() { return has_this_properties_; } void set_has_this_properties(bool flag) { has_this_properties_ = flag; } @@ -169,19 +132,8 @@ class CompilationInfo BASE_EMBEDDED { // Derived accessors. Scope* scope() { return function()->scope(); } - // Add a bailout with two live values. - Label* AddBailout(Register left, Register right) { - Bailout* bailout = new Bailout(left, right); - bailouts_.Add(bailout); - return bailout->label(); - } - - // Add a bailout with no live values. - Label* AddBailout() { return AddBailout(no_reg, no_reg); } - private: void Initialize() { - mode_ = PRIMARY; has_this_properties_ = false; has_globals_ = false; } @@ -191,7 +143,6 @@ class CompilationInfo BASE_EMBEDDED { Handle