summaryrefslogtreecommitdiffstats
path: root/src/full-codegen.cc
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2012-04-11 10:23:59 +0100
committerBen Murdoch <benm@google.com>2012-04-11 15:40:41 +0100
commit5d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0b (patch)
tree7b717e53b80c4a64bf9b723aabcf7c909ae3c243 /src/full-codegen.cc
parentc7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9 (diff)
downloadandroid_external_v8-5d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0b.tar.gz
android_external_v8-5d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0b.tar.bz2
android_external_v8-5d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0b.zip
Merge V8 3.9 at 3.9.24.9
http://v8.googlecode.com/svn/branches/3.9@11260 Bug: 5688872 Change-Id: Iddd944e82189d92df3fc427dc5f0d3f1b2f0c6c8
Diffstat (limited to 'src/full-codegen.cc')
-rw-r--r--src/full-codegen.cc166
1 files changed, 142 insertions, 24 deletions
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index 4d1707d7..d963979a 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -51,7 +51,37 @@ void BreakableStatementChecker::Check(Expression* expr) {
}
-void BreakableStatementChecker::VisitDeclaration(Declaration* decl) {
+void BreakableStatementChecker::VisitVariableDeclaration(
+ VariableDeclaration* decl) {
+}
+
+void BreakableStatementChecker::VisitFunctionDeclaration(
+ FunctionDeclaration* decl) {
+}
+
+void BreakableStatementChecker::VisitModuleDeclaration(
+ ModuleDeclaration* decl) {
+}
+
+void BreakableStatementChecker::VisitImportDeclaration(
+ ImportDeclaration* decl) {
+}
+
+void BreakableStatementChecker::VisitExportDeclaration(
+ ExportDeclaration* decl) {
+}
+
+
+void BreakableStatementChecker::VisitModuleLiteral(ModuleLiteral* module) {
+}
+
+void BreakableStatementChecker::VisitModuleVariable(ModuleVariable* module) {
+}
+
+void BreakableStatementChecker::VisitModulePath(ModulePath* module) {
+}
+
+void BreakableStatementChecker::VisitModuleUrl(ModuleUrl* module) {
}
@@ -273,8 +303,8 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
masm.positions_recorder()->StartGDBJITLineInfoRecording();
#endif
- FullCodeGenerator cgen(&masm);
- cgen.Generate(info);
+ FullCodeGenerator cgen(&masm, info);
+ cgen.Generate();
if (cgen.HasStackOverflow()) {
ASSERT(!isolate->has_pending_exception());
return false;
@@ -283,8 +313,12 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
Code::Flags flags = Code::ComputeFlags(Code::FUNCTION);
Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
- code->set_optimizable(info->IsOptimizable());
+ code->set_optimizable(info->IsOptimizable() &&
+ !info->function()->flags()->Contains(kDontOptimize));
+ code->set_self_optimization_header(cgen.has_self_optimization_header_);
cgen.PopulateDeoptimizationData(code);
+ cgen.PopulateTypeFeedbackInfo(code);
+ cgen.PopulateTypeFeedbackCells(code);
code->set_has_deoptimization_support(info->HasDeoptimizationSupport());
code->set_handler_table(*cgen.handler_table());
#ifdef ENABLE_DEBUGGER_SUPPORT
@@ -296,6 +330,9 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
code->set_stack_check_table_offset(table_offset);
CodeGenerator::PrintCode(code, info);
info->SetCode(code); // May be an empty handle.
+ if (!code.is_null()) {
+ isolate->runtime_profiler()->NotifyCodeGenerated(code->instruction_size());
+ }
#ifdef ENABLE_GDB_JIT_INTERFACE
if (FLAG_gdbjit && !code.is_null()) {
GDBJITLineInfo* lineinfo =
@@ -329,8 +366,7 @@ void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) {
ASSERT(info_->HasDeoptimizationSupport() || bailout_entries_.is_empty());
if (!info_->HasDeoptimizationSupport()) return;
int length = bailout_entries_.length();
- Handle<DeoptimizationOutputData> data =
- isolate()->factory()->
+ Handle<DeoptimizationOutputData> data = isolate()->factory()->
NewDeoptimizationOutputData(length, TENURED);
for (int i = 0; i < length; i++) {
data->SetAstId(i, Smi::FromInt(bailout_entries_[i].id));
@@ -340,6 +376,30 @@ void FullCodeGenerator::PopulateDeoptimizationData(Handle<Code> code) {
}
+void FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) {
+ Handle<TypeFeedbackInfo> info = isolate()->factory()->NewTypeFeedbackInfo();
+ info->set_ic_total_count(ic_total_count_);
+ ASSERT(!isolate()->heap()->InNewSpace(*info));
+ code->set_type_feedback_info(*info);
+}
+
+
+void FullCodeGenerator::PopulateTypeFeedbackCells(Handle<Code> code) {
+ if (type_feedback_cells_.is_empty()) return;
+ int length = type_feedback_cells_.length();
+ int array_size = TypeFeedbackCells::LengthOfFixedArray(length);
+ Handle<TypeFeedbackCells> cache = Handle<TypeFeedbackCells>::cast(
+ isolate()->factory()->NewFixedArray(array_size, TENURED));
+ for (int i = 0; i < length; i++) {
+ cache->SetAstId(i, Smi::FromInt(type_feedback_cells_[i].ast_id));
+ cache->SetCell(i, *type_feedback_cells_[i].cell);
+ }
+ TypeFeedbackInfo::cast(code->type_feedback_info())->set_type_feedback_cells(
+ *cache);
+}
+
+
+
void FullCodeGenerator::PrepareForBailout(Expression* node, State state) {
PrepareForBailoutForId(node->id(), state);
}
@@ -365,9 +425,10 @@ void FullCodeGenerator::RecordJSReturnSite(Call* call) {
void FullCodeGenerator::PrepareForBailoutForId(unsigned id, State state) {
// There's no need to prepare this code for bailouts from already optimized
// code or code that can't be optimized.
- if (!FLAG_deopt || !info_->HasDeoptimizationSupport()) return;
+ if (!info_->HasDeoptimizationSupport()) return;
unsigned pc_and_state =
StateField::encode(state) | PcField::encode(masm_->pc_offset());
+ ASSERT(Smi::IsValid(pc_and_state));
BailoutEntry entry = { id, pc_and_state };
#ifdef DEBUG
if (FLAG_enable_slow_asserts) {
@@ -385,6 +446,13 @@ void FullCodeGenerator::PrepareForBailoutForId(unsigned id, State state) {
}
+void FullCodeGenerator::RecordTypeFeedbackCell(
+ unsigned id, Handle<JSGlobalPropertyCell> cell) {
+ TypeFeedbackCellEntry entry = { id, cell };
+ type_feedback_cells_.Add(entry);
+}
+
+
void FullCodeGenerator::RecordStackCheck(unsigned ast_id) {
// The pc offset does not need to be encoded and packed together with a
// state.
@@ -503,24 +571,24 @@ void FullCodeGenerator::DoTest(const TestContext* context) {
void FullCodeGenerator::VisitDeclarations(
ZoneList<Declaration*>* declarations) {
- int length = declarations->length();
- int global_count = 0;
- for (int i = 0; i < length; i++) {
- Declaration* decl = declarations->at(i);
- EmitDeclaration(decl->proxy(), decl->mode(), decl->fun(), &global_count);
- }
+ int save_global_count = global_count_;
+ global_count_ = 0;
+
+ AstVisitor::VisitDeclarations(declarations);
// Batch declare global functions and variables.
- if (global_count > 0) {
+ if (global_count_ > 0) {
Handle<FixedArray> array =
- isolate()->factory()->NewFixedArray(2 * global_count, TENURED);
+ isolate()->factory()->NewFixedArray(2 * global_count_, TENURED);
+ int length = declarations->length();
for (int j = 0, i = 0; i < length; i++) {
Declaration* decl = declarations->at(i);
Variable* var = decl->proxy()->var();
if (var->IsUnallocated()) {
array->set(j++, *(var->name()));
- if (decl->fun() == NULL) {
+ FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration();
+ if (fun_decl == NULL) {
if (var->binding_needs_init()) {
// In case this binding needs initialization use the hole.
array->set_the_hole(j++);
@@ -529,7 +597,7 @@ void FullCodeGenerator::VisitDeclarations(
}
} else {
Handle<SharedFunctionInfo> function =
- Compiler::BuildFunctionInfo(decl->fun(), script());
+ Compiler::BuildFunctionInfo(fun_decl->fun(), script());
// Check for stack-overflow exception.
if (function.is_null()) {
SetStackOverflow();
@@ -543,6 +611,53 @@ void FullCodeGenerator::VisitDeclarations(
// declaration the global functions and variables.
DeclareGlobals(array);
}
+
+ global_count_ = save_global_count;
+}
+
+
+void FullCodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) {
+ EmitDeclaration(decl->proxy(), decl->mode(), NULL);
+}
+
+
+void FullCodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) {
+ EmitDeclaration(decl->proxy(), decl->mode(), decl->fun());
+}
+
+
+void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* decl) {
+ EmitDeclaration(decl->proxy(), decl->mode(), NULL);
+}
+
+
+void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* decl) {
+ EmitDeclaration(decl->proxy(), decl->mode(), NULL);
+}
+
+
+void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* decl) {
+ // TODO(rossberg)
+}
+
+
+void FullCodeGenerator::VisitModuleLiteral(ModuleLiteral* module) {
+ // TODO(rossberg)
+}
+
+
+void FullCodeGenerator::VisitModuleVariable(ModuleVariable* module) {
+ // TODO(rossberg)
+}
+
+
+void FullCodeGenerator::VisitModulePath(ModulePath* module) {
+ // TODO(rossberg)
+}
+
+
+void FullCodeGenerator::VisitModuleUrl(ModuleUrl* decl) {
+ // TODO(rossberg)
}
@@ -997,7 +1112,7 @@ void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
// Check stack before looping.
PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
__ bind(&stack_check);
- EmitStackCheck(stmt);
+ EmitStackCheck(stmt, &body);
__ jmp(&body);
PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
@@ -1026,7 +1141,7 @@ void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
SetStatementPosition(stmt);
// Check stack before looping.
- EmitStackCheck(stmt);
+ EmitStackCheck(stmt, &body);
__ bind(&test);
VisitForControl(stmt->cond(),
@@ -1045,6 +1160,10 @@ void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
Label test, body;
Iteration loop_statement(this, stmt);
+
+ // Set statement position for a break slot before entering the for-body.
+ SetStatementPosition(stmt);
+
if (stmt->init() != NULL) {
Visit(stmt->init());
}
@@ -1059,7 +1178,6 @@ void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
__ bind(loop_statement.continue_label());
- SetStatementPosition(stmt);
if (stmt->next() != NULL) {
Visit(stmt->next());
}
@@ -1069,7 +1187,7 @@ void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
SetStatementPosition(stmt);
// Check stack before looping.
- EmitStackCheck(stmt);
+ EmitStackCheck(stmt, &body);
__ bind(&test);
if (stmt->cond() != NULL) {
@@ -1125,7 +1243,7 @@ void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
// Try block code. Sets up the exception handler chain.
__ bind(&try_entry);
- __ PushTryHandler(IN_JAVASCRIPT, TRY_CATCH_HANDLER, stmt->index());
+ __ PushTryHandler(StackHandler::CATCH, stmt->index());
{ TryCatch try_body(this);
Visit(stmt->try_block());
}
@@ -1182,7 +1300,7 @@ void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
// Set up try handler.
__ bind(&try_entry);
- __ PushTryHandler(IN_JAVASCRIPT, TRY_FINALLY_HANDLER, stmt->index());
+ __ PushTryHandler(StackHandler::FINALLY, stmt->index());
{ TryFinally try_body(this, &finally_entry);
Visit(stmt->try_block());
}