Instead, this CL wraps sync*'s sync_op in an additional function
that captures local copies of the necessary closure state.
Notably this state includes the parameters of the original sync* function
as these also need to be cloned for each instance.
Note: a large number of .expect files have a small number of changes
due to the additional wrapper function, as well as some extra plumbing.
Bug: https://github.com/dart-lang/sdk/issues/37753
Change-Id: If099dbfe9e5d62979626b852386fd0173fc76de5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/136190
Commit-Queue: Clement Skau <cskau@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
For a method invocation temps might get allocated for both the receiver
and argument(s) so that:
A().foo(await null)
becomes:
Future<void> tmp0
...
tmp0 = A() // <- Type mismatch.
yield ...
tmp0 = tmp0.foo(:result) // <- Correct type.
This happens because the liveness analysis finds that the (previously
dynamic) temps can be reused.
Unfortunately 121988 added typing information to these temps, which
means they can't be simply reused in all cases.
This fix makes the temps dynamic again (by removing the type) but adds
unsafecasts to all VariableGets to propagate the know type.
Bug: https://github.com/flutter/flutter/issues/51828
Change-Id: I89c82763e0d4f8b102bb55dec3b694d017345517
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/138500
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Clement Skau <cskau@google.com>
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>
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>
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>
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>
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>
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>
This CL adds context ID operand to AllocateContext, CloneContext,
LoadContextVar and StoreContextVar bytecode instructions.
The context ID will be used to create distinct Slots and disambiguate
accesses to context objects corresponding to different scopes.
Change-Id: I98850ab763017b71c1dcacfccaffc085bd850e00
Reviewed-on: https://dart-review.googlesource.com/c/84681
Auto-Submit: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Régis Crelier <regis@google.com>
Reviewed-by: Régis Crelier <regis@google.com>
Number of AssertBoolean instructions in the 100Mb dynamic trace of
Richards benchmark in pure interpreted mode (platform with bytecode):
Before: 1812005
After: 251451
Change-Id: I9fe9d37499d73ffa7636c9ca5fb9c2c18dbc1397
Reviewed-on: https://dart-review.googlesource.com/c/84643
Auto-Submit: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Zach Anderson <zra@google.com>
Reviewed-by: Zach Anderson <zra@google.com>
Make StoreIntanceField and LoadField instructions use a single uniform
abstraction: Slot (used to be called NativeFieldDesc), which represents
either a real Dart field (i.e. a field that has a corresponding Field object)
or a native VM field that does not have a corresponding Field object.
This refactoring eliminates raw stores/loads that were just using offsets
before - now we always know what kind of slots we are accessing and
this yields better aliasing information.
Change-Id: I2f48332d58258219565bd961764e8cc9dd4d75ce
Reviewed-on: https://dart-review.googlesource.com/c/74582
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
In order to enable OSR, CheckStackOverflow IL instructions are attributed
with a non-zero loop depth. The original loop depth is passed as operand
of CheckStack bytecode instruction.
Change-Id: I771f59ba9f8d071680a3b7156be380e0f606b7b2
Reviewed-on: https://dart-review.googlesource.com/c/84081
Reviewed-by: Régis Crelier <regis@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Previously MoveSpecial bytecode instruction used unsigned 8-bit A field
to encode target local variable index. This is too restrictive as we allow
signed 16-bit local variable indices.
After this change MoveSpecial has A_X encoding, with A field used for
special index (0 or 1), and signed 16-bit X field used for target local.
Change-Id: Ib87992e192b2923a39a9968913c39476947d3ea5
Reviewed-on: https://dart-review.googlesource.com/c/81440
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Régis Crelier <regis@google.com>
Reviewed-by: Régis Crelier <regis@google.com>
Auto-Submit: Alexander Markov <alexmarkov@google.com>
The new argument order matches the runtime call and requires less copying.
Simplify Function::HasCode()
Remove obsolete workaround when updating type test cache.
Change-Id: I57c988f97ee2259a22730f445f336cd2a085959e
Reviewed-on: https://dart-review.googlesource.com/76584
Commit-Queue: Régis Crelier <regis@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
These bytecode instructions are added in order to shrink constant pools
and reduce time spent for reading constant pool entries.
Change-Id: I8522f73dc7a6236969ac0422c6cb89b945559b2d
Reviewed-on: https://dart-review.googlesource.com/75125
Reviewed-by: Zach Anderson <zra@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Async transformation uses dynamic variables in few places (e.g.
for temporaries and for incomming arguments) - which creates
not strongly typed AST with method invocations having dynamic
receivers and non-null interface targets at the same time.
To maintain strong typedness of the AST we insert unsafeCast
when accessing the temporaries.
Bug: https://github.com/dart-lang/sdk/issues/34463
Change-Id: I11e38c128645ebc8acb0c982a80fe4c5c4036673
Reviewed-on: https://dart-review.googlesource.com/75000
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
This CL adds support for _dynamic_ calls (which are routed through
dynamic invocation forwarders) to bytecode pipeline.
This allows to skip argument type checks for non-covariant and
non-generic-convarint-impl parameters in bytecode when calling instance
members through known interface targets. In case of dynamic call, dynamic
invocation forwarders perform type checks which are otherwise skipped.
This CL also corrects argument type checks in forwarding stubs.
Forwarding stubs are synthetic methods, introduced by front-end to ensure
type safety if some of the argument type checks are skipped.
The specifics of forwarding stubs is that they should use parameter types
of a *target* of a stub for the argument type checks.
This change unifies how argument type checks are performed in bytecode
and in the VM in JIT mode. This allows to mix bytecode methods with
methods JIT-compiled from kernel AST in more cases.
Change-Id: I3a2720a488c8bbb91de1b189eb36ee8c51684a78
Reviewed-on: https://dart-review.googlesource.com/72543
Reviewed-by: Samir Jindel <sjindel@google.com>
Reviewed-by: Régis Crelier <regis@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This CL adds EntryFixed bytecode instruction in bytecode generator and
interpreter. The new instruction is used instead of Entry in prologues of
closures with fixed arguments in order to check number of arguments.
Fixes language_2/closure_call_wrong_argument_count_test in bytecode mode.
Change-Id: I873166a73c5f33e7faca8739cd6f210370e81b2e
Reviewed-on: https://dart-review.googlesource.com/71231
Reviewed-by: Régis Crelier <regis@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This optimization reduces number of context allocations and decreases
number of context levels, making access to captured variables more
efficient.
This change reduces number of context levels in synthetic bodies of
sync* methods to 1. This is important for correctness because
_SyncIterable::iterator clones unerlying sync* closure to create a new
Iterator using _Closure._clone(), and _Closure._clone() clones only
1 level of context.
Fixes language_2/syncstar_yield_test in bytecode mode.
Change-Id: I7a783702b024a7454253f7f4423ec4b2e08ef61f
Reviewed-on: https://dart-review.googlesource.com/70984
Reviewed-by: Régis Crelier <regis@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>