Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(208)

Unified Diff: src/d8.cc

Issue 1415383004: Fixing --verify-predictable mode. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: d8 now uses its own PredictablePlatform implementation Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/execution.cc » ('j') | src/heap/heap-inl.h » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/d8.cc
diff --git a/src/d8.cc b/src/d8.cc
index b73ab0bd6a6be5b171a1c1258d65e05c0c8f079f..398eaead9c6bd0793ce95bf3971797d63ac9800c 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -101,6 +101,117 @@ class MockArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
};
+class PredictablePlatform : public Platform {
+ public:
+ PredictablePlatform() {}
+ ~PredictablePlatform() override;
+
+ bool PumpMessageLoop(v8::Isolate* isolate);
+
+ // v8::Platform implementation. This is a cut down version of default
+ // platform implementation. All background and foreground tasks are
+ // run immediately. Only delayed tasks are put in a queue.
+
+ void CallOnBackgroundThread(Task* task,
+ ExpectedRuntime expected_runtime) override {
+ task->Run();
+ delete task;
+ }
+
+ void CallOnForegroundThread(v8::Isolate* isolate, Task* task) override {
+ task->Run();
+ delete task;
+ }
+ void CallDelayedOnForegroundThread(v8::Isolate* isolate, Task* task,
+ 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
+
+ void CallIdleOnForegroundThread(v8::Isolate* isolate,
+ IdleTask* task) override {
+ UNREACHABLE();
+ }
+
+ bool IdleTasksEnabled(v8::Isolate* isolate) override { return false; }
+
+ double MonotonicallyIncreasingTime() override {
+ return synthetic_time_in_sec_ += 0.000001;
+ }
+
+ private:
+ Task* PopTaskInMainThreadDelayedQueue(v8::Isolate* isolate);
+
+ base::Mutex lock_;
+
+ typedef std::pair<double, Task*> DelayedEntry;
+ struct DelayedEntryGreater {
+ bool operator()(const DelayedEntry& a, const DelayedEntry& b) {
+ return a.first > b.first;
+ }
+ };
+ std::map<v8::Isolate*,
+ std::priority_queue<DelayedEntry, std::vector<DelayedEntry>,
+ DelayedEntryGreater> >
+ main_thread_delayed_queue_;
+
+ double synthetic_time_in_sec_ = 0.0;
+
+ DISALLOW_COPY_AND_ASSIGN(PredictablePlatform);
+};
+
+
+PredictablePlatform::~PredictablePlatform() {
+ base::LockGuard<base::Mutex> guard(&lock_);
+ for (auto i = main_thread_delayed_queue_.begin();
+ i != main_thread_delayed_queue_.end(); ++i) {
+ while (!i->second.empty()) {
+ delete i->second.top().second;
+ i->second.pop();
+ }
+ }
+}
+
+
+Task* PredictablePlatform::PopTaskInMainThreadDelayedQueue(
+ v8::Isolate* isolate) {
+ auto it = main_thread_delayed_queue_.find(isolate);
+ if (it == main_thread_delayed_queue_.end() || it->second.empty()) {
+ return NULL;
+ }
+ double now = MonotonicallyIncreasingTime();
+ DelayedEntry deadline_and_task = it->second.top();
+ if (deadline_and_task.first > now) {
+ return NULL;
+ }
+ it->second.pop();
+ return deadline_and_task.second;
+}
+
+
+bool PredictablePlatform::PumpMessageLoop(v8::Isolate* isolate) {
+ bool executed = false;
+ Task* task = NULL;
+ for (;;) {
+ {
+ base::LockGuard<base::Mutex> guard(&lock_);
+ task = PopTaskInMainThreadDelayedQueue(isolate);
+ }
+ if (task == NULL) break;
+
+ executed = true;
+ task->Run();
+ delete task;
+ }
+ return executed;
+}
+
+
+void PredictablePlatform::CallDelayedOnForegroundThread(
+ v8::Isolate* isolate, Task* task, double delay_in_seconds) {
+ base::LockGuard<base::Mutex> guard(&lock_);
+ double deadline = MonotonicallyIncreasingTime() + delay_in_seconds;
+ main_thread_delayed_queue_[isolate].push(std::make_pair(deadline, task));
+}
+
+
v8::Platform* g_platform = NULL;
@@ -425,13 +536,11 @@ int PerIsolateData::RealmIndexOrThrow(
#ifndef V8_SHARED
// performance.now() returns a time stamp as double, measured in milliseconds.
-// When FLAG_verify_predictable mode is enabled it returns current value
-// of Heap::allocations_count().
+// When FLAG_verify_predictable mode is enabled it returns result of
+// v8::Platform::MonotonicallyIncreasingTime().
void Shell::PerformanceNow(const v8::FunctionCallbackInfo<v8::Value>& args) {
if (i::FLAG_verify_predictable) {
- Isolate* v8_isolate = args.GetIsolate();
- i::Heap* heap = reinterpret_cast<i::Isolate*>(v8_isolate)->heap();
- args.GetReturnValue().Set(heap->synthetic_time());
+ args.GetReturnValue().Set(g_platform->MonotonicallyIncreasingTime());
} else {
base::TimeDelta delta =
base::TimeTicks::HighResolutionNow() - kInitialTicks;
@@ -2016,7 +2125,13 @@ void Shell::CollectGarbage(Isolate* isolate) {
void Shell::EmptyMessageQueues(Isolate* isolate) {
- while (v8::platform::PumpMessageLoop(g_platform, isolate)) continue;
+ if (i::FLAG_verify_predictable) {
+ PredictablePlatform* platform =
+ reinterpret_cast<PredictablePlatform*>(g_platform);
+ while (platform->PumpMessageLoop(isolate)) continue;
+ } else {
+ while (v8::platform::PumpMessageLoop(g_platform, isolate)) continue;
+ }
}
@@ -2358,7 +2473,9 @@ int Shell::Main(int argc, char* argv[]) {
#endif // defined(_WIN32) || defined(_WIN64)
if (!SetOptions(argc, argv)) return 1;
v8::V8::InitializeICU(options.icu_data_file);
- g_platform = v8::platform::CreateDefaultPlatform();
+ g_platform = i::FLAG_verify_predictable
+ ? new PredictablePlatform()
+ : v8::platform::CreateDefaultPlatform();
v8::V8::InitializePlatform(g_platform);
v8::V8::Initialize();
if (options.natives_blob || options.snapshot_blob) {
« no previous file with comments | « no previous file | src/execution.cc » ('j') | src/heap/heap-inl.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698