| Index: src/background-parser-thread.cc
|
| diff --git a/src/background-parser-thread.cc b/src/background-parser-thread.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..86b8e7fcc7a9bd27ceda752ce2778719d5cf6162
|
| --- /dev/null
|
| +++ b/src/background-parser-thread.cc
|
| @@ -0,0 +1,106 @@
|
| +// Copyright 2014 the V8 project authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "src/background-parser-thread.h"
|
| +
|
| +#include "src/parser.h"
|
| +
|
| +namespace v8 {
|
| +namespace internal {
|
| +
|
| +static const int kBackgroundParserThreadStackSize = 64 * KB;
|
| +
|
| +// To be called on the main thread.
|
| +class FinalizeParsingTask : public v8::Task {
|
| + public:
|
| + FinalizeParsingTask(ScriptCompiler::StreamedSource* source, Isolate* isolate,
|
| + ScriptCompiler::StreamingCompleteCallback callback,
|
| + void* callback_data)
|
| + : source_(source),
|
| + isolate_(isolate),
|
| + callback_(callback),
|
| + callback_data_(callback_data) {}
|
| +
|
| + virtual void Run() V8_OVERRIDE {
|
| + // The source is now ready for compilation. For that, we need to pass the
|
| + // control back to the embedder, to get Context etc. set up correctly.
|
| + callback_(source_, callback_data_);
|
| + }
|
| +
|
| + private:
|
| + ScriptCompiler::StreamedSource* source_;
|
| + Isolate* isolate_;
|
| + ScriptCompiler::StreamingCompleteCallback callback_;
|
| + void* callback_data_;
|
| +};
|
| +
|
| +
|
| +void BackgroundParsingTask::Run() {
|
| + uintptr_t limit =
|
| + reinterpret_cast<uintptr_t>(&limit) - kBackgroundParserThreadStackSize;
|
| + Parser parser(source_->info, limit, hash_seed_);
|
| + parser.set_allow_lazy(allow_lazy_);
|
| + parser.ParseOnBackground();
|
| +
|
| + if (script_data_ != NULL) {
|
| + source_->cached_data = new ScriptCompiler::CachedData(
|
| + script_data_->data(), script_data_->length(),
|
| + ScriptCompiler::CachedData::BufferOwned);
|
| + script_data_->ReleaseDataOwnership();
|
| + delete script_data_;
|
| + script_data_ = NULL;
|
| + }
|
| +
|
| + // The task is destroyed automatically.
|
| + V8::GetCurrentPlatform()->CallOnForegroundThread(
|
| + reinterpret_cast<v8::Isolate*>(isolate_),
|
| + new FinalizeParsingTask(source_, isolate_, callback_, callback_data_));
|
| +}
|
| +
|
| +
|
| +BackgroundParserThread::BackgroundParserThread()
|
| + : Thread(Thread::Options("v8::BackgroundParserThread",
|
| + kBackgroundParserThreadStackSize)),
|
| + task_(NULL),
|
| + have_work_(0),
|
| + should_stop_(false) {}
|
| +
|
| +
|
| +void BackgroundParserThread::Run() {
|
| + DisallowHeapAllocation no_allocation;
|
| + DisallowHandleAllocation no_handles;
|
| + DisallowHandleDereference no_deref;
|
| +
|
| + while (true) {
|
| + have_work_.Wait();
|
| + if (should_stop_) {
|
| + break;
|
| + }
|
| + DCHECK(task_ != NULL);
|
| + task_->Run();
|
| + delete task_;
|
| + task_ = NULL;
|
| + }
|
| +}
|
| +
|
| +
|
| +void BackgroundParserThread::Stop() {
|
| + should_stop_ = true;
|
| + have_work_.Signal();
|
| + Join();
|
| +}
|
| +
|
| +
|
| +void BackgroundParserThread::SetTask(BackgroundParsingTask* task) {
|
| + // This can only be called when the thread is not already running a task. The
|
| + // upper layer will take care of not tryng to add a task before the previous
|
| + // one is done. TODO(marja): In the future we'll we want to parse multiple
|
| + // scripts on the background. We might need several background threads to
|
| + // distribute the tasks to.
|
| + DCHECK(task_ == NULL);
|
| + task_ = task;
|
| + have_work_.Signal();
|
| +}
|
| +}
|
| +} // namespace v8::internal
|
|
|