Open Bug 1589523 Opened 5 years ago Updated 2 years ago

include async callers in captured stacks (SavedFrame chains) for free

Categories

(Core :: JavaScript Engine, task, P2)

task

Tracking

()

People

(Reporter: jimb, Unassigned)

References

(Blocks 1 open bug)

Details

When we capture a stack (for an error, etc.), we can include async callers (awaiters) in the captured stacks without imposing any new overhead on execution. This sort of async caller capture could be enabled by default in content code.

When a stack traversal reaches a frame for a call to an asynchronous function, if that call has ever awaited, there are no further JavaScript frames on the stack: a suspended asynchronous call is only resumed by a microtask checkpoint, so the resumed async call is the oldest frame.

SpiderMonkey has in the past tried to supply previously captured stacks as async extensions of such calls, but we can't supply them unless we capture them, and those captures significantly affected the performance of all code, even if it never ended up capturing a stack at all.

But even without capturing stacks in advance, SpiderMonkey has enough information to furnish asynchronous callers to stack captures. Calling an asynchronous function produces a promise of its return value. The call must retain a pointer to this promise, since it needs to resolve it when it throws or returns. If the caller is an 'await' expression, then the 'await' expression attaches a handler to this promise which will resume the async caller, by resuming its internal generator object.

That is: the async callee must point to the promise, which must point to the handler, which must point to the internal generator for the async caller, which has all the information needed to resume that call - including the promise of its own value, so stackwalking can continue.

SpiderMonkey's SavedStacks system should take advantage of this linkage to include async callers in captured stacks.

It seems like this could share some machinery with bug 1523865, as both are concerned with extracting a continuation from an async frame via its result promise's list of handlers.

See Also: → dbg-async-stacks
Priority: -- → P2
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.