diff options
| author | Ben Murdoch <benm@google.com> | 2012-04-11 10:23:59 +0100 |
|---|---|---|
| committer | Ben Murdoch <benm@google.com> | 2012-04-11 15:40:41 +0100 |
| commit | 5d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0b (patch) | |
| tree | 7b717e53b80c4a64bf9b723aabcf7c909ae3c243 /src/full-codegen.cc | |
| parent | c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9 (diff) | |
| download | android_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.cc | 166 |
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()); } |
