| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are |
| 4 // met: |
| 5 // |
| 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided |
| 11 // with the distribution. |
| 12 // * Neither the name of Google Inc. nor the names of its |
| 13 // contributors may be used to endorse or promote products derived |
| 14 // from this software without specific prior written permission. |
| 15 // |
| 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 |
| 28 #include "parser-thread.h" |
| 29 |
| 30 #include "api.h" |
| 31 #include "platform/condition-variable.h" |
| 32 #include "preparse-data.h" |
| 33 #include "scanner-character-streams.h" |
| 34 #include "unbound-queue.h" |
| 35 |
| 36 namespace v8 { |
| 37 namespace internal { |
| 38 |
| 39 static const int kFastParserThreadStackSize = 64 * KB; |
| 40 |
| 41 class BackgroundParsingTask { |
| 42 public: |
| 43 BackgroundParsingTask(Utf16CharacterStream* stream, |
| 44 bool allow_harmony_scoping, |
| 45 bool allow_modules, |
| 46 bool allow_natives_syntax, |
| 47 bool allow_generators, |
| 48 bool allow_for_of, |
| 49 bool allow_harmony_numeric_literals) |
| 50 : stream_(stream), |
| 51 result_(PreParser::kPreParseSuccess), |
| 52 allow_harmony_scoping_(allow_harmony_scoping), |
| 53 allow_modules_(allow_modules), |
| 54 allow_natives_syntax_(allow_natives_syntax), |
| 55 allow_generators_(allow_generators), |
| 56 allow_for_of_(allow_for_of), |
| 57 allow_harmony_numeric_literals_(allow_harmony_numeric_literals) {} |
| 58 |
| 59 |
| 60 ~BackgroundParsingTask() { |
| 61 delete stream_; |
| 62 } |
| 63 |
| 64 |
| 65 void Produce(int start, int end, int literals, |
| 66 int properties, StrictMode strict_mode) { |
| 67 LockGuard<Mutex> lock_guard(&mutex_); |
| 68 LazyFunction function(start, end, literals, properties, strict_mode); |
| 69 data_.Enqueue(function); |
| 70 have_data_.NotifyOne(); |
| 71 } |
| 72 |
| 73 |
| 74 void Consume(int* start, int* end, int* literals, |
| 75 int* properties, StrictMode* strict_mode) { |
| 76 LockGuard<Mutex> lock_guard(&mutex_); |
| 77 if (data_.IsEmpty()) |
| 78 have_data_.Wait(&mutex_); // Implicitly unlocks and locks the mutex. |
| 79 ASSERT(!data_.IsEmpty()); |
| 80 LazyFunction function; |
| 81 data_.Dequeue(&function); |
| 82 *start = function.start; |
| 83 *end = function.end; |
| 84 *literals = function.literals; |
| 85 *properties = function.properties; |
| 86 *strict_mode = function.strict_mode; |
| 87 } |
| 88 |
| 89 |
| 90 void Run(FastParserThread* thread) { |
| 91 DisallowHeapAllocation no_allocation; |
| 92 DisallowHandleAllocation no_handles; |
| 93 DisallowHandleDereference no_deref; |
| 94 UnicodeCache unicode_cache; |
| 95 Scanner scanner(&unicode_cache); |
| 96 uintptr_t limit = |
| 97 reinterpret_cast<uintptr_t>(&limit) - kFastParserThreadStackSize; |
| 98 PreParser preparser(&scanner, &recorder_, limit, thread); |
| 99 preparser.set_allow_lazy(true); |
| 100 preparser.set_allow_harmony_scoping(allow_harmony_scoping_); |
| 101 preparser.set_allow_modules(allow_modules_); |
| 102 preparser.set_allow_natives_syntax(allow_natives_syntax_); |
| 103 preparser.set_allow_generators(allow_generators_); |
| 104 preparser.set_allow_for_of(allow_for_of_); |
| 105 preparser.set_allow_harmony_numeric_literals( |
| 106 allow_harmony_numeric_literals_); |
| 107 scanner.Initialize(stream_); |
| 108 result_ = preparser.PreParseProgram(); |
| 109 |
| 110 // Queue a dummy data element, so that the Parser doesn't wait forever if it |
| 111 // expects the thread to produce more data than it will. (For example, when |
| 112 // the thread parses a function and encounters an error.) |
| 113 Produce(-1, -1, -1, -1, SLOPPY); |
| 114 } |
| 115 |
| 116 private: |
| 117 friend class FastParserThread; |
| 118 struct LazyFunction { |
| 119 int start; |
| 120 int end; |
| 121 int literals; |
| 122 int properties; |
| 123 StrictMode strict_mode; |
| 124 LazyFunction(int s, int e, int l, int p, StrictMode st) |
| 125 : start(s), end(e), literals(l), properties(p), strict_mode(st) {} |
| 126 LazyFunction() |
| 127 : start(-1), |
| 128 end(-1), |
| 129 literals(-1), |
| 130 properties(-1), |
| 131 strict_mode(SLOPPY) {} |
| 132 }; |
| 133 |
| 134 Utf16CharacterStream* stream_; |
| 135 SingletonLogger recorder_; |
| 136 Mutex mutex_; |
| 137 ConditionVariable have_data_; |
| 138 UnboundQueue<LazyFunction> data_; |
| 139 PreParser::PreParseResult result_; |
| 140 bool allow_harmony_scoping_; |
| 141 bool allow_modules_; |
| 142 bool allow_natives_syntax_; |
| 143 bool allow_generators_; |
| 144 bool allow_for_of_; |
| 145 bool allow_harmony_numeric_literals_; |
| 146 }; |
| 147 |
| 148 |
| 149 FastParserThread::FastParserThread() |
| 150 : Thread( |
| 151 Thread::Options("v8::FastParserThread", kFastParserThreadStackSize)), |
| 152 current_task_(NULL), |
| 153 have_work_(0), |
| 154 work_done_(0), |
| 155 should_stop_(false) {} |
| 156 |
| 157 |
| 158 void FastParserThread::StartBackgroundParsing( |
| 159 Utf16CharacterStream* stream, bool allow_harmony_scoping, |
| 160 bool allow_modules, bool allow_natives_syntax, bool allow_generators, |
| 161 bool allow_for_of, bool allow_harmony_numeric_literals) { |
| 162 ASSERT(current_task_ == NULL); |
| 163 current_task_ = new BackgroundParsingTask( |
| 164 stream, allow_harmony_scoping, allow_modules, allow_natives_syntax, |
| 165 allow_generators, allow_for_of, allow_harmony_numeric_literals); |
| 166 have_work_.Signal(); |
| 167 } |
| 168 |
| 169 |
| 170 void FastParserThread::FinishBackgroundParsing() { |
| 171 work_done_.Wait(); |
| 172 delete current_task_; |
| 173 current_task_ = NULL; |
| 174 } |
| 175 |
| 176 |
| 177 void FastParserThread::Run() { |
| 178 while (true) { |
| 179 have_work_.Wait(); |
| 180 if (should_stop_) { |
| 181 break; |
| 182 } |
| 183 ASSERT(current_task_ != NULL); |
| 184 current_task_->Run(this); |
| 185 work_done_.Signal(); |
| 186 } |
| 187 } |
| 188 |
| 189 |
| 190 void FastParserThread::Stop() { |
| 191 should_stop_ = true; |
| 192 have_work_.Signal(); |
| 193 Join(); |
| 194 } |
| 195 |
| 196 |
| 197 void FastParserThread::Produce(int start, int end, int literals, int properties, |
| 198 StrictMode strict_mode) { |
| 199 ASSERT(current_task_); |
| 200 current_task_->Produce(start, end, literals, properties, strict_mode); |
| 201 } |
| 202 |
| 203 |
| 204 void FastParserThread::Consume(int* start, int* end, int* literals, |
| 205 int* properties, StrictMode* strict_mode) { |
| 206 ASSERT(current_task_); |
| 207 current_task_->Consume(start, end, literals, properties, strict_mode); |
| 208 } |
| 209 |
| 210 |
| 211 PreParser::PreParseResult FastParserThread::result() const { |
| 212 ASSERT(current_task_); |
| 213 return current_task_->result_; |
| 214 } |
| 215 |
| 216 |
| 217 const SingletonLogger* FastParserThread::recorder() const { |
| 218 ASSERT(current_task_); |
| 219 return &(current_task_->recorder_); |
| 220 } |
| 221 |
| 222 |
| 223 } } // namespace v8::internal |
| OLD | NEW |