Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler.h" | 5 #include "src/compiler.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "src/asmjs/asm-js.h" | 10 #include "src/asmjs/asm-js.h" |
| 11 #include "src/asmjs/asm-typer.h" | 11 #include "src/asmjs/asm-typer.h" |
| 12 #include "src/ast/ast-numbering.h" | 12 #include "src/ast/ast-numbering.h" |
| 13 #include "src/ast/collect-eager-literals.h" | |
| 13 #include "src/ast/prettyprinter.h" | 14 #include "src/ast/prettyprinter.h" |
| 14 #include "src/ast/scopes.h" | 15 #include "src/ast/scopes.h" |
| 15 #include "src/bootstrapper.h" | 16 #include "src/bootstrapper.h" |
| 16 #include "src/codegen.h" | 17 #include "src/codegen.h" |
| 17 #include "src/compilation-cache.h" | 18 #include "src/compilation-cache.h" |
| 18 #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h" | 19 #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h" |
| 19 #include "src/compiler/pipeline.h" | 20 #include "src/compiler/pipeline.h" |
| 20 #include "src/crankshaft/hydrogen.h" | 21 #include "src/crankshaft/hydrogen.h" |
| 21 #include "src/debug/debug.h" | 22 #include "src/debug/debug.h" |
| 22 #include "src/debug/liveedit.h" | 23 #include "src/debug/liveedit.h" |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 64 | 65 |
| 65 ~ScopedTimer() { *location_ += timer_.Elapsed(); } | 66 ~ScopedTimer() { *location_ += timer_.Elapsed(); } |
| 66 | 67 |
| 67 base::ElapsedTimer timer_; | 68 base::ElapsedTimer timer_; |
| 68 base::TimeDelta* location_; | 69 base::TimeDelta* location_; |
| 69 }; | 70 }; |
| 70 | 71 |
| 71 // ---------------------------------------------------------------------------- | 72 // ---------------------------------------------------------------------------- |
| 72 // Implementation of CompilationJob | 73 // Implementation of CompilationJob |
| 73 | 74 |
| 75 CompilationJob::CompilationJob(Isolate* isolate, CompilationInfo* info, | |
| 76 const char* compiler_name, State initial_state) | |
| 77 : info_(info), | |
| 78 compiler_name_(compiler_name), | |
| 79 state_(initial_state), | |
| 80 stack_limit_(isolate->stack_guard()->real_climit()) {} | |
| 81 | |
| 82 CompilationJob::~CompilationJob() {} | |
| 83 | |
| 74 CompilationJob::Status CompilationJob::PrepareJob() { | 84 CompilationJob::Status CompilationJob::PrepareJob() { |
| 75 DCHECK(ThreadId::Current().Equals(info()->isolate()->thread_id())); | 85 DCHECK(ThreadId::Current().Equals(info()->isolate()->thread_id())); |
| 76 DisallowJavascriptExecution no_js(isolate()); | 86 DisallowJavascriptExecution no_js(isolate()); |
| 77 | 87 |
| 78 if (FLAG_trace_opt && info()->IsOptimizing()) { | 88 if (FLAG_trace_opt && info()->IsOptimizing()) { |
| 79 OFStream os(stdout); | 89 OFStream os(stdout); |
| 80 os << "[compiling method " << Brief(*info()->closure()) << " using " | 90 os << "[compiling method " << Brief(*info()->closure()) << " using " |
| 81 << compiler_name_; | 91 << compiler_name_; |
| 82 if (info()->is_osr()) os << " OSR"; | 92 if (info()->is_osr()) os << " OSR"; |
| 83 os << "]" << std::endl; | 93 os << "]" << std::endl; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 181 } | 191 } |
| 182 if (FLAG_hydrogen_stats) { | 192 if (FLAG_hydrogen_stats) { |
| 183 isolate()->GetHStatistics()->IncrementSubtotals(time_taken_to_prepare_, | 193 isolate()->GetHStatistics()->IncrementSubtotals(time_taken_to_prepare_, |
| 184 time_taken_to_execute_, | 194 time_taken_to_execute_, |
| 185 time_taken_to_finalize_); | 195 time_taken_to_finalize_); |
| 186 } | 196 } |
| 187 } | 197 } |
| 188 | 198 |
| 189 Isolate* CompilationJob::isolate() const { return info()->isolate(); } | 199 Isolate* CompilationJob::isolate() const { return info()->isolate(); } |
| 190 | 200 |
| 201 void CompilationJob::TakeOwnershipOfCompilationInfo() { | |
| 202 DCHECK_NULL(compilation_info_.get()); | |
| 203 compilation_info_.reset(info_); | |
| 204 parse_info_.reset(info_->parse_info()); | |
| 205 zone_.reset(info_->parse_info()->zone()); | |
| 206 } | |
| 207 | |
| 191 namespace { | 208 namespace { |
| 192 | 209 |
| 193 void AddWeakObjectToCodeDependency(Isolate* isolate, Handle<HeapObject> object, | 210 void AddWeakObjectToCodeDependency(Isolate* isolate, Handle<HeapObject> object, |
| 194 Handle<Code> code) { | 211 Handle<Code> code) { |
| 195 Handle<WeakCell> cell = Code::WeakCellFor(code); | 212 Handle<WeakCell> cell = Code::WeakCellFor(code); |
| 196 Heap* heap = isolate->heap(); | 213 Heap* heap = isolate->heap(); |
| 197 if (heap->InNewSpace(*object)) { | 214 if (heap->InNewSpace(*object)) { |
| 198 heap->AddWeakNewSpaceObjectToCodeDependency(object, cell); | 215 heap->AddWeakNewSpaceObjectToCodeDependency(object, cell); |
| 199 } else { | 216 } else { |
| 200 Handle<DependentCode> dep(heap->LookupWeakObjectToCodeDependency(object)); | 217 Handle<DependentCode> dep(heap->LookupWeakObjectToCodeDependency(object)); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 339 // Checks whether top level functions should be passed by the filter. | 356 // Checks whether top level functions should be passed by the filter. |
| 340 if (info->shared_info()->is_toplevel()) { | 357 if (info->shared_info()->is_toplevel()) { |
| 341 Vector<const char> filter = CStrVector(FLAG_ignition_filter); | 358 Vector<const char> filter = CStrVector(FLAG_ignition_filter); |
| 342 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); | 359 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); |
| 343 } | 360 } |
| 344 | 361 |
| 345 // Finally respect the filter. | 362 // Finally respect the filter. |
| 346 return info->shared_info()->PassesFilter(FLAG_ignition_filter); | 363 return info->shared_info()->PassesFilter(FLAG_ignition_filter); |
| 347 } | 364 } |
| 348 | 365 |
| 349 CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) { | 366 bool Renumber(ParseInfo* parse_info) { |
| 367 // Create a canonical handle scope if compiling ignition bytecode. This is | |
| 368 // required by the constant array builder to de-duplicate objects without | |
| 369 // dereferencing handles. | |
| 370 std::unique_ptr<CanonicalHandleScope> canonical; | |
| 371 if (FLAG_ignition) { | |
| 372 canonical.reset(new CanonicalHandleScope(parse_info->isolate())); | |
| 373 } | |
| 374 | |
| 375 if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(), | |
| 376 parse_info->literal())) { | |
| 377 return false; | |
| 378 } | |
| 379 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info(); | |
| 380 if (!shared_info.is_null()) { | |
| 381 FunctionLiteral* lit = parse_info->literal(); | |
| 382 shared_info->set_ast_node_count(lit->ast_node_count()); | |
| 383 if (lit->dont_optimize_reason() != kNoReason) { | |
| 384 shared_info->DisableOptimization(lit->dont_optimize_reason()); | |
| 385 } | |
| 386 if (lit->flags() & AstProperties::kDontCrankshaft) { | |
| 387 shared_info->set_dont_crankshaft(true); | |
| 388 } | |
| 389 } | |
| 390 return true; | |
| 391 } | |
| 392 | |
| 393 std::vector<std::unique_ptr<CompilationJob>> GetUnoptimizedCompilationJobs( | |
| 394 CompilationInfo* info) { | |
| 350 // Function should have been parsed and analyzed before creating a compilation | 395 // Function should have been parsed and analyzed before creating a compilation |
| 351 // job. | 396 // job. |
| 352 DCHECK_NOT_NULL(info->literal()); | 397 DCHECK_NOT_NULL(info->literal()); |
| 353 DCHECK_NOT_NULL(info->scope()); | 398 DCHECK_NOT_NULL(info->scope()); |
| 354 | 399 |
| 355 EnsureFeedbackMetadata(info); | 400 EnsureFeedbackMetadata(info); |
| 401 | |
| 402 std::vector<std::unique_ptr<CompilationJob>> result; | |
| 403 | |
| 356 if (ShouldUseIgnition(info)) { | 404 if (ShouldUseIgnition(info)) { |
| 357 return interpreter::Interpreter::NewCompilationJob(info); | 405 // When compiling eagerly, the majority of work might happen in the |
| 406 // finalization phase, when we get the SharedFunctionInfos for all the | |
| 407 // functions referenced from the function we actually want to compile. | |
| 408 // | |
| 409 // This is undesirable when we want to schedule the compilation work (which | |
| 410 // is only the case for ignition at this point). To avoid this compilation | |
| 411 // during finalization, walk the AST and create separate compilation jobs | |
| 412 // for each eager function literal we encounter. | |
| 413 // | |
| 414 // This doesn't work for debug code, as GetSharedFunctionInfo only caches | |
| 415 // the SharedFunctionInfos with non-debug code. | |
| 416 ShouldCompile should_compile = | |
| 417 (FLAG_ignition_split_jobs && !info->is_debug()) | |
| 418 ? ShouldCompile::kNever | |
| 419 : ShouldCompile::kIfNecessary; | |
| 420 result.push_back(std::unique_ptr<CompilationJob>( | |
| 421 interpreter::Interpreter::NewCompilationJob(info, should_compile))); | |
| 422 | |
| 423 if (should_compile == ShouldCompile::kNever) { | |
| 424 CollectEagerLiterals collector(info); | |
| 425 collector.Run(); | |
| 426 | |
| 427 for (auto fun : collector.eager_literals()) { | |
| 428 Handle<SharedFunctionInfo> sfi = Compiler::GetSharedFunctionInfo( | |
| 429 fun, info->script(), info, ShouldCompile::kNever); | |
| 430 | |
| 431 std::unique_ptr<ParseInfo> parse_info(new ParseInfo( | |
| 432 new Zone(info->isolate()->allocator()), info->script())); | |
| 433 parse_info->set_literal(fun); | |
| 434 parse_info->set_shared_info(sfi); | |
| 435 parse_info->set_language_mode(fun->scope()->language_mode()); | |
| 436 | |
| 437 std::unique_ptr<CompilationInfo> compilation_info(new CompilationInfo( | |
| 438 parse_info.release(), Handle<JSFunction>::null())); | |
| 439 if (info->will_serialize()) compilation_info->PrepareForSerializing(); | |
| 440 DCHECK(!info->is_debug()); | |
| 441 | |
| 442 Renumber(compilation_info->parse_info()); | |
| 443 EnsureFeedbackMetadata(compilation_info.get()); | |
| 444 DCHECK(ShouldUseIgnition(compilation_info.get())); | |
| 445 std::unique_ptr<CompilationJob> job( | |
| 446 interpreter::Interpreter::NewCompilationJob( | |
| 447 compilation_info.release(), ShouldCompile::kNever)); | |
| 448 job->TakeOwnershipOfCompilationInfo(); | |
| 449 result.push_back(std::move(job)); | |
| 450 } | |
| 451 } | |
| 452 | |
| 453 return result; | |
| 358 } else { | 454 } else { |
| 359 return FullCodeGenerator::NewCompilationJob(info); | 455 std::unique_ptr<CompilationJob> job( |
| 456 FullCodeGenerator::NewCompilationJob(info)); | |
| 457 result.push_back(std::move(job)); | |
| 458 return result; | |
| 360 } | 459 } |
| 361 } | 460 } |
| 362 | 461 |
| 363 void InstallSharedScopeInfo(CompilationInfo* info, | 462 void InstallSharedScopeInfo(CompilationInfo* info, |
| 364 Handle<SharedFunctionInfo> shared) { | 463 Handle<SharedFunctionInfo> shared) { |
| 365 Handle<ScopeInfo> scope_info = info->scope()->scope_info(); | 464 Handle<ScopeInfo> scope_info = info->scope()->scope_info(); |
| 366 shared->set_scope_info(*scope_info); | 465 shared->set_scope_info(*scope_info); |
| 367 Scope* outer_scope = info->scope()->GetOuterScopeWithContext(); | 466 Scope* outer_scope = info->scope()->GetOuterScopeWithContext(); |
| 368 if (outer_scope) { | 467 if (outer_scope) { |
| 369 shared->set_outer_scope_info(*outer_scope->scope_info()); | 468 shared->set_outer_scope_info(*outer_scope->scope_info()); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 412 MaybeHandle<FixedArray> wasm_data; | 511 MaybeHandle<FixedArray> wasm_data; |
| 413 wasm_data = AsmJs::ConvertAsmToWasm(info->parse_info()); | 512 wasm_data = AsmJs::ConvertAsmToWasm(info->parse_info()); |
| 414 if (!wasm_data.is_null()) { | 513 if (!wasm_data.is_null()) { |
| 415 info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked()); | 514 info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked()); |
| 416 info->SetCode(info->isolate()->builtins()->InstantiateAsmJs()); | 515 info->SetCode(info->isolate()->builtins()->InstantiateAsmJs()); |
| 417 InstallUnoptimizedCode(info); | 516 InstallUnoptimizedCode(info); |
| 418 return true; | 517 return true; |
| 419 } | 518 } |
| 420 } | 519 } |
| 421 | 520 |
| 422 std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info)); | 521 std::vector<std::unique_ptr<CompilationJob>> jobs( |
| 423 if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false; | 522 GetUnoptimizedCompilationJobs(info)); |
| 424 if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false; | 523 for (auto& job : jobs) { |
| 425 if (FinalizeUnoptimizedCompilationJob(job.get()) != | 524 if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false; |
| 426 CompilationJob::SUCCEEDED) { | 525 if (job->ExecuteJob() != CompilationJob::SUCCEEDED) return false; |
| 427 return false; | 526 if (FinalizeUnoptimizedCompilationJob(job.get()) != |
| 527 CompilationJob::SUCCEEDED) { | |
| 528 return false; | |
| 529 } | |
| 530 job.reset(); | |
| 428 } | 531 } |
| 429 return true; | 532 return true; |
| 430 } | 533 } |
| 431 | 534 |
| 432 bool CompileUnoptimizedCode(CompilationInfo* info) { | 535 bool CompileUnoptimizedCode(CompilationInfo* info) { |
| 433 DCHECK(AllowCompilation::IsAllowed(info->isolate())); | 536 DCHECK(AllowCompilation::IsAllowed(info->isolate())); |
| 434 if (!Compiler::Analyze(info->parse_info()) || | 537 if (!Compiler::Analyze(info->parse_info()) || |
| 435 !GenerateUnoptimizedCode(info)) { | 538 !GenerateUnoptimizedCode(info)) { |
| 436 Isolate* isolate = info->isolate(); | 539 Isolate* isolate = info->isolate(); |
| 437 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 540 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 490 | 593 |
| 491 // Cache optimized context-specific code. | 594 // Cache optimized context-specific code. |
| 492 Handle<JSFunction> function = info->closure(); | 595 Handle<JSFunction> function = info->closure(); |
| 493 Handle<SharedFunctionInfo> shared(function->shared()); | 596 Handle<SharedFunctionInfo> shared(function->shared()); |
| 494 Handle<LiteralsArray> literals(function->literals()); | 597 Handle<LiteralsArray> literals(function->literals()); |
| 495 Handle<Context> native_context(function->context()->native_context()); | 598 Handle<Context> native_context(function->context()->native_context()); |
| 496 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, | 599 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, |
| 497 literals, info->osr_ast_id()); | 600 literals, info->osr_ast_id()); |
| 498 } | 601 } |
| 499 | 602 |
| 500 bool Renumber(ParseInfo* parse_info) { | |
| 501 // Create a canonical handle scope if compiling ignition bytecode. This is | |
| 502 // required by the constant array builder to de-duplicate objects without | |
| 503 // dereferencing handles. | |
| 504 std::unique_ptr<CanonicalHandleScope> canonical; | |
| 505 if (FLAG_ignition) { | |
| 506 canonical.reset(new CanonicalHandleScope(parse_info->isolate())); | |
| 507 } | |
| 508 | |
| 509 if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(), | |
| 510 parse_info->literal())) { | |
| 511 return false; | |
| 512 } | |
| 513 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info(); | |
| 514 if (!shared_info.is_null()) { | |
| 515 FunctionLiteral* lit = parse_info->literal(); | |
| 516 shared_info->set_ast_node_count(lit->ast_node_count()); | |
| 517 if (lit->dont_optimize_reason() != kNoReason) { | |
| 518 shared_info->DisableOptimization(lit->dont_optimize_reason()); | |
| 519 } | |
| 520 if (lit->flags() & AstProperties::kDontCrankshaft) { | |
| 521 shared_info->set_dont_crankshaft(true); | |
| 522 } | |
| 523 } | |
| 524 return true; | |
| 525 } | |
| 526 | |
| 527 bool UseTurboFan(Handle<SharedFunctionInfo> shared) { | 603 bool UseTurboFan(Handle<SharedFunctionInfo> shared) { |
| 528 bool optimization_disabled = shared->optimization_disabled(); | 604 bool optimization_disabled = shared->optimization_disabled(); |
| 529 bool dont_crankshaft = shared->dont_crankshaft(); | 605 bool dont_crankshaft = shared->dont_crankshaft(); |
| 530 | 606 |
| 531 // Check the enabling conditions for Turbofan. | 607 // Check the enabling conditions for Turbofan. |
| 532 // 1. "use asm" code. | 608 // 1. "use asm" code. |
| 533 bool is_turbofanable_asm = | 609 bool is_turbofanable_asm = |
| 534 FLAG_turbo_asm && shared->asm_function() && !optimization_disabled; | 610 FLAG_turbo_asm && shared->asm_function() && !optimization_disabled; |
| 535 | 611 |
| 536 // 2. Fallback for features unsupported by Crankshaft. | 612 // 2. Fallback for features unsupported by Crankshaft. |
| (...skipping 1150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1687 CompilationInfo compile_info(parse_info, Handle<JSFunction>::null()); | 1763 CompilationInfo compile_info(parse_info, Handle<JSFunction>::null()); |
| 1688 | 1764 |
| 1689 // The source was parsed lazily, so compiling for debugging is not possible. | 1765 // The source was parsed lazily, so compiling for debugging is not possible. |
| 1690 DCHECK(!compile_info.is_debug()); | 1766 DCHECK(!compile_info.is_debug()); |
| 1691 | 1767 |
| 1692 Handle<SharedFunctionInfo> result = CompileToplevel(&compile_info); | 1768 Handle<SharedFunctionInfo> result = CompileToplevel(&compile_info); |
| 1693 if (!result.is_null()) isolate->debug()->OnAfterCompile(script); | 1769 if (!result.is_null()) isolate->debug()->OnAfterCompile(script); |
| 1694 return result; | 1770 return result; |
| 1695 } | 1771 } |
| 1696 | 1772 |
| 1697 | |
| 1698 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo( | 1773 Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo( |
| 1699 FunctionLiteral* literal, Handle<Script> script, | 1774 FunctionLiteral* literal, Handle<Script> script, |
| 1700 CompilationInfo* outer_info) { | 1775 CompilationInfo* outer_info, ShouldCompile should_compile) { |
| 1701 // Precondition: code has been parsed and scopes have been analyzed. | 1776 // Precondition: code has been parsed and scopes have been analyzed. |
| 1702 Isolate* isolate = outer_info->isolate(); | 1777 Isolate* isolate = outer_info->isolate(); |
| 1703 MaybeHandle<SharedFunctionInfo> maybe_existing; | 1778 MaybeHandle<SharedFunctionInfo> maybe_existing; |
| 1704 | 1779 |
| 1705 // Find any previously allocated shared function info for the given literal. | 1780 // Find any previously allocated shared function info for the given literal. |
| 1706 if (outer_info->shared_info()->never_compiled()) { | 1781 if (outer_info->shared_info()->never_compiled() && |
| 1782 should_compile == ShouldCompile::kIfNecessary) { | |
| 1707 // On the first compile, there are no existing shared function info for | 1783 // On the first compile, there are no existing shared function info for |
| 1708 // inner functions yet, so do not try to find them. All bets are off for | 1784 // inner functions yet, so do not try to find them. All bets are off for |
| 1709 // live edit though. | 1785 // live edit though. |
| 1710 SLOW_DCHECK(script->FindSharedFunctionInfo(literal).is_null() || | 1786 SLOW_DCHECK(script->FindSharedFunctionInfo(literal).is_null() || |
| 1711 isolate->debug()->live_edit_enabled()); | 1787 isolate->debug()->live_edit_enabled()); |
| 1712 } else { | 1788 } else { |
| 1713 maybe_existing = script->FindSharedFunctionInfo(literal); | 1789 maybe_existing = script->FindSharedFunctionInfo(literal); |
| 1714 } | 1790 } |
| 1715 | 1791 |
| 1716 // We found an existing shared function info. If it has any sort of code | 1792 // We found an existing shared function info. If it has any sort of code |
| 1717 // attached, don't worry about compiling and simply return it. Otherwise, | 1793 // attached, don't worry about compiling and simply return it. Otherwise, |
| 1718 // continue to decide whether to eagerly compile. | 1794 // continue to decide whether to eagerly compile. |
| 1719 // Note that we also carry on if we are compiling eager to obtain code for | 1795 // Note that we also carry on if we are compiling eager to obtain code for |
| 1720 // debugging, unless we already have code with debug break slots. | 1796 // debugging, unless we already have code with debug break slots. |
| 1721 Handle<SharedFunctionInfo> existing; | 1797 Handle<SharedFunctionInfo> existing; |
| 1722 if (maybe_existing.ToHandle(&existing)) { | 1798 if (maybe_existing.ToHandle(&existing)) { |
| 1723 DCHECK(!existing->is_toplevel()); | 1799 DCHECK(!existing->is_toplevel()); |
| 1724 if (existing->HasBaselineCode() || existing->HasBytecodeArray()) { | 1800 if (existing->HasBaselineCode() || existing->HasBytecodeArray()) { |
| 1725 if (!outer_info->is_debug() || existing->HasDebugCode()) { | 1801 if (!outer_info->is_debug() || existing->HasDebugCode()) { |
| 1726 return existing; | 1802 return existing; |
| 1727 } | 1803 } |
| 1804 } else if (should_compile == ShouldCompile::kNever) { | |
| 1805 return existing; | |
|
Michael Starzinger
2016/10/17 13:16:03
nit: Please add a DCHECK(!outer_info->is_debug())
| |
| 1728 } | 1806 } |
| 1729 } | 1807 } |
| 1730 | 1808 |
| 1731 // Allocate a shared function info object. | 1809 // Allocate a shared function info object. |
| 1732 Handle<SharedFunctionInfo> result; | 1810 Handle<SharedFunctionInfo> result; |
| 1733 if (!maybe_existing.ToHandle(&result)) { | 1811 if (!maybe_existing.ToHandle(&result)) { |
| 1734 result = NewSharedFunctionInfoForLiteral(isolate, literal, script); | 1812 result = NewSharedFunctionInfoForLiteral(isolate, literal, script); |
| 1735 result->set_is_toplevel(false); | 1813 result->set_is_toplevel(false); |
| 1736 | 1814 |
| 1737 // If the outer function has been compiled before, we cannot be sure that | 1815 // If the outer function has been compiled before, we cannot be sure that |
| 1738 // shared function info for this function literal has been created for the | 1816 // shared function info for this function literal has been created for the |
| 1739 // first time. It may have already been compiled previously. | 1817 // first time. It may have already been compiled previously. |
| 1740 result->set_never_compiled(outer_info->shared_info()->never_compiled()); | 1818 result->set_never_compiled(outer_info->shared_info()->never_compiled()); |
| 1741 } | 1819 } |
| 1742 | 1820 |
| 1743 Zone zone(isolate->allocator()); | 1821 Zone zone(isolate->allocator()); |
| 1744 ParseInfo parse_info(&zone, script); | 1822 ParseInfo parse_info(&zone, script); |
| 1745 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); | 1823 CompilationInfo info(&parse_info, Handle<JSFunction>::null()); |
| 1746 parse_info.set_literal(literal); | 1824 parse_info.set_literal(literal); |
| 1747 parse_info.set_shared_info(result); | 1825 parse_info.set_shared_info(result); |
| 1748 parse_info.set_language_mode(literal->scope()->language_mode()); | 1826 parse_info.set_language_mode(literal->scope()->language_mode()); |
| 1749 if (outer_info->will_serialize()) info.PrepareForSerializing(); | 1827 if (outer_info->will_serialize()) info.PrepareForSerializing(); |
| 1750 if (outer_info->is_debug()) info.MarkAsDebug(); | 1828 if (outer_info->is_debug()) info.MarkAsDebug(); |
| 1751 | 1829 |
| 1752 // Generate code | 1830 // Generate code |
| 1753 TimerEventScope<TimerEventCompileCode> timer(isolate); | 1831 TimerEventScope<TimerEventCompileCode> timer(isolate); |
| 1754 RuntimeCallTimerScope runtimeTimer(isolate, &RuntimeCallStats::CompileCode); | 1832 RuntimeCallTimerScope runtimeTimer(isolate, &RuntimeCallStats::CompileCode); |
| 1755 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode"); | 1833 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode"); |
| 1756 | 1834 |
| 1757 if (!literal->ShouldEagerCompile()) { | 1835 if (!literal->ShouldEagerCompile() || |
| 1836 should_compile == ShouldCompile::kNever) { | |
| 1758 info.SetCode(isolate->builtins()->CompileLazy()); | 1837 info.SetCode(isolate->builtins()->CompileLazy()); |
| 1759 Scope* outer_scope = literal->scope()->GetOuterScopeWithContext(); | 1838 Scope* outer_scope = literal->scope()->GetOuterScopeWithContext(); |
| 1760 if (outer_scope) { | 1839 if (outer_scope) { |
| 1761 result->set_outer_scope_info(*outer_scope->scope_info()); | 1840 result->set_outer_scope_info(*outer_scope->scope_info()); |
| 1762 } | 1841 } |
| 1763 } else if (Renumber(info.parse_info()) && GenerateUnoptimizedCode(&info)) { | 1842 } else if (Renumber(info.parse_info()) && GenerateUnoptimizedCode(&info)) { |
| 1764 // Code generation will ensure that the feedback vector is present and | 1843 // Code generation will ensure that the feedback vector is present and |
| 1765 // appropriately sized. | 1844 // appropriately sized. |
| 1766 DCHECK(!info.code().is_null()); | 1845 DCHECK(!info.code().is_null()); |
| 1767 if (literal->should_be_used_once_hint()) { | 1846 if (literal->should_be_used_once_hint()) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1811 } | 1890 } |
| 1812 | 1891 |
| 1813 MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function, | 1892 MaybeHandle<Code> Compiler::GetOptimizedCodeForOSR(Handle<JSFunction> function, |
| 1814 BailoutId osr_ast_id, | 1893 BailoutId osr_ast_id, |
| 1815 JavaScriptFrame* osr_frame) { | 1894 JavaScriptFrame* osr_frame) { |
| 1816 DCHECK(!osr_ast_id.IsNone()); | 1895 DCHECK(!osr_ast_id.IsNone()); |
| 1817 DCHECK_NOT_NULL(osr_frame); | 1896 DCHECK_NOT_NULL(osr_frame); |
| 1818 return GetOptimizedCode(function, NOT_CONCURRENT, osr_ast_id, osr_frame); | 1897 return GetOptimizedCode(function, NOT_CONCURRENT, osr_ast_id, osr_frame); |
| 1819 } | 1898 } |
| 1820 | 1899 |
| 1821 CompilationJob* Compiler::PrepareUnoptimizedCompilationJob( | 1900 std::vector<std::unique_ptr<CompilationJob>> |
| 1822 CompilationInfo* info) { | 1901 Compiler::PrepareUnoptimizedCompilationJobs(CompilationInfo* info) { |
| 1823 VMState<COMPILER> state(info->isolate()); | 1902 VMState<COMPILER> state(info->isolate()); |
| 1824 std::unique_ptr<CompilationJob> job(GetUnoptimizedCompilationJob(info)); | 1903 std::vector<std::unique_ptr<CompilationJob>> jobs( |
| 1825 if (job->PrepareJob() != CompilationJob::SUCCEEDED) { | 1904 GetUnoptimizedCompilationJobs(info)); |
| 1826 return nullptr; | 1905 for (auto& job : jobs) { |
| 1906 if (job->PrepareJob() != CompilationJob::SUCCEEDED) { | |
| 1907 std::vector<std::unique_ptr<CompilationJob>> result; | |
| 1908 return result; | |
| 1909 } | |
| 1827 } | 1910 } |
| 1828 return job.release(); | 1911 return jobs; |
| 1829 } | 1912 } |
| 1830 | 1913 |
| 1831 bool Compiler::FinalizeCompilationJob(CompilationJob* raw_job) { | 1914 bool Compiler::FinalizeCompilationJob(CompilationJob* raw_job) { |
| 1832 // Take ownership of compilation job. Deleting job also tears down the zone. | 1915 // Take ownership of compilation job. Deleting job also tears down the zone. |
| 1833 std::unique_ptr<CompilationJob> job(raw_job); | 1916 std::unique_ptr<CompilationJob> job(raw_job); |
| 1834 | 1917 |
| 1835 VMState<COMPILER> state(job->info()->isolate()); | 1918 VMState<COMPILER> state(job->info()->isolate()); |
| 1836 if (job->info()->IsOptimizing()) { | 1919 if (job->info()->IsOptimizing()) { |
| 1837 return FinalizeOptimizedCompilationJob(job.get()) == | 1920 return FinalizeOptimizedCompilationJob(job.get()) == |
| 1838 CompilationJob::SUCCEEDED; | 1921 CompilationJob::SUCCEEDED; |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 1868 DCHECK(shared->is_compiled()); | 1951 DCHECK(shared->is_compiled()); |
| 1869 function->set_literals(cached.literals); | 1952 function->set_literals(cached.literals); |
| 1870 } else if (shared->is_compiled()) { | 1953 } else if (shared->is_compiled()) { |
| 1871 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. | 1954 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. |
| 1872 JSFunction::EnsureLiterals(function); | 1955 JSFunction::EnsureLiterals(function); |
| 1873 } | 1956 } |
| 1874 } | 1957 } |
| 1875 | 1958 |
| 1876 } // namespace internal | 1959 } // namespace internal |
| 1877 } // namespace v8 | 1960 } // namespace v8 |
| OLD | NEW |