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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler-dispatcher/compiler-dispatcher-job.h ('k') | src/objects.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler-dispatcher/compiler-dispatcher-job.cc
diff --git a/src/compiler-dispatcher/compiler-dispatcher-job.cc b/src/compiler-dispatcher/compiler-dispatcher-job.cc
index 2ca26011bb5646dbacef9b725ac015d2de52af5c..fdb975a5e419fde3427a53514cc5a8730ec33694 100644
--- a/src/compiler-dispatcher/compiler-dispatcher-job.cc
+++ b/src/compiler-dispatcher/compiler-dispatcher-job.cc
@@ -22,6 +22,46 @@
namespace v8 {
namespace internal {
+namespace {
+
+class OneByteWrapper : public v8::String::ExternalOneByteStringResource {
+ public:
+ OneByteWrapper(const void* data, int length) : data_(data), length_(length) {}
+ ~OneByteWrapper() override = default;
+
+ const char* data() const override {
+ return reinterpret_cast<const char*>(data_);
+ }
+
+ size_t length() const override { return static_cast<size_t>(length_); }
+
+ private:
+ const void* data_;
+ int length_;
+
+ DISALLOW_COPY_AND_ASSIGN(OneByteWrapper);
+};
+
+class TwoByteWrapper : public v8::String::ExternalStringResource {
+ public:
+ TwoByteWrapper(const void* data, int length) : data_(data), length_(length) {}
+ ~TwoByteWrapper() override = default;
+
+ const uint16_t* data() const override {
+ return reinterpret_cast<const uint16_t*>(data_);
+ }
+
+ size_t length() const override { return static_cast<size_t>(length_); }
+
+ private:
+ const void* data_;
+ int length_;
+
+ DISALLOW_COPY_AND_ASSIGN(TwoByteWrapper);
+};
+
+} // namespace
+
CompilerDispatcherJob::CompilerDispatcherJob(Isolate* isolate,
CompilerDispatcherTracer* tracer,
Handle<SharedFunctionInfo> shared,
@@ -31,14 +71,11 @@ CompilerDispatcherJob::CompilerDispatcherJob(Isolate* isolate,
shared_(Handle<SharedFunctionInfo>::cast(
isolate_->global_handles()->Create(*shared))),
max_stack_size_(max_stack_size),
- can_compile_on_background_thread_(false),
trace_compiler_dispatcher_jobs_(FLAG_trace_compiler_dispatcher_jobs) {
HandleScope scope(isolate_);
DCHECK(!shared_->outer_scope_info()->IsTheHole(isolate_));
Handle<Script> script(Script::cast(shared_->script()), isolate_);
Handle<String> source(String::cast(script->source()), isolate_);
- can_parse_on_background_thread_ =
- source->IsExternalTwoByteString() || source->IsExternalOneByteString();
if (trace_compiler_dispatcher_jobs_) {
PrintF("CompilerDispatcherJob[%p] created for ", static_cast<void*>(this));
shared_->ShortPrint();
@@ -78,11 +115,68 @@ void CompilerDispatcherJob::PrepareToParseOnMainThread() {
source, shared_->start_position(), shared_->end_position()));
} else {
source = String::Flatten(source);
- // Have to globalize the reference here, so it survives between function
- // calls.
- source_ = Handle<String>::cast(isolate_->global_handles()->Create(*source));
- character_stream_.reset(ScannerStream::For(
- source_, shared_->start_position(), shared_->end_position()));
+ const void* data;
+ int offset = 0;
+ int length = source->length();
+
+ // Objects in lo_space don't move, so we can just read the contents from
+ // any thread.
+ if (isolate_->heap()->lo_space()->Contains(*source)) {
+ // We need to globalize the handle to the flattened string here, in
+ // case it's not referenced from anywhere else.
+ source_ =
+ Handle<String>::cast(isolate_->global_handles()->Create(*source));
+ DisallowHeapAllocation no_allocation;
+ String::FlatContent content = source->GetFlatContent();
+ DCHECK(content.IsFlat());
+ data =
+ content.IsOneByte()
+ ? reinterpret_cast<const void*>(content.ToOneByteVector().start())
+ : reinterpret_cast<const void*>(content.ToUC16Vector().start());
+ } else {
+ // Otherwise, create a copy of the part of the string we'll parse in the
+ // zone.
+ length = (shared_->end_position() - shared_->start_position());
+ offset = shared_->start_position();
+
+ int byte_len = length * (source->IsOneByteRepresentation() ? 1 : 2);
+ data = zone_->New(byte_len);
+
+ DisallowHeapAllocation no_allocation;
+ String::FlatContent content = source->GetFlatContent();
+ DCHECK(content.IsFlat());
+ if (content.IsOneByte()) {
+ MemCopy(const_cast<void*>(data),
+ &content.ToOneByteVector().at(shared_->start_position()),
+ byte_len);
+ } else {
+ MemCopy(const_cast<void*>(data),
+ &content.ToUC16Vector().at(shared_->start_position()),
+ byte_len);
+ }
+ }
+ Handle<String> wrapper;
+ if (source->IsOneByteRepresentation()) {
+ ExternalOneByteString::Resource* resource =
+ new OneByteWrapper(data, length);
+ source_wrapper_.reset(resource);
+ wrapper = isolate_->factory()
+ ->NewExternalStringFromOneByte(resource)
+ .ToHandleChecked();
+ } else {
+ ExternalTwoByteString::Resource* resource =
+ new TwoByteWrapper(data, length);
+ source_wrapper_.reset(resource);
+ wrapper = isolate_->factory()
+ ->NewExternalStringFromTwoByte(resource)
+ .ToHandleChecked();
+ }
+ wrapper_ =
+ Handle<String>::cast(isolate_->global_handles()->Create(*wrapper));
+
+ character_stream_.reset(
+ ScannerStream::For(wrapper_, shared_->start_position() - offset,
+ shared_->end_position() - offset));
}
parse_info_.reset(new ParseInfo(zone_.get()));
parse_info_->set_isolate(isolate_);
@@ -111,8 +205,6 @@ void CompilerDispatcherJob::PrepareToParseOnMainThread() {
}
void CompilerDispatcherJob::Parse() {
- DCHECK(can_parse_on_background_thread_ ||
- ThreadId::Current().Equals(isolate_->thread_id()));
DCHECK(status() == CompileJobStatus::kReadyToParse);
COMPILER_DISPATCHER_TRACE_SCOPE_WITH_NUM(
tracer_, kParse,
@@ -123,12 +215,7 @@ void CompilerDispatcherJob::Parse() {
DisallowHeapAllocation no_allocation;
DisallowHandleAllocation no_handles;
- std::unique_ptr<DisallowHandleDereference> no_deref;
- // If we can't parse on a background thread, we need to be able to deref the
- // source string.
- if (can_parse_on_background_thread_) {
- no_deref.reset(new DisallowHandleDereference());
- }
+ DisallowHandleDereference no_deref;
// Nullify the Isolate temporarily so that the parser doesn't accidentally
// use it.
@@ -157,6 +244,10 @@ bool CompilerDispatcherJob::FinalizeParsingOnMainThread() {
i::GlobalHandles::Destroy(Handle<Object>::cast(source_).location());
source_ = Handle<String>::null();
}
+ if (!wrapper_.is_null()) {
+ i::GlobalHandles::Destroy(Handle<Object>::cast(wrapper_).location());
+ wrapper_ = Handle<String>::null();
+ }
if (parse_info_->literal() == nullptr) {
status_ = CompileJobStatus::kFailed;
@@ -217,16 +308,13 @@ bool CompilerDispatcherJob::PrepareToCompileOnMainThread() {
return false;
}
- can_compile_on_background_thread_ =
- compile_job_->can_execute_on_background_thread();
+ CHECK(compile_job_->can_execute_on_background_thread());
status_ = CompileJobStatus::kReadyToCompile;
return true;
}
void CompilerDispatcherJob::Compile() {
DCHECK(status() == CompileJobStatus::kReadyToCompile);
- DCHECK(can_compile_on_background_thread_ ||
- ThreadId::Current().Equals(isolate_->thread_id()));
COMPILER_DISPATCHER_TRACE_SCOPE_WITH_NUM(
tracer_, kCompile, parse_info_->literal()->ast_node_count());
if (trace_compiler_dispatcher_jobs_) {
@@ -293,6 +381,10 @@ void CompilerDispatcherJob::ResetOnMainThread() {
i::GlobalHandles::Destroy(Handle<Object>::cast(source_).location());
source_ = Handle<String>::null();
}
+ if (!wrapper_.is_null()) {
+ i::GlobalHandles::Destroy(Handle<Object>::cast(wrapper_).location());
+ wrapper_ = Handle<String>::null();
+ }
status_ = CompileJobStatus::kInitial;
}
« 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