2877d78576
This is a reland of commit 22021cc120
I showed some excerpts of Golem results to @mraleph for varying targets
and constant CPU, patch A, and patch B. Those constants being:
CPU: Intel Xeon
patch A: revision=115869&patch=20143
patch B: revision=115876
(example results:
https://golem.corp.goog/Comparison?repository=dart#targetA%3Ddart%3BmachineTypeA%3Dlinux-x64%3BrevisionA%3D115869%3BpatchA%3Dderekx-Reland---VM%2FService--Record-timeline-events-representing-completed-microtasks--4%3BtargetB%3Ddart%3BmachineTypeB%3Dlinux-x64%3BrevisionB%3D115876%3BpatchB%3DNone)
He said that this change could be relanded as long as the following
"RunTime as Score" regressions of the "dart" target were noted in the
commit message:
- StreamSingleSubTest: -3.907% (-0.8 noise)
- ScheduleMicrotaskTest: -12.67% (-0.6 noise)
TEST=pkg/vm_service/test/timeline_events_for_completed_microtasks_test
Original change's description:
> [VM/Service] Record timeline events representing completed microtasks
>
> TEST=pkg/vm_service/test/timeline_events_for_completed_microtasks_test
>
> CoreLibraryReviewExempt: This CL does not include any core library API
> changes, it only modifies the implementation of microtasks (by
> instrumenting them).
> Change-Id: I54d886db9519c73f9e3218a9cc1c46bc9fe9acc3
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/420221
> Commit-Queue: Derek Xu <derekx@google.com>
> Reviewed-by: Ben Konyi <bkonyi@google.com>
CoreLibraryReviewExempt: This CL does not include any core library API
changes, it only modifies the implementation of microtasks (by
instrumenting them).
Change-Id: Ia7741a9bb9ab948e8d5fff1cf9abe9915e247d81
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/423921
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Derek Xu <derekx@google.com>
111 lines
4.1 KiB
C++
111 lines
4.1 KiB
C++
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#include "lib/stacktrace.h"
|
|
#include "platform/assert.h"
|
|
#include "vm/bootstrap_natives.h"
|
|
#include "vm/debugger.h"
|
|
#include "vm/exceptions.h"
|
|
#include "vm/flags.h"
|
|
#include "vm/microtask_mirror_queues.h"
|
|
#include "vm/native_entry.h"
|
|
#include "vm/object_store.h"
|
|
#include "vm/runtime_entry.h"
|
|
|
|
namespace dart {
|
|
|
|
DEFINE_NATIVE_ENTRY(AsyncStarMoveNext_debuggerStepCheck, 0, 1) {
|
|
#if !defined(PRODUCT)
|
|
GET_NON_NULL_NATIVE_ARGUMENT(Closure, generator, arguments->NativeArgAt(0));
|
|
Debugger* debugger = isolate->debugger();
|
|
if (debugger != nullptr && debugger->IsSingleStepping()) {
|
|
debugger->AsyncStepInto(generator);
|
|
}
|
|
#endif
|
|
return Object::null();
|
|
}
|
|
|
|
// Instantiate generic [closure] using the type argument T
|
|
// corresponding to Future<T> in the given [future] instance
|
|
// (which may extend or implement Future).
|
|
DEFINE_NATIVE_ENTRY(SuspendState_instantiateClosureWithFutureTypeArgument,
|
|
0,
|
|
2) {
|
|
GET_NON_NULL_NATIVE_ARGUMENT(Closure, closure, arguments->NativeArgAt(0));
|
|
GET_NON_NULL_NATIVE_ARGUMENT(Instance, future, arguments->NativeArgAt(1));
|
|
IsolateGroup* isolate_group = thread->isolate_group();
|
|
|
|
const auto& future_class =
|
|
Class::Handle(zone, isolate_group->object_store()->future_class());
|
|
ASSERT(future_class.NumTypeArguments() == 1);
|
|
|
|
const auto& cls = Class::Handle(zone, future.clazz());
|
|
auto& type = Type::Handle(zone, cls.GetInstantiationOf(zone, future_class));
|
|
ASSERT(!type.IsNull());
|
|
if (!type.IsInstantiated()) {
|
|
const auto& instance_type_args =
|
|
TypeArguments::Handle(zone, future.GetTypeArguments());
|
|
type ^=
|
|
type.InstantiateFrom(instance_type_args, Object::null_type_arguments(),
|
|
kNoneFree, Heap::kOld);
|
|
}
|
|
auto& type_args = TypeArguments::Handle(zone, type.arguments());
|
|
ASSERT(type_args.IsNull() || type_args.Length() == 1);
|
|
type_args = type_args.Canonicalize(thread);
|
|
|
|
ASSERT(closure.delayed_type_arguments() ==
|
|
Object::empty_type_arguments().ptr());
|
|
closure.set_delayed_type_arguments(type_args);
|
|
return closure.ptr();
|
|
}
|
|
|
|
DEFINE_NATIVE_ENTRY(MicrotaskMirrorQueue_onScheduleAsyncCallback, 0, 0) {
|
|
// There is logic in `sdk/lib/async/schedule_microtask.dart` that ensures that
|
|
// this function can only ever be called when the `--profile-microtasks` CLI
|
|
// flag is set in non-PRODUCT modes.
|
|
#if !defined(PRODUCT)
|
|
const StackTrace& stack_trace = GetCurrentStackTrace(
|
|
// We pass a `skip_frames` argument of 1 to skip the
|
|
// `_MicrotaskMirrorQueue._onScheduleAsyncCallback` frame.
|
|
1);
|
|
MicrotaskMirrorQueues::GetQueue(static_cast<int64_t>(isolate->main_port()))
|
|
->OnScheduleAsyncCallback(stack_trace);
|
|
return Object::null();
|
|
#else
|
|
UNREACHABLE();
|
|
#endif // !defined(PRODUCT)
|
|
}
|
|
|
|
DEFINE_NATIVE_ENTRY(MicrotaskMirrorQueue_onSchedulePriorityAsyncCallback,
|
|
0,
|
|
0) {
|
|
// There is logic in `sdk/lib/async/schedule_microtask.dart` that ensures that
|
|
// this function can only ever be called when the `--profile-microtasks` CLI
|
|
// flag is set in non-PRODUCT modes.
|
|
#if !defined(PRODUCT)
|
|
MicrotaskMirrorQueues::GetQueue(static_cast<int64_t>(isolate->main_port()))
|
|
->OnSchedulePriorityAsyncCallback();
|
|
return Object::null();
|
|
#else
|
|
UNREACHABLE();
|
|
#endif // !defined(PRODUCT)
|
|
}
|
|
|
|
DEFINE_NATIVE_ENTRY(MicrotaskMirrorQueue_onAsyncCallbackComplete, 0, 2) {
|
|
// There is logic in `sdk/lib/async/schedule_microtask.dart` that ensures that
|
|
// this function can only ever be called when the `--profile-microtasks` CLI
|
|
// flag is set in non-PRODUCT modes.
|
|
#if !defined(PRODUCT)
|
|
GET_NON_NULL_NATIVE_ARGUMENT(Integer, start_time, arguments->NativeArgAt(0));
|
|
GET_NON_NULL_NATIVE_ARGUMENT(Integer, end_time, arguments->NativeArgAt(1));
|
|
MicrotaskMirrorQueues::GetQueue(static_cast<int64_t>(isolate->main_port()))
|
|
->OnAsyncCallbackComplete(start_time.Value(), end_time.Value());
|
|
return Object::null();
|
|
#else
|
|
UNREACHABLE();
|
|
#endif // !defined(PRODUCT)
|
|
}
|
|
|
|
} // namespace dart
|