Chromium Code Reviews| 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 void Produce(int start, int end, int literals, | |
| 61 int properties, StrictMode strict_mode) { | |
| 62 LockGuard<Mutex> lock_guard(&mutex_); | |
| 63 LazyFunction function(start, end, literals, properties, strict_mode); | |
| 64 data_.Enqueue(function); | |
| 65 have_data_.NotifyOne(); | |
| 66 } | |
| 67 | |
| 68 | |
| 69 void Consume(int* start, int* end, int* literals, | |
| 70 int* properties, StrictMode* strict_mode) { | |
| 71 LockGuard<Mutex> lock_guard(&mutex_); | |
| 72 if (data_.IsEmpty()) | |
| 73 have_data_.Wait(&mutex_); // Implicitly unlocks and locks the mutex. | |
| 74 ASSERT(!data_.IsEmpty()); | |
| 75 LazyFunction function; | |
| 76 data_.Dequeue(&function); | |
| 77 *start = function.start; | |
| 78 *end = function.end; | |
| 79 *literals = function.literals; | |
| 80 *properties = function.properties; | |
| 81 *strict_mode = function.strict_mode; | |
| 82 } | |
| 83 | |
| 84 | |
| 85 void Run(FastParserThread* thread) { | |
| 86 DisallowHeapAllocation no_allocation; | |
| 87 DisallowHandleAllocation no_handles; | |
| 88 DisallowHandleDereference no_deref; | |
| 89 UnicodeCache unicode_cache; | |
| 90 Scanner scanner(&unicode_cache); | |
| 91 uintptr_t limit = | |
| 92 reinterpret_cast<uintptr_t>(&limit) - kFastParserThreadStackSize; | |
| 93 PreParser preparser(&scanner, &recorder_, limit, thread); | |
| 94 preparser.set_allow_lazy(true); | |
|
ulan
2014/04/23 10:18:20
Would it be worthwhile to put these flags into a s
Sven Panne
2014/04/23 10:36:29
+1 for this proposal, see http://refactoring.com/c
| |
| 95 preparser.set_allow_harmony_scoping(allow_harmony_scoping_); | |
| 96 preparser.set_allow_modules(allow_modules_); | |
| 97 preparser.set_allow_natives_syntax(allow_natives_syntax_); | |
| 98 preparser.set_allow_generators(allow_generators_); | |
| 99 preparser.set_allow_for_of(allow_for_of_); | |
| 100 preparser.set_allow_harmony_numeric_literals( | |
| 101 allow_harmony_numeric_literals_); | |
| 102 scanner.Initialize(stream_); | |
| 103 result_ = preparser.PreParseProgram(); | |
| 104 | |
| 105 // Queue a dummy data element, so that the Parser doesn't wait forever if it | |
| 106 // expects the thread to produce more data than it will. (For example, when | |
| 107 // the thread parses a function and encounters an error.) | |
| 108 Produce(-1, -1, -1, -1, SLOPPY); | |
| 109 } | |
| 110 | |
| 111 private: | |
| 112 friend class FastParserThread; | |
| 113 struct LazyFunction { | |
| 114 int start; | |
| 115 int end; | |
| 116 int literals; | |
| 117 int properties; | |
| 118 StrictMode strict_mode; | |
| 119 LazyFunction(int s, int e, int l, int p, StrictMode st) | |
| 120 : start(s), end(e), literals(l), properties(p), strict_mode(st) {} | |
| 121 LazyFunction() | |
| 122 : start(-1), | |
| 123 end(-1), | |
| 124 literals(-1), | |
| 125 properties(-1), | |
| 126 strict_mode(SLOPPY) {} | |
| 127 }; | |
| 128 | |
| 129 Utf16CharacterStream* stream_; | |
| 130 SingletonLogger recorder_; | |
| 131 Mutex mutex_; | |
| 132 ConditionVariable have_data_; | |
| 133 UnboundQueue<LazyFunction> data_; | |
| 134 PreParser::PreParseResult result_; | |
| 135 bool allow_harmony_scoping_; | |
| 136 bool allow_modules_; | |
| 137 bool allow_natives_syntax_; | |
| 138 bool allow_generators_; | |
| 139 bool allow_for_of_; | |
| 140 bool allow_harmony_numeric_literals_; | |
| 141 }; | |
| 142 | |
| 143 | |
| 144 FastParserThread::FastParserThread() | |
| 145 : Thread( | |
| 146 Thread::Options("v8::FastParserThread", kFastParserThreadStackSize)), | |
| 147 current_task_(NULL), | |
| 148 have_work_(0), | |
| 149 work_done_(0), | |
| 150 should_stop_(false) {} | |
| 151 | |
| 152 | |
| 153 void FastParserThread::StartBackgroundParsing( | |
| 154 Utf16CharacterStream* stream, bool allow_harmony_scoping, | |
| 155 bool allow_modules, bool allow_natives_syntax, bool allow_generators, | |
| 156 bool allow_for_of, bool allow_harmony_numeric_literals) { | |
| 157 ASSERT(current_task_ == NULL); | |
| 158 current_task_ = new BackgroundParsingTask( | |
| 159 stream, allow_harmony_scoping, allow_modules, allow_natives_syntax, | |
| 160 allow_generators, allow_for_of, allow_harmony_numeric_literals); | |
| 161 have_work_.Signal(); | |
| 162 } | |
| 163 | |
| 164 | |
| 165 void FastParserThread::FinishBackgroundParsing() { | |
| 166 work_done_.Wait(); | |
| 167 delete current_task_; | |
|
Michael Starzinger
2014/04/23 09:07:10
This deletes the background parsing task, but I ca
| |
| 168 current_task_ = NULL; | |
| 169 } | |
| 170 | |
| 171 | |
| 172 void FastParserThread::Run() { | |
| 173 while (true) { | |
| 174 have_work_.Wait(); | |
| 175 if (should_stop_) { | |
| 176 break; | |
| 177 } | |
| 178 ASSERT(current_task_ != NULL); | |
| 179 current_task_->Run(this); | |
| 180 work_done_.Signal(); | |
| 181 } | |
| 182 } | |
| 183 | |
| 184 | |
| 185 void FastParserThread::Stop() { | |
| 186 should_stop_ = true; | |
| 187 have_work_.Signal(); | |
| 188 Join(); | |
| 189 } | |
| 190 | |
| 191 | |
| 192 void FastParserThread::Produce(int start, int end, int literals, int properties, | |
| 193 StrictMode strict_mode) { | |
| 194 ASSERT(current_task_); | |
| 195 current_task_->Produce(start, end, literals, properties, strict_mode); | |
| 196 } | |
| 197 | |
| 198 | |
| 199 void FastParserThread::Consume(int* start, int* end, int* literals, | |
| 200 int* properties, StrictMode* strict_mode) { | |
| 201 ASSERT(current_task_); | |
| 202 current_task_->Consume(start, end, literals, properties, strict_mode); | |
| 203 } | |
| 204 | |
| 205 | |
| 206 PreParser::PreParseResult FastParserThread::result() const { | |
| 207 ASSERT(current_task_); | |
| 208 return current_task_->result_; | |
| 209 } | |
| 210 | |
| 211 | |
| 212 const SingletonLogger* FastParserThread::recorder() const { | |
| 213 ASSERT(current_task_); | |
| 214 return &(current_task_->recorder_); | |
| 215 } | |
| 216 | |
| 217 | |
| 218 } } // namespace v8::internal | |
| OLD | NEW |