Skip to content

Commit d727680

Browse files
backesCommit Bot
authored andcommitted
[d8] Bring PredictablePlatform in line with default platform
This removes a lot of special handling for the predictable platform. Instead of executing spawned foreground and background tasks immediately (i.e. inside the scope that spawns the tasks), just add both to the foreground task queue. This avoids existing special handling for predictable mode in wasm async compilation, and should fix current failures on the predictable bot. BUG=v8:6427 Change-Id: Idbaa764a3dc8c230c29f3937d885e12174691ac4 Reviewed-on: https://chromium-review.googlesource.com/509694 Reviewed-by: Jochen Eisinger <jochen@chromium.org> Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Cr-Commit-Position: refs/heads/master@{#45538}
1 parent 6b31174 commit d727680

3 files changed

Lines changed: 56 additions & 86 deletions

File tree

src/d8.cc

Lines changed: 43 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -192,72 +192,61 @@ class MockArrayBufferAllocator : public ArrayBufferAllocatorBase {
192192
}
193193
};
194194

195-
196-
// Predictable v8::Platform implementation. All background and foreground
197-
// tasks are run immediately, delayed tasks are not executed at all.
195+
// Predictable v8::Platform implementation. Background tasks and idle tasks are
196+
// disallowed, and the time reported by {MonotonicallyIncreasingTime} is
197+
// deterministic.
198198
class PredictablePlatform : public Platform {
199199
public:
200-
PredictablePlatform() {}
200+
explicit PredictablePlatform(std::unique_ptr<Platform> platform)
201+
: platform_(std::move(platform)) {
202+
DCHECK_NOT_NULL(platform_);
203+
}
201204

202205
void CallOnBackgroundThread(Task* task,
203206
ExpectedRuntime expected_runtime) override {
207+
// It's not defined when background tasks are being executed, so we can just
208+
// execute them right away.
204209
task->Run();
205210
delete task;
206211
}
207212

208213
void CallOnForegroundThread(v8::Isolate* isolate, Task* task) override {
209-
task->Run();
210-
delete task;
214+
platform_->CallOnForegroundThread(isolate, task);
211215
}
212216

213217
void CallDelayedOnForegroundThread(v8::Isolate* isolate, Task* task,
214218
double delay_in_seconds) override {
215-
delete task;
219+
platform_->CallDelayedOnForegroundThread(isolate, task, delay_in_seconds);
216220
}
217221

218-
void CallIdleOnForegroundThread(v8::Isolate* isolate,
219-
IdleTask* task) override {
222+
void CallIdleOnForegroundThread(Isolate* isolate, IdleTask* task) override {
220223
UNREACHABLE();
221224
}
222225

223-
bool IdleTasksEnabled(v8::Isolate* isolate) override { return false; }
226+
bool IdleTasksEnabled(Isolate* isolate) override { return false; }
224227

225228
double MonotonicallyIncreasingTime() override {
226229
return synthetic_time_in_sec_ += 0.00001;
227230
}
228231

229-
using Platform::AddTraceEvent;
230-
uint64_t AddTraceEvent(char phase, const uint8_t* categoryEnabledFlag,
231-
const char* name, const char* scope, uint64_t id,
232-
uint64_t bind_id, int numArgs, const char** argNames,
233-
const uint8_t* argTypes, const uint64_t* argValues,
234-
unsigned int flags) override {
235-
return 0;
236-
}
237-
238-
void UpdateTraceEventDuration(const uint8_t* categoryEnabledFlag,
239-
const char* name, uint64_t handle) override {}
240-
241-
const uint8_t* GetCategoryGroupEnabled(const char* name) override {
242-
static uint8_t no = 0;
243-
return &no;
244-
}
245-
246-
const char* GetCategoryGroupName(
247-
const uint8_t* categoryEnabledFlag) override {
248-
static const char* dummy = "dummy";
249-
return dummy;
250-
}
232+
Platform* platform() const { return platform_.get(); }
251233

252234
private:
253235
double synthetic_time_in_sec_ = 0.0;
236+
std::unique_ptr<Platform> platform_;
254237

255238
DISALLOW_COPY_AND_ASSIGN(PredictablePlatform);
256239
};
257240

258241

259242
v8::Platform* g_platform = NULL;
260243

244+
v8::Platform* GetDefaultPlatform() {
245+
return i::FLAG_verify_predictable
246+
? static_cast<PredictablePlatform*>(g_platform)->platform()
247+
: g_platform;
248+
}
249+
261250
static Local<Value> Throw(Isolate* isolate, const char* message) {
262251
return isolate->ThrowException(
263252
String::NewFromUtf8(isolate, message, NewStringType::kNormal)
@@ -1386,8 +1375,6 @@ void Shell::Quit(const v8::FunctionCallbackInfo<v8::Value>& args) {
13861375
const_cast<v8::FunctionCallbackInfo<v8::Value>*>(&args));
13871376
}
13881377

1389-
// Note that both WaitUntilDone and NotifyDone are no-op when
1390-
// --verify-predictable. See comment in Shell::EnsureEventLoopInitialized.
13911378
void Shell::WaitUntilDone(const v8::FunctionCallbackInfo<v8::Value>& args) {
13921379
SetWaitUntilDone(args.GetIsolate(), true);
13931380
}
@@ -2764,13 +2751,8 @@ void Shell::CollectGarbage(Isolate* isolate) {
27642751
}
27652752

27662753
void Shell::EnsureEventLoopInitialized(Isolate* isolate) {
2767-
// When using PredictablePlatform (i.e. FLAG_verify_predictable),
2768-
// we don't need event loop support, because tasks are completed
2769-
// immediately - both background and foreground ones.
2770-
if (!i::FLAG_verify_predictable) {
2771-
v8::platform::EnsureEventLoopInitialized(g_platform, isolate);
2772-
SetWaitUntilDone(isolate, false);
2773-
}
2754+
v8::platform::EnsureEventLoopInitialized(GetDefaultPlatform(), isolate);
2755+
SetWaitUntilDone(isolate, false);
27742756
}
27752757

27762758
void Shell::SetWaitUntilDone(Isolate* isolate, bool value) {
@@ -2789,29 +2771,32 @@ bool Shell::IsWaitUntilDone(Isolate* isolate) {
27892771
}
27902772

27912773
void Shell::CompleteMessageLoop(Isolate* isolate) {
2792-
// See comment in EnsureEventLoopInitialized.
2793-
if (i::FLAG_verify_predictable) return;
2774+
Platform* platform = GetDefaultPlatform();
27942775
while (v8::platform::PumpMessageLoop(
2795-
g_platform, isolate,
2776+
platform, isolate,
27962777
Shell::IsWaitUntilDone(isolate)
27972778
? platform::MessageLoopBehavior::kWaitForWork
27982779
: platform::MessageLoopBehavior::kDoNotWait)) {
27992780
isolate->RunMicrotasks();
28002781
}
2801-
v8::platform::RunIdleTasks(g_platform, isolate,
2802-
50.0 / base::Time::kMillisecondsPerSecond);
2782+
if (platform->IdleTasksEnabled(isolate)) {
2783+
v8::platform::RunIdleTasks(platform, isolate,
2784+
50.0 / base::Time::kMillisecondsPerSecond);
2785+
}
28032786
}
28042787

28052788
void Shell::EmptyMessageQueues(Isolate* isolate) {
2806-
if (i::FLAG_verify_predictable) return;
2789+
Platform* platform = GetDefaultPlatform();
28072790
// Pump the message loop until it is empty.
28082791
while (v8::platform::PumpMessageLoop(
2809-
g_platform, isolate, platform::MessageLoopBehavior::kDoNotWait)) {
2792+
platform, isolate, platform::MessageLoopBehavior::kDoNotWait)) {
28102793
isolate->RunMicrotasks();
28112794
}
28122795
// Run the idle tasks.
2813-
v8::platform::RunIdleTasks(g_platform, isolate,
2814-
50.0 / base::Time::kMillisecondsPerSecond);
2796+
if (platform->IdleTasksEnabled(isolate)) {
2797+
v8::platform::RunIdleTasks(platform, isolate,
2798+
50.0 / base::Time::kMillisecondsPerSecond);
2799+
}
28152800
}
28162801

28172802
class Serializer : public ValueSerializer::Delegate {
@@ -3069,24 +3054,22 @@ int Shell::Main(int argc, char* argv[]) {
30693054
? v8::platform::InProcessStackDumping::kDisabled
30703055
: v8::platform::InProcessStackDumping::kEnabled;
30713056

3072-
g_platform = i::FLAG_verify_predictable
3073-
? new PredictablePlatform()
3074-
: v8::platform::CreateDefaultPlatform(
3075-
0, v8::platform::IdleTaskSupport::kEnabled,
3076-
in_process_stack_dumping);
3057+
g_platform = v8::platform::CreateDefaultPlatform(
3058+
0, v8::platform::IdleTaskSupport::kEnabled, in_process_stack_dumping);
3059+
if (i::FLAG_verify_predictable) {
3060+
g_platform = new PredictablePlatform(std::unique_ptr<Platform>(g_platform));
3061+
}
30773062

30783063
platform::tracing::TracingController* tracing_controller;
3079-
if (options.trace_enabled) {
3064+
if (options.trace_enabled && !i::FLAG_verify_predictable) {
30803065
trace_file.open("v8_trace.json");
30813066
tracing_controller = new platform::tracing::TracingController();
30823067
platform::tracing::TraceBuffer* trace_buffer =
30833068
platform::tracing::TraceBuffer::CreateTraceBufferRingBuffer(
30843069
platform::tracing::TraceBuffer::kRingBufferChunks,
30853070
platform::tracing::TraceWriter::CreateJSONTraceWriter(trace_file));
30863071
tracing_controller->Initialize(trace_buffer);
3087-
if (!i::FLAG_verify_predictable) {
3088-
platform::SetTracingController(g_platform, tracing_controller);
3089-
}
3072+
platform::SetTracingController(g_platform, tracing_controller);
30903073
}
30913074

30923075
v8::V8::InitializePlatform(g_platform);
@@ -3135,6 +3118,7 @@ int Shell::Main(int argc, char* argv[]) {
31353118
}
31363119

31373120
Isolate* isolate = Isolate::New(create_params);
3121+
31383122
D8Console console(isolate);
31393123
{
31403124
Isolate::Scope scope(isolate);
@@ -3204,9 +3188,6 @@ int Shell::Main(int argc, char* argv[]) {
32043188
V8::Dispose();
32053189
V8::ShutdownPlatform();
32063190
delete g_platform;
3207-
if (i::FLAG_verify_predictable) {
3208-
delete tracing_controller;
3209-
}
32103191

32113192
return result;
32123193
}

src/libplatform/default-platform.cc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,25 +43,25 @@ v8::Platform* CreateDefaultPlatform(
4343

4444
bool PumpMessageLoop(v8::Platform* platform, v8::Isolate* isolate,
4545
MessageLoopBehavior behavior) {
46-
return reinterpret_cast<DefaultPlatform*>(platform)->PumpMessageLoop(
47-
isolate, behavior);
46+
return static_cast<DefaultPlatform*>(platform)->PumpMessageLoop(isolate,
47+
behavior);
4848
}
4949

5050
void EnsureEventLoopInitialized(v8::Platform* platform, v8::Isolate* isolate) {
51-
return reinterpret_cast<DefaultPlatform*>(platform)
52-
->EnsureEventLoopInitialized(isolate);
51+
return static_cast<DefaultPlatform*>(platform)->EnsureEventLoopInitialized(
52+
isolate);
5353
}
5454

5555
void RunIdleTasks(v8::Platform* platform, v8::Isolate* isolate,
5656
double idle_time_in_seconds) {
57-
reinterpret_cast<DefaultPlatform*>(platform)->RunIdleTasks(
58-
isolate, idle_time_in_seconds);
57+
static_cast<DefaultPlatform*>(platform)->RunIdleTasks(isolate,
58+
idle_time_in_seconds);
5959
}
6060

6161
void SetTracingController(
6262
v8::Platform* platform,
6363
v8::platform::tracing::TracingController* tracing_controller) {
64-
return reinterpret_cast<DefaultPlatform*>(platform)->SetTracingController(
64+
return static_cast<DefaultPlatform*>(platform)->SetTracingController(
6565
tracing_controller);
6666
}
6767

src/wasm/wasm-module.cc

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2728,10 +2728,6 @@ void wasm::AsyncInstantiate(Isolate* isolate, Handle<JSPromise> promise,
27282728
// foreground task. All other tasks (e.g. decoding and validating, the majority
27292729
// of the work of compilation) can be background tasks.
27302730
// TODO(wasm): factor out common parts of this with the synchronous pipeline.
2731-
//
2732-
// Note: In predictable mode, DoSync and DoAsync execute the referenced function
2733-
// immediately before returning. Thus we handle the predictable mode specially,
2734-
// e.g. when we synchronizing tasks or when we delete the AyncCompileJob.
27352731
class AsyncCompileJob {
27362732
// TODO(ahaas): Fix https://bugs.chromium.org/p/v8/issues/detail?id=6263 to
27372733
// make sure that d8 does not shut down before the AsyncCompileJob is
@@ -2796,14 +2792,14 @@ class AsyncCompileJob {
27962792
RejectPromise(isolate_, context_, thrower, module_promise_);
27972793
// The AsyncCompileJob is finished, we resolved the promise, we do not need
27982794
// the data anymore. We can delete the AsyncCompileJob object.
2799-
if (!FLAG_verify_predictable) delete this;
2795+
delete this;
28002796
}
28012797

28022798
void AsyncCompileSucceeded(Handle<Object> result) {
28032799
ResolvePromise(isolate_, context_, module_promise_, result);
28042800
// The AsyncCompileJob is finished, we resolved the promise, we do not need
28052801
// the data anymore. We can delete the AsyncCompileJob object.
2806-
if (!FLAG_verify_predictable) delete this;
2802+
delete this;
28072803
}
28082804

28092805
enum TaskType { SYNC, ASYNC };
@@ -3008,9 +3004,7 @@ class AsyncCompileJob {
30083004
break;
30093005
}
30103006
}
3011-
// Special handling for predictable mode, see above.
3012-
if (!FLAG_verify_predictable)
3013-
job_->helper_->module_->pending_tasks.get()->Signal();
3007+
job_->helper_->module_->pending_tasks.get()->Signal();
30143008
}
30153009
};
30163010

@@ -3090,12 +3084,9 @@ class AsyncCompileJob {
30903084
// Bump next_unit_, such that background tasks stop processing the queue.
30913085
job_->helper_->next_unit_.SetValue(
30923086
job_->helper_->compilation_units_.size());
3093-
// Special handling for predictable mode, see above.
3094-
if (!FLAG_verify_predictable) {
3095-
for (size_t i = 0; i < job_->num_background_tasks_; ++i) {
3096-
// We wait for it to finish.
3097-
job_->helper_->module_->pending_tasks.get()->Wait();
3098-
}
3087+
for (size_t i = 0; i < job_->num_background_tasks_; ++i) {
3088+
// We wait for it to finish.
3089+
job_->helper_->module_->pending_tasks.get()->Wait();
30993090
}
31003091
if (thrower_.error()) {
31013092
job_->DoSync<FailCompile>(std::move(thrower_));
@@ -3256,8 +3247,6 @@ void wasm::AsyncCompile(Isolate* isolate, Handle<JSPromise> promise,
32563247
auto job = new AsyncCompileJob(isolate, std::move(copy), bytes.length(),
32573248
handle(isolate->context()), promise);
32583249
job->Start();
3259-
// Special handling for predictable mode, see above.
3260-
if (FLAG_verify_predictable) delete job;
32613250
}
32623251

32633252
Handle<Code> wasm::CompileLazy(Isolate* isolate) {

0 commit comments

Comments
 (0)