summaryrefslogtreecommitdiff
path: root/deps/v8/src/codegen.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/codegen.cc')
-rw-r--r--deps/v8/src/codegen.cc98
1 files changed, 59 insertions, 39 deletions
diff --git a/deps/v8/src/codegen.cc b/deps/v8/src/codegen.cc
index 40c2583f4..f46269fe9 100644
--- a/deps/v8/src/codegen.cc
+++ b/deps/v8/src/codegen.cc
@@ -38,27 +38,41 @@
#include "scopeinfo.h"
#include "stub-cache.h"
-namespace v8 { namespace internal {
-
-DeferredCode::DeferredCode(CodeGenerator* generator)
- : generator_(generator),
- masm_(generator->masm()),
- enter_(generator),
- exit_(generator, JumpTarget::BIDIRECTIONAL),
- statement_position_(masm_->current_statement_position()),
- position_(masm_->current_position()) {
- generator->AddDeferred(this);
+namespace v8 {
+namespace internal {
+
+
+CodeGenerator* CodeGeneratorScope::top_ = NULL;
+
+
+DeferredCode::DeferredCode()
+ : masm_(CodeGeneratorScope::Current()->masm()),
+ statement_position_(masm_->current_statement_position()),
+ position_(masm_->current_position()) {
ASSERT(statement_position_ != RelocInfo::kNoPosition);
ASSERT(position_ != RelocInfo::kNoPosition);
+
+ CodeGeneratorScope::Current()->AddDeferred(this);
#ifdef DEBUG
comment_ = "";
#endif
-}
-
-void CodeGenerator::ClearDeferred() {
- for (int i = 0; i < deferred_.length(); i++) {
- deferred_[i]->Clear();
+ // Copy the register locations from the code generator's frame.
+ // These are the registers that will be spilled on entry to the
+ // deferred code and restored on exit.
+ VirtualFrame* frame = CodeGeneratorScope::Current()->frame();
+ int sp_offset = frame->fp_relative(frame->stack_pointer_);
+ for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
+ int loc = frame->register_location(i);
+ if (loc == VirtualFrame::kIllegalIndex) {
+ registers_[i] = kIgnore;
+ } else if (frame->elements_[loc].is_synced()) {
+ // Needs to be restored on exit but not saved on entry.
+ registers_[i] = frame->fp_relative(loc) | kSyncedFlag;
+ } else {
+ int offset = frame->fp_relative(loc);
+ registers_[i] = (offset < sp_offset) ? kPush : offset;
+ }
}
}
@@ -66,17 +80,19 @@ void CodeGenerator::ClearDeferred() {
void CodeGenerator::ProcessDeferred() {
while (!deferred_.is_empty()) {
DeferredCode* code = deferred_.RemoveLast();
- MacroAssembler* masm = code->masm();
+ ASSERT(masm_ == code->masm());
// Record position of deferred code stub.
- masm->RecordStatementPosition(code->statement_position());
+ masm_->RecordStatementPosition(code->statement_position());
if (code->position() != RelocInfo::kNoPosition) {
- masm->RecordPosition(code->position());
+ masm_->RecordPosition(code->position());
}
// Generate the code.
- Comment cmnt(masm, code->comment());
+ Comment cmnt(masm_, code->comment());
+ masm_->bind(code->entry_label());
+ code->SaveRegisters();
code->Generate();
- ASSERT(code->enter()->is_bound());
- code->Clear();
+ code->RestoreRegisters();
+ masm_->jmp(code->exit_label());
}
}
@@ -104,7 +120,6 @@ void CodeGenerator::SetFrame(VirtualFrame* new_frame,
void CodeGenerator::DeleteFrame() {
if (has_valid_frame()) {
frame_->DetachFromCodeGenerator();
- delete frame_;
frame_ = NULL;
}
}
@@ -155,17 +170,21 @@ Handle<Code> CodeGenerator::MakeCode(FunctionLiteral* flit,
// Generate code.
const int initial_buffer_size = 4 * KB;
CodeGenerator cgen(initial_buffer_size, script, is_eval);
+ CodeGeneratorScope scope(&cgen);
cgen.GenCode(flit);
if (cgen.HasStackOverflow()) {
ASSERT(!Top::has_pending_exception());
return Handle<Code>::null();
}
- // Allocate and install the code.
+ // Allocate and install the code. Time the rest of this function as
+ // code creation.
+ HistogramTimerScope timer(&Counters::code_creation);
CodeDesc desc;
cgen.masm()->GetCode(&desc);
- ScopeInfo<> sinfo(flit->scope());
- Code::Flags flags = Code::ComputeFlags(Code::FUNCTION);
+ ZoneScopeInfo sinfo(flit->scope());
+ InLoopFlag in_loop = (cgen.loop_nesting() != 0) ? IN_LOOP : NOT_IN_LOOP;
+ Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, in_loop);
Handle<Code> code = Factory::NewCode(desc,
&sinfo,
flags,
@@ -206,7 +225,7 @@ Handle<Code> CodeGenerator::MakeCode(FunctionLiteral* flit,
bool CodeGenerator::ShouldGenerateLog(Expression* type) {
ASSERT(type != NULL);
- if (!Logger::is_enabled()) return false;
+ if (!Logger::IsEnabled()) return false;
Handle<String> name = Handle<String>::cast(type->AsLiteral()->handle());
if (FLAG_log_regexp) {
static Vector<const char> kRegexp = CStrVector("regexp");
@@ -317,17 +336,18 @@ Handle<JSFunction> CodeGenerator::BuildBoilerplate(FunctionLiteral* node) {
}
-Handle<Code> CodeGenerator::ComputeCallInitialize(int argc) {
- CALL_HEAP_FUNCTION(StubCache::ComputeCallInitialize(argc), Code);
-}
-
-
-Handle<Code> CodeGenerator::ComputeCallInitializeInLoop(int argc) {
- // Force the creation of the corresponding stub outside loops,
- // because it will be used when clearing the ICs later - when we
- // don't know if we're inside a loop or not.
- ComputeCallInitialize(argc);
- CALL_HEAP_FUNCTION(StubCache::ComputeCallInitializeInLoop(argc), Code);
+Handle<Code> CodeGenerator::ComputeCallInitialize(
+ int argc,
+ InLoopFlag in_loop) {
+ if (in_loop == IN_LOOP) {
+ // Force the creation of the corresponding stub outside loops,
+ // because it may be used when clearing the ICs later - it is
+ // possible for a series of IC transitions to lose the in-loop
+ // information, and the IC clearing code can't generate a stub
+ // that it needs so we need to ensure it is generated already.
+ ComputeCallInitialize(argc, NOT_IN_LOOP);
+ }
+ CALL_HEAP_FUNCTION(StubCache::ComputeCallInitialize(argc, in_loop), Code);
}
@@ -507,8 +527,8 @@ void CodeGenerator::GenerateFastCaseSwitchCases(
// frame. Otherwise, we have to merge the existing one to the
// start frame as part of the previous case.
if (!has_valid_frame()) {
- RegisterFile non_frame_registers = RegisterAllocator::Reserved();
- SetFrame(new VirtualFrame(start_frame), &non_frame_registers);
+ RegisterFile empty;
+ SetFrame(new VirtualFrame(start_frame), &empty);
} else {
frame_->MergeTo(start_frame);
}