OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 | 5 |
6 // Defined when linking against shared lib on Windows. | 6 // Defined when linking against shared lib on Windows. |
7 #if defined(USING_V8_SHARED) && !defined(V8_SHARED) | 7 #if defined(USING_V8_SHARED) && !defined(V8_SHARED) |
8 #define V8_SHARED | 8 #define V8_SHARED |
9 #endif | 9 #endif |
10 | 10 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
94 void* data = AllocateUninitialized(actual_length); | 94 void* data = AllocateUninitialized(actual_length); |
95 return data == NULL ? data : memset(data, 0, actual_length); | 95 return data == NULL ? data : memset(data, 0, actual_length); |
96 } | 96 } |
97 void* AllocateUninitialized(size_t length) override { | 97 void* AllocateUninitialized(size_t length) override { |
98 return length > 10 * MB ? malloc(1) : malloc(length); | 98 return length > 10 * MB ? malloc(1) : malloc(length); |
99 } | 99 } |
100 void Free(void* p, size_t) override { free(p); } | 100 void Free(void* p, size_t) override { free(p); } |
101 }; | 101 }; |
102 | 102 |
103 | 103 |
104 class PredictablePlatform : public Platform { | |
105 public: | |
106 PredictablePlatform() {} | |
107 ~PredictablePlatform() override; | |
108 | |
109 bool PumpMessageLoop(v8::Isolate* isolate); | |
110 | |
111 // v8::Platform implementation. This is a cut down version of default | |
112 // platform implementation. All background and foreground tasks are | |
113 // run immediately. Only delayed tasks are put in a queue. | |
114 | |
115 void CallOnBackgroundThread(Task* task, | |
116 ExpectedRuntime expected_runtime) override { | |
117 task->Run(); | |
118 delete task; | |
119 } | |
120 | |
121 void CallOnForegroundThread(v8::Isolate* isolate, Task* task) override { | |
122 task->Run(); | |
123 delete task; | |
124 } | |
125 void CallDelayedOnForegroundThread(v8::Isolate* isolate, Task* task, | |
126 double delay_in_seconds) override; | |
ulan
2015/11/12 11:38:15
Maybe disable memory-reducer in predictable mode?
Igor Sheludko
2015/11/12 11:53:30
Yes, it makes sense to disable the memory reducer
| |
127 | |
128 void CallIdleOnForegroundThread(v8::Isolate* isolate, | |
129 IdleTask* task) override { | |
130 UNREACHABLE(); | |
131 } | |
132 | |
133 bool IdleTasksEnabled(v8::Isolate* isolate) override { return false; } | |
134 | |
135 double MonotonicallyIncreasingTime() override { | |
136 return synthetic_time_in_sec_ += 0.000001; | |
137 } | |
138 | |
139 private: | |
140 Task* PopTaskInMainThreadDelayedQueue(v8::Isolate* isolate); | |
141 | |
142 base::Mutex lock_; | |
143 | |
144 typedef std::pair<double, Task*> DelayedEntry; | |
145 struct DelayedEntryGreater { | |
146 bool operator()(const DelayedEntry& a, const DelayedEntry& b) { | |
147 return a.first > b.first; | |
148 } | |
149 }; | |
150 std::map<v8::Isolate*, | |
151 std::priority_queue<DelayedEntry, std::vector<DelayedEntry>, | |
152 DelayedEntryGreater> > | |
153 main_thread_delayed_queue_; | |
154 | |
155 double synthetic_time_in_sec_ = 0.0; | |
156 | |
157 DISALLOW_COPY_AND_ASSIGN(PredictablePlatform); | |
158 }; | |
159 | |
160 | |
161 PredictablePlatform::~PredictablePlatform() { | |
162 base::LockGuard<base::Mutex> guard(&lock_); | |
163 for (auto i = main_thread_delayed_queue_.begin(); | |
164 i != main_thread_delayed_queue_.end(); ++i) { | |
165 while (!i->second.empty()) { | |
166 delete i->second.top().second; | |
167 i->second.pop(); | |
168 } | |
169 } | |
170 } | |
171 | |
172 | |
173 Task* PredictablePlatform::PopTaskInMainThreadDelayedQueue( | |
174 v8::Isolate* isolate) { | |
175 auto it = main_thread_delayed_queue_.find(isolate); | |
176 if (it == main_thread_delayed_queue_.end() || it->second.empty()) { | |
177 return NULL; | |
178 } | |
179 double now = MonotonicallyIncreasingTime(); | |
180 DelayedEntry deadline_and_task = it->second.top(); | |
181 if (deadline_and_task.first > now) { | |
182 return NULL; | |
183 } | |
184 it->second.pop(); | |
185 return deadline_and_task.second; | |
186 } | |
187 | |
188 | |
189 bool PredictablePlatform::PumpMessageLoop(v8::Isolate* isolate) { | |
190 bool executed = false; | |
191 Task* task = NULL; | |
192 for (;;) { | |
193 { | |
194 base::LockGuard<base::Mutex> guard(&lock_); | |
195 task = PopTaskInMainThreadDelayedQueue(isolate); | |
196 } | |
197 if (task == NULL) break; | |
198 | |
199 executed = true; | |
200 task->Run(); | |
201 delete task; | |
202 } | |
203 return executed; | |
204 } | |
205 | |
206 | |
207 void PredictablePlatform::CallDelayedOnForegroundThread( | |
208 v8::Isolate* isolate, Task* task, double delay_in_seconds) { | |
209 base::LockGuard<base::Mutex> guard(&lock_); | |
210 double deadline = MonotonicallyIncreasingTime() + delay_in_seconds; | |
211 main_thread_delayed_queue_[isolate].push(std::make_pair(deadline, task)); | |
212 } | |
213 | |
214 | |
104 v8::Platform* g_platform = NULL; | 215 v8::Platform* g_platform = NULL; |
105 | 216 |
106 | 217 |
107 static Local<Value> Throw(Isolate* isolate, const char* message) { | 218 static Local<Value> Throw(Isolate* isolate, const char* message) { |
108 return isolate->ThrowException( | 219 return isolate->ThrowException( |
109 String::NewFromUtf8(isolate, message, NewStringType::kNormal) | 220 String::NewFromUtf8(isolate, message, NewStringType::kNormal) |
110 .ToLocalChecked()); | 221 .ToLocalChecked()); |
111 } | 222 } |
112 | 223 |
113 | 224 |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
418 if (index < 0 || index >= realm_count_ || realms_[index].IsEmpty()) { | 529 if (index < 0 || index >= realm_count_ || realms_[index].IsEmpty()) { |
419 Throw(args.GetIsolate(), "Invalid realm index"); | 530 Throw(args.GetIsolate(), "Invalid realm index"); |
420 return -1; | 531 return -1; |
421 } | 532 } |
422 return index; | 533 return index; |
423 } | 534 } |
424 | 535 |
425 | 536 |
426 #ifndef V8_SHARED | 537 #ifndef V8_SHARED |
427 // performance.now() returns a time stamp as double, measured in milliseconds. | 538 // performance.now() returns a time stamp as double, measured in milliseconds. |
428 // When FLAG_verify_predictable mode is enabled it returns current value | 539 // When FLAG_verify_predictable mode is enabled it returns result of |
429 // of Heap::allocations_count(). | 540 // v8::Platform::MonotonicallyIncreasingTime(). |
430 void Shell::PerformanceNow(const v8::FunctionCallbackInfo<v8::Value>& args) { | 541 void Shell::PerformanceNow(const v8::FunctionCallbackInfo<v8::Value>& args) { |
431 if (i::FLAG_verify_predictable) { | 542 if (i::FLAG_verify_predictable) { |
432 Isolate* v8_isolate = args.GetIsolate(); | 543 args.GetReturnValue().Set(g_platform->MonotonicallyIncreasingTime()); |
433 i::Heap* heap = reinterpret_cast<i::Isolate*>(v8_isolate)->heap(); | |
434 args.GetReturnValue().Set(heap->synthetic_time()); | |
435 } else { | 544 } else { |
436 base::TimeDelta delta = | 545 base::TimeDelta delta = |
437 base::TimeTicks::HighResolutionNow() - kInitialTicks; | 546 base::TimeTicks::HighResolutionNow() - kInitialTicks; |
438 args.GetReturnValue().Set(delta.InMillisecondsF()); | 547 args.GetReturnValue().Set(delta.InMillisecondsF()); |
439 } | 548 } |
440 } | 549 } |
441 #endif // !V8_SHARED | 550 #endif // !V8_SHARED |
442 | 551 |
443 | 552 |
444 // Realm.current() returns the index of the currently active realm. | 553 // Realm.current() returns the index of the currently active realm. |
(...skipping 1564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2009 if (options.invoke_weak_callbacks) { | 2118 if (options.invoke_weak_callbacks) { |
2010 // By sending a low memory notifications, we will try hard to collect all | 2119 // By sending a low memory notifications, we will try hard to collect all |
2011 // garbage and will therefore also invoke all weak callbacks of actually | 2120 // garbage and will therefore also invoke all weak callbacks of actually |
2012 // unreachable persistent handles. | 2121 // unreachable persistent handles. |
2013 isolate->LowMemoryNotification(); | 2122 isolate->LowMemoryNotification(); |
2014 } | 2123 } |
2015 } | 2124 } |
2016 | 2125 |
2017 | 2126 |
2018 void Shell::EmptyMessageQueues(Isolate* isolate) { | 2127 void Shell::EmptyMessageQueues(Isolate* isolate) { |
2019 while (v8::platform::PumpMessageLoop(g_platform, isolate)) continue; | 2128 if (i::FLAG_verify_predictable) { |
2129 PredictablePlatform* platform = | |
2130 reinterpret_cast<PredictablePlatform*>(g_platform); | |
2131 while (platform->PumpMessageLoop(isolate)) continue; | |
2132 } else { | |
2133 while (v8::platform::PumpMessageLoop(g_platform, isolate)) continue; | |
2134 } | |
2020 } | 2135 } |
2021 | 2136 |
2022 | 2137 |
2023 #ifndef V8_SHARED | 2138 #ifndef V8_SHARED |
2024 bool Shell::SerializeValue(Isolate* isolate, Local<Value> value, | 2139 bool Shell::SerializeValue(Isolate* isolate, Local<Value> value, |
2025 const ObjectList& to_transfer, | 2140 const ObjectList& to_transfer, |
2026 ObjectList* seen_objects, | 2141 ObjectList* seen_objects, |
2027 SerializationData* out_data) { | 2142 SerializationData* out_data) { |
2028 DCHECK(out_data); | 2143 DCHECK(out_data); |
2029 Local<Context> context = isolate->GetCurrentContext(); | 2144 Local<Context> context = isolate->GetCurrentContext(); |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2351 _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); | 2466 _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); |
2352 _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE); | 2467 _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE); |
2353 _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); | 2468 _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); |
2354 _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE); | 2469 _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE); |
2355 _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); | 2470 _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); |
2356 _set_error_mode(_OUT_TO_STDERR); | 2471 _set_error_mode(_OUT_TO_STDERR); |
2357 #endif // defined(_MSC_VER) | 2472 #endif // defined(_MSC_VER) |
2358 #endif // defined(_WIN32) || defined(_WIN64) | 2473 #endif // defined(_WIN32) || defined(_WIN64) |
2359 if (!SetOptions(argc, argv)) return 1; | 2474 if (!SetOptions(argc, argv)) return 1; |
2360 v8::V8::InitializeICU(options.icu_data_file); | 2475 v8::V8::InitializeICU(options.icu_data_file); |
2361 g_platform = v8::platform::CreateDefaultPlatform(); | 2476 g_platform = i::FLAG_verify_predictable |
2477 ? new PredictablePlatform() | |
2478 : v8::platform::CreateDefaultPlatform(); | |
2362 v8::V8::InitializePlatform(g_platform); | 2479 v8::V8::InitializePlatform(g_platform); |
2363 v8::V8::Initialize(); | 2480 v8::V8::Initialize(); |
2364 if (options.natives_blob || options.snapshot_blob) { | 2481 if (options.natives_blob || options.snapshot_blob) { |
2365 v8::V8::InitializeExternalStartupData(options.natives_blob, | 2482 v8::V8::InitializeExternalStartupData(options.natives_blob, |
2366 options.snapshot_blob); | 2483 options.snapshot_blob); |
2367 } else { | 2484 } else { |
2368 v8::V8::InitializeExternalStartupData(argv[0]); | 2485 v8::V8::InitializeExternalStartupData(argv[0]); |
2369 } | 2486 } |
2370 SetFlagsFromString("--trace-hydrogen-file=hydrogen.cfg"); | 2487 SetFlagsFromString("--trace-hydrogen-file=hydrogen.cfg"); |
2371 SetFlagsFromString("--trace-turbo-cfg-file=turbo.cfg"); | 2488 SetFlagsFromString("--trace-turbo-cfg-file=turbo.cfg"); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2476 } | 2593 } |
2477 | 2594 |
2478 } // namespace v8 | 2595 } // namespace v8 |
2479 | 2596 |
2480 | 2597 |
2481 #ifndef GOOGLE3 | 2598 #ifndef GOOGLE3 |
2482 int main(int argc, char* argv[]) { | 2599 int main(int argc, char* argv[]) { |
2483 return v8::Shell::Main(argc, argv); | 2600 return v8::Shell::Main(argc, argv); |
2484 } | 2601 } |
2485 #endif | 2602 #endif |
OLD | NEW |