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" |
(...skipping 21 matching lines...) Expand all Loading... |
32 #include "src/parsing/parsing.h" | 32 #include "src/parsing/parsing.h" |
33 #include "src/parsing/rewriter.h" | 33 #include "src/parsing/rewriter.h" |
34 #include "src/parsing/scanner-character-streams.h" | 34 #include "src/parsing/scanner-character-streams.h" |
35 #include "src/runtime-profiler.h" | 35 #include "src/runtime-profiler.h" |
36 #include "src/snapshot/code-serializer.h" | 36 #include "src/snapshot/code-serializer.h" |
37 #include "src/vm-state-inl.h" | 37 #include "src/vm-state-inl.h" |
38 | 38 |
39 namespace v8 { | 39 namespace v8 { |
40 namespace internal { | 40 namespace internal { |
41 | 41 |
42 // A wrapper around a ParseInfo that detaches the parser handles from the | |
43 // underlying DeferredHandleScope and stores them in info_ on destruction. | |
44 class ParseHandleScope final { | |
45 public: | |
46 explicit ParseHandleScope(ParseInfo* info) | |
47 : deferred_(info->isolate()), info_(info) {} | |
48 ~ParseHandleScope() { info_->set_deferred_handles(deferred_.Detach()); } | |
49 | |
50 private: | |
51 DeferredHandleScope deferred_; | |
52 ParseInfo* info_; | |
53 }; | |
54 | |
55 // A wrapper around a CompilationInfo that detaches the Handles from | 42 // A wrapper around a CompilationInfo that detaches the Handles from |
56 // the underlying DeferredHandleScope and stores them in info_ on | 43 // the underlying DeferredHandleScope and stores them in info_ on |
57 // destruction. | 44 // destruction. |
58 class CompilationHandleScope final { | 45 class CompilationHandleScope final { |
59 public: | 46 public: |
60 explicit CompilationHandleScope(CompilationInfo* info) | 47 explicit CompilationHandleScope(CompilationInfo* info) |
61 : deferred_(info->isolate()), info_(info) {} | 48 : deferred_(info->isolate()), info_(info) {} |
62 ~CompilationHandleScope() { info_->set_deferred_handles(deferred_.Detach()); } | 49 ~CompilationHandleScope() { info_->set_deferred_handles(deferred_.Detach()); } |
63 | 50 |
64 private: | 51 private: |
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 if (FinalizeUnoptimizedCompilationJob(job.get()) != | 505 if (FinalizeUnoptimizedCompilationJob(job.get()) != |
519 CompilationJob::SUCCEEDED) { | 506 CompilationJob::SUCCEEDED) { |
520 return false; | 507 return false; |
521 } | 508 } |
522 return true; | 509 return true; |
523 } | 510 } |
524 | 511 |
525 bool CompileUnoptimizedInnerFunctions( | 512 bool CompileUnoptimizedInnerFunctions( |
526 Compiler::EagerInnerFunctionLiterals* literals, | 513 Compiler::EagerInnerFunctionLiterals* literals, |
527 Compiler::ConcurrencyMode inner_function_mode, | 514 Compiler::ConcurrencyMode inner_function_mode, |
528 std::shared_ptr<Zone> parse_zone, CompilationInfo* outer_info) { | 515 CompilationInfo* outer_info) { |
529 Isolate* isolate = outer_info->isolate(); | 516 Isolate* isolate = outer_info->isolate(); |
530 Handle<Script> script = outer_info->script(); | 517 Handle<Script> script = outer_info->script(); |
531 bool is_debug = outer_info->is_debug(); | 518 bool is_debug = outer_info->is_debug(); |
532 bool will_serialize = outer_info->will_serialize(); | 519 bool will_serialize = outer_info->will_serialize(); |
533 RuntimeCallTimerScope runtimeTimer(isolate, | 520 RuntimeCallTimerScope runtimeTimer(isolate, |
534 &RuntimeCallStats::CompileInnerFunction); | 521 &RuntimeCallStats::CompileInnerFunction); |
535 | 522 |
536 for (auto it : *literals) { | 523 for (auto it : *literals) { |
537 FunctionLiteral* literal = it->value(); | 524 FunctionLiteral* literal = it->value(); |
538 Handle<SharedFunctionInfo> shared = | 525 Handle<SharedFunctionInfo> shared = |
539 Compiler::GetSharedFunctionInfo(literal, script, outer_info); | 526 Compiler::GetSharedFunctionInfo(literal, script, outer_info); |
540 if (shared->is_compiled()) continue; | 527 if (shared->is_compiled()) continue; |
541 | 528 |
542 // The {literal} has already been numbered because AstNumbering decends into | 529 // The {literal} has already been numbered because AstNumbering decends into |
543 // eagerly compiled function literals. | 530 // eagerly compiled function literals. |
544 SetSharedFunctionFlagsFromLiteral(literal, shared); | 531 SetSharedFunctionFlagsFromLiteral(literal, shared); |
545 | 532 |
546 // Try to enqueue the eager function on the compiler dispatcher. | 533 // Try to enqueue the eager function on the compiler dispatcher. |
547 CompilerDispatcher* dispatcher = isolate->compiler_dispatcher(); | 534 CompilerDispatcher* dispatcher = isolate->compiler_dispatcher(); |
548 if (UseCompilerDispatcher(inner_function_mode, dispatcher, literal->scope(), | 535 if (UseCompilerDispatcher(inner_function_mode, dispatcher, literal->scope(), |
549 shared, is_debug, will_serialize) && | 536 shared, is_debug, will_serialize) && |
550 dispatcher->EnqueueAndStep(shared, literal, parse_zone, | 537 dispatcher->EnqueueAndStep(shared, literal)) { |
551 outer_info->parse_info()->deferred_handles(), | |
552 outer_info->deferred_handles())) { | |
553 // If we have successfully queued up the function for compilation on the | 538 // If we have successfully queued up the function for compilation on the |
554 // compiler dispatcher then we are done. | 539 // compiler dispatcher then we are done. |
555 continue; | 540 continue; |
556 } else { | 541 } else { |
557 // Otherwise generate unoptimized code now. | 542 // Otherwise generate unoptimized code now. |
558 ParseInfo parse_info(script); | 543 ParseInfo parse_info(script); |
559 CompilationInfo info(parse_info.zone(), &parse_info, | 544 CompilationInfo info(parse_info.zone(), &parse_info, |
560 Handle<JSFunction>::null()); | 545 Handle<JSFunction>::null()); |
561 | 546 |
562 parse_info.set_literal(literal); | 547 parse_info.set_literal(literal); |
(...skipping 24 matching lines...) Expand all Loading... |
587 } | 572 } |
588 return false; | 573 return false; |
589 } | 574 } |
590 | 575 |
591 bool CompileUnoptimizedCode(CompilationInfo* info, | 576 bool CompileUnoptimizedCode(CompilationInfo* info, |
592 Compiler::ConcurrencyMode inner_function_mode) { | 577 Compiler::ConcurrencyMode inner_function_mode) { |
593 Isolate* isolate = info->isolate(); | 578 Isolate* isolate = info->isolate(); |
594 DCHECK(AllowCompilation::IsAllowed(isolate)); | 579 DCHECK(AllowCompilation::IsAllowed(isolate)); |
595 | 580 |
596 Compiler::EagerInnerFunctionLiterals inner_literals; | 581 Compiler::EagerInnerFunctionLiterals inner_literals; |
597 { | 582 if (!Compiler::Analyze(info->parse_info(), &inner_literals)) { |
598 std::unique_ptr<CompilationHandleScope> compilation_handle_scope; | 583 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
599 if (inner_function_mode == Compiler::CONCURRENT) { | 584 return false; |
600 compilation_handle_scope.reset(new CompilationHandleScope(info)); | |
601 } | |
602 if (!Compiler::Analyze(info->parse_info(), &inner_literals)) { | |
603 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | |
604 return false; | |
605 } | |
606 } | 585 } |
607 | 586 |
608 // Disable concurrent inner compilation for asm-wasm code. | 587 // Disable concurrent inner compilation for asm-wasm code. |
609 // TODO(rmcilroy,bradnelson): Remove this AsmWasm check once the asm-wasm | 588 // TODO(rmcilroy,bradnelson): Remove this AsmWasm check once the asm-wasm |
610 // builder doesn't do parsing when visiting function declarations. | 589 // builder doesn't do parsing when visiting function declarations. |
611 if (info->scope()->IsAsmModule() || | 590 if (info->scope()->IsAsmModule() || |
612 InnerFunctionIsAsmModule(&inner_literals)) { | 591 InnerFunctionIsAsmModule(&inner_literals)) { |
613 inner_function_mode = Compiler::NOT_CONCURRENT; | 592 inner_function_mode = Compiler::NOT_CONCURRENT; |
614 } | 593 } |
615 | 594 |
616 std::shared_ptr<Zone> parse_zone; | |
617 if (inner_function_mode == Compiler::CONCURRENT) { | 595 if (inner_function_mode == Compiler::CONCURRENT) { |
618 // Seal the parse zone so that it can be shared by parallel inner function | 596 // Seal the parse zone so that it can be shared by parallel inner function |
619 // compilation jobs. | 597 // compilation jobs. |
620 DCHECK_NE(info->parse_info()->zone(), info->zone()); | 598 DCHECK_NE(info->parse_info()->zone(), info->zone()); |
621 parse_zone = info->parse_info()->zone_shared(); | 599 info->parse_info()->zone()->Seal(); |
622 parse_zone->Seal(); | |
623 } | 600 } |
624 | 601 |
625 if (!CompileUnoptimizedInnerFunctions(&inner_literals, inner_function_mode, | 602 if (!CompileUnoptimizedInnerFunctions(&inner_literals, inner_function_mode, |
626 parse_zone, info) || | 603 info) || |
627 !GenerateUnoptimizedCode(info)) { | 604 !GenerateUnoptimizedCode(info)) { |
628 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 605 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
629 return false; | 606 return false; |
630 } | 607 } |
631 | 608 |
632 // TODO(rmcilroy): Remove this once the enqueued tasks can keep the parsed | 609 // TODO(rmcilroy): Remove this once the enqueued tasks can keep the parsed |
633 // zone and handles alive and replace with a check in CompileLazy to finish | 610 // zone and handles alive and replace with a check in CompileLazy to finish |
634 // the task itself. | 611 // the task itself. |
635 RuntimeCallTimerScope runtimeTimer( | 612 RuntimeCallTimerScope runtimeTimer( |
636 isolate, &RuntimeCallStats::CompileWaitForDispatcher); | 613 isolate, &RuntimeCallStats::CompileWaitForDispatcher); |
(...skipping 20 matching lines...) Expand all Loading... |
657 info->script()->set_shared_function_infos(*infos); | 634 info->script()->set_shared_function_infos(*infos); |
658 } | 635 } |
659 | 636 |
660 MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode( | 637 MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode( |
661 CompilationInfo* info, Compiler::ConcurrencyMode inner_function_mode) { | 638 CompilationInfo* info, Compiler::ConcurrencyMode inner_function_mode) { |
662 RuntimeCallTimerScope runtimeTimer( | 639 RuntimeCallTimerScope runtimeTimer( |
663 info->isolate(), &RuntimeCallStats::CompileGetUnoptimizedCode); | 640 info->isolate(), &RuntimeCallStats::CompileGetUnoptimizedCode); |
664 VMState<COMPILER> state(info->isolate()); | 641 VMState<COMPILER> state(info->isolate()); |
665 PostponeInterruptsScope postpone(info->isolate()); | 642 PostponeInterruptsScope postpone(info->isolate()); |
666 | 643 |
667 // Parse and update ParseInfo with the results. | 644 // Parse and update CompilationInfo with the results. |
668 { | 645 if (!parsing::ParseAny(info->parse_info())) return MaybeHandle<Code>(); |
669 if (!parsing::ParseAny(info->parse_info(), | |
670 inner_function_mode != Compiler::CONCURRENT)) { | |
671 return MaybeHandle<Code>(); | |
672 } | |
673 | |
674 if (inner_function_mode == Compiler::CONCURRENT) { | |
675 ParseHandleScope parse_handles(info->parse_info()); | |
676 info->parse_info()->ReopenHandlesInNewHandleScope(); | |
677 info->parse_info()->ast_value_factory()->Internalize(info->isolate()); | |
678 } | |
679 } | |
680 | |
681 if (info->parse_info()->is_toplevel()) { | 646 if (info->parse_info()->is_toplevel()) { |
682 EnsureSharedFunctionInfosArrayOnScript(info->parse_info()); | 647 EnsureSharedFunctionInfosArrayOnScript(info->parse_info()); |
683 } | 648 } |
684 DCHECK_EQ(info->shared_info()->language_mode(), | 649 DCHECK_EQ(info->shared_info()->language_mode(), |
685 info->literal()->language_mode()); | 650 info->literal()->language_mode()); |
686 | 651 |
687 // Compile either unoptimized code or bytecode for the interpreter. | 652 // Compile either unoptimized code or bytecode for the interpreter. |
688 if (!CompileUnoptimizedCode(info, inner_function_mode)) { | 653 if (!CompileUnoptimizedCode(info, inner_function_mode)) { |
689 return MaybeHandle<Code>(); | 654 return MaybeHandle<Code>(); |
690 } | 655 } |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1162 | 1127 |
1163 Handle<Script> script = parse_info->script(); | 1128 Handle<Script> script = parse_info->script(); |
1164 | 1129 |
1165 // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile? | 1130 // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile? |
1166 FixedArray* array = isolate->native_context()->embedder_data(); | 1131 FixedArray* array = isolate->native_context()->embedder_data(); |
1167 script->set_context_data(array->get(v8::Context::kDebugIdIndex)); | 1132 script->set_context_data(array->get(v8::Context::kDebugIdIndex)); |
1168 | 1133 |
1169 Handle<SharedFunctionInfo> result; | 1134 Handle<SharedFunctionInfo> result; |
1170 | 1135 |
1171 { VMState<COMPILER> state(info->isolate()); | 1136 { VMState<COMPILER> state(info->isolate()); |
1172 if (parse_info->literal() == nullptr) { | 1137 if (parse_info->literal() == nullptr && |
1173 if (!parsing::ParseProgram(parse_info, false)) { | 1138 !parsing::ParseProgram(parse_info)) { |
1174 return Handle<SharedFunctionInfo>::null(); | 1139 return Handle<SharedFunctionInfo>::null(); |
1175 } | |
1176 | |
1177 { | |
1178 ParseHandleScope parse_handles(parse_info); | |
1179 parse_info->ReopenHandlesInNewHandleScope(); | |
1180 parse_info->ast_value_factory()->Internalize(info->isolate()); | |
1181 } | |
1182 } | 1140 } |
1183 | 1141 |
1184 EnsureSharedFunctionInfosArrayOnScript(parse_info); | 1142 EnsureSharedFunctionInfosArrayOnScript(parse_info); |
1185 | 1143 |
1186 // Measure how long it takes to do the compilation; only take the | 1144 // Measure how long it takes to do the compilation; only take the |
1187 // rest of the function into account to avoid overlap with the | 1145 // rest of the function into account to avoid overlap with the |
1188 // parsing statistics. | 1146 // parsing statistics. |
1189 HistogramTimer* rate = parse_info->is_eval() | 1147 HistogramTimer* rate = parse_info->is_eval() |
1190 ? info->isolate()->counters()->compile_eval() | 1148 ? info->isolate()->counters()->compile_eval() |
1191 : info->isolate()->counters()->compile(); | 1149 : info->isolate()->counters()->compile(); |
(...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1911 } | 1869 } |
1912 | 1870 |
1913 if (shared->is_compiled()) { | 1871 if (shared->is_compiled()) { |
1914 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. | 1872 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. |
1915 JSFunction::EnsureLiterals(function); | 1873 JSFunction::EnsureLiterals(function); |
1916 } | 1874 } |
1917 } | 1875 } |
1918 | 1876 |
1919 } // namespace internal | 1877 } // namespace internal |
1920 } // namespace v8 | 1878 } // namespace v8 |
OLD | NEW |