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