| 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 |