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
This commit is contained in:
parent
0045327b7d
commit
dc49c566a4
@ -143,7 +143,9 @@ CodeGenerator::CodeGenerator(MacroAssembler* masm,
|
||||
// r1: called JS function
|
||||
// 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.
|
||||
CodeForFunctionPosition(fun);
|
||||
|
||||
@ -169,8 +171,7 @@ void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) {
|
||||
// r1: called JS function
|
||||
// cp: callee's context
|
||||
allocator_->Initialize();
|
||||
frame_->Enter();
|
||||
// tos: code slot
|
||||
|
||||
#ifdef DEBUG
|
||||
if (strlen(FLAG_stop_at) > 0 &&
|
||||
fun->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
|
||||
@ -179,13 +180,13 @@ void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) {
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mode == PRIMARY) {
|
||||
frame_->Enter();
|
||||
// tos: code slot
|
||||
|
||||
// Allocate space for locals and initialize them. This also checks
|
||||
// for stack overflow.
|
||||
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;
|
||||
int heap_slots = scope_->num_heap_slots();
|
||||
@ -231,7 +232,8 @@ void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) {
|
||||
Variable* par = scope_->parameter(i);
|
||||
Slot* slot = par->slot();
|
||||
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));
|
||||
// Loads r2 with context; used below in RecordWrite.
|
||||
__ str(r1, SlotOperand(slot, r2));
|
||||
@ -276,6 +278,19 @@ void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) {
|
||||
frame_->EmitPush(ip);
|
||||
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
|
||||
// (source elements). In case of an illegal redeclaration we need to
|
||||
|
@ -150,6 +150,15 @@ class CodeGenState BASE_EMBEDDED {
|
||||
|
||||
class CodeGenerator: public AstVisitor {
|
||||
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
|
||||
// be called by compiler.cc.
|
||||
static Handle<Code> MakeCode(FunctionLiteral* fun,
|
||||
@ -240,7 +249,7 @@ class CodeGenerator: public AstVisitor {
|
||||
inline void VisitStatementsAndSpill(ZoneList<Statement*>* statements);
|
||||
|
||||
// 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.
|
||||
void LoadReference(Reference* ref);
|
||||
|
@ -111,6 +111,7 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun, CompilationInfo* info) {
|
||||
// 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.
|
||||
|
||||
|
@ -228,7 +228,7 @@ Handle<Code> CodeGenerator::MakeCode(FunctionLiteral* fun,
|
||||
MacroAssembler masm(NULL, kInitialBufferSize);
|
||||
CodeGenerator cgen(&masm, script, is_eval);
|
||||
CodeGeneratorScope scope(&cgen);
|
||||
cgen.GenCode(fun, info);
|
||||
cgen.Generate(fun, PRIMARY, info);
|
||||
if (cgen.HasStackOverflow()) {
|
||||
ASSERT(!Top::has_pending_exception());
|
||||
return Handle<Code>::null();
|
||||
|
@ -55,7 +55,7 @@
|
||||
// CodeGenerator
|
||||
// ~CodeGenerator
|
||||
// ProcessDeferred
|
||||
// GenCode
|
||||
// Generate
|
||||
// ComputeLazyCompile
|
||||
// BuildBoilerplate
|
||||
// ComputeCallInitialize
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "codegen-inl.h"
|
||||
#include "data-flow.h"
|
||||
#include "fast-codegen.h"
|
||||
#include "full-codegen.h"
|
||||
#include "scopes.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -358,9 +357,10 @@ Handle<Code> FastCodeGenerator::MakeCode(FunctionLiteral* fun,
|
||||
|
||||
// Generate the full code for the function in bailout mode, using the same
|
||||
// macro assembler.
|
||||
FullCodeGenerator full_cgen(&masm, script, is_eval);
|
||||
full_cgen.Generate(fun, FullCodeGenerator::SECONDARY);
|
||||
if (full_cgen.HasStackOverflow()) {
|
||||
CodeGenerator cgen(&masm, script, is_eval);
|
||||
CodeGeneratorScope scope(&cgen);
|
||||
cgen.Generate(fun, CodeGenerator::SECONDARY, info);
|
||||
if (cgen.HasStackOverflow()) {
|
||||
ASSERT(!Top::has_pending_exception());
|
||||
return Handle<Code>::null();
|
||||
}
|
||||
|
@ -126,7 +126,9 @@ CodeGenerator::CodeGenerator(MacroAssembler* masm,
|
||||
// edi: called JS function
|
||||
// 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.
|
||||
CodeForFunctionPosition(fun);
|
||||
|
||||
@ -167,14 +169,12 @@ void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) {
|
||||
// edi: called JS function
|
||||
// esi: callee's context
|
||||
allocator_->Initialize();
|
||||
|
||||
if (mode == PRIMARY) {
|
||||
frame_->Enter();
|
||||
|
||||
// Allocate space for locals and initialize them.
|
||||
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.
|
||||
int heap_slots = scope_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
|
||||
@ -256,6 +256,18 @@ void CodeGenerator::GenCode(FunctionLiteral* fun, CompilationInfo* info) {
|
||||
frame_->Push(Factory::the_hole_value());
|
||||
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
|
||||
// (source elements). In case of an illegal redeclaration we need to
|
||||
|
@ -294,6 +294,15 @@ enum ArgumentsAllocationMode {
|
||||
|
||||
class CodeGenerator: public AstVisitor {
|
||||
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
|
||||
// be called by compiler.cc.
|
||||
static Handle<Code> MakeCode(FunctionLiteral* fun,
|
||||
@ -379,7 +388,7 @@ class CodeGenerator: public AstVisitor {
|
||||
void VisitStatementsAndSpill(ZoneList<Statement*>* statements);
|
||||
|
||||
// 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
|
||||
// once per compiled function, immediately after binding the return
|
||||
|
@ -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.
|
||||
CodeForFunctionPosition(function);
|
||||
ZoneList<Statement*>* body = function->body();
|
||||
@ -318,14 +320,12 @@ void CodeGenerator::GenCode(FunctionLiteral* function, CompilationInfo* info) {
|
||||
// rdi: called JS function
|
||||
// rsi: callee's context
|
||||
allocator_->Initialize();
|
||||
|
||||
if (mode == PRIMARY) {
|
||||
frame_->Enter();
|
||||
|
||||
// Allocate space for locals and initialize them.
|
||||
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.
|
||||
int heap_slots = scope_->num_heap_slots();
|
||||
@ -407,6 +407,18 @@ void CodeGenerator::GenCode(FunctionLiteral* function, CompilationInfo* info) {
|
||||
frame_->Push(Factory::the_hole_value());
|
||||
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
|
||||
// (source elements). In case of an illegal redeclaration we need to
|
||||
|
@ -294,6 +294,15 @@ enum ArgumentsAllocationMode {
|
||||
|
||||
class CodeGenerator: public AstVisitor {
|
||||
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
|
||||
// be called by compiler.cc.
|
||||
static Handle<Code> MakeCode(FunctionLiteral* fun,
|
||||
@ -381,7 +390,7 @@ class CodeGenerator: public AstVisitor {
|
||||
void VisitStatementsAndSpill(ZoneList<Statement*>* statements);
|
||||
|
||||
// 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
|
||||
// once per compiled function, immediately after binding the return
|
||||
|
Loading…
Reference in New Issue
Block a user