Commit 7c2aef08 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[d8] Add --stress-delay-tasks flag

This flag stresses different interleavings of background and foreground
tasks by delaying the execution of each task by a random value between
0 and 100ms (with a quadratic distribution favoring smaller delayes).

The implementation is encapsulated in the new {DelayedTasksPlatform}
class, which wraps each task in a {DelayedTask} which first sleeps for
the given number of microseconds, then executes the actual task.

Both the old {PredictablePlatform} and the new {DelayedTasksPlatform}
are moved to the new d8-platforms.cc file with an interface to create
them in d8-platforms.h.

R=yangguo@chromium.org, mslekova@chromium.org

Bug: v8:8278
Change-Id: I5847fb2da31ffde773195da7ad3f56a0390cc05b
Reviewed-on: https://chromium-review.googlesource.com/c/1270592
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56496}
parent 96fba5f3
......@@ -3550,6 +3550,8 @@ v8_executable("d8") {
"src/async-hooks-wrapper.h",
"src/d8-console.cc",
"src/d8-console.h",
"src/d8-platforms.cc",
"src/d8-platforms.h",
"src/d8.cc",
"src/d8.h",
]
......
This diff is collapsed.
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_D8_PLATFORMS_H_
#define V8_D8_PLATFORMS_H_
#include <cstdint>
#include <memory>
namespace v8 {
class Platform;
// Returns a predictable v8::Platform implementation.
// orker threads are disabled, idle tasks are disallowed, and the time reported
// by {MonotonicallyIncreasingTime} is deterministic.
std::unique_ptr<Platform> MakePredictablePlatform(
std::unique_ptr<Platform> platform);
// Returns a v8::Platform implementation which randomly delays tasks (both
// foreground and background) for stress-testing different interleavings.
// If {random_seed} is 0, a random seed is chosen.
std::unique_ptr<Platform> MakeDelayedTasksPlatform(
std::unique_ptr<Platform> platform, int64_t random_seed);
} // namespace v8
#endif // V8_D8_PLATFORMS_H_
/// Copyright 2012 the V8 project authors. All rights reserved.
// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
......@@ -17,10 +17,6 @@
#include "src/third_party/vtune/v8-vtune.h"
#endif
#include "src/d8-console.h"
#include "src/d8.h"
#include "src/ostreams.h"
#include "include/libplatform/libplatform.h"
#include "include/libplatform/v8-tracing.h"
#include "include/v8-inspector.h"
......@@ -31,11 +27,15 @@
#include "src/base/platform/time.h"
#include "src/base/sys-info.h"
#include "src/basic-block-profiler.h"
#include "src/d8-console.h"
#include "src/d8-platforms.h"
#include "src/d8.h"
#include "src/debug/debug-interface.h"
#include "src/interpreter/interpreter.h"
#include "src/msan.h"
#include "src/objects-inl.h"
#include "src/objects.h"
#include "src/ostreams.h"
#include "src/snapshot/natives.h"
#include "src/trap-handler/trap-handler.h"
#include "src/utils.h"
......@@ -190,92 +190,9 @@ class MockArrayBufferAllocatiorWithLimit : public MockArrayBufferAllocator {
std::atomic<size_t> space_left_;
};
// Predictable v8::Platform implementation. Worker threads are disabled, idle
// tasks are disallowed, and the time reported by {MonotonicallyIncreasingTime}
// is deterministic.
class PredictablePlatform : public Platform {
public:
explicit PredictablePlatform(std::unique_ptr<Platform> platform)
: platform_(std::move(platform)) {
DCHECK_NOT_NULL(platform_);
}
PageAllocator* GetPageAllocator() override {
return platform_->GetPageAllocator();
}
void OnCriticalMemoryPressure() override {
platform_->OnCriticalMemoryPressure();
}
bool OnCriticalMemoryPressure(size_t length) override {
return platform_->OnCriticalMemoryPressure(length);
}
std::shared_ptr<TaskRunner> GetForegroundTaskRunner(
v8::Isolate* isolate) override {
return platform_->GetForegroundTaskRunner(isolate);
}
int NumberOfWorkerThreads() override { return 0; }
void CallOnWorkerThread(std::unique_ptr<Task> task) override {
// It's not defined when background tasks are being executed, so we can just
// execute them right away.
task->Run();
}
void CallDelayedOnWorkerThread(std::unique_ptr<Task> task,
double delay_in_seconds) override {
// Never run delayed tasks.
}
void CallOnForegroundThread(v8::Isolate* isolate, Task* task) override {
// This is a deprecated function and should not be called anymore.
UNREACHABLE();
}
void CallDelayedOnForegroundThread(v8::Isolate* isolate, Task* task,
double delay_in_seconds) override {
// This is a deprecated function and should not be called anymore.
UNREACHABLE();
}
void CallIdleOnForegroundThread(Isolate* isolate, IdleTask* task) override {
UNREACHABLE();
}
bool IdleTasksEnabled(Isolate* isolate) override { return false; }
double MonotonicallyIncreasingTime() override {
return synthetic_time_in_sec_ += 0.00001;
}
double CurrentClockTimeMillis() override {
return MonotonicallyIncreasingTime() * base::Time::kMillisecondsPerSecond;
}
v8::TracingController* GetTracingController() override {
return platform_->GetTracingController();
}
Platform* platform() const { return platform_.get(); }
private:
double synthetic_time_in_sec_ = 0.0;
std::unique_ptr<Platform> platform_;
DISALLOW_COPY_AND_ASSIGN(PredictablePlatform);
};
v8::Platform* g_default_platform;
std::unique_ptr<v8::Platform> g_platform;
v8::Platform* GetDefaultPlatform() {
return i::FLAG_verify_predictable
? static_cast<PredictablePlatform*>(g_platform.get())->platform()
: g_platform.get();
}
static Local<Value> Throw(Isolate* isolate, const char* message) {
return isolate->ThrowException(
String::NewFromUtf8(isolate, message, NewStringType::kNormal)
......@@ -3077,17 +2994,17 @@ namespace {
bool ProcessMessages(
Isolate* isolate,
const std::function<platform::MessageLoopBehavior()>& behavior) {
Platform* platform = GetDefaultPlatform();
while (true) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
i::SaveContext saved_context(i_isolate);
i_isolate->set_context(nullptr);
SealHandleScope shs(isolate);
while (v8::platform::PumpMessageLoop(platform, isolate, behavior())) {
while (v8::platform::PumpMessageLoop(g_default_platform, isolate,
behavior())) {
isolate->RunMicrotasks();
}
if (platform->IdleTasksEnabled(isolate)) {
v8::platform::RunIdleTasks(platform, isolate,
if (g_default_platform->IdleTasksEnabled(isolate)) {
v8::platform::RunIdleTasks(g_default_platform, isolate,
50.0 / base::Time::kMillisecondsPerSecond);
}
HandleScope handle_scope(isolate);
......@@ -3426,8 +3343,16 @@ int Shell::Main(int argc, char* argv[]) {
g_platform = v8::platform::NewDefaultPlatform(
options.thread_pool_size, v8::platform::IdleTaskSupport::kEnabled,
in_process_stack_dumping, std::move(tracing));
g_default_platform = g_platform.get();
if (i::FLAG_verify_predictable) {
g_platform.reset(new PredictablePlatform(std::move(g_platform)));
g_platform = MakePredictablePlatform(std::move(g_platform));
}
if (i::FLAG_stress_delay_tasks) {
int64_t random_seed = i::FLAG_fuzzer_random_seed;
if (!random_seed) random_seed = i::FLAG_random_seed;
// If random_seed is still 0 here, the {DelayedTasksPlatform} will choose a
// random seed.
g_platform = MakeDelayedTasksPlatform(std::move(g_platform), random_seed);
}
if (i::FLAG_trace_turbo_cfg_file == nullptr) {
......
......@@ -335,6 +335,11 @@ DEFINE_VALUE_IMPLICATION(optimize_for_size, max_semi_space_size, 1)
DEFINE_BOOL(unbox_double_arrays, true, "automatically unbox arrays of doubles")
DEFINE_BOOL_READONLY(string_slices, true, "use string slices")
// Flag to stress different interleavings of tasks.
DEFINE_BOOL(
stress_delay_tasks, false,
"delay execution of tasks by 0-100ms randomly (based on --random-seed)")
// Flags for Ignition for no-snapshot builds.
#undef FLAG
#ifndef V8_USE_SNAPSHOT
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment