Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: src/compiler-dispatcher/compiler-dispatcher-job.cc

Issue 2625413004: [compiler-dispatcher] make it so that we can always parse on bg threads (Closed)
Patch Set: updates Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler-dispatcher/compiler-dispatcher-job.h ('k') | src/objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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-dispatcher/compiler-dispatcher-tracer.h"
10 #include "src/compiler.h" 10 #include "src/compiler.h"
11 #include "src/flags.h" 11 #include "src/flags.h"
12 #include "src/global-handles.h" 12 #include "src/global-handles.h"
13 #include "src/isolate.h" 13 #include "src/isolate.h"
14 #include "src/objects-inl.h" 14 #include "src/objects-inl.h"
15 #include "src/parsing/parse-info.h" 15 #include "src/parsing/parse-info.h"
16 #include "src/parsing/parser.h" 16 #include "src/parsing/parser.h"
17 #include "src/parsing/scanner-character-streams.h" 17 #include "src/parsing/scanner-character-streams.h"
18 #include "src/unicode-cache.h" 18 #include "src/unicode-cache.h"
19 #include "src/utils.h" 19 #include "src/utils.h"
20 #include "src/zone/zone.h" 20 #include "src/zone/zone.h"
21 21
22 namespace v8 { 22 namespace v8 {
23 namespace internal { 23 namespace internal {
24 24
25 namespace {
26
27 class OneByteWrapper : public v8::String::ExternalOneByteStringResource {
28 public:
29 OneByteWrapper(const void* data, int length) : data_(data), length_(length) {}
30 ~OneByteWrapper() override = default;
31
32 const char* data() const override {
33 return reinterpret_cast<const char*>(data_);
34 }
35
36 size_t length() const override { return static_cast<size_t>(length_); }
37
38 private:
39 const void* data_;
40 int length_;
41
42 DISALLOW_COPY_AND_ASSIGN(OneByteWrapper);
43 };
44
45 class TwoByteWrapper : public v8::String::ExternalStringResource {
46 public:
47 TwoByteWrapper(const void* data, int length) : data_(data), length_(length) {}
48 ~TwoByteWrapper() override = default;
49
50 const uint16_t* data() const override {
51 return reinterpret_cast<const uint16_t*>(data_);
52 }
53
54 size_t length() const override { return static_cast<size_t>(length_); }
55
56 private:
57 const void* data_;
58 int length_;
59
60 DISALLOW_COPY_AND_ASSIGN(TwoByteWrapper);
61 };
62
63 } // namespace
64
25 CompilerDispatcherJob::CompilerDispatcherJob(Isolate* isolate, 65 CompilerDispatcherJob::CompilerDispatcherJob(Isolate* isolate,
26 CompilerDispatcherTracer* tracer, 66 CompilerDispatcherTracer* tracer,
27 Handle<SharedFunctionInfo> shared, 67 Handle<SharedFunctionInfo> shared,
28 size_t max_stack_size) 68 size_t max_stack_size)
29 : isolate_(isolate), 69 : isolate_(isolate),
30 tracer_(tracer), 70 tracer_(tracer),
31 shared_(Handle<SharedFunctionInfo>::cast( 71 shared_(Handle<SharedFunctionInfo>::cast(
32 isolate_->global_handles()->Create(*shared))), 72 isolate_->global_handles()->Create(*shared))),
33 max_stack_size_(max_stack_size), 73 max_stack_size_(max_stack_size),
34 can_compile_on_background_thread_(false),
35 trace_compiler_dispatcher_jobs_(FLAG_trace_compiler_dispatcher_jobs) { 74 trace_compiler_dispatcher_jobs_(FLAG_trace_compiler_dispatcher_jobs) {
36 HandleScope scope(isolate_); 75 HandleScope scope(isolate_);
37 DCHECK(!shared_->outer_scope_info()->IsTheHole(isolate_)); 76 DCHECK(!shared_->outer_scope_info()->IsTheHole(isolate_));
38 Handle<Script> script(Script::cast(shared_->script()), isolate_); 77 Handle<Script> script(Script::cast(shared_->script()), isolate_);
39 Handle<String> source(String::cast(script->source()), isolate_); 78 Handle<String> source(String::cast(script->source()), isolate_);
40 can_parse_on_background_thread_ =
41 source->IsExternalTwoByteString() || source->IsExternalOneByteString();
42 if (trace_compiler_dispatcher_jobs_) { 79 if (trace_compiler_dispatcher_jobs_) {
43 PrintF("CompilerDispatcherJob[%p] created for ", static_cast<void*>(this)); 80 PrintF("CompilerDispatcherJob[%p] created for ", static_cast<void*>(this));
44 shared_->ShortPrint(); 81 shared_->ShortPrint();
45 PrintF("\n"); 82 PrintF("\n");
46 } 83 }
47 } 84 }
48 85
49 CompilerDispatcherJob::~CompilerDispatcherJob() { 86 CompilerDispatcherJob::~CompilerDispatcherJob() {
50 DCHECK(ThreadId::Current().Equals(isolate_->thread_id())); 87 DCHECK(ThreadId::Current().Equals(isolate_->thread_id()));
51 DCHECK(status_ == CompileJobStatus::kInitial || 88 DCHECK(status_ == CompileJobStatus::kInitial ||
(...skipping 19 matching lines...) Expand all
71 zone_.reset(new Zone(isolate_->allocator(), ZONE_NAME)); 108 zone_.reset(new Zone(isolate_->allocator(), ZONE_NAME));
72 Handle<Script> script(Script::cast(shared_->script()), isolate_); 109 Handle<Script> script(Script::cast(shared_->script()), isolate_);
73 DCHECK(script->type() != Script::TYPE_NATIVE); 110 DCHECK(script->type() != Script::TYPE_NATIVE);
74 111
75 Handle<String> source(String::cast(script->source()), isolate_); 112 Handle<String> source(String::cast(script->source()), isolate_);
76 if (source->IsExternalTwoByteString() || source->IsExternalOneByteString()) { 113 if (source->IsExternalTwoByteString() || source->IsExternalOneByteString()) {
77 character_stream_.reset(ScannerStream::For( 114 character_stream_.reset(ScannerStream::For(
78 source, shared_->start_position(), shared_->end_position())); 115 source, shared_->start_position(), shared_->end_position()));
79 } else { 116 } else {
80 source = String::Flatten(source); 117 source = String::Flatten(source);
81 // Have to globalize the reference here, so it survives between function 118 const void* data;
82 // calls. 119 int offset = 0;
83 source_ = Handle<String>::cast(isolate_->global_handles()->Create(*source)); 120 int length = source->length();
84 character_stream_.reset(ScannerStream::For( 121
85 source_, shared_->start_position(), shared_->end_position())); 122 // Objects in lo_space don't move, so we can just read the contents from
123 // any thread.
124 if (isolate_->heap()->lo_space()->Contains(*source)) {
125 // We need to globalize the handle to the flattened string here, in
126 // case it's not referenced from anywhere else.
127 source_ =
128 Handle<String>::cast(isolate_->global_handles()->Create(*source));
129 DisallowHeapAllocation no_allocation;
130 String::FlatContent content = source->GetFlatContent();
131 DCHECK(content.IsFlat());
132 data =
133 content.IsOneByte()
134 ? reinterpret_cast<const void*>(content.ToOneByteVector().start())
135 : reinterpret_cast<const void*>(content.ToUC16Vector().start());
136 } else {
137 // Otherwise, create a copy of the part of the string we'll parse in the
138 // zone.
139 length = (shared_->end_position() - shared_->start_position());
140 offset = shared_->start_position();
141
142 int byte_len = length * (source->IsOneByteRepresentation() ? 1 : 2);
143 data = zone_->New(byte_len);
144
145 DisallowHeapAllocation no_allocation;
146 String::FlatContent content = source->GetFlatContent();
147 DCHECK(content.IsFlat());
148 if (content.IsOneByte()) {
149 MemCopy(const_cast<void*>(data),
150 &content.ToOneByteVector().at(shared_->start_position()),
151 byte_len);
152 } else {
153 MemCopy(const_cast<void*>(data),
154 &content.ToUC16Vector().at(shared_->start_position()),
155 byte_len);
156 }
157 }
158 Handle<String> wrapper;
159 if (source->IsOneByteRepresentation()) {
160 ExternalOneByteString::Resource* resource =
161 new OneByteWrapper(data, length);
162 source_wrapper_.reset(resource);
163 wrapper = isolate_->factory()
164 ->NewExternalStringFromOneByte(resource)
165 .ToHandleChecked();
166 } else {
167 ExternalTwoByteString::Resource* resource =
168 new TwoByteWrapper(data, length);
169 source_wrapper_.reset(resource);
170 wrapper = isolate_->factory()
171 ->NewExternalStringFromTwoByte(resource)
172 .ToHandleChecked();
173 }
174 wrapper_ =
175 Handle<String>::cast(isolate_->global_handles()->Create(*wrapper));
176
177 character_stream_.reset(
178 ScannerStream::For(wrapper_, shared_->start_position() - offset,
179 shared_->end_position() - offset));
86 } 180 }
87 parse_info_.reset(new ParseInfo(zone_.get())); 181 parse_info_.reset(new ParseInfo(zone_.get()));
88 parse_info_->set_isolate(isolate_); 182 parse_info_->set_isolate(isolate_);
89 parse_info_->set_character_stream(character_stream_.get()); 183 parse_info_->set_character_stream(character_stream_.get());
90 parse_info_->set_hash_seed(isolate_->heap()->HashSeed()); 184 parse_info_->set_hash_seed(isolate_->heap()->HashSeed());
91 parse_info_->set_is_named_expression(shared_->is_named_expression()); 185 parse_info_->set_is_named_expression(shared_->is_named_expression());
92 parse_info_->set_compiler_hints(shared_->compiler_hints()); 186 parse_info_->set_compiler_hints(shared_->compiler_hints());
93 parse_info_->set_start_position(shared_->start_position()); 187 parse_info_->set_start_position(shared_->start_position());
94 parse_info_->set_end_position(shared_->end_position()); 188 parse_info_->set_end_position(shared_->end_position());
95 parse_info_->set_unicode_cache(unicode_cache_.get()); 189 parse_info_->set_unicode_cache(unicode_cache_.get());
96 parse_info_->set_language_mode(shared_->language_mode()); 190 parse_info_->set_language_mode(shared_->language_mode());
97 parse_info_->set_function_literal_id(shared_->function_literal_id()); 191 parse_info_->set_function_literal_id(shared_->function_literal_id());
98 192
99 parser_.reset(new Parser(parse_info_.get())); 193 parser_.reset(new Parser(parse_info_.get()));
100 Handle<ScopeInfo> outer_scope_info( 194 Handle<ScopeInfo> outer_scope_info(
101 handle(ScopeInfo::cast(shared_->outer_scope_info()))); 195 handle(ScopeInfo::cast(shared_->outer_scope_info())));
102 parser_->DeserializeScopeChain(parse_info_.get(), 196 parser_->DeserializeScopeChain(parse_info_.get(),
103 outer_scope_info->length() > 0 197 outer_scope_info->length() > 0
104 ? MaybeHandle<ScopeInfo>(outer_scope_info) 198 ? MaybeHandle<ScopeInfo>(outer_scope_info)
105 : MaybeHandle<ScopeInfo>()); 199 : MaybeHandle<ScopeInfo>());
106 200
107 Handle<String> name(String::cast(shared_->name())); 201 Handle<String> name(String::cast(shared_->name()));
108 parse_info_->set_function_name( 202 parse_info_->set_function_name(
109 parse_info_->ast_value_factory()->GetString(name)); 203 parse_info_->ast_value_factory()->GetString(name));
110 status_ = CompileJobStatus::kReadyToParse; 204 status_ = CompileJobStatus::kReadyToParse;
111 } 205 }
112 206
113 void CompilerDispatcherJob::Parse() { 207 void CompilerDispatcherJob::Parse() {
114 DCHECK(can_parse_on_background_thread_ ||
115 ThreadId::Current().Equals(isolate_->thread_id()));
116 DCHECK(status() == CompileJobStatus::kReadyToParse); 208 DCHECK(status() == CompileJobStatus::kReadyToParse);
117 COMPILER_DISPATCHER_TRACE_SCOPE_WITH_NUM( 209 COMPILER_DISPATCHER_TRACE_SCOPE_WITH_NUM(
118 tracer_, kParse, 210 tracer_, kParse,
119 parse_info_->end_position() - parse_info_->start_position()); 211 parse_info_->end_position() - parse_info_->start_position());
120 if (trace_compiler_dispatcher_jobs_) { 212 if (trace_compiler_dispatcher_jobs_) {
121 PrintF("CompilerDispatcherJob[%p]: Parsing\n", static_cast<void*>(this)); 213 PrintF("CompilerDispatcherJob[%p]: Parsing\n", static_cast<void*>(this));
122 } 214 }
123 215
124 DisallowHeapAllocation no_allocation; 216 DisallowHeapAllocation no_allocation;
125 DisallowHandleAllocation no_handles; 217 DisallowHandleAllocation no_handles;
126 std::unique_ptr<DisallowHandleDereference> no_deref; 218 DisallowHandleDereference no_deref;
127 // If we can't parse on a background thread, we need to be able to deref the
128 // source string.
129 if (can_parse_on_background_thread_) {
130 no_deref.reset(new DisallowHandleDereference());
131 }
132 219
133 // Nullify the Isolate temporarily so that the parser doesn't accidentally 220 // Nullify the Isolate temporarily so that the parser doesn't accidentally
134 // use it. 221 // use it.
135 parse_info_->set_isolate(nullptr); 222 parse_info_->set_isolate(nullptr);
136 223
137 uintptr_t stack_limit = GetCurrentStackPosition() - max_stack_size_ * KB; 224 uintptr_t stack_limit = GetCurrentStackPosition() - max_stack_size_ * KB;
138 225
139 parser_->set_stack_limit(stack_limit); 226 parser_->set_stack_limit(stack_limit);
140 parser_->ParseOnBackground(parse_info_.get()); 227 parser_->ParseOnBackground(parse_info_.get());
141 228
142 parse_info_->set_isolate(isolate_); 229 parse_info_->set_isolate(isolate_);
143 230
144 status_ = CompileJobStatus::kParsed; 231 status_ = CompileJobStatus::kParsed;
145 } 232 }
146 233
147 bool CompilerDispatcherJob::FinalizeParsingOnMainThread() { 234 bool CompilerDispatcherJob::FinalizeParsingOnMainThread() {
148 DCHECK(ThreadId::Current().Equals(isolate_->thread_id())); 235 DCHECK(ThreadId::Current().Equals(isolate_->thread_id()));
149 DCHECK(status() == CompileJobStatus::kParsed); 236 DCHECK(status() == CompileJobStatus::kParsed);
150 COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kFinalizeParsing); 237 COMPILER_DISPATCHER_TRACE_SCOPE(tracer_, kFinalizeParsing);
151 if (trace_compiler_dispatcher_jobs_) { 238 if (trace_compiler_dispatcher_jobs_) {
152 PrintF("CompilerDispatcherJob[%p]: Finalizing parsing\n", 239 PrintF("CompilerDispatcherJob[%p]: Finalizing parsing\n",
153 static_cast<void*>(this)); 240 static_cast<void*>(this));
154 } 241 }
155 242
156 if (!source_.is_null()) { 243 if (!source_.is_null()) {
157 i::GlobalHandles::Destroy(Handle<Object>::cast(source_).location()); 244 i::GlobalHandles::Destroy(Handle<Object>::cast(source_).location());
158 source_ = Handle<String>::null(); 245 source_ = Handle<String>::null();
159 } 246 }
247 if (!wrapper_.is_null()) {
248 i::GlobalHandles::Destroy(Handle<Object>::cast(wrapper_).location());
249 wrapper_ = Handle<String>::null();
250 }
160 251
161 if (parse_info_->literal() == nullptr) { 252 if (parse_info_->literal() == nullptr) {
162 status_ = CompileJobStatus::kFailed; 253 status_ = CompileJobStatus::kFailed;
163 } else { 254 } else {
164 status_ = CompileJobStatus::kReadyToAnalyse; 255 status_ = CompileJobStatus::kReadyToAnalyse;
165 } 256 }
166 257
167 DeferredHandleScope scope(isolate_); 258 DeferredHandleScope scope(isolate_);
168 { 259 {
169 Handle<Script> script(Script::cast(shared_->script()), isolate_); 260 Handle<Script> script(Script::cast(shared_->script()), isolate_);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 Compiler::PrepareUnoptimizedCompilationJob(compile_info_.get())); 301 Compiler::PrepareUnoptimizedCompilationJob(compile_info_.get()));
211 } 302 }
212 compile_info_->set_deferred_handles(scope.Detach()); 303 compile_info_->set_deferred_handles(scope.Detach());
213 304
214 if (!compile_job_.get()) { 305 if (!compile_job_.get()) {
215 if (!isolate_->has_pending_exception()) isolate_->StackOverflow(); 306 if (!isolate_->has_pending_exception()) isolate_->StackOverflow();
216 status_ = CompileJobStatus::kFailed; 307 status_ = CompileJobStatus::kFailed;
217 return false; 308 return false;
218 } 309 }
219 310
220 can_compile_on_background_thread_ = 311 CHECK(compile_job_->can_execute_on_background_thread());
221 compile_job_->can_execute_on_background_thread();
222 status_ = CompileJobStatus::kReadyToCompile; 312 status_ = CompileJobStatus::kReadyToCompile;
223 return true; 313 return true;
224 } 314 }
225 315
226 void CompilerDispatcherJob::Compile() { 316 void CompilerDispatcherJob::Compile() {
227 DCHECK(status() == CompileJobStatus::kReadyToCompile); 317 DCHECK(status() == CompileJobStatus::kReadyToCompile);
228 DCHECK(can_compile_on_background_thread_ ||
229 ThreadId::Current().Equals(isolate_->thread_id()));
230 COMPILER_DISPATCHER_TRACE_SCOPE_WITH_NUM( 318 COMPILER_DISPATCHER_TRACE_SCOPE_WITH_NUM(
231 tracer_, kCompile, parse_info_->literal()->ast_node_count()); 319 tracer_, kCompile, parse_info_->literal()->ast_node_count());
232 if (trace_compiler_dispatcher_jobs_) { 320 if (trace_compiler_dispatcher_jobs_) {
233 PrintF("CompilerDispatcherJob[%p]: Compiling\n", static_cast<void*>(this)); 321 PrintF("CompilerDispatcherJob[%p]: Compiling\n", static_cast<void*>(this));
234 } 322 }
235 323
236 // Disallowing of handle dereference and heap access dealt with in 324 // Disallowing of handle dereference and heap access dealt with in
237 // CompilationJob::ExecuteJob. 325 // CompilationJob::ExecuteJob.
238 326
239 uintptr_t stack_limit = GetCurrentStackPosition() - max_stack_size_ * KB; 327 uintptr_t stack_limit = GetCurrentStackPosition() - max_stack_size_ * KB;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 parse_info_.reset(); 374 parse_info_.reset();
287 handles_from_parsing_.reset(); 375 handles_from_parsing_.reset();
288 compile_info_.reset(); 376 compile_info_.reset();
289 compile_job_.reset(); 377 compile_job_.reset();
290 zone_.reset(); 378 zone_.reset();
291 379
292 if (!source_.is_null()) { 380 if (!source_.is_null()) {
293 i::GlobalHandles::Destroy(Handle<Object>::cast(source_).location()); 381 i::GlobalHandles::Destroy(Handle<Object>::cast(source_).location());
294 source_ = Handle<String>::null(); 382 source_ = Handle<String>::null();
295 } 383 }
384 if (!wrapper_.is_null()) {
385 i::GlobalHandles::Destroy(Handle<Object>::cast(wrapper_).location());
386 wrapper_ = Handle<String>::null();
387 }
296 388
297 status_ = CompileJobStatus::kInitial; 389 status_ = CompileJobStatus::kInitial;
298 } 390 }
299 391
300 double CompilerDispatcherJob::EstimateRuntimeOfNextStepInMs() const { 392 double CompilerDispatcherJob::EstimateRuntimeOfNextStepInMs() const {
301 switch (status_) { 393 switch (status_) {
302 case CompileJobStatus::kInitial: 394 case CompileJobStatus::kInitial:
303 return tracer_->EstimatePrepareToParseInMs(); 395 return tracer_->EstimatePrepareToParseInMs();
304 396
305 case CompileJobStatus::kReadyToParse: 397 case CompileJobStatus::kReadyToParse:
(...skipping 22 matching lines...) Expand all
328 return 0.0; 420 return 0.0;
329 } 421 }
330 422
331 void CompilerDispatcherJob::ShortPrint() { 423 void CompilerDispatcherJob::ShortPrint() {
332 DCHECK(ThreadId::Current().Equals(isolate_->thread_id())); 424 DCHECK(ThreadId::Current().Equals(isolate_->thread_id()));
333 shared_->ShortPrint(); 425 shared_->ShortPrint();
334 } 426 }
335 427
336 } // namespace internal 428 } // namespace internal
337 } // namespace v8 429 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler-dispatcher/compiler-dispatcher-job.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698