OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "src/background-parser-thread.h" |
| 6 |
| 7 #include "src/parser.h" |
| 8 |
| 9 namespace v8 { |
| 10 namespace internal { |
| 11 |
| 12 static const int kBackgroundParserThreadStackSize = 64 * KB; |
| 13 |
| 14 // To be called on the main thread. |
| 15 class FinalizeParsingTask : public v8::Task { |
| 16 public: |
| 17 FinalizeParsingTask(ScriptCompiler::StreamedSource* source, Isolate* isolate, |
| 18 ScriptCompiler::StreamingCompleteCallback callback, |
| 19 void* callback_data) |
| 20 : source_(source), |
| 21 isolate_(isolate), |
| 22 callback_(callback), |
| 23 callback_data_(callback_data) {} |
| 24 |
| 25 virtual void Run() V8_OVERRIDE { |
| 26 // The source is now ready for compilation. For that, we need to pass the |
| 27 // control back to the embedder, to get Context etc. set up correctly. |
| 28 callback_(source_, callback_data_); |
| 29 } |
| 30 |
| 31 private: |
| 32 ScriptCompiler::StreamedSource* source_; |
| 33 Isolate* isolate_; |
| 34 ScriptCompiler::StreamingCompleteCallback callback_; |
| 35 void* callback_data_; |
| 36 }; |
| 37 |
| 38 |
| 39 void BackgroundParsingTask::Run() { |
| 40 uintptr_t limit = |
| 41 reinterpret_cast<uintptr_t>(&limit) - kBackgroundParserThreadStackSize; |
| 42 Parser parser(source_->info, limit, hash_seed_); |
| 43 parser.set_allow_lazy(allow_lazy_); |
| 44 parser.ParseOnBackground(); |
| 45 |
| 46 if (script_data_ != NULL) { |
| 47 source_->cached_data = new ScriptCompiler::CachedData( |
| 48 script_data_->data(), script_data_->length(), |
| 49 ScriptCompiler::CachedData::BufferOwned); |
| 50 script_data_->ReleaseDataOwnership(); |
| 51 delete script_data_; |
| 52 script_data_ = NULL; |
| 53 } |
| 54 |
| 55 // The task is destroyed automatically. |
| 56 V8::GetCurrentPlatform()->CallOnForegroundThread( |
| 57 reinterpret_cast<v8::Isolate*>(isolate_), |
| 58 new FinalizeParsingTask(source_, isolate_, callback_, callback_data_)); |
| 59 } |
| 60 |
| 61 |
| 62 BackgroundParserThread::BackgroundParserThread() |
| 63 : Thread(Thread::Options("v8::BackgroundParserThread", |
| 64 kBackgroundParserThreadStackSize)), |
| 65 task_(NULL), |
| 66 have_work_(0), |
| 67 should_stop_(false) {} |
| 68 |
| 69 |
| 70 void BackgroundParserThread::Run() { |
| 71 DisallowHeapAllocation no_allocation; |
| 72 DisallowHandleAllocation no_handles; |
| 73 DisallowHandleDereference no_deref; |
| 74 |
| 75 while (true) { |
| 76 have_work_.Wait(); |
| 77 if (should_stop_) { |
| 78 break; |
| 79 } |
| 80 DCHECK(task_ != NULL); |
| 81 task_->Run(); |
| 82 delete task_; |
| 83 task_ = NULL; |
| 84 } |
| 85 } |
| 86 |
| 87 |
| 88 void BackgroundParserThread::Stop() { |
| 89 should_stop_ = true; |
| 90 have_work_.Signal(); |
| 91 Join(); |
| 92 } |
| 93 |
| 94 |
| 95 void BackgroundParserThread::SetTask(BackgroundParsingTask* task) { |
| 96 // This can only be called when the thread is not already running a task. The |
| 97 // upper layer will take care of not tryng to add a task before the previous |
| 98 // one is done. TODO(marja): In the future we'll we want to parse multiple |
| 99 // scripts on the background. We might need several background threads to |
| 100 // distribute the tasks to. |
| 101 DCHECK(task_ == NULL); |
| 102 task_ = task; |
| 103 have_work_.Signal(); |
| 104 } |
| 105 } |
| 106 } // namespace v8::internal |
OLD | NEW |