[promises] Move async debug event creation to c++

BUG=v8:5343

Review-Url: https://codereview.chromium.org/2415023002
Cr-Commit-Position: refs/heads/master@{#40369}
This commit is contained in:
gsathya 2016-10-17 08:37:47 -07:00 committed by Commit bot
parent 0e0123a61c
commit 18a116c7bd
16 changed files with 89 additions and 115 deletions

View File

@ -1658,10 +1658,12 @@ MaybeHandle<Object> Debug::MakeCompileEvent(Handle<Script> script,
return CallFunction("MakeCompileEvent", arraysize(argv), argv);
}
MaybeHandle<Object> Debug::MakeAsyncTaskEvent(Handle<JSObject> task_event) {
MaybeHandle<Object> Debug::MakeAsyncTaskEvent(Handle<String> type,
Handle<Object> id,
Handle<String> name) {
DCHECK(id->IsNumber());
// Create the async task event object.
Handle<Object> argv[] = { task_event };
Handle<Object> argv[] = {type, id, name};
return CallFunction("MakeAsyncTaskEvent", arraysize(argv), argv);
}
@ -1781,8 +1783,9 @@ void Debug::OnAfterCompile(Handle<Script> script) {
ProcessCompileEvent(v8::AfterCompile, script);
}
void Debug::OnAsyncTaskEvent(Handle<JSObject> data) {
void Debug::OnAsyncTaskEvent(Handle<String> type, Handle<Object> id,
Handle<String> name) {
DCHECK(id->IsNumber());
if (in_debug_scope() || ignore_events()) return;
HandleScope scope(isolate_);
@ -1792,7 +1795,7 @@ void Debug::OnAsyncTaskEvent(Handle<JSObject> data) {
// Create the script collected state object.
Handle<Object> event_data;
// Bail out and don't call debugger if exception.
if (!MakeAsyncTaskEvent(data).ToHandle(&event_data)) return;
if (!MakeAsyncTaskEvent(type, id, name).ToHandle(&event_data)) return;
// Process debug event.
ProcessDebugEvent(v8::AsyncTaskEvent,

View File

@ -417,7 +417,8 @@ class Debug {
void OnCompileError(Handle<Script> script);
void OnBeforeCompile(Handle<Script> script);
void OnAfterCompile(Handle<Script> script);
void OnAsyncTaskEvent(Handle<JSObject> data);
void OnAsyncTaskEvent(Handle<String> type, Handle<Object> id,
Handle<String> name);
// API facing.
void SetEventListener(Handle<Object> callback, Handle<Object> data);
@ -588,8 +589,9 @@ class Debug {
Handle<Object> promise);
MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent(
Handle<Script> script, v8::DebugEvent type);
MUST_USE_RESULT MaybeHandle<Object> MakeAsyncTaskEvent(
Handle<JSObject> task_event);
MUST_USE_RESULT MaybeHandle<Object> MakeAsyncTaskEvent(Handle<String> type,
Handle<Object> id,
Handle<String> name);
// Mirror cache handling.
void ClearMirrorCache();

View File

@ -1142,15 +1142,15 @@ function MakeScriptObject_(script, include_source) {
}
function MakeAsyncTaskEvent(event_data) {
return new AsyncTaskEvent(event_data);
function MakeAsyncTaskEvent(type, id, name) {
return new AsyncTaskEvent(type, id, name);
}
function AsyncTaskEvent(event_data) {
this.type_ = event_data.type;
this.name_ = event_data.name;
this.id_ = event_data.id;
function AsyncTaskEvent(type, id, name) {
this.type_ = type;
this.id_ = id;
this.name_ = name;
}

View File

@ -935,7 +935,7 @@ Handle<Struct> Factory::NewStruct(InstanceType type) {
Handle<PromiseResolveThenableJobInfo> Factory::NewPromiseResolveThenableJobInfo(
Handle<JSReceiver> thenable, Handle<JSReceiver> then,
Handle<JSFunction> resolve, Handle<JSFunction> reject,
Handle<Object> before_debug_event, Handle<Object> after_debug_event) {
Handle<Object> debug_id, Handle<Object> debug_name) {
Handle<PromiseResolveThenableJobInfo> result =
Handle<PromiseResolveThenableJobInfo>::cast(
NewStruct(PROMISE_RESOLVE_THENABLE_JOB_INFO_TYPE));
@ -943,22 +943,22 @@ Handle<PromiseResolveThenableJobInfo> Factory::NewPromiseResolveThenableJobInfo(
result->set_then(*then);
result->set_resolve(*resolve);
result->set_reject(*reject);
result->set_before_debug_event(*before_debug_event);
result->set_after_debug_event(*after_debug_event);
result->set_debug_id(*debug_id);
result->set_debug_name(*debug_name);
return result;
}
Handle<PromiseReactionJobInfo> Factory::NewPromiseReactionJobInfo(
Handle<Object> value, Handle<Object> tasks, Handle<Object> deferred,
Handle<Object> before_debug_event, Handle<Object> after_debug_event,
Handle<Object> debug_id, Handle<Object> debug_name,
Handle<Context> context) {
Handle<PromiseReactionJobInfo> result = Handle<PromiseReactionJobInfo>::cast(
NewStruct(PROMISE_REACTION_JOB_INFO_TYPE));
result->set_value(*value);
result->set_tasks(*tasks);
result->set_deferred(*deferred);
result->set_before_debug_event(*before_debug_event);
result->set_after_debug_event(*after_debug_event);
result->set_debug_id(*debug_id);
result->set_debug_name(*debug_name);
result->set_context(*context);
return result;
}

View File

@ -64,14 +64,14 @@ class V8_EXPORT_PRIVATE Factory final {
// Create a new PromiseReactionJobInfo struct.
Handle<PromiseReactionJobInfo> NewPromiseReactionJobInfo(
Handle<Object> value, Handle<Object> tasks, Handle<Object> deferred,
Handle<Object> before_debug, Handle<Object> after_debug_event,
Handle<Object> debug_id, Handle<Object> debug_name,
Handle<Context> context);
// Create a new PromiseResolveThenableJobInfo struct.
Handle<PromiseResolveThenableJobInfo> NewPromiseResolveThenableJobInfo(
Handle<JSReceiver> thenable, Handle<JSReceiver> then,
Handle<JSFunction> resolve, Handle<JSFunction> reject,
Handle<Object> before_debug_event, Handle<Object> after_debug_event);
Handle<Object> debug_id, Handle<Object> debug_name);
// Create a new PrototypeInfo struct.
Handle<PrototypeInfo> NewPrototypeInfo();

View File

@ -53,6 +53,7 @@
V(default_string, "default") \
V(defineProperty_string, "defineProperty") \
V(deleteProperty_string, "deleteProperty") \
V(did_handle_string, "didHandle") \
V(display_name_string, "displayName") \
V(done_string, "done") \
V(dot_result_string, ".result") \
@ -174,6 +175,7 @@
V(WeakMap_string, "WeakMap") \
V(WeakSet_string, "WeakSet") \
V(weekday_string, "weekday") \
V(will_handle_string, "willHandle") \
V(writable_string, "writable") \
V(year_string, "year")

View File

@ -3081,26 +3081,31 @@ void Isolate::ReportPromiseReject(Handle<JSObject> promise,
namespace {
class PromiseDebugEventScope {
public:
PromiseDebugEventScope(Isolate* isolate, Object* before, Object* after)
PromiseDebugEventScope(Isolate* isolate, Object* id, Object* name)
: isolate_(isolate),
after_(after, isolate_),
is_debug_active_(isolate_->debug()->is_active() &&
before->IsJSObject() && after->IsJSObject()) {
id_(id, isolate_),
name_(name, isolate_),
is_debug_active_(isolate_->debug()->is_active() && id_->IsNumber() &&
name_->IsString()) {
if (is_debug_active_) {
isolate_->debug()->OnAsyncTaskEvent(
handle(JSObject::cast(before), isolate_));
isolate_->factory()->will_handle_string(), id_,
Handle<String>::cast(name_));
}
}
~PromiseDebugEventScope() {
if (is_debug_active_) {
isolate_->debug()->OnAsyncTaskEvent(Handle<JSObject>::cast(after_));
isolate_->debug()->OnAsyncTaskEvent(
isolate_->factory()->did_handle_string(), id_,
Handle<String>::cast(name_));
}
}
private:
Isolate* isolate_;
Handle<Object> after_;
Handle<Object> id_;
Handle<Object> name_;
bool is_debug_active_;
};
} // namespace
@ -3108,8 +3113,7 @@ class PromiseDebugEventScope {
void Isolate::PromiseReactionJob(Handle<PromiseReactionJobInfo> info,
MaybeHandle<Object>* result,
MaybeHandle<Object>* maybe_exception) {
PromiseDebugEventScope helper(this, info->before_debug_event(),
info->after_debug_event());
PromiseDebugEventScope helper(this, info->debug_id(), info->debug_name());
Handle<Object> value(info->value(), this);
Handle<Object> tasks(info->tasks(), this);
@ -3150,8 +3154,7 @@ void Isolate::PromiseReactionJob(Handle<PromiseReactionJobInfo> info,
void Isolate::PromiseResolveThenableJob(
Handle<PromiseResolveThenableJobInfo> info, MaybeHandle<Object>* result,
MaybeHandle<Object>* maybe_exception) {
PromiseDebugEventScope helper(this, info->before_debug_event(),
info->after_debug_event());
PromiseDebugEventScope helper(this, info->debug_id(), info->debug_name());
Handle<JSReceiver> thenable(info->thenable(), this);
Handle<JSFunction> resolve(info->resolve(), this);

View File

@ -145,11 +145,7 @@ function AsyncFunctionPromiseCreate() {
// resumptions from await.
var id = PromiseNextMicrotaskID();
SET_PRIVATE(promise, promiseAsyncStackIDSymbol, id);
%DebugAsyncTaskEvent({
type: "enqueueRecurring",
id: id,
name: "async function",
});
%DebugAsyncTaskEvent("enqueueRecurring", id, "async function");
}
return promise;
}
@ -162,11 +158,7 @@ function AsyncFunctionPromiseRelease(promise) {
// Don't send invalid events when catch prediction is turned on in
// the middle of some async operation.
if (!IS_UNDEFINED(id)) {
%DebugAsyncTaskEvent({
type: "cancel",
id: id,
name: "async function",
});
%DebugAsyncTaskEvent("cancel", id, "async function");
}
// Pop the Promise under construction in an async function on
// from catch prediction stack.

View File

@ -185,7 +185,7 @@ function PromiseHandle(value, handler, deferred) {
}
function PromiseEnqueue(value, tasks, deferreds, status) {
var id, name, beforeDebug, afterDebug, instrumenting = DEBUG_IS_ACTIVE;
var id, name, instrumenting = DEBUG_IS_ACTIVE;
if (instrumenting) {
// In an async function, reuse the existing stack related to the outer
@ -204,14 +204,10 @@ function PromiseEnqueue(value, tasks, deferreds, status) {
} else {
id = PromiseNextMicrotaskID();
name = status === kFulfilled ? "Promise.resolve" : "Promise.reject";
%DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name });
%DebugAsyncTaskEvent("enqueue", id, name);
}
beforeDebug = { type: "willHandle", id: id, name: name };
afterDebug = { type: "didHandle", id: id, name: name };
}
%EnqueuePromiseReactionJob(value, tasks, deferreds, beforeDebug, afterDebug);
%EnqueuePromiseReactionJob(value, tasks, deferreds, id, name);
}
function PromiseAttachCallbacks(promise, deferred, onResolve, onReject) {
@ -305,33 +301,18 @@ function ResolvePromise(promise, resolution) {
if (IS_CALLABLE(then)) {
var callbacks = CreateResolvingFunctions(promise, false);
var id, before_debug_event, after_debug_event;
var instrumenting = DEBUG_IS_ACTIVE;
var id, name, instrumenting = DEBUG_IS_ACTIVE;
if (instrumenting) {
if (IsPromise(resolution)) {
// Mark the dependency of the new promise on the resolution
SET_PRIVATE(resolution, promiseHandledBySymbol, promise);
}
id = PromiseNextMicrotaskID();
before_debug_event = {
type: "willHandle",
id: id,
name: "PromiseResolveThenableJob"
};
after_debug_event = {
type: "didHandle",
id: id,
name: "PromiseResolveThenableJob"
};
%DebugAsyncTaskEvent({
type: "enqueue",
id: id,
name: "PromiseResolveThenableJob"
});
name = "PromiseResolveThenableJob";
%DebugAsyncTaskEvent("enqueue", id, name);
}
%EnqueuePromiseResolveThenableJob(
resolution, then, callbacks.resolve, callbacks.reject,
before_debug_event, after_debug_event);
resolution, then, callbacks.resolve, callbacks.reject, id, name);
return;
}
}

View File

@ -922,10 +922,8 @@ void PromiseResolveThenableJobInfo::PromiseResolveThenableJobInfoVerify() {
CHECK(then()->IsJSReceiver());
CHECK(resolve()->IsJSFunction());
CHECK(reject()->IsJSFunction());
CHECK(before_debug_event()->IsJSObject() ||
before_debug_event()->IsUndefined(isolate));
CHECK(after_debug_event()->IsJSObject() ||
after_debug_event()->IsUndefined(isolate));
CHECK(debug_id()->IsNumber() || debug_id()->IsUndefined(isolate));
CHECK(debug_name()->IsString() || debug_name()->IsUndefined(isolate));
}
void PromiseReactionJobInfo::PromiseReactionJobInfoVerify() {
@ -934,10 +932,8 @@ void PromiseReactionJobInfo::PromiseReactionJobInfoVerify() {
CHECK(value()->IsObject());
CHECK(tasks()->IsJSArray() || tasks()->IsCallable());
CHECK(deferred()->IsJSObject() || deferred()->IsUndefined(isolate));
CHECK(before_debug_event()->IsJSObject() ||
before_debug_event()->IsUndefined(isolate));
CHECK(after_debug_event()->IsJSObject() ||
after_debug_event()->IsUndefined(isolate));
CHECK(debug_id()->IsNumber() || debug_id()->IsUndefined(isolate));
CHECK(debug_name()->IsString() || debug_name()->IsUndefined(isolate));
CHECK(context()->IsContext());
}

View File

@ -5707,18 +5707,14 @@ ACCESSORS(PromiseResolveThenableJobInfo, thenable, JSReceiver, kThenableOffset)
ACCESSORS(PromiseResolveThenableJobInfo, then, JSReceiver, kThenOffset)
ACCESSORS(PromiseResolveThenableJobInfo, resolve, JSFunction, kResolveOffset)
ACCESSORS(PromiseResolveThenableJobInfo, reject, JSFunction, kRejectOffset)
ACCESSORS(PromiseResolveThenableJobInfo, before_debug_event, Object,
kBeforeDebugEventOffset)
ACCESSORS(PromiseResolveThenableJobInfo, after_debug_event, Object,
kAfterDebugEventOffset)
ACCESSORS(PromiseResolveThenableJobInfo, debug_id, Object, kDebugIdOffset)
ACCESSORS(PromiseResolveThenableJobInfo, debug_name, Object, kDebugNameOffset)
ACCESSORS(PromiseReactionJobInfo, value, Object, kValueOffset);
ACCESSORS(PromiseReactionJobInfo, tasks, Object, kTasksOffset);
ACCESSORS(PromiseReactionJobInfo, deferred, Object, kDeferredOffset);
ACCESSORS(PromiseReactionJobInfo, before_debug_event, Object,
kBeforeDebugEventOffset);
ACCESSORS(PromiseReactionJobInfo, after_debug_event, Object,
kAfterDebugEventOffset);
ACCESSORS(PromiseReactionJobInfo, debug_id, Object, kDebugIdOffset);
ACCESSORS(PromiseReactionJobInfo, debug_name, Object, kDebugNameOffset);
ACCESSORS(PromiseReactionJobInfo, context, Context, kContextOffset);
Map* PrototypeInfo::ObjectCreateMap() {

View File

@ -1168,8 +1168,8 @@ void PromiseResolveThenableJobInfo::PromiseResolveThenableJobInfoPrint(
os << "\n - then: " << Brief(then());
os << "\n - resolve: " << Brief(resolve());
os << "\n - reject: " << Brief(reject());
os << "\n - before debug event: " << Brief(before_debug_event());
os << "\n - after debug event: " << Brief(after_debug_event());
os << "\n - debug id: " << Brief(debug_id());
os << "\n - debug name: " << Brief(debug_name());
os << "\n";
}
@ -1179,8 +1179,8 @@ void PromiseReactionJobInfo::PromiseReactionJobInfoPrint(
os << "\n - value: " << Brief(value());
os << "\n - tasks: " << Brief(tasks());
os << "\n - deferred: " << Brief(deferred());
os << "\n - before debug event: " << Brief(before_debug_event());
os << "\n - after debug event: " << Brief(after_debug_event());
os << "\n - debug id: " << Brief(debug_id());
os << "\n - debug name: " << Brief(debug_name());
os << "\n - reaction context: " << Brief(context());
os << "\n";
}

View File

@ -6754,17 +6754,16 @@ class PromiseResolveThenableJobInfo : public Struct {
DECL_ACCESSORS(then, JSReceiver)
DECL_ACCESSORS(resolve, JSFunction)
DECL_ACCESSORS(reject, JSFunction)
DECL_ACCESSORS(before_debug_event, Object)
DECL_ACCESSORS(after_debug_event, Object)
DECL_ACCESSORS(debug_id, Object)
DECL_ACCESSORS(debug_name, Object)
static const int kThenableOffset = Struct::kHeaderSize;
static const int kThenOffset = kThenableOffset + kPointerSize;
static const int kResolveOffset = kThenOffset + kPointerSize;
static const int kRejectOffset = kResolveOffset + kPointerSize;
static const int kBeforeDebugEventOffset = kRejectOffset + kPointerSize;
static const int kAfterDebugEventOffset =
kBeforeDebugEventOffset + kPointerSize;
static const int kSize = kAfterDebugEventOffset + kPointerSize;
static const int kDebugIdOffset = kRejectOffset + kPointerSize;
static const int kDebugNameOffset = kDebugIdOffset + kPointerSize;
static const int kSize = kDebugNameOffset + kPointerSize;
DECLARE_CAST(PromiseResolveThenableJobInfo)
DECLARE_PRINTER(PromiseResolveThenableJobInfo)
@ -6780,17 +6779,16 @@ class PromiseReactionJobInfo : public Struct {
DECL_ACCESSORS(value, Object)
DECL_ACCESSORS(tasks, Object)
DECL_ACCESSORS(deferred, Object)
DECL_ACCESSORS(before_debug_event, Object)
DECL_ACCESSORS(after_debug_event, Object)
DECL_ACCESSORS(debug_id, Object)
DECL_ACCESSORS(debug_name, Object)
DECL_ACCESSORS(context, Context)
static const int kValueOffset = Struct::kHeaderSize;
static const int kTasksOffset = kValueOffset + kPointerSize;
static const int kDeferredOffset = kTasksOffset + kPointerSize;
static const int kBeforeDebugEventOffset = kDeferredOffset + kPointerSize;
static const int kAfterDebugEventOffset =
kBeforeDebugEventOffset + kPointerSize;
static const int kContextOffset = kAfterDebugEventOffset + kPointerSize;
static const int kDebugIdOffset = kDeferredOffset + kPointerSize;
static const int kDebugNameOffset = kDebugIdOffset + kPointerSize;
static const int kContextOffset = kDebugNameOffset + kPointerSize;
static const int kSize = kContextOffset + kPointerSize;
DECLARE_CAST(PromiseReactionJobInfo)

View File

@ -1824,10 +1824,12 @@ RUNTIME_FUNCTION(Runtime_DebugPopPromise) {
RUNTIME_FUNCTION(Runtime_DebugAsyncTaskEvent) {
DCHECK(args.length() == 1);
DCHECK(args.length() == 3);
HandleScope scope(isolate);
CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
isolate->debug()->OnAsyncTaskEvent(data);
CONVERT_ARG_HANDLE_CHECKED(String, type, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, id, 1);
CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
isolate->debug()->OnAsyncTaskEvent(type, id, name);
return isolate->heap()->undefined_value();
}

View File

@ -577,12 +577,12 @@ RUNTIME_FUNCTION(Runtime_EnqueuePromiseReactionJob) {
CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, tasks, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, deferred, 2);
CONVERT_ARG_HANDLE_CHECKED(Object, before_debug_event, 3);
CONVERT_ARG_HANDLE_CHECKED(Object, after_debug_event, 4);
CONVERT_ARG_HANDLE_CHECKED(Object, debug_id, 3);
CONVERT_ARG_HANDLE_CHECKED(Object, debug_name, 4);
Handle<PromiseReactionJobInfo> info =
isolate->factory()->NewPromiseReactionJobInfo(
value, tasks, deferred, before_debug_event, after_debug_event,
isolate->native_context());
isolate->factory()->NewPromiseReactionJobInfo(value, tasks, deferred,
debug_id, debug_name,
isolate->native_context());
isolate->EnqueueMicrotask(info);
return isolate->heap()->undefined_value();
}
@ -594,12 +594,11 @@ RUNTIME_FUNCTION(Runtime_EnqueuePromiseResolveThenableJob) {
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, then, 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, resolve, 2);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, reject, 3);
CONVERT_ARG_HANDLE_CHECKED(Object, before_debug_event, 4);
CONVERT_ARG_HANDLE_CHECKED(Object, after_debug_event, 5);
CONVERT_ARG_HANDLE_CHECKED(Object, debug_id, 4);
CONVERT_ARG_HANDLE_CHECKED(Object, debug_name, 5);
Handle<PromiseResolveThenableJobInfo> info =
isolate->factory()->NewPromiseResolveThenableJobInfo(
resolution, then, resolve, reject, before_debug_event,
after_debug_event);
resolution, then, resolve, reject, debug_id, debug_name);
isolate->EnqueueMicrotask(info);
return isolate->heap()->undefined_value();
}

View File

@ -196,7 +196,7 @@ namespace internal {
F(DebugRecordAsyncFunction, 1, 1) \
F(DebugPushPromise, 1, 1) \
F(DebugPopPromise, 0, 1) \
F(DebugAsyncTaskEvent, 1, 1) \
F(DebugAsyncTaskEvent, 3, 1) \
F(DebugIsActive, 0, 1) \
F(DebugBreakInOptimizedCode, 0, 1) \
F(GetWasmFunctionOffsetTable, 1, 1) \