Commit dc49c566 authored by ager@chromium.org's avatar ager@chromium.org

Use the virtual-frame based optimizing compiler for split-compilation

bailouts.  For now the virtual-frame state at entry of a function is
hard-coded when using the virtual-frame based compiler as the
secondary compiler.

Setup frame pointer correctly on function entry on ARM in
fast-codegen-arm.

Review URL: http://codereview.chromium.org/569010

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3776 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 0045327b
...@@ -143,7 +143,9 @@ CodeGenerator::CodeGenerator(MacroAssembler* masm, ...@@ -143,7 +143,9 @@ CodeGenerator::CodeGenerator(MacroAssembler* masm,
// r1: called JS function // r1: called JS function
// cp: callee's context // cp: callee's context
void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) { void CodeGenerator::Generate(FunctionLiteral* fun,
Mode mode,
CompilationInfo* info) {
// Record the position for debugging purposes. // Record the position for debugging purposes.
CodeForFunctionPosition(fun); CodeForFunctionPosition(fun);
...@@ -169,8 +171,7 @@ void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) { ...@@ -169,8 +171,7 @@ void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) {
// r1: called JS function // r1: called JS function
// cp: callee's context // cp: callee's context
allocator_->Initialize(); allocator_->Initialize();
frame_->Enter();
// tos: code slot
#ifdef DEBUG #ifdef DEBUG
if (strlen(FLAG_stop_at) > 0 && if (strlen(FLAG_stop_at) > 0 &&
fun->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { fun->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
...@@ -179,13 +180,13 @@ void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) { ...@@ -179,13 +180,13 @@ void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) {
} }
#endif #endif
if (mode == PRIMARY) {
frame_->Enter();
// tos: code slot
// Allocate space for locals and initialize them. This also checks // Allocate space for locals and initialize them. This also checks
// for stack overflow. // for stack overflow.
frame_->AllocateStackSlots(); frame_->AllocateStackSlots();
// Initialize the function return target after the locals are set
// up, because it needs the expected frame height from the frame.
function_return_.set_direction(JumpTarget::BIDIRECTIONAL);
function_return_is_shadowed_ = false;
VirtualFrame::SpilledScope spilled_scope; VirtualFrame::SpilledScope spilled_scope;
int heap_slots = scope_->num_heap_slots(); int heap_slots = scope_->num_heap_slots();
...@@ -231,7 +232,8 @@ void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) { ...@@ -231,7 +232,8 @@ void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) {
Variable* par = scope_->parameter(i); Variable* par = scope_->parameter(i);
Slot* slot = par->slot(); Slot* slot = par->slot();
if (slot != NULL && slot->type() == Slot::CONTEXT) { if (slot != NULL && slot->type() == Slot::CONTEXT) {
ASSERT(!scope_->is_global_scope()); // no parameters in global scope // No parameters in global scope.
ASSERT(!scope_->is_global_scope());
__ ldr(r1, frame_->ParameterAt(i)); __ ldr(r1, frame_->ParameterAt(i));
// Loads r2 with context; used below in RecordWrite. // Loads r2 with context; used below in RecordWrite.
__ str(r1, SlotOperand(slot, r2)); __ str(r1, SlotOperand(slot, r2));
...@@ -276,6 +278,19 @@ void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) { ...@@ -276,6 +278,19 @@ void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) {
frame_->EmitPush(ip); frame_->EmitPush(ip);
StoreToSlot(scope_->function()->slot(), NOT_CONST_INIT); 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);
allocator_->Unuse(r1);
allocator_->Unuse(lr);
}
// Initialize the function return target after the locals are set
// up, because it needs the expected frame height from the frame.
function_return_.set_direction(JumpTarget::BIDIRECTIONAL);
function_return_is_shadowed_ = false;
// Generate code to 'execute' declarations and initialize functions // Generate code to 'execute' declarations and initialize functions
// (source elements). In case of an illegal redeclaration we need to // (source elements). In case of an illegal redeclaration we need to
......
...@@ -150,6 +150,15 @@ class CodeGenState BASE_EMBEDDED { ...@@ -150,6 +150,15 @@ class CodeGenState BASE_EMBEDDED {
class CodeGenerator: public AstVisitor { class CodeGenerator: public AstVisitor {
public: 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
};
// Takes a function literal, generates code for it. This function should only // Takes a function literal, generates code for it. This function should only
// be called by compiler.cc. // be called by compiler.cc.
static Handle<Code> MakeCode(FunctionLiteral* fun, static Handle<Code> MakeCode(FunctionLiteral* fun,
...@@ -240,7 +249,7 @@ class CodeGenerator: public AstVisitor { ...@@ -240,7 +249,7 @@ class CodeGenerator: public AstVisitor {
inline void VisitStatementsAndSpill(ZoneList<Statement*>* statements); inline void VisitStatementsAndSpill(ZoneList<Statement*>* statements);
// Main code generation function // Main code generation function
void GenCode(FunctionLiteral* fun, CompilationInfo* info); void Generate(FunctionLiteral* fun, Mode mode, CompilationInfo* info);
// The following are used by class Reference. // The following are used by class Reference.
void LoadReference(Reference* ref); void LoadReference(Reference* ref);
......
...@@ -111,6 +111,7 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun, CompilationInfo* info) { ...@@ -111,6 +111,7 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun, CompilationInfo* info) {
// Save the caller's frame pointer and set up our own. // Save the caller's frame pointer and set up our own.
Comment prologue_cmnt(masm(), ";; Prologue"); Comment prologue_cmnt(masm(), ";; Prologue");
__ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit()); __ 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 // Note that we keep a live register reference to cp (context) at
// this point. // this point.
......
...@@ -228,7 +228,7 @@ Handle<Code> CodeGenerator::MakeCode(FunctionLiteral* fun, ...@@ -228,7 +228,7 @@ Handle<Code> CodeGenerator::MakeCode(FunctionLiteral* fun,
MacroAssembler masm(NULL, kInitialBufferSize); MacroAssembler masm(NULL, kInitialBufferSize);
CodeGenerator cgen(&masm, script, is_eval); CodeGenerator cgen(&masm, script, is_eval);
CodeGeneratorScope scope(&cgen); CodeGeneratorScope scope(&cgen);
cgen.GenCode(fun, info); cgen.Generate(fun, PRIMARY, info);
if (cgen.HasStackOverflow()) { if (cgen.HasStackOverflow()) {
ASSERT(!Top::has_pending_exception()); ASSERT(!Top::has_pending_exception());
return Handle<Code>::null(); return Handle<Code>::null();
......
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
// CodeGenerator // CodeGenerator
// ~CodeGenerator // ~CodeGenerator
// ProcessDeferred // ProcessDeferred
// GenCode // Generate
// ComputeLazyCompile // ComputeLazyCompile
// BuildBoilerplate // BuildBoilerplate
// ComputeCallInitialize // ComputeCallInitialize
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include "codegen-inl.h" #include "codegen-inl.h"
#include "data-flow.h" #include "data-flow.h"
#include "fast-codegen.h" #include "fast-codegen.h"
#include "full-codegen.h"
#include "scopes.h" #include "scopes.h"
namespace v8 { namespace v8 {
...@@ -358,9 +357,10 @@ Handle<Code> FastCodeGenerator::MakeCode(FunctionLiteral* fun, ...@@ -358,9 +357,10 @@ Handle<Code> FastCodeGenerator::MakeCode(FunctionLiteral* fun,
// Generate the full code for the function in bailout mode, using the same // Generate the full code for the function in bailout mode, using the same
// macro assembler. // macro assembler.
FullCodeGenerator full_cgen(&masm, script, is_eval); CodeGenerator cgen(&masm, script, is_eval);
full_cgen.Generate(fun, FullCodeGenerator::SECONDARY); CodeGeneratorScope scope(&cgen);
if (full_cgen.HasStackOverflow()) { cgen.Generate(fun, CodeGenerator::SECONDARY, info);
if (cgen.HasStackOverflow()) {
ASSERT(!Top::has_pending_exception()); ASSERT(!Top::has_pending_exception());
return Handle<Code>::null(); return Handle<Code>::null();
} }
......
...@@ -126,7 +126,9 @@ CodeGenerator::CodeGenerator(MacroAssembler* masm, ...@@ -126,7 +126,9 @@ CodeGenerator::CodeGenerator(MacroAssembler* masm,
// edi: called JS function // edi: called JS function
// esi: callee's context // esi: callee's context
void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) { void CodeGenerator::Generate(FunctionLiteral* fun,
Mode mode,
CompilationInfo* info) {
// Record the position for debugging purposes. // Record the position for debugging purposes.
CodeForFunctionPosition(fun); CodeForFunctionPosition(fun);
...@@ -167,14 +169,12 @@ void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) { ...@@ -167,14 +169,12 @@ void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) {
// edi: called JS function // edi: called JS function
// esi: callee's context // esi: callee's context
allocator_->Initialize(); allocator_->Initialize();
if (mode == PRIMARY) {
frame_->Enter(); frame_->Enter();
// Allocate space for locals and initialize them. // Allocate space for locals and initialize them.
frame_->AllocateStackSlots(); frame_->AllocateStackSlots();
// Initialize the function return target after the locals are set
// up, because it needs the expected frame height from the frame.
function_return_.set_direction(JumpTarget::BIDIRECTIONAL);
function_return_is_shadowed_ = false;
// Allocate the local context if needed. // Allocate the local context if needed.
int heap_slots = scope_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; int heap_slots = scope_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
...@@ -256,6 +256,18 @@ void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) { ...@@ -256,6 +256,18 @@ void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) {
frame_->Push(Factory::the_hole_value()); 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, ebp, esi,
// and edi have been pushed on the stack. Adjust the virtual
// frame to match this state.
frame_->Adjust(3);
allocator_->Unuse(edi);
}
// Initialize the function return target after the locals are set
// up, because it needs the expected frame height from the frame.
function_return_.set_direction(JumpTarget::BIDIRECTIONAL);
function_return_is_shadowed_ = false;
// Generate code to 'execute' declarations and initialize functions // Generate code to 'execute' declarations and initialize functions
// (source elements). In case of an illegal redeclaration we need to // (source elements). In case of an illegal redeclaration we need to
......
...@@ -294,6 +294,15 @@ enum ArgumentsAllocationMode { ...@@ -294,6 +294,15 @@ enum ArgumentsAllocationMode {
class CodeGenerator: public AstVisitor { class CodeGenerator: public AstVisitor {
public: 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
};
// Takes a function literal, generates code for it. This function should only // Takes a function literal, generates code for it. This function should only
// be called by compiler.cc. // be called by compiler.cc.
static Handle<Code> MakeCode(FunctionLiteral* fun, static Handle<Code> MakeCode(FunctionLiteral* fun,
...@@ -379,7 +388,7 @@ class CodeGenerator: public AstVisitor { ...@@ -379,7 +388,7 @@ class CodeGenerator: public AstVisitor {
void VisitStatementsAndSpill(ZoneList<Statement*>* statements); void VisitStatementsAndSpill(ZoneList<Statement*>* statements);
// Main code generation function // Main code generation function
void GenCode(FunctionLiteral* fun, CompilationInfo* info); void Generate(FunctionLiteral* fun, Mode mode, CompilationInfo* info);
// Generate the return sequence code. Should be called no more than // Generate the return sequence code. Should be called no more than
// once per compiled function, immediately after binding the return // once per compiled function, immediately after binding the return
......
...@@ -278,7 +278,9 @@ void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { ...@@ -278,7 +278,9 @@ void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
} }
void CodeGenerator::GenCode(FunctionLiteral* function, CompilationInfo* info) { void CodeGenerator::Generate(FunctionLiteral* function,
Mode mode,
CompilationInfo* info) {
// Record the position for debugging purposes. // Record the position for debugging purposes.
CodeForFunctionPosition(function); CodeForFunctionPosition(function);
ZoneList<Statement*>* body = function->body(); ZoneList<Statement*>* body = function->body();
...@@ -318,14 +320,12 @@ void CodeGenerator::GenCode(FunctionLiteral* function, CompilationInfo* info) { ...@@ -318,14 +320,12 @@ void CodeGenerator::GenCode(FunctionLiteral* function, CompilationInfo* info) {
// rdi: called JS function // rdi: called JS function
// rsi: callee's context // rsi: callee's context
allocator_->Initialize(); allocator_->Initialize();
if (mode == PRIMARY) {
frame_->Enter(); frame_->Enter();
// Allocate space for locals and initialize them. // Allocate space for locals and initialize them.
frame_->AllocateStackSlots(); frame_->AllocateStackSlots();
// Initialize the function return target after the locals are set
// up, because it needs the expected frame height from the frame.
function_return_.set_direction(JumpTarget::BIDIRECTIONAL);
function_return_is_shadowed_ = false;
// Allocate the local context if needed. // Allocate the local context if needed.
int heap_slots = scope_->num_heap_slots(); int heap_slots = scope_->num_heap_slots();
...@@ -407,6 +407,18 @@ void CodeGenerator::GenCode(FunctionLiteral* function, CompilationInfo* info) { ...@@ -407,6 +407,18 @@ void CodeGenerator::GenCode(FunctionLiteral* function, CompilationInfo* info) {
frame_->Push(Factory::the_hole_value()); 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,
// and rdi have been pushed on the stack. Adjust the virtual
// frame to match this state.
frame_->Adjust(3);
allocator_->Unuse(rdi);
}
// Initialize the function return target after the locals are set
// up, because it needs the expected frame height from the frame.
function_return_.set_direction(JumpTarget::BIDIRECTIONAL);
function_return_is_shadowed_ = false;
// Generate code to 'execute' declarations and initialize functions // Generate code to 'execute' declarations and initialize functions
// (source elements). In case of an illegal redeclaration we need to // (source elements). In case of an illegal redeclaration we need to
......
...@@ -294,6 +294,15 @@ enum ArgumentsAllocationMode { ...@@ -294,6 +294,15 @@ enum ArgumentsAllocationMode {
class CodeGenerator: public AstVisitor { class CodeGenerator: public AstVisitor {
public: 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
};
// Takes a function literal, generates code for it. This function should only // Takes a function literal, generates code for it. This function should only
// be called by compiler.cc. // be called by compiler.cc.
static Handle<Code> MakeCode(FunctionLiteral* fun, static Handle<Code> MakeCode(FunctionLiteral* fun,
...@@ -381,7 +390,7 @@ class CodeGenerator: public AstVisitor { ...@@ -381,7 +390,7 @@ class CodeGenerator: public AstVisitor {
void VisitStatementsAndSpill(ZoneList<Statement*>* statements); void VisitStatementsAndSpill(ZoneList<Statement*>* statements);
// Main code generation function // Main code generation function
void GenCode(FunctionLiteral* fun, CompilationInfo* info); void Generate(FunctionLiteral* fun, Mode mode, CompilationInfo* info);
// Generate the return sequence code. Should be called no more than // Generate the return sequence code. Should be called no more than
// once per compiled function, immediately after binding the return // once per compiled function, immediately after binding the return
......
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