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 |