Chromium Code Reviews| 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 |