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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 | 63 |
64 ~ScopedTimer() { *location_ += timer_.Elapsed(); } | 64 ~ScopedTimer() { *location_ += timer_.Elapsed(); } |
65 | 65 |
66 base::ElapsedTimer timer_; | 66 base::ElapsedTimer timer_; |
67 base::TimeDelta* location_; | 67 base::TimeDelta* location_; |
68 }; | 68 }; |
69 | 69 |
70 // ---------------------------------------------------------------------------- | 70 // ---------------------------------------------------------------------------- |
71 // Implementation of CompilationJob | 71 // Implementation of CompilationJob |
72 | 72 |
| 73 CompilationJob::CompilationJob(Isolate* isolate, CompilationInfo* info, |
| 74 const char* compiler_name, State initial_state) |
| 75 : info_(info), |
| 76 isolate_thread_id_(isolate->thread_id()), |
| 77 compiler_name_(compiler_name), |
| 78 state_(initial_state), |
| 79 stack_limit_(isolate->stack_guard()->real_climit()), |
| 80 executed_on_background_thread_(false) {} |
| 81 |
73 CompilationJob::Status CompilationJob::PrepareJob() { | 82 CompilationJob::Status CompilationJob::PrepareJob() { |
74 DCHECK(ThreadId::Current().Equals(info()->isolate()->thread_id())); | 83 DCHECK(ThreadId::Current().Equals(info()->isolate()->thread_id())); |
75 DisallowJavascriptExecution no_js(isolate()); | 84 DisallowJavascriptExecution no_js(isolate()); |
76 | 85 |
77 if (FLAG_trace_opt && info()->IsOptimizing()) { | 86 if (FLAG_trace_opt && info()->IsOptimizing()) { |
78 OFStream os(stdout); | 87 OFStream os(stdout); |
79 os << "[compiling method " << Brief(*info()->closure()) << " using " | 88 os << "[compiling method " << Brief(*info()->closure()) << " using " |
80 << compiler_name_; | 89 << compiler_name_; |
81 if (info()->is_osr()) os << " OSR"; | 90 if (info()->is_osr()) os << " OSR"; |
82 os << "]" << std::endl; | 91 os << "]" << std::endl; |
83 } | 92 } |
84 | 93 |
85 // Delegate to the underlying implementation. | 94 // Delegate to the underlying implementation. |
86 DCHECK(state() == State::kReadyToPrepare); | 95 DCHECK(state() == State::kReadyToPrepare); |
87 ScopedTimer t(&time_taken_to_prepare_); | 96 ScopedTimer t(&time_taken_to_prepare_); |
88 return UpdateState(PrepareJobImpl(), State::kReadyToExecute); | 97 return UpdateState(PrepareJobImpl(), State::kReadyToExecute); |
89 } | 98 } |
90 | 99 |
91 CompilationJob::Status CompilationJob::ExecuteJob() { | 100 CompilationJob::Status CompilationJob::ExecuteJob() { |
92 std::unique_ptr<DisallowHeapAllocation> no_allocation; | 101 std::unique_ptr<DisallowHeapAllocation> no_allocation; |
93 std::unique_ptr<DisallowHandleAllocation> no_handles; | 102 std::unique_ptr<DisallowHandleAllocation> no_handles; |
94 std::unique_ptr<DisallowHandleDereference> no_deref; | 103 std::unique_ptr<DisallowHandleDereference> no_deref; |
95 std::unique_ptr<DisallowCodeDependencyChange> no_dependency_change; | 104 std::unique_ptr<DisallowCodeDependencyChange> no_dependency_change; |
96 if (can_execute_on_background_thread()) { | 105 if (can_execute_on_background_thread()) { |
97 no_allocation.reset(new DisallowHeapAllocation()); | 106 no_allocation.reset(new DisallowHeapAllocation()); |
98 no_handles.reset(new DisallowHandleAllocation()); | 107 no_handles.reset(new DisallowHandleAllocation()); |
99 no_deref.reset(new DisallowHandleDereference()); | 108 no_deref.reset(new DisallowHandleDereference()); |
100 no_dependency_change.reset(new DisallowCodeDependencyChange()); | 109 no_dependency_change.reset(new DisallowCodeDependencyChange()); |
| 110 executed_on_background_thread_ = |
| 111 !ThreadId::Current().Equals(isolate_thread_id_); |
101 } else { | 112 } else { |
102 DCHECK(ThreadId::Current().Equals(info()->isolate()->thread_id())); | 113 DCHECK(ThreadId::Current().Equals(isolate_thread_id_)); |
103 } | 114 } |
104 | 115 |
105 // Delegate to the underlying implementation. | 116 // Delegate to the underlying implementation. |
106 DCHECK(state() == State::kReadyToExecute); | 117 DCHECK(state() == State::kReadyToExecute); |
107 ScopedTimer t(&time_taken_to_execute_); | 118 ScopedTimer t(&time_taken_to_execute_); |
108 return UpdateState(ExecuteJobImpl(), State::kReadyToFinalize); | 119 return UpdateState(ExecuteJobImpl(), State::kReadyToFinalize); |
109 } | 120 } |
110 | 121 |
111 CompilationJob::Status CompilationJob::FinalizeJob() { | 122 CompilationJob::Status CompilationJob::FinalizeJob() { |
112 DCHECK(ThreadId::Current().Equals(info()->isolate()->thread_id())); | 123 DCHECK(ThreadId::Current().Equals(info()->isolate()->thread_id())); |
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 info->max_function_literal_id() + 1); | 481 info->max_function_literal_id() + 1); |
471 return; | 482 return; |
472 } | 483 } |
473 Isolate* isolate = info->isolate(); | 484 Isolate* isolate = info->isolate(); |
474 Handle<FixedArray> infos( | 485 Handle<FixedArray> infos( |
475 isolate->factory()->NewFixedArray(info->max_function_literal_id() + 1)); | 486 isolate->factory()->NewFixedArray(info->max_function_literal_id() + 1)); |
476 info->script()->set_shared_function_infos(*infos); | 487 info->script()->set_shared_function_infos(*infos); |
477 } | 488 } |
478 | 489 |
479 MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(CompilationInfo* info) { | 490 MUST_USE_RESULT MaybeHandle<Code> GetUnoptimizedCode(CompilationInfo* info) { |
| 491 RuntimeCallTimerScope runtimeTimer( |
| 492 info->isolate(), &RuntimeCallStats::CompileGetUnoptimizedCode); |
480 VMState<COMPILER> state(info->isolate()); | 493 VMState<COMPILER> state(info->isolate()); |
481 PostponeInterruptsScope postpone(info->isolate()); | 494 PostponeInterruptsScope postpone(info->isolate()); |
482 | 495 |
483 // Parse and update CompilationInfo with the results. | 496 // Parse and update CompilationInfo with the results. |
484 if (!parsing::ParseAny(info->parse_info())) return MaybeHandle<Code>(); | 497 if (!parsing::ParseAny(info->parse_info())) return MaybeHandle<Code>(); |
485 if (info->parse_info()->is_toplevel()) { | 498 if (info->parse_info()->is_toplevel()) { |
486 EnsureSharedFunctionInfosArrayOnScript(info->parse_info()); | 499 EnsureSharedFunctionInfosArrayOnScript(info->parse_info()); |
487 } | 500 } |
488 DCHECK_EQ(info->shared_info()->language_mode(), | 501 DCHECK_EQ(info->shared_info()->language_mode(), |
489 info->literal()->language_mode()); | 502 info->literal()->language_mode()); |
490 | 503 |
491 // Compile either unoptimized code or bytecode for the interpreter. | 504 // Compile either unoptimized code or bytecode for the interpreter. |
492 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); | 505 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); |
493 | 506 |
494 // Record the function compilation event. | 507 // Record the function compilation event. |
495 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); | 508 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info); |
496 | 509 |
497 return info->code(); | 510 return info->code(); |
498 } | 511 } |
499 | 512 |
500 MUST_USE_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeMap( | 513 MUST_USE_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeMap( |
501 Handle<JSFunction> function, BailoutId osr_ast_id) { | 514 Handle<JSFunction> function, BailoutId osr_ast_id) { |
| 515 RuntimeCallTimerScope runtimeTimer( |
| 516 function->GetIsolate(), |
| 517 &RuntimeCallStats::CompileGetFromOptimizedCodeMap); |
502 Handle<SharedFunctionInfo> shared(function->shared()); | 518 Handle<SharedFunctionInfo> shared(function->shared()); |
503 DisallowHeapAllocation no_gc; | 519 DisallowHeapAllocation no_gc; |
504 CodeAndLiterals cached = shared->SearchOptimizedCodeMap( | 520 CodeAndLiterals cached = shared->SearchOptimizedCodeMap( |
505 function->context()->native_context(), osr_ast_id); | 521 function->context()->native_context(), osr_ast_id); |
506 if (cached.code != nullptr) { | 522 if (cached.code != nullptr) { |
507 // Caching of optimized code enabled and optimized code found. | 523 // Caching of optimized code enabled and optimized code found. |
508 if (cached.literals != nullptr) function->set_literals(cached.literals); | 524 if (cached.literals != nullptr) function->set_literals(cached.literals); |
509 DCHECK(!cached.code->marked_for_deoptimization()); | 525 DCHECK(!cached.code->marked_for_deoptimization()); |
510 DCHECK(function->shared()->is_compiled()); | 526 DCHECK(function->shared()->is_compiled()); |
511 return Handle<Code>(cached.code); | 527 return Handle<Code>(cached.code); |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
875 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, &info); | 891 RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, &info); |
876 | 892 |
877 return info.code(); | 893 return info.code(); |
878 } | 894 } |
879 | 895 |
880 MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) { | 896 MaybeHandle<Code> GetLazyCode(Handle<JSFunction> function) { |
881 Isolate* isolate = function->GetIsolate(); | 897 Isolate* isolate = function->GetIsolate(); |
882 DCHECK(!isolate->has_pending_exception()); | 898 DCHECK(!isolate->has_pending_exception()); |
883 DCHECK(!function->is_compiled()); | 899 DCHECK(!function->is_compiled()); |
884 TimerEventScope<TimerEventCompileCode> compile_timer(isolate); | 900 TimerEventScope<TimerEventCompileCode> compile_timer(isolate); |
885 RuntimeCallTimerScope runtimeTimer(isolate, | |
886 &RuntimeCallStats::CompileCodeLazy); | |
887 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode"); | 901 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileCode"); |
888 AggregatedHistogramTimerScope timer(isolate->counters()->compile_lazy()); | 902 AggregatedHistogramTimerScope timer(isolate->counters()->compile_lazy()); |
889 | 903 |
890 Handle<Code> cached_code; | 904 Handle<Code> cached_code; |
891 if (GetCodeFromOptimizedCodeMap(function, BailoutId::None()) | 905 if (GetCodeFromOptimizedCodeMap(function, BailoutId::None()) |
892 .ToHandle(&cached_code)) { | 906 .ToHandle(&cached_code)) { |
893 if (FLAG_trace_opt) { | 907 if (FLAG_trace_opt) { |
894 PrintF("[found optimized code for "); | 908 PrintF("[found optimized code for "); |
895 function->ShortPrint(); | 909 function->ShortPrint(); |
896 PrintF(" during unoptimized compile]\n"); | 910 PrintF(" during unoptimized compile]\n"); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1038 return result; | 1052 return result; |
1039 } | 1053 } |
1040 | 1054 |
1041 } // namespace | 1055 } // namespace |
1042 | 1056 |
1043 // ---------------------------------------------------------------------------- | 1057 // ---------------------------------------------------------------------------- |
1044 // Implementation of Compiler | 1058 // Implementation of Compiler |
1045 | 1059 |
1046 bool Compiler::Analyze(ParseInfo* info) { | 1060 bool Compiler::Analyze(ParseInfo* info) { |
1047 DCHECK_NOT_NULL(info->literal()); | 1061 DCHECK_NOT_NULL(info->literal()); |
| 1062 RuntimeCallTimerScope runtimeTimer(info->isolate(), |
| 1063 &RuntimeCallStats::CompileAnalyse); |
1048 if (!Rewriter::Rewrite(info)) return false; | 1064 if (!Rewriter::Rewrite(info)) return false; |
1049 DeclarationScope::Analyze(info, AnalyzeMode::kRegular); | 1065 DeclarationScope::Analyze(info, AnalyzeMode::kRegular); |
1050 if (!Renumber(info)) return false; | 1066 if (!Renumber(info)) return false; |
1051 DCHECK_NOT_NULL(info->scope()); | 1067 DCHECK_NOT_NULL(info->scope()); |
1052 return true; | 1068 return true; |
1053 } | 1069 } |
1054 | 1070 |
1055 bool Compiler::ParseAndAnalyze(ParseInfo* info) { | 1071 bool Compiler::ParseAndAnalyze(ParseInfo* info) { |
1056 if (!parsing::ParseAny(info)) return false; | 1072 if (!parsing::ParseAny(info)) return false; |
1057 if (info->is_toplevel()) EnsureSharedFunctionInfosArrayOnScript(info); | 1073 if (info->is_toplevel()) EnsureSharedFunctionInfosArrayOnScript(info); |
(...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1746 DCHECK(shared->is_compiled()); | 1762 DCHECK(shared->is_compiled()); |
1747 function->set_literals(cached.literals); | 1763 function->set_literals(cached.literals); |
1748 } else if (shared->is_compiled()) { | 1764 } else if (shared->is_compiled()) { |
1749 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. | 1765 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. |
1750 JSFunction::EnsureLiterals(function); | 1766 JSFunction::EnsureLiterals(function); |
1751 } | 1767 } |
1752 } | 1768 } |
1753 | 1769 |
1754 } // namespace internal | 1770 } // namespace internal |
1755 } // namespace v8 | 1771 } // namespace v8 |
OLD | NEW |