OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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-dispatcher/compiler-dispatcher-job.h" | 5 #include "src/compiler-dispatcher/compiler-dispatcher-job.h" |
6 | 6 |
7 #include "src/assert-scope.h" | 7 #include "src/assert-scope.h" |
8 #include "src/compilation-info.h" | 8 #include "src/compilation-info.h" |
| 9 #include "src/compiler-dispatcher/compiler-dispatcher-tracer.h" |
9 #include "src/compiler.h" | 10 #include "src/compiler.h" |
10 #include "src/global-handles.h" | 11 #include "src/global-handles.h" |
11 #include "src/isolate.h" | 12 #include "src/isolate.h" |
12 #include "src/objects-inl.h" | 13 #include "src/objects-inl.h" |
13 #include "src/parsing/parse-info.h" | 14 #include "src/parsing/parse-info.h" |
14 #include "src/parsing/parser.h" | 15 #include "src/parsing/parser.h" |
15 #include "src/parsing/scanner-character-streams.h" | 16 #include "src/parsing/scanner-character-streams.h" |
16 #include "src/unicode-cache.h" | 17 #include "src/unicode-cache.h" |
17 #include "src/zone/zone.h" | 18 #include "src/zone/zone.h" |
18 | 19 |
19 namespace v8 { | 20 namespace v8 { |
20 namespace internal { | 21 namespace internal { |
21 | 22 |
22 CompilerDispatcherJob::CompilerDispatcherJob(Isolate* isolate, | 23 CompilerDispatcherJob::CompilerDispatcherJob(Isolate* isolate, |
23 Handle<SharedFunctionInfo> shared, | 24 Handle<SharedFunctionInfo> shared, |
24 size_t max_stack_size) | 25 size_t max_stack_size) |
25 : isolate_(isolate), | 26 : isolate_(isolate), |
| 27 tracer_(isolate_->compiler_dispatcher_tracer()), |
26 shared_(Handle<SharedFunctionInfo>::cast( | 28 shared_(Handle<SharedFunctionInfo>::cast( |
27 isolate_->global_handles()->Create(*shared))), | 29 isolate_->global_handles()->Create(*shared))), |
28 max_stack_size_(max_stack_size), | 30 max_stack_size_(max_stack_size), |
29 can_compile_on_background_thread_(false) { | 31 can_compile_on_background_thread_(false) { |
30 HandleScope scope(isolate_); | 32 HandleScope scope(isolate_); |
31 DCHECK(!shared_->outer_scope_info()->IsTheHole(isolate_)); | 33 DCHECK(!shared_->outer_scope_info()->IsTheHole(isolate_)); |
32 Handle<Script> script(Script::cast(shared_->script()), isolate_); | 34 Handle<Script> script(Script::cast(shared_->script()), isolate_); |
33 Handle<String> source(String::cast(script->source()), isolate_); | 35 Handle<String> source(String::cast(script->source()), isolate_); |
34 can_parse_on_background_thread_ = | 36 can_parse_on_background_thread_ = |
35 source->IsExternalTwoByteString() || source->IsExternalOneByteString(); | 37 source->IsExternalTwoByteString() || source->IsExternalOneByteString(); |
36 } | 38 } |
37 | 39 |
38 CompilerDispatcherJob::~CompilerDispatcherJob() { | 40 CompilerDispatcherJob::~CompilerDispatcherJob() { |
39 DCHECK(ThreadId::Current().Equals(isolate_->thread_id())); | 41 DCHECK(ThreadId::Current().Equals(isolate_->thread_id())); |
40 DCHECK(status_ == CompileJobStatus::kInitial || | 42 DCHECK(status_ == CompileJobStatus::kInitial || |
41 status_ == CompileJobStatus::kDone); | 43 status_ == CompileJobStatus::kDone); |
42 i::GlobalHandles::Destroy(Handle<Object>::cast(shared_).location()); | 44 i::GlobalHandles::Destroy(Handle<Object>::cast(shared_).location()); |
43 } | 45 } |
44 | 46 |
45 void CompilerDispatcherJob::PrepareToParseOnMainThread() { | 47 void CompilerDispatcherJob::PrepareToParseOnMainThread() { |
46 DCHECK(ThreadId::Current().Equals(isolate_->thread_id())); | 48 DCHECK(ThreadId::Current().Equals(isolate_->thread_id())); |
47 DCHECK(status() == CompileJobStatus::kInitial); | 49 DCHECK(status() == CompileJobStatus::kInitial); |
| 50 COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kPrepareToParse); |
48 HandleScope scope(isolate_); | 51 HandleScope scope(isolate_); |
49 unicode_cache_.reset(new UnicodeCache()); | 52 unicode_cache_.reset(new UnicodeCache()); |
50 zone_.reset(new Zone(isolate_->allocator())); | 53 zone_.reset(new Zone(isolate_->allocator())); |
51 Handle<Script> script(Script::cast(shared_->script()), isolate_); | 54 Handle<Script> script(Script::cast(shared_->script()), isolate_); |
52 DCHECK(script->type() != Script::TYPE_NATIVE); | 55 DCHECK(script->type() != Script::TYPE_NATIVE); |
53 | 56 |
54 Handle<String> source(String::cast(script->source()), isolate_); | 57 Handle<String> source(String::cast(script->source()), isolate_); |
55 if (source->IsExternalTwoByteString() || source->IsExternalOneByteString()) { | 58 if (source->IsExternalTwoByteString() || source->IsExternalOneByteString()) { |
56 character_stream_.reset(ScannerStream::For( | 59 character_stream_.reset(ScannerStream::For( |
57 source, shared_->start_position(), shared_->end_position())); | 60 source, shared_->start_position(), shared_->end_position())); |
(...skipping 27 matching lines...) Expand all Loading... |
85 Handle<String> name(String::cast(shared_->name())); | 88 Handle<String> name(String::cast(shared_->name())); |
86 parse_info_->set_function_name( | 89 parse_info_->set_function_name( |
87 parse_info_->ast_value_factory()->GetString(name)); | 90 parse_info_->ast_value_factory()->GetString(name)); |
88 status_ = CompileJobStatus::kReadyToParse; | 91 status_ = CompileJobStatus::kReadyToParse; |
89 } | 92 } |
90 | 93 |
91 void CompilerDispatcherJob::Parse() { | 94 void CompilerDispatcherJob::Parse() { |
92 DCHECK(can_parse_on_background_thread_ || | 95 DCHECK(can_parse_on_background_thread_ || |
93 ThreadId::Current().Equals(isolate_->thread_id())); | 96 ThreadId::Current().Equals(isolate_->thread_id())); |
94 DCHECK(status() == CompileJobStatus::kReadyToParse); | 97 DCHECK(status() == CompileJobStatus::kReadyToParse); |
| 98 COMPILER_DISPATCHER_TRACE_SCOPE_WITH_NUM( |
| 99 tracer_, kParse, |
| 100 parse_info_->end_position() - parse_info_->start_position()); |
95 | 101 |
96 DisallowHeapAllocation no_allocation; | 102 DisallowHeapAllocation no_allocation; |
97 DisallowHandleAllocation no_handles; | 103 DisallowHandleAllocation no_handles; |
98 std::unique_ptr<DisallowHandleDereference> no_deref; | 104 std::unique_ptr<DisallowHandleDereference> no_deref; |
99 // If we can't parse on a background thread, we need to be able to deref the | 105 // If we can't parse on a background thread, we need to be able to deref the |
100 // source string. | 106 // source string. |
101 if (can_parse_on_background_thread_) { | 107 if (can_parse_on_background_thread_) { |
102 no_deref.reset(new DisallowHandleDereference()); | 108 no_deref.reset(new DisallowHandleDereference()); |
103 } | 109 } |
104 | 110 |
105 // Nullify the Isolate temporarily so that the parser doesn't accidentally | 111 // Nullify the Isolate temporarily so that the parser doesn't accidentally |
106 // use it. | 112 // use it. |
107 parse_info_->set_isolate(nullptr); | 113 parse_info_->set_isolate(nullptr); |
108 | 114 |
109 uintptr_t stack_limit = GetCurrentStackPosition() - max_stack_size_ * KB; | 115 uintptr_t stack_limit = GetCurrentStackPosition() - max_stack_size_ * KB; |
110 | 116 |
111 parser_->set_stack_limit(stack_limit); | 117 parser_->set_stack_limit(stack_limit); |
112 parser_->ParseOnBackground(parse_info_.get()); | 118 parser_->ParseOnBackground(parse_info_.get()); |
113 | 119 |
114 parse_info_->set_isolate(isolate_); | 120 parse_info_->set_isolate(isolate_); |
115 | 121 |
116 status_ = CompileJobStatus::kParsed; | 122 status_ = CompileJobStatus::kParsed; |
117 } | 123 } |
118 | 124 |
119 bool CompilerDispatcherJob::FinalizeParsingOnMainThread() { | 125 bool CompilerDispatcherJob::FinalizeParsingOnMainThread() { |
120 DCHECK(ThreadId::Current().Equals(isolate_->thread_id())); | 126 DCHECK(ThreadId::Current().Equals(isolate_->thread_id())); |
121 DCHECK(status() == CompileJobStatus::kParsed); | 127 DCHECK(status() == CompileJobStatus::kParsed); |
| 128 COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kFinalizeParsing); |
122 | 129 |
123 if (!source_.is_null()) { | 130 if (!source_.is_null()) { |
124 i::GlobalHandles::Destroy(Handle<Object>::cast(source_).location()); | 131 i::GlobalHandles::Destroy(Handle<Object>::cast(source_).location()); |
125 source_ = Handle<String>::null(); | 132 source_ = Handle<String>::null(); |
126 } | 133 } |
127 | 134 |
128 if (parse_info_->literal() == nullptr) { | 135 if (parse_info_->literal() == nullptr) { |
129 status_ = CompileJobStatus::kFailed; | 136 status_ = CompileJobStatus::kFailed; |
130 } else { | 137 } else { |
131 status_ = CompileJobStatus::kReadyToAnalyse; | 138 status_ = CompileJobStatus::kReadyToAnalyse; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 character_stream_.reset(); | 170 character_stream_.reset(); |
164 } | 171 } |
165 handles_from_parsing_.reset(scope.Detach()); | 172 handles_from_parsing_.reset(scope.Detach()); |
166 | 173 |
167 return status_ != CompileJobStatus::kFailed; | 174 return status_ != CompileJobStatus::kFailed; |
168 } | 175 } |
169 | 176 |
170 bool CompilerDispatcherJob::PrepareToCompileOnMainThread() { | 177 bool CompilerDispatcherJob::PrepareToCompileOnMainThread() { |
171 DCHECK(ThreadId::Current().Equals(isolate_->thread_id())); | 178 DCHECK(ThreadId::Current().Equals(isolate_->thread_id())); |
172 DCHECK(status() == CompileJobStatus::kReadyToAnalyse); | 179 DCHECK(status() == CompileJobStatus::kReadyToAnalyse); |
| 180 COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kPrepareToCompile); |
173 | 181 |
174 compile_info_.reset( | 182 compile_info_.reset( |
175 new CompilationInfo(parse_info_.get(), Handle<JSFunction>::null())); | 183 new CompilationInfo(parse_info_.get(), Handle<JSFunction>::null())); |
176 | 184 |
177 DeferredHandleScope scope(isolate_); | 185 DeferredHandleScope scope(isolate_); |
178 if (Compiler::Analyze(parse_info_.get())) { | 186 if (Compiler::Analyze(parse_info_.get())) { |
179 compile_job_.reset( | 187 compile_job_.reset( |
180 Compiler::PrepareUnoptimizedCompilationJob(compile_info_.get())); | 188 Compiler::PrepareUnoptimizedCompilationJob(compile_info_.get())); |
181 } | 189 } |
182 compile_info_->set_deferred_handles(scope.Detach()); | 190 compile_info_->set_deferred_handles(scope.Detach()); |
183 | 191 |
184 if (!compile_job_.get()) { | 192 if (!compile_job_.get()) { |
185 if (!isolate_->has_pending_exception()) isolate_->StackOverflow(); | 193 if (!isolate_->has_pending_exception()) isolate_->StackOverflow(); |
186 status_ = CompileJobStatus::kFailed; | 194 status_ = CompileJobStatus::kFailed; |
187 return false; | 195 return false; |
188 } | 196 } |
189 | 197 |
190 can_compile_on_background_thread_ = | 198 can_compile_on_background_thread_ = |
191 compile_job_->can_execute_on_background_thread(); | 199 compile_job_->can_execute_on_background_thread(); |
192 status_ = CompileJobStatus::kReadyToCompile; | 200 status_ = CompileJobStatus::kReadyToCompile; |
193 return true; | 201 return true; |
194 } | 202 } |
195 | 203 |
196 void CompilerDispatcherJob::Compile() { | 204 void CompilerDispatcherJob::Compile() { |
197 DCHECK(status() == CompileJobStatus::kReadyToCompile); | 205 DCHECK(status() == CompileJobStatus::kReadyToCompile); |
198 DCHECK(can_compile_on_background_thread_ || | 206 DCHECK(can_compile_on_background_thread_ || |
199 ThreadId::Current().Equals(isolate_->thread_id())); | 207 ThreadId::Current().Equals(isolate_->thread_id())); |
| 208 COMPILER_DISPATCHER_TRACE_SCOPE_WITH_NUM( |
| 209 tracer_, kCompile, parse_info_->literal()->ast_node_count()); |
200 | 210 |
201 // Disallowing of handle dereference and heap access dealt with in | 211 // Disallowing of handle dereference and heap access dealt with in |
202 // CompilationJob::ExecuteJob. | 212 // CompilationJob::ExecuteJob. |
203 | 213 |
204 uintptr_t stack_limit = GetCurrentStackPosition() - max_stack_size_ * KB; | 214 uintptr_t stack_limit = GetCurrentStackPosition() - max_stack_size_ * KB; |
205 compile_job_->set_stack_limit(stack_limit); | 215 compile_job_->set_stack_limit(stack_limit); |
206 | 216 |
207 CompilationJob::Status status = compile_job_->ExecuteJob(); | 217 CompilationJob::Status status = compile_job_->ExecuteJob(); |
208 USE(status); | 218 USE(status); |
209 | 219 |
210 // Always transition to kCompiled - errors will be reported by | 220 // Always transition to kCompiled - errors will be reported by |
211 // FinalizeCompilingOnMainThread. | 221 // FinalizeCompilingOnMainThread. |
212 status_ = CompileJobStatus::kCompiled; | 222 status_ = CompileJobStatus::kCompiled; |
213 } | 223 } |
214 | 224 |
215 bool CompilerDispatcherJob::FinalizeCompilingOnMainThread() { | 225 bool CompilerDispatcherJob::FinalizeCompilingOnMainThread() { |
216 DCHECK(ThreadId::Current().Equals(isolate_->thread_id())); | 226 DCHECK(ThreadId::Current().Equals(isolate_->thread_id())); |
217 DCHECK(status() == CompileJobStatus::kCompiled); | 227 DCHECK(status() == CompileJobStatus::kCompiled); |
| 228 COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kFinalizeCompiling); |
218 | 229 |
219 if (compile_job_->state() == CompilationJob::State::kFailed || | 230 if (compile_job_->state() == CompilationJob::State::kFailed || |
220 !Compiler::FinalizeCompilationJob(compile_job_.release())) { | 231 !Compiler::FinalizeCompilationJob(compile_job_.release())) { |
221 if (!isolate_->has_pending_exception()) isolate_->StackOverflow(); | 232 if (!isolate_->has_pending_exception()) isolate_->StackOverflow(); |
222 status_ = CompileJobStatus::kFailed; | 233 status_ = CompileJobStatus::kFailed; |
223 return false; | 234 return false; |
224 } | 235 } |
225 | 236 |
226 zone_.reset(); | 237 zone_.reset(); |
227 parse_info_.reset(); | 238 parse_info_.reset(); |
(...skipping 20 matching lines...) Expand all Loading... |
248 if (!source_.is_null()) { | 259 if (!source_.is_null()) { |
249 i::GlobalHandles::Destroy(Handle<Object>::cast(source_).location()); | 260 i::GlobalHandles::Destroy(Handle<Object>::cast(source_).location()); |
250 source_ = Handle<String>::null(); | 261 source_ = Handle<String>::null(); |
251 } | 262 } |
252 | 263 |
253 status_ = CompileJobStatus::kInitial; | 264 status_ = CompileJobStatus::kInitial; |
254 } | 265 } |
255 | 266 |
256 } // namespace internal | 267 } // namespace internal |
257 } // namespace v8 | 268 } // namespace v8 |
OLD | NEW |