Commit a52f2b9 which reworked awaiter stack unwinding and its
integration with debugger introduced the following regression:
it stopped treating `Future` listeners which had both `onValue`
and `onError` callbacks as catch all exception handlers. Only
listners with `onError` callback (those created with
`Future.onError`) were treated as a catch all handler.
This meant that debugger started to treat exceptions in the
code below as uncaught:
```
Future<void> foo() {
await 0;
throw '';
}
await foo().then(..., onError: (e, st) {
});
```
This change fixes this regression by checking if
`FutureListener.state & stateCatchError != 0` instead of
more narrow `FutureListener.state == stateCatchError` which
only detects listeners which only catch errors but do not
handle values. The new predicate matches
`FutureListener.handlesError`.
This relands 38e0046cad
with a fix to ensure that we correctly detect `onError`
callbacks which simply forward to a suspended async
function. We do this by marking FutureListener's that originate
from `await` using a bit in the state.
Fixes https://github.com/dart-lang/sdk/issues/53334
TEST=service/pause_on_unhandled_async_exceptions{_zones,}_test
Fixed: 53334
CoreLibraryReviewExempt: No fundamental changes to _FutureListener implementation, just additional bit to detect that this listener originates from await
Change-Id: I90385fc619cbb52925e075dd5c7b171a31ca4cab
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/323481
Commit-Queue: Slava Egorov <vegorov@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
This reverts commit 38e0046cad.
Reason for revert: https://github.com/flutter/flutter/issues/133677
Original change's description:
> [vm] Treat Future.then(..., onError:...) as catch all handler
>
> Commit a52f2b9 which reworked awaiter stack unwinding and its
> integration with debugger introduced the following regression:
> it stopped treating `Future` listeners which had both `onValue`
> and `onError` callbacks as catch all exception handlers. Only
> listners with `onError` callback (those created with
> `Future.onError`) were treated as a catch all handler.
>
> This meant that debugger started to treat exceptions in the
> code below as uncaught:
>
> ```
> Future<void> foo() {
> await 0;
> throw '';
> }
>
> await foo().then(..., onError: (e, st) {
>
> });
> ```
>
> This change fixes this regression by checking if
> `FutureListener.state & stateCatchError != 0` instead of
> more narrow `FutureListener.state == stateCatchError` which
> only detects listeners which only catch errors but do not
> handle values. The new predicate matches
> `FutureListener.handlesError`.
>
> Fixes https://github.com/dart-lang/sdk/issues/53334
>
> TEST=service/pause_on_unhandled_async_exceptions_test
>
> Fixed: 53334
> Change-Id: I374114b7a7b2ef86b7ed6bf7d5e7cf71ba6054dc
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/323280
> Reviewed-by: Alexander Markov <alexmarkov@google.com>
> Reviewed-by: Ben Konyi <bkonyi@google.com>
> Commit-Queue: Slava Egorov <vegorov@google.com>
Change-Id: Id20a6929aac93511173c7467caee91e2488696ed
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/323429
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Siva Annamalai <asiva@google.com>
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit a52f2b9 which reworked awaiter stack unwinding and its
integration with debugger introduced the following regression:
it stopped treating `Future` listeners which had both `onValue`
and `onError` callbacks as catch all exception handlers. Only
listners with `onError` callback (those created with
`Future.onError`) were treated as a catch all handler.
This meant that debugger started to treat exceptions in the
code below as uncaught:
```
Future<void> foo() {
await 0;
throw '';
}
await foo().then(..., onError: (e, st) {
});
```
This change fixes this regression by checking if
`FutureListener.state & stateCatchError != 0` instead of
more narrow `FutureListener.state == stateCatchError` which
only detects listeners which only catch errors but do not
handle values. The new predicate matches
`FutureListener.handlesError`.
Fixes https://github.com/dart-lang/sdk/issues/53334
TEST=service/pause_on_unhandled_async_exceptions_test
Fixed: 53334
Change-Id: I374114b7a7b2ef86b7ed6bf7d5e7cf71ba6054dc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/323280
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Slava Egorov <vegorov@google.com>
The main contribution of this CL is unification of disparate
handling of various functions like `Future.timeout`,
`Future.wait`, `_SuspendState.createAsyncCallbacks` and
`_SuspendState._createAsyncStarCallback` into a single
`@pragma('vm:awaiter-link')` which allows Dart developers
to specify where awaiter unwinder should look for the next
awaiter.
For example this allows unwinding to succeed for the code like this:
Future<int> outer(Future<int> inner) {
@pragma('vm:awaiter-link')
final completer = Completer<int>();
inner.then((v) => completer.complete(v));
return completer.future;
}
This refactoring also ensures that we preserve information
(including Function & Code objects) required for awaiter
unwinding across all modes (JIT, AOT and AOT with DWARF stack
traces). This guarantees users will get the same information
no matter which mode they are running in. Previously
we have been disabling awaiter_stacks tests in some AOT
modes - which led to regressions in the quality of produced
stacks.
This CL also cleans up relationship between debugger and awaiter
stack returned by StackTrace.current - which makes stack trace
displayed by debugger (used for stepping out and determinining
whether exception is caught or not) and `StackTrace.current`
consistent.
Finally we make one user visible change to the stack trace:
awaiter stack will no always include intermediate listeners
created through `Future.then`. Previously we would sometimes
include these listeners at the tail of the stack trace,
which was inconsistent.
Ultimately this means that code like this:
Future<int> inner() async {
await null; // asynchronous gap
print(StackTrace.current); // (*)
return 0;
}
Future<int> outer() async {
int process(int v) {
return v + 1;
}
return await inner().then(process);
}
void main() async {
await outer();
}
Produces stack trace like this:
inner
<asynchronous suspension>
outer.process
<asynchronous suspension>
outer
<asynchronous suspension>
main
<asynchronous suspension>
And when stepping out of `inner` execution will stop at `outer.process`
first and the next step out will bring execution to `outer` next.
Fixes https://github.com/dart-lang/sdk/issues/52797
Fixes https://github.com/dart-lang/sdk/issues/52203
Issue https://github.com/dart-lang/sdk/issues/47985
TEST=ci
Bug: b/279929839
CoreLibraryReviewExempt: CL just adds @pragma to facilitate unwinding
Cq-Include-Trybots: luci.dart.try:vm-aot-linux-product-x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-release-x64-try,vm-aot-obfuscate-linux-release-x64-try,vm-aot-dwarf-linux-product-x64-try
Change-Id: If377d5329d6a11c86effb9369dc603a7ae616fe7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/311680
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Slava Egorov <vegorov@google.com>
This reverts commit 69f32d6ad7.
Reason for revert: We seem to have a number of tests failing with timeouts in CBUILD after this change, please see logs at
https://dart-in-g3-qa-prod.corp.google.com/dg3/Home#/cbuild/find/69f32d6ad7e724e3148cb2eb6601e63165e76ad3
Original change's description:
> Refactor `_Future`.
>
> This is a major rewrite of the `_Future` class,
> which is the default implementation of the `Future` interface.
>
> The main goal was to reduce the number of expensive type checks
> in the internal passing around of data.
> Expensive type checks are things like
> * `is _Future<T>` (more expensive than just `is _Future`, the latter
> can be a single class-ID check.
> * Covariant generic parameter checks (using `T` covariantly in a
> parameter forces a run-time type check).
>
> Also removed some plain unnecessary casts and turned some
> implicit casts from `dynamic` into `unsafeCast`s.
>
> This seems to be an success, at least on very primitive benchmarks, according to Golem:
> FutureCatchErrorTest 41.22% (1.9 noise)
> FutureValueTest 46.51% (2.8 noise)
> EmptyFutureTest 59.15% (3.1 noise)
> FutureWhenCompleteTest 51.10% (3.2 noise)
>
> A secondary goal was to clean up a very old and messy class,
> and make it clearer for other `dart:async` how to interact
> with the future.
>
> The change has a memory cost: The `_FutureListener<S,T>` class,
> which represents a `then`, `catchError` or `whenComplete`
> call on a `_Future`, now contains a reference to its source future,
> the one which provides the inputs to the callbacks,
> as well as the result future returned by the call.
> That's one extra memory slot per listener.
>
> In return, the `_FutureListener` now does not need to
> get its source future as an argument, which needs a covariant
> generic type check, and the methods of `_Future` can be written
> in a way which ignores the type parameters of both `_Future`
> and `_FutureListener`, which reduces complex type checks
> significantly.
>
> In general, typed code is in `_FutureListener`, which knows both
> the source and target types of the listener callbacks, and which
> contains the futures already at that type, so no extra type checking
> is needed.
> The `_Future` class is mostly untyped, except for its "public"
> API, called by other classes, which checks inputs,
> and code interacting with non-native futures.
> Invariants ensure that only correctly typed values
> are stored in the untyped shared `_resultOrListeners` field
> on `_Future`, as determined by its `_state` integer.
> (This was already partially true, and has simply been made
> more consistent.)
>
> Further, we now throw an error in a situation that was previously
> unhandled: When a `_Future` is completed with *itself*.
> That would ensure that the future would never complete
> (it waits for itself to complete before it can complete),
> and may potentially have caused weird loops in the representation.
> In practice, it probably never happens. Now it makes the error
> fail with an error.
> Currently a private `_FutureCyclicDependencyError` which presents
> as an `UnsupportedError`.
> That avoids code like
> ```dart
> import "dart:async";
> void main() {
> var c = Completer();
> c.complete(c.future); // bad.
> print("well!");
> var d = Completer();
> d.complete(c.future);
> print("shucks!");
> }
> ```
> from hanging the runtime by busily searching for the end of a cycle.
>
> See https://github.com/dart-lang/sdk/issues/48225
> Fixes#48225
>
> TEST= refactoring covered by existing tests, few new tests.
>
> Change-Id: Id9fc5af5fe011deb0af3e1e8a4ea3a91799f9da4
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/244241
> Reviewed-by: Martin Kustermann <kustermann@google.com>
> Commit-Queue: Lasse Nielsen <lrn@google.com>
TBR=lrn@google.com,kustermann@google.com,sra@google.com,sigmund@google.com,nshahan@google.com
Change-Id: I455be5a04b4c346df26d4ded0fa7388baccb0f8c
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/247762
Reviewed-by: Siva Annamalai <asiva@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Alexander Aprelev <aam@google.com>
This is a major rewrite of the `_Future` class,
which is the default implementation of the `Future` interface.
The main goal was to reduce the number of expensive type checks
in the internal passing around of data.
Expensive type checks are things like
* `is _Future<T>` (more expensive than just `is _Future`, the latter
can be a single class-ID check.
* Covariant generic parameter checks (using `T` covariantly in a
parameter forces a run-time type check).
Also removed some plain unnecessary casts and turned some
implicit casts from `dynamic` into `unsafeCast`s.
This seems to be an success, at least on very primitive benchmarks, according to Golem:
FutureCatchErrorTest 41.22% (1.9 noise)
FutureValueTest 46.51% (2.8 noise)
EmptyFutureTest 59.15% (3.1 noise)
FutureWhenCompleteTest 51.10% (3.2 noise)
A secondary goal was to clean up a very old and messy class,
and make it clearer for other `dart:async` how to interact
with the future.
The change has a memory cost: The `_FutureListener<S,T>` class,
which represents a `then`, `catchError` or `whenComplete`
call on a `_Future`, now contains a reference to its source future,
the one which provides the inputs to the callbacks,
as well as the result future returned by the call.
That's one extra memory slot per listener.
In return, the `_FutureListener` now does not need to
get its source future as an argument, which needs a covariant
generic type check, and the methods of `_Future` can be written
in a way which ignores the type parameters of both `_Future`
and `_FutureListener`, which reduces complex type checks
significantly.
In general, typed code is in `_FutureListener`, which knows both
the source and target types of the listener callbacks, and which
contains the futures already at that type, so no extra type checking
is needed.
The `_Future` class is mostly untyped, except for its "public"
API, called by other classes, which checks inputs,
and code interacting with non-native futures.
Invariants ensure that only correctly typed values
are stored in the untyped shared `_resultOrListeners` field
on `_Future`, as determined by its `_state` integer.
(This was already partially true, and has simply been made
more consistent.)
Further, we now throw an error in a situation that was previously
unhandled: When a `_Future` is completed with *itself*.
That would ensure that the future would never complete
(it waits for itself to complete before it can complete),
and may potentially have caused weird loops in the representation.
In practice, it probably never happens. Now it makes the error
fail with an error.
Currently a private `_FutureCyclicDependencyError` which presents
as an `UnsupportedError`.
That avoids code like
```dart
import "dart:async";
void main() {
var c = Completer();
c.complete(c.future); // bad.
print("well!");
var d = Completer();
d.complete(c.future);
print("shucks!");
}
```
from hanging the runtime by busily searching for the end of a cycle.
See https://github.com/dart-lang/sdk/issues/48225Fixes#48225
TEST= refactoring covered by existing tests, few new tests.
Change-Id: Id9fc5af5fe011deb0af3e1e8a4ea3a91799f9da4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/244241
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Lasse Nielsen <lrn@google.com>
During 'await', when registering 'then' and 'error' callbacks in
a custom Zone, the stack trace should be collected synchronously
as there are no awaiters yet, but the suspended function and its
callers are still on the stack.
This change corrects the new implementation of async to collect
these stack traces synchronously.
Class StackZoneSpecification from package:stack_trace relies on the
stack traces during callback registration in order to provide more
detailed chain of async stack traces via Chain.capture.
Without this change package:stack_trace captured truncated Chains.
Issue: https://github.com/dart-lang/sdk/issues/48378
Issue: https://github.com/flutter/flutter/issues/105340
TEST=vm/dart/causal_stacks/zone_callback_stack_traces_test
Change-Id: Iee348aa5c9abb4126f6c5d8215a6dc2cee57e124
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/247620
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
The new implementation moves away from desugaring of async
functions on kernel AST, state machine generated in the flow graph and
capturing all local variables in the context.
Instead, async/await is implemented using a few stubs
(InitSuspendableFunction, Suspend, Resume, Return and
AsyncExceptionHandler). The stubs are implemented in a
platform-independent way using (macro-)assembler helpers.
When suspending a function, its frame is copied into a SuspendState
object, and when resuming a function it is copied back onto the stack.
No extra code is generated for accessing local variables.
Callback closures are created lazily on the first await.
Design doc: go/compact-async-await.
Part 1 (kernel): https://dart-review.googlesource.com/c/sdk/+/241842
TEST=ci
Issue: https://github.com/dart-lang/sdk/issues/48378
Change-Id: Ibad757035b7cc438ebdff80b460728b1d3eff1f5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/242000
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
This fixes an issue where VM would run the async* generator after a
`yield` / `yield*` even though the subscription may be paused or
cancelled.
Furthermore this fixes an issue where `StackTrace.current` used
in async* generator crashes VM and/or produces truncated stack
trace.
This fixes the following existing tests that were failing before:
* co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t08
* co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t09
* co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t10
* language/async_star/async_star_cancel_test
* language/async_star/pause_test
New in reland: Allow the generator to to cause cancelling it's own consumer.
This addresses the issue of original revert
-> see https://github.com/flutter/flutter/issues/101514
Issue https://github.com/flutter/flutter/issues/100441
Issue https://github.com/dart-lang/sdk/issues/48695
Issue https://github.com/dart-lang/sdk/issues/34775
TEST=vm/dart{,_2}/causal_stacks/flutter_regress_100441_test
Change-Id: I091b7159d59ea15fc31162b4b6b17260d523d7cb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/242400
Reviewed-by: Lasse Nielsen <lrn@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
This reverts commit 837ee17b43.
Reason for revert: Please see https://github.com/flutter/flutter/issues/101514
Original change's description:
> [vm] Fix some async* semantics issues: Only run generator if there's active subscription (not paused/cancelled)
>
> This fixes an issue where VM would run the async* generator after a
> `yield` / `yield*` even though the subscription may be paused or
> cancelled.
>
> Furthermore this fixes an issue where `StackTrace.current` used
> in async* generator crashes VM and/or produces truncated stack
> trace.
>
> This fixes the following existing tests that were failing before:
>
> * co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t08
> * co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t09
> * co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t10
> * language/async_star/async_star_cancel_test
> * language/async_star/pause_test
>
> Issue https://github.com/flutter/flutter/issues/100441
> Issue https://github.com/dart-lang/sdk/issues/48695
> Issue https://github.com/dart-lang/sdk/issues/34775
>
> TEST=vm/dart{,_2}/causal_stacks/flutter_regress_100441_test
>
> Change-Id: I73f7d0b70937a3e3766b992740fa6fe6e6d57cec
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/239421
> Reviewed-by: Lasse Nielsen <lrn@google.com>
> Commit-Queue: Martin Kustermann <kustermann@google.com>
# Not skipping CQ checks because original CL landed > 1 day ago.
Change-Id: Ic3d9c0508310a33a2aaee67860c0bb2ec83bab4a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/240506
Reviewed-by: Siva Annamalai <asiva@google.com>
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Siva Annamalai <asiva@google.com>
This fixes an issue where VM would run the async* generator after a
`yield` / `yield*` even though the subscription may be paused or
cancelled.
Furthermore this fixes an issue where `StackTrace.current` used
in async* generator crashes VM and/or produces truncated stack
trace.
This fixes the following existing tests that were failing before:
* co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t08
* co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t09
* co19/Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t10
* language/async_star/async_star_cancel_test
* language/async_star/pause_test
Issue https://github.com/flutter/flutter/issues/100441
Issue https://github.com/dart-lang/sdk/issues/48695
Issue https://github.com/dart-lang/sdk/issues/34775
TEST=vm/dart{,_2}/causal_stacks/flutter_regress_100441_test
Change-Id: I73f7d0b70937a3e3766b992740fa6fe6e6d57cec
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/239421
Reviewed-by: Lasse Nielsen <lrn@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
This CL
* Makes :async_op only have two parameters: We take advantage
of the fact that errors not only have exception != null but
also stacktrace != null.
* Makes :async_op have no optional parameters. This reduces
code size significantly.
* Removes unused parameter in _awaitHelper calls
* Wrap the then callback instead of the error callback. (needed
to make optional parameters required)
This results in 2% code savings on a big g3 app.
The size of :async_op shrinks on average by 11%
TEST=ci
Change-Id: I38d5fba4ebebc780b48dac5aa6a250d2c7952bfd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/233362
Reviewed-by: Slava Egorov <vegorov@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
If the _FutureListener.handleValue function gets deoptimized at a point
when the `this` is no longer needed/live the deoptimization procedure
may override the `this` slot in the caller frame with "<optimized out>".
This has been triggered on the "iso-stress" builder due to using VM
testing flags that cause many deoptimizations in many places.
The stack walking code should take this possibility into consideration
and be therefore conservative.
Alternatives considered:
* Use "copy parameters" into our own frame approach - like we do
with methods that have optional parameters
=> This will make all unoptimized code slower.
* Add a reachability fence to the _FutureListener.handleValue function
=> The reachabilityFench is only available in dart:_internal for VM
=> If the function could be debugged after fence but before return
one might be able to trigger the issue nonetheless.
Closes https://github.com/dart-lang/sdk/issues/46823
TEST=Should remove flaky crashes on "iso-stress" builder.
Change-Id: I9d953706b292e02d2ba75fd794c872865faf45d0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/227401
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
Previously VM had a hardcoded constant values for context indices of
_future variables in _Future.timeout and Future.wait (used while
collecting stack traces). As those variables are allocated in
the context after captured parameters, their indices depend on
whether the parameters are captured.
I'd like to improve tree shaking so that it will remove
part of Future.wait method and make one of the parameters
not captured, which changes the context index (and it may vary
between modes and for different programs).
So, instead of hardcoding those indices, they are now calculated
at compile time and stored in ObjectStore. This is more flexible
and accommodates for future changes in tree shaker.
TEST=existing tests
Change-Id: I47629b41e497843fe3e998e813e793cf77c18bdd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/207202
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Clement Skau <cskau@google.com>
Creates HasParent() as a predicate for Function objects with a non-null
parent function and makes IsLocalFunction() specific to local closures
(i.e. explicit closures with non-null parent functions).
Creates HasSavedArgumentsDescriptor() as a predicate to determine when
saved_args_desc() can be used, to avoid the caller having to do explicit
predicate checks for each dispatcher type that contains one.
Also simplifies Function::PrintName, creates different suffixes for a
SyncGenClosureMaker and its associateed SyncGenClosure, adds suffixes
for skipping more than one generated body when printing the parent name,
and changes ArgumentsDescriptor::PrintTo to match the compact syntax
Function::PrintName used for signifying the arguments descriptor for
certain dispatchers.
TEST=pkg/vm_snapshot_analysis/test/instruction_sizes_test
Cq-Include-Trybots: luci.dart.try:app-kernel-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,pkg-linux-release-try
Change-Id: I0ac1226d1ffe1d81743b5c6788da170d5a4010c5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/191560
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
This is a reland of b6dc4dad4d
TEST=ci
Original change's description:
> [vm/aot] Avoid using most Code objects in stack traces with --dwarf-stack-traces
>
> The following changes are done in preparation for the removal of Code
> objects in AOT with --dwarf-stack-traces:
>
> * Stack trace objects are extended to hold uword PCs (which may not
> fit into Smi range).
>
> * Scanning stack frames in GC (StackFrame::VisitObjectPointers)
> now avoids using Code objects.
> In order to find CompressedStackMaps it now calls
> ReversePc::FindCompressedStackMaps.
>
> * Singleton Code object (StubCode::UnknownDartCode()) is prepared as
> a replacement for Code objects in stack traces. It has
> PayloadStart() == 0 and Size() == kUwordMax so it includes
> arbitrary PCs.
>
> * In --dwarf-stack-traces mode, most Code objects obtained from stack
> frames are replaced with StubCode::UnknownDartCode().
> This simulates future behavior of ReversePc::Lookup when Code objects
> will be removed.
>
> Issue: https://github.com/dart-lang/sdk/issues/44852
> Change-Id: I7cec7b8b9396c9cfeca3c256a412ba4e82a7e0c4
> TEST=ci
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/182720
> Commit-Queue: Alexander Markov <alexmarkov@google.com>
> Reviewed-by: Tess Strickland <sstrickl@google.com>
> Reviewed-by: Martin Kustermann <kustermann@google.com>
Change-Id: Ia2fc4672a085cd963b7fc103369851df3603590c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/186202
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Tess Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
This reverts commit b6dc4dad4d.
Reason for revert: broke package:vm_snapshot_analysis in Flutter
(https://github.com/flutter/flutter/issues/76313).
Original change's description:
> [vm/aot] Avoid using most Code objects in stack traces with --dwarf-stack-traces
>
> The following changes are done in preparation for the removal of Code
> objects in AOT with --dwarf-stack-traces:
>
> * Stack trace objects are extended to hold uword PCs (which may not
> fit into Smi range).
>
> * Scanning stack frames in GC (StackFrame::VisitObjectPointers)
> now avoids using Code objects.
> In order to find CompressedStackMaps it now calls
> ReversePc::FindCompressedStackMaps.
>
> * Singleton Code object (StubCode::UnknownDartCode()) is prepared as
> a replacement for Code objects in stack traces. It has
> PayloadStart() == 0 and Size() == kUwordMax so it includes
> arbitrary PCs.
>
> * In --dwarf-stack-traces mode, most Code objects obtained from stack
> frames are replaced with StubCode::UnknownDartCode().
> This simulates future behavior of ReversePc::Lookup when Code objects
> will be removed.
>
> Issue: https://github.com/dart-lang/sdk/issues/44852
> Change-Id: I7cec7b8b9396c9cfeca3c256a412ba4e82a7e0c4
> TEST=ci
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/182720
> Commit-Queue: Alexander Markov <alexmarkov@google.com>
> Reviewed-by: Tess Strickland <sstrickl@google.com>
> Reviewed-by: Martin Kustermann <kustermann@google.com>
Issue: https://github.com/dart-lang/sdk/issues/44852
Change-Id: I6f66171eecf1133363a7ce56193e782e43a20baf
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/185488
Reviewed-by: Zach Anderson <zra@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
The following changes are done in preparation for the removal of Code
objects in AOT with --dwarf-stack-traces:
* Stack trace objects are extended to hold uword PCs (which may not
fit into Smi range).
* Scanning stack frames in GC (StackFrame::VisitObjectPointers)
now avoids using Code objects.
In order to find CompressedStackMaps it now calls
ReversePc::FindCompressedStackMaps.
* Singleton Code object (StubCode::UnknownDartCode()) is prepared as
a replacement for Code objects in stack traces. It has
PayloadStart() == 0 and Size() == kUwordMax so it includes
arbitrary PCs.
* In --dwarf-stack-traces mode, most Code objects obtained from stack
frames are replaced with StubCode::UnknownDartCode().
This simulates future behavior of ReversePc::Lookup when Code objects
will be removed.
Issue: https://github.com/dart-lang/sdk/issues/44852
Change-Id: I7cec7b8b9396c9cfeca3c256a412ba4e82a7e0c4
TEST=ci
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/182720
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Tess Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Currently we have things called XPtr which are not what you get from ptr().
Old world:
handle->raw() returns RawObject* (tagged)
raw_obj->ptr() returns RawObject* (untagged)
After 6fe15f6df9:
handle->raw() returns ObjectPtr
obj_ptr->ptr() returns ObjectLayout*
New world:
handle->ptr() returns ObjectPtr
obj_ptr->untag() returns UntaggedObject*
TEST=ci
Change-Id: I6c7f34014cf20737607caaf84979838300d12df2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/149367
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
All existing embedders have been opted into --lazy-async-stacks, the
VM also uses it as it's default in all configurations.
After this CL, any user of --causal-async-stacks will get an error
message when trying to use it.
=> In any such case, please simply remove the flag.
TEST=Exhaustive CQ.
Bug: https://github.com/dart-lang/sdk/issues/37668
Change-Id: Ia440afcf2dba464aa8b8cf381b93bbac8eb9f8dc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/172564
Commit-Queue: Clement Skau <cskau@google.com>
Reviewed-by: Clement Skau <cskau@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
This adds a debugger mechanism to replace part of
--causal-async-stack's _asyncStackTraceHelper runtime entry.
It recognises async and async* functions and adds a synthetic
breakpoint on entry into the wrapped async_op, making sure we
don't get "synthetic" frames as we're stepping in and out of
the async code.
Change-Id: I1df6e6874de2fa9185f27a1a8873ad0071ad9fb6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/157480
Commit-Queue: Clement Skau <cskau@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
- Makes Future.wait a recognised function, and asserts its chained
future, _future is allocated at a known index in the context.
- Adds logic to locate, extract the chained future during lazy async
stack unwinding.
- Adds tests for the Future.wait async case.
- Minor consistency nits, comments.
This change is similar to a previous CL, adding Future.timeout support:
https://dart-review.googlesource.com/c/sdk/+/152328
Change-Id: I7439750968595d25d7bbac0068ad64fcc891e176
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/155420
Commit-Queue: Clement Skau <cskau@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Symbolic and non-symbolic stack traces had separate ToCString
implementations with the same general structure, but those
implementations diverged enough to cause issues in certain async stack
modes. They are now merged, with the --dwarf-stack-traces-mode flag
checked where appropriate within the merged method.
Also, now non-symbolic stack traces do not include frames for Code with
invisible Function owners unless the flag --show-invisible-frames is
enabled. With this change, pkg/native_stack_traces no longer needs to
guess at which frames corresponding to Dart code should be treated as
internal.
Tested by adding --dwarf-stack-traces version of the tests
in runtime/tests/vm/dart/causal_stacks.
Fixes https://github.com/dart-lang/sdk/issues/41578
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-obfuscate-linux-release-x64-try
Change-Id: I41a887129616c88acd7729492addf7364d95df33
Bug: 41578
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/143816
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Clement Skau <cskau@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Make them form its own source set (libdart_compiler) and completely exclude
them from AOT runtime targets.
Previously we had some inconsistencies, with some files were using
DART_PRECOMPILED_RUNTIME to fully or partially exclude either contents
from their headers or from implementation, while other files did nothing
and relied on linker to throw their contents away.
This change tries to address this inconsistency.
A follow up change would include a check in most compiler headers which
would prohibit to use them while building AOT runtime.
Change-Id: Ief11b11cbc518b301d3e93fce80580a31bbad151
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/142993
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
In particular, don't serialize a function if its code is used by the
dispatch table, but there's no need for the function object itself
at runtime like dynamic lookup or dynamic invocation forwarders.
However, just because the owning function is not needed at runtime,
it may be used during serialization for things like assembly label
creation. Thus, instead of just clearing out the Code's owner field,
we add a new WeakSerializationReference (WSR) object whose target is
the original contents of the owner field. The WSR allows the
serializer to access the original owner, but also signals to the
serializer that the target should not be serialized in AOT snapshots
unless there are additional strong (non-WSR) references.
If no strong references are found, then the references to the WSR
in the snapshot are replaced with a reference to a WSR that only
contains the class ID of the original target. The serializer creates
only one WSR per class ID.
If strong references are found, then the target is still serialized.
In this case, the WSR is dropped entirely and any reference to it is
replaced with a direct reference to the serialized target. Thus, WSRs
only exist in the precompiled runtime for targets with no strong
references.
Changes on the Flutter gallery in release mode:
arm7: total size -1.10%, isolate size -6.08%
arm8: total size -1.16%, isolate size -6.09%
Bug: https://github.com/dart-lang/sdk/issues/41052
Change-Id: I5b435ca71ef85f50fe3484789087471a91aa4fe2
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-linux-release-simarm_x64-try,vm-kernel-precomp-mac-release-simarm64-try,vm-kernel-precomp-win-release-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/137104
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
- Handle bytecode for e.g. dartkb-simarm64 does not have source position.
- Use existing GetCallerSp() instead of working across frames.
- Nit: Adds clarifying comments to test.
- Nit: Updates name of non-async-stack test to clarify flags used.
Tested:
- CQ with --lazy-async-stacks on by default.
- vm/dart/causal_stacks and language_2/vm/causal_async_exception_stack_test with current flags.
Bug: https://github.com/dart-lang/sdk/issues/39525
Change-Id: Ie6581a734cdcafbd4fb641bd86bffc03ed241532
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/133063
Commit-Queue: Clement Skau <cskau@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>