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

Unified Diff: src/runtime/runtime-promise.cc

Issue 2606093002: [promises] Refactor debug code (Closed)
Patch Set: make debug_name a smi Created 4 years 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
« src/objects-debug.cc ('K') | « src/runtime/runtime-debug.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime/runtime-promise.cc
diff --git a/src/runtime/runtime-promise.cc b/src/runtime/runtime-promise.cc
index 8da5568b1d3d76315c595c33522be80d64d0e6f6..dddb31352f667534afee3abaea821d6107e2aabb 100644
--- a/src/runtime/runtime-promise.cc
+++ b/src/runtime/runtime-promise.cc
@@ -60,33 +60,75 @@ RUNTIME_FUNCTION(Runtime_PromiseRevokeReject) {
}
namespace {
+
+void PromiseFulfillDebugInfo(Isolate* isolate,
adamk 2016/12/30 00:10:04 This doesn't "fulfill" anything...should this be c
gsathya 2016/12/30 01:48:51 Done.
+ Handle<PromiseReactionJobInfo> info, int status) {
+ int id = isolate->GetNextDebugMicrotaskId();
+ DCHECK(status != v8::Promise::kPending);
+ PromiseDebugActionName name = status == v8::Promise::kFulfilled
+ ? DEBUG_PROMISE_RESOLVE
+ : DEBUG_PROMISE_REJECT;
+
+ isolate->debug()->OnAsyncTaskEvent(DEBUG_ENQUEUE, id, name);
+ info->set_debug_id(id);
+ info->set_debug_name(name);
+}
+
+// In an async function, reuse the existing stack related to the outer
+// Promise. Otherwise, e.g. in a direct call to then, save a new stack.
+// Promises with multiple reactions with one or more of them being async
+// functions will not get a good stack trace, as async functions require
+// different stacks from direct Promise use, but we save and restore a
+// stack once for all reactions.
+//
+// If this isn't a case of async function, then we fall back to normal
+// promise resolution debug events.
+//
+// TODO(littledan): Improve this case.
+void AsyncFunctionDebugInfo(Isolate* isolate,
adamk 2016/12/30 00:10:04 This function name reads oddly to me, it seems to
gsathya 2016/12/30 01:48:51 Done.
+ Handle<PromiseReactionJobInfo> info, int status) {
+ // deferred_promise can be Undefined, FixedArray or userland promise object.
+ if (!info->deferred_promise()->IsJSPromise()) {
+ PromiseFulfillDebugInfo(isolate, info, status);
+ return;
adamk 2016/12/30 00:10:04 I think it would be clearer to factor these multip
gsathya 2016/12/30 01:48:51 Done.
+ }
+
+ Handle<JSPromise> deferred_promise(JSPromise::cast(info->deferred_promise()),
+ isolate);
+ Handle<Symbol> handled_by_symbol =
+ isolate->factory()->promise_handled_by_symbol();
+ Handle<Object> handled_by_promise =
+ JSObject::GetDataProperty(deferred_promise, handled_by_symbol);
+
+ if (!handled_by_promise->IsJSPromise()) {
+ PromiseFulfillDebugInfo(isolate, info, status);
+ return;
+ }
+
+ Handle<JSPromise> handled_by_promise_js =
+ Handle<JSPromise>::cast(handled_by_promise);
+ Handle<Symbol> async_stack_id_symbol =
+ isolate->factory()->promise_async_stack_id_symbol();
+ Handle<Object> id =
+ JSObject::GetDataProperty(handled_by_promise_js, async_stack_id_symbol);
+
+ // id can be Undefined or Smi.
+ if (!id->IsSmi()) {
+ PromiseFulfillDebugInfo(isolate, info, status);
+ return;
+ }
+
+ info->set_debug_id(Handle<Smi>::cast(id)->value());
+ info->set_debug_name(DEBUG_ASYNC_FUNCTION);
+}
+
void EnqueuePromiseReactionJob(Isolate* isolate,
Handle<PromiseReactionJobInfo> info,
- Handle<Object> status) {
+ int status) {
if (isolate->debug()->is_active()) {
- MaybeHandle<Object> maybe_result;
- Handle<Object> deferred_obj(info->deferred_promise(), isolate);
-
- if (info->deferred_promise()->IsFixedArray()) {
- deferred_obj = isolate->factory()->undefined_value();
- }
-
- Handle<Object> argv[] = {deferred_obj, status};
- maybe_result = Execution::TryCall(
- isolate, isolate->promise_debug_get_info(),
- isolate->factory()->undefined_value(), arraysize(argv), argv);
-
- Handle<Object> result;
- if ((maybe_result).ToHandle(&result)) {
- CHECK(result->IsJSArray());
- Handle<JSArray> array = Handle<JSArray>::cast(result);
- ElementsAccessor* accessor = array->GetElementsAccessor();
- DCHECK(accessor->HasElement(array, 0));
- DCHECK(accessor->HasElement(array, 1));
- info->set_debug_id(*accessor->Get(array, 0));
- info->set_debug_name(*accessor->Get(array, 1));
- }
+ AsyncFunctionDebugInfo(isolate, info, status);
}
+
isolate->EnqueueMicrotask(info);
}
@@ -101,11 +143,11 @@ void PromiseSet(Isolate* isolate, Handle<JSPromise> promise, int status,
promise->set_reject_reactions(isolate->heap()->undefined_value());
}
-void PromiseFulfill(Isolate* isolate, Handle<JSPromise> promise,
- Handle<Smi> status, Handle<Object> value) {
+void PromiseFulfill(Isolate* isolate, Handle<JSPromise> promise, int status,
+ Handle<Object> value) {
// Check if there are any callbacks.
if (!promise->deferred_promise()->IsUndefined(isolate)) {
- Handle<Object> tasks((status->value() == v8::Promise::kFulfilled)
+ Handle<Object> tasks((status == v8::Promise::kFulfilled)
? promise->fulfill_reactions()
: promise->reject_reactions(),
isolate);
@@ -118,7 +160,7 @@ void PromiseFulfill(Isolate* isolate, Handle<JSPromise> promise,
EnqueuePromiseReactionJob(isolate, info, status);
}
- PromiseSet(isolate, promise, status->value(), value);
+ PromiseSet(isolate, promise, status, value);
}
} // namespace
@@ -131,9 +173,8 @@ RUNTIME_FUNCTION(Runtime_PromiseReject) {
CONVERT_BOOLEAN_ARG_CHECKED(debug_event, 2);
PromiseRejectEvent(isolate, promise, promise, reason, debug_event);
+ PromiseFulfill(isolate, promise, v8::Promise::kRejected, reason);
- Handle<Smi> status(Smi::FromInt(v8::Promise::kRejected), isolate);
- PromiseFulfill(isolate, promise, status, reason);
return isolate->heap()->undefined_value();
}
@@ -141,7 +182,7 @@ RUNTIME_FUNCTION(Runtime_PromiseFulfill) {
DCHECK(args.length() == 3);
HandleScope scope(isolate);
CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
- CONVERT_ARG_HANDLE_CHECKED(Smi, status, 1);
+ CONVERT_SMI_ARG_CHECKED(status, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
PromiseFulfill(isolate, promise, status, value);
return isolate->heap()->undefined_value();
@@ -151,7 +192,7 @@ RUNTIME_FUNCTION(Runtime_EnqueuePromiseReactionJob) {
HandleScope scope(isolate);
DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(PromiseReactionJobInfo, info, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, status, 1);
+ CONVERT_SMI_ARG_CHECKED(status, 1);
EnqueuePromiseReactionJob(isolate, info, status);
return isolate->heap()->undefined_value();
}
@@ -170,17 +211,12 @@ RUNTIME_FUNCTION(Runtime_EnqueuePromiseResolveThenableJob) {
PromiseUtils::CreateResolvingFunctions(
isolate, promise, isolate->factory()->false_value(), &resolve, &reject);
- Handle<Object> debug_id, debug_name;
+ int debug_id = 0;
adamk 2016/12/30 00:10:04 Please define a constant somewhere for this 0, som
gsathya 2016/12/30 01:48:51 Done.
+ PromiseDebugActionName debug_name = DEBUG_NOT_ACTIVE;
if (isolate->debug()->is_active()) {
- debug_id =
- handle(Smi::FromInt(isolate->GetNextDebugMicrotaskId()), isolate);
- debug_name = isolate->factory()->PromiseResolveThenableJob_string();
- isolate->debug()->OnAsyncTaskEvent(isolate->factory()->enqueue_string(),
- debug_id,
- Handle<String>::cast(debug_name));
- } else {
- debug_id = isolate->factory()->undefined_value();
- debug_name = isolate->factory()->undefined_value();
+ debug_id = isolate->GetNextDebugMicrotaskId();
+ debug_name = DEBUG_PROMISE_RESOLVE_THENABLE_JOB;
+ isolate->debug()->OnAsyncTaskEvent(DEBUG_ENQUEUE, debug_id, debug_name);
}
Handle<PromiseResolveThenableJobInfo> info =
« src/objects-debug.cc ('K') | « src/runtime/runtime-debug.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698