This is done by collecting all frames on the current stack until an async/async* frame is hit
which has yielded before (i.e. is not in sync-async case).
From there on it finds the closure of the async/async* frame and starts traversing the listeners:
while (closure != null) {
yield_index = closure.context[Context::kAsyncJumpVarIndex]
pc = closure.function.code.pc_descriptors.LookupPcFromYieldIndex(yield_index);
<emit pc in frame>
closure = closure.context[Context::kAsyncCompleterVarIndex]._future._resultOrListeners.callback;
}
Bug: https://github.com/dart-lang/sdk/issues/37668
Change-Id: I97030d22e529bf8a74ecd30a8a2589cfe57ad330
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122644
Commit-Queue: Clement Skau <cskau@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
This is the follow-up for 46cef9bfdd.
After that change, VM's optimizer (canonicalization) removes
initializing stores which store null, even if they're overwriting the
result of another initializing store. This causes incorrect behavior
in cases like this:
class A {
int x = 3;
A() : x = null {}
}
To accomodate for this change in the VM's optimizer, bytecode generator
should elide duplicate stores, similarly to AST-based flow graph
builder.
Fixes language_2/field_parameter_test in AOT mode with bytecode.
Change-Id: I9b1e25840f639d88bf62dc990f183878ecf1b59b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/121649
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
For a switch statement
switch(foo) {
case c_1: ...
...
case c_N: ...
}
Bytecode was calling foo.operator==(c_i). This is less efficient than
c_i.operator==(foo), as c_i is a constant with a known actual type
and operator== can be always devirtualized and inlined.
Change-Id: I786ea193de1fa1830854602318e436f601296f5e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/121405
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Régis Crelier <regis@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
In order to support causal-async-stacks, the following synthetic calls
are inserted: _asyncStackTraceHelper, _setAsyncThreadStackTrace and
_clearAsyncThreadStackTrace.
_asyncStackTraceHelper is always generated in the async transformation.
_setAsyncThreadStackTrace and _clearAsyncThreadStackTrace are inserted
during bytecode generation (or in the flow graph builder in case of AST
pipeline). If bytecode generation options are set inconsistently with
--causal-async-stacks VM option, then it was possible that
_asyncStackTraceHelper was generated but other calls were not generated,
causing incorrect (full, non-truncated) async stack traces. This also
causes performance regression as collecting full stack traces takes
much more time.
This change makes generation of all these calls more consistent: if
causal async stacks are disabled during bytecode generation, then all
three calls are omitted. Also, in case these calls were generated and
present in bytecode, but VM option --causal-async-stacks is disabled,
then bytecode flow graph builder turns all these three calls into no-ops.
Change-Id: I93eb1d83c675ee093799bb8e37ca3d60a3c5c19d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/120927
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Régis Crelier <regis@google.com>
Previously, calls through field/getter were generated as dynamic calls
because InterfaceCall with field/getter target doesn't correctly
represent what such call should do. This results in a quite inefficient
code in AOT mode.
With this change, calls through fields/getters are decomposed into two
calls, while keeping the same order of evaluation.
Change-Id: Ieb33927c1b39d1b4d8eafb7bd542675820474068
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/120628
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Régis Crelier <regis@google.com>
AOT transformations add vm.direct-call.metadata with devirtualization
information to AST nodes.
Bytecode generator should take this information into account when
generating bytecode in case of AOT. Bytecode format is extended with
CheckReceiverForNull and UncheckedDirectCall instructions, and
DirectCallViaDynamicForwarder constant pool entry in order to represent
devirtualized calls.
Change-Id: I697432ddd0b58d2d0413715132ba5e90eb606ec1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/119201
Reviewed-by: Régis Crelier <regis@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
When generating deopt info in SIMDBC mode (DeoptInfoBuilder::AddCopy,
DeoptInfoBuilder::ToCpuRegisterSource) kSpecialDbcRegister source
locations are not supported.
In order to avoid such deopt info, this change moves CheckStack bytecode
instruction after function type arguments handling is finished (function
type arguments handling uses arguments descriptor which resides in
kArgsDescriptorsReg special DBC register). This placement of CheckStack is
also more aligned with what AST-based flow graph builder generates.
Fixes lib_2/math/min_max_test with bytecode in dartk-reload-mac-release-simdbc64
configuration.
Change-Id: I7d9863b8290a78a6e24e5806cc5053d55c93ce5c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/117221
Reviewed-by: Régis Crelier <regis@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
VM no longer relies on distinct ICData entries in constant pool, and
it no longer creates actual ICData objects.
This change introduces new DynamicCall constant pool entry which is
* de-duplicated;
* stores arguments descriptor inline instead of allocating a separate
constant pool entry and referencing it by index;
* reserves extra slot in constant pool (like other call constants), so
we can eventually remove creation of extra UnlinkedCall objects.
Change-Id: I8d21954803ca5be5b6fc8335b700e8a9086245cf
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/116120
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Régis Crelier <regis@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
PushStatic instruction expects field object to be pushed onto the stack.
This is useless, as PushStatic also references field with its D operand.
This change replaces PushStatic instruction with LoadStatic which doesn't
take field object on the stack, so PushConstant/PushStatic pair is replaced
with a single LoadStatic instruction.
This change also enables constant propagation of values of injected CID
fields, which are not known at bytecode generation time.
Change-Id: Ifbdd3aea2aab338f6c9ec3e5728948c4d8541a4b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/112489
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Régis Crelier <regis@google.com>
Size of a large application:
Before: 26628600
After: 21480120 (-19.3%)
Size of snapshots:
isolate_snapshot_framework.bin
Before: 9322496
After: 6782976 (-27.2%)
isolate_snapshot_product_framework.bin
Before: 9166848
After: 6602752 (-27.9%)
Regressions in tests:
1) Test language_2/type_alias_equality_test/04 fails similarly to default mode, as VM
does not implement comparison of function types according to the specification.
Previously this test was passing as function types were canonicalized in bytecode,
which was not always correct. This CL fixes the problem with canonicalization of
function types in bytecode and the test starts failing again.
2) Tests standalone_2/entrypoints_verification_test, standalone_2/io/test_extension_test,
standalone_2/io/test_extension_fail_test fail as native extensions are not supported
in bytecode yet. These tests start passing after df5e7aac17,
which switched bytecode tests to kernel service (on x64), because kernel service doesn't
drop ASTs. This CL switches from reading AST library declarations to bytecode even if
AST is not removed, so tests fail again.
Change-Id: I8b7ba44bfa49d0b1599b2509553ff7c831a4e244
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/104700
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Régis Crelier <regis@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Pkg/vm tests were adjusted after constant evaluation was enabled in the front-end.
As constant evaluation was reverted (4b7d256a06),
we also need to revert corresponding changes in pkg/vm unit tests.
Revert "[vm/bytecode] Update expectations for bytecode generator unit test"
This reverts commit 734c50cbf2.
Revert "[vm/aot/tfa] Update TFA tests after front-end starts evaluating constants"
This reverts commit 25cb45c02f.
Change-Id: I2fcc30571bec2dd904925724ddb7105567c7ecda
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99782
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
In the VM-specific async transformation, an index is used to generate
fresh temporary names for values that are live across an await.
Before it was always 0 when translating a statement because there are
no live values on entry or exit to a statement.
When translating statements nested inside block expressions there can
be live values, so the index should not be reset.
Closes https://github.com/dart-lang/sdk/issues/36466
Change-Id: I6103d75c25f312ab1538a7c0f8fee0fea9f01b27
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/98664
Commit-Queue: Kevin Millikin <kmillikin@google.com>
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
This change replaces kernel AST declarations of fields and functions
with bytecode declarations.
Size of dilp files is reduced by 11-12%.
Startup latency:
Time to the first full frame: 1.945s -> 1.687s
FinalizeClass: 554ms -> 277ms
FinishClassLoading: 296ms -> 156ms
There are following regressions in bytecode mode, which will be fixed
in future:
* dart:mirrors are not supported yet (implementation of mirrors relies
on reading kernel AST in certain cases).
As the result, lib_2/mirrors/* tests fail.
* native extensions are not supported yet (annotations on libraries
and classes in AST are cleaned up as they could reference members
which are now removed from AST).
As the result, standalone_2/entrypoints_verification_test test fails.
* language_2/spread_collections/const_error_test/* tests fail
due to https://github.com/dart-lang/sdk/issues/36286.
Change-Id: I5130f401fd7b84038b136136e7ccc1a6e51b6cea
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/97561
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
* Type arguments are moved to global object table (and de-duplicated).
* Finalize non-recursive generic types at bytecode generation time.
* Constants are moved to global object table (and de-duplicated).
* ICData creation is avoided for direct calls.
* Interface calls reference target member instead of selector name.
Size of a dilp files: 17868K => 15896K (-11%).
Change-Id: I0c9bf338137a0fae6ed90ab6b125ed2b24a1a8ad
Reviewed-on: https://dart-review.googlesource.com/c/91108
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Zach Anderson <zra@google.com>
Reviewed-by: Régis Crelier <regis@google.com>
When creating a closure, receiver is loaded in order to obtain
instantiator type arguments. That access was not capturing
receiver, if a closure was created inside another closure.
Change-Id: I9ec6d9f2c90643e6deb9c4efde1b070a3255a387
Reviewed-on: https://dart-review.googlesource.com/c/91442
Commit-Queue: Régis Crelier <regis@google.com>
Auto-Submit: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Zach Anderson <zra@google.com>
Reviewed-by: Régis Crelier <regis@google.com>
Dispatch interface calls via hashtable rather than inline cache.
InterfaceCall doesn't need to take arguments descriptor into account
when doing method lookup.
Change-Id: I30eae6ea638d1d2ad2cf3ff073c653fee3377f31
Reviewed-on: https://dart-review.googlesource.com/c/86106
Reviewed-by: Zach Anderson <zra@google.com>
Commit-Queue: Régis Crelier <regis@google.com>
This is a major revamp of bytecode metadata format. Now bytecode has
its own serialization mechanisms.
This CL adds 'bytecode component' metadata, which contains bytecode
object table and string table. All references from bytecode (constant
pools) to libraries, classes, members, types and strings now have a new
format. References to frequently used objects are represented as indices
in object table, while rarely used objects are written inline.
This allows VM to cache frequently used objects while reading bytecode.
Representation of strings is aligned with VM - string characters are
stored in separate pools of one-byte and two-byte strings. This allows
VM to avoid UTF-8 decoding and extra copying.
Closure declarations are now explicit. Type parameters no longer require
enslosing scopes when reading/writing them.
Benchmarks:
GenKernelKernelReadAllBytecode (Intel Core i5) +29.84%
GenKernelKernelReadAllBytecode (Intel Xeon) +28.74%
Change-Id: I4b80009733a8f8c038264af74f97c4e094b9e311
Reviewed-on: https://dart-review.googlesource.com/c/85469
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Régis Crelier <regis@google.com>
Reviewed-by: Zach Anderson <zra@google.com>