The inliner code is called from AOT/JIT call specializer on functions
where it knows the target. The callsite might be dynamic, in which case
the target function is a dyn:* forwarder (for calls which have one or
more non-implicit arguments).
The dyn:* forwarders inherit the recognized kind from their target. That
means the inliner has to take special care when trying to inline
functions: It can only rely on the static type safety for interface
calls, not for dynamic calls.
This CL fixes an existing bug where the call specializer knows the
target is a list and method recognizer builds custom graph for the list
indexing operator without ensuring that the index is actually an
integer.
The existing test will start failing on a dependent CL:
tests/language_2/list/double_index_in_loop2_test.dart
Issue https://github.com/dart-lang/sdk/issues/37737
Change-Id: Ic107fe736c1b6151562880919c39d1c650c119fd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151849
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Tess Strickland <sstrickl@google.com>
After constant propagation is performed on the callee function body
during inlining, there are extra opportunities for specializing
calls. Unspecialized calls are not inlined, so it is important to
specialize those calls during inlining to open further opportunities
for inlining.
With this extra pass inliner is able to inline get:length after
specializing inlined List.generate constructor, and eliminate
bounds check from the initialization loop.
This change improves micro-benchmark creating 100,000 lists using
List<int>.generate(1000, (int x) => x, growable: false);
in AOT mode on x64 from 308ms to 167ms.
This makes it on par with pre-NNBD fixed-size list initialization:
var result = List<int>(1000);
for (var i = 0; i < 1000; i++) {
result[i] = i;
}
In fact, after all optimizations final flow graph (and generated
code) for List.generate and explicit loop become very similar.
This change has no effect on Flutter gallery size in release mode.
Issue: https://github.com/dart-lang/sdk/issues/42283
Change-Id: I3566386608733226e1c11cb5d6892cd869e564d7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151466
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Instead of having identical cases for every instruction that implements
RedefinedValue, just have one generic piece of code.
Change-Id: If3f4905a578eb345ae3d740d1f539d346c6223af
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150985
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Commit-Queue: Aske Simon Christensen <askesc@google.com>
This includes support for calling Dart_PropagateError in native code
when doing FFI calls, and catching uncaught exceptions with Dart_IsError
when doing FFI callbacks.
The support for Dart_PropagateError adds a catch entry to the FFI
trampoline, which prevents inlining these trampolines in AOT. This
regresses the FfiCall benchmarks by 1-2% in AOT.
In addition, Dart_PropagateError requires maintaining a bit whether we
entered native/VM code from generated code through FFI or not. That way
we can do the proper transition on the exception path. When entering
generated code, we store this bit on the stack, right after the entry
frame.
Design: http://go/dart-ffi-handles
Issue: https://github.com/dart-lang/sdk/issues/36858
Issue: https://github.com/dart-lang/sdk/issues/41319
Change-Id: Idfd7ff69132fb29cc730931a4113d914d4437396
Cq-Include-Trybots: luci.dart.try:vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64-try,app-kernel-linux-debug-x64-try,vm-kernel-linux-debug-ia32-try,vm-kernel-win-debug-x64-try,vm-kernel-win-debug-ia32-try,vm-kernel-precomp-linux-debug-x64-try,vm-dartkb-linux-release-x64-abi-try,vm-kernel-precomp-android-release-arm64-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-simarm64-try,vm-kernel-precomp-android-release-arm_x64-try,vm-kernel-precomp-obfuscate-linux-release-x64-try,dart-sdk-linux-try,analyzer-analysis-server-linux-try,analyzer-linux-release-try,front-end-linux-release-x64-try,vm-kernel-precomp-win-release-x64-try,vm-kernel-mac-debug-x64-try,vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-nnbd-linux-debug-x64-try,analyzer-nnbd-linux-release-try,front-end-nnbd-linux-release-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/145591
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Operator== has parameter type Object, which is non-nullable in NNBD
strong mode. This is useful, as null should be handled magically by
the implementation, and the body of operator== should never receive
null.
However, VM handles comparison of an object with null inside
operator==, so its parameter type should not be taken into account
when inferring type of ParameterInstr. Otherwise implicit null
handling code is removed by the optimizer.
Fixes https://github.com/dart-lang/sdk/issues/42287
Change-Id: I856a2ce47a11309e8c32d4d9bb481d7cc03bab85
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151021
Reviewed-by: Régis Crelier <regis@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This is a reland of 6ecd8a10ea
Original change's description:
> [vm] MemoryCopy instruction for copying between typed data and strings.
>
> Used for copying the bytes from the Uint8List to the _OneByteString in
> String.fromCharCodes and the pure-ASCII case of UTF-8 decoding.
>
> Issue https://github.com/dart-lang/sdk/issues/42072
> Closes https://github.com/dart-lang/sdk/issues/41703
>
> Change-Id: I1ae300222877d1c6e64e32c2f40b8fb187a584c0
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/149500
> Commit-Queue: Aske Simon Christensen <askesc@google.com>
> Reviewed-by: Martin Kustermann <kustermann@google.com>
Change-Id: Ia231c521e5f2db168cfc6094dfc7322327dedc6d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150925
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Aske Simon Christensen <askesc@google.com>
This is a reland of 6a98e2719e
Original change's description:
> [VM/nnbd] Canonicalize TypeParameter objects in the VM.
>
> Prior to this CL, type parameters were all assumed canonical, even duplicate ones.
>
> Per a new convention introduced in this CL, the type parameter array in generic classes and generic functions contains canonical type parameters. As these type parameters get cloned with a different nullability, they are inserted in a new hash table of canonical type parameters.
>
> This fixes performance issue https://github.com/dart-lang/sdk/issues/41421
>
> Change-Id: I9086158fa6b6261e9997bb50edec6d7c54abbfa1
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/148223
> Commit-Queue: Régis Crelier <regis@google.com>
> Reviewed-by: Ryan Macnak <rmacnak@google.com>
Change-Id: I4a42d0f9d53c2244b1a638432ed2cd6a055fa72a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150266
Commit-Queue: Régis Crelier <regis@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
This reverts commit 6ecd8a10ea.
Reason for revert: Breaks ABI
Original change's description:
> [vm] MemoryCopy instruction for copying between typed data and strings.
>
> Used for copying the bytes from the Uint8List to the _OneByteString in
> String.fromCharCodes and the pure-ASCII case of UTF-8 decoding.
>
> Issue https://github.com/dart-lang/sdk/issues/42072
> Closes https://github.com/dart-lang/sdk/issues/41703
>
> Change-Id: I1ae300222877d1c6e64e32c2f40b8fb187a584c0
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/149500
> Commit-Queue: Aske Simon Christensen <askesc@google.com>
> Reviewed-by: Martin Kustermann <kustermann@google.com>
TBR=kustermann@google.com,askesc@google.com
Change-Id: I5fc0b58da80dca23c91b57ec2833492e9d0885a8
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150802
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Speeds up decoding across the board, with medium-length pure ASCII
strings seeing about 2x on X64 and IA32.
Closes https://github.com/dart-lang/sdk/issues/41702
Change-Id: I1c8e0bc69baaaeb6755d4c775e6fa0e6d18e1c57
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/148762
Commit-Queue: Aske Simon Christensen <askesc@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
This reverts commit 6a98e2719e.
Reason for revert: Unexpected test failures
Original change's description:
> [VM/nnbd] Canonicalize TypeParameter objects in the VM.
>
> Prior to this CL, type parameters were all assumed canonical, even duplicate ones.
>
> Per a new convention introduced in this CL, the type parameter array in generic classes and generic functions contains canonical type parameters. As these type parameters get cloned with a different nullability, they are inserted in a new hash table of canonical type parameters.
>
> This fixes performance issue https://github.com/dart-lang/sdk/issues/41421
>
> Change-Id: I9086158fa6b6261e9997bb50edec6d7c54abbfa1
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/148223
> Commit-Queue: Régis Crelier <regis@google.com>
> Reviewed-by: Ryan Macnak <rmacnak@google.com>
TBR=rmacnak@google.com,alexmarkov@google.com,asiva@google.com,regis@google.com
Change-Id: I0ca3b6b66e2281c285eba6b564f78c0e6b2f2217
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150265
Reviewed-by: Régis Crelier <regis@google.com>
Commit-Queue: Régis Crelier <regis@google.com>
Prior to this CL, type parameters were all assumed canonical, even duplicate ones.
Per a new convention introduced in this CL, the type parameter array in generic classes and generic functions contains canonical type parameters. As these type parameters get cloned with a different nullability, they are inserted in a new hash table of canonical type parameters.
This fixes performance issue https://github.com/dart-lang/sdk/issues/41421
Change-Id: I9086158fa6b6261e9997bb50edec6d7c54abbfa1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/148223
Commit-Queue: Régis Crelier <regis@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Clean up signatures of runtime functions in object.{cc,h} using the trail to avoid cycles. Move the trail to the last parameter of these functions.
Introduce a trail in IsSubtypeOf() to avoid cycles introduced by bounds of F-bounded types. Issue uncovered by the new normalization tests.
Change-Id: I3241c7e4023a09c122e1594b7aff90b5b103f4f4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150180
Commit-Queue: Régis Crelier <regis@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Initializer functions are created lazily at compile time when generating
LoadField which calls initializer. This may happen in the background
compiler thread, where Field objects are cloned.
EnsureInitializerFunction should be called from original field, and it
should be properly synchronized to make sure there are no races with
mutator thread.
Change-Id: Icc339afa2ee410385019c72c717737719767d367
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150166
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
We already have tests that exercise this, namely:
- ffi_2/regress_39044_test
- ffi_2/vmspecific_send_port_id_test
Though the bug only appears if C++ compiler decides to evaluate arguments
in a different order. This happens to be only the case on Windows.
We don't have Windows hardware with Android phones on our CI, which is
why this was not caught earlier.
We have manually confirmed (via building app on windows with this fix
and running on android) that the issue is fixed by this change.
Fixes https://github.com/flutter/flutter/issues/54948
Change-Id: I51109cf1062964a5fb77948cffb9e2ba8fe2055f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/149980
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
When replacing an unboxed phi with its contant value we should not
try to insert unboxing instruction before the phi - as phis exist
outside of the normal stream of instructions and InsertBefore does
not work on them.
Instead we should insert unboxing into the block which contains
the phi.
Original test is expanded to cover this case as well now.
Fixes https://github.com/dart-lang/sdk/issues/42164
TEST=vm/cc/ConstantPropagator_Regress35371
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-debug-x64-try
Fixed: 42164
Change-Id: I53f984216e53195206fb8247b0ed8999590415a3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/149842
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
This addresses an issue that AOT snapshot, disassembly and flowgraph are different when generated on Windows vs Linux.
Difference is caused by different order of targets in CallTargets, caused by the fact that qsort doesn't have to preserve the order of equal elements in the original list.
While qsort on Linux preserves original (by id) order, on Windows it does not.
See https://github.com/flutter/flutter/issues/44425 for context.
Change-Id: I74c17fd83e5ae21f9733712a87de8f55a1ba94fd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/149496
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Aprelev <aam@google.com>
At present calling convention code is guarded by _WIN64 macro, which indicates that compiler is running on Windows, doesn't take into account target os. This causes problems when one attempts to generate aot snapshot for Android os.
Fixes https://github.com/flutter/flutter/issues/44425.
Change-Id: I8b21d9e9c357071f29632826dd7bbedc19be00a2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/149497
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Aprelev <aam@google.com>
Load*Field and Init*Field IL instructions are fused into load
instructions with 'calls_initializer' flag.
A new, more powerful elimination of lazy initializer calls uses
data flow analysis and load forwarding (place numbering).
In addition to improved elimination of initializer calls,
fusing instructions avoids extra load after field is already
loaded for lazy initialization check.
Fixes https://github.com/dart-lang/sdk/issues/41417
Change-Id: Ibb2a63f84b9b0c970db67b3d6684ec15384a64e7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/148283
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
To avoid stopping all mutators when updating subtype test caches, we
ensure that any updates to the subtype test cache will be visible in a
consistent way to mutators by adding a store-release barrier when
updating the backing array of the STC.
Since STCs are always grown by allocating a new array with size+1, there
is no need to actually add barriers when accessing the individual
entries of the backing store.
To prevent multiple writers creating STCs and patching the pool or
updating a STC we add a mutex.
Issue https://github.com/dart-lang/sdk/issues/36097
Change-Id: Ic705619fe16772565ac11438fd15d3977cbb49c0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/149164
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
Recognized factories have known result type and its type arguments
and length are automatically forwarded (length is forwarded only for
fixed-size lists).
List.filled factory is recognized only if optional 'growable' parameter
is not passed.
Fixes https://github.com/dart-lang/sdk/issues/42019
Change-Id: I0d63428f1c4667f3981447a939dbef67170e542e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/149385
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Before this change we would replace unboxed definitions (those with
representation not equal to kTagged) which is too loose and causes issues
in subsequent passes, which assume that replacements have normalised
representation.
After this change we make sure that replacement has a matching
representation.
Closes https://github.com/dart-lang/sdk/issues/35371
Fixes https://github.com/dart-lang/sdk/issues/41971
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-debug-x64-try
Change-Id: I48543893562acf4f8516651196eba7c0c0769a22
Fixed: 35371,41971
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/103139
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
In --enable-isolate group is
* turned off, then we have 1<->1 mapping between isolate and isolate
group, so moving the locks should have no impact
* turned on, then we have N<->1 mapping between isolates and isolate
group, mutators need to use the same locks to guarantee exclusive
access (e.g. to symbol table, type canonicalization, type arguments
canonicalization, ...)
This is a follow-up to share the program structure in AOT mode across
multiple isoltes.
In order to move the existing `Isolate::type_canonicalization_mutex_` to
`IsolateGroup` (and thereby make all mutators use the same lock), we need
to remove the `RunWithMutatorsStopped()` usage in the runtime entry.
=> Without this it can lead to deadlocks.
In order to remove usage of `RunWithMutatorsStopped()` we will change
access to the cached type arguments array to use load-acquire barriers
in generated code and store-release barriers in runtime code.
A nice side effect is that it reduces `sizeof(dart::Isolate)`.
Closes https://github.com/dart-lang/sdk/issues/41912
Issue https://github.com/dart-lang/sdk/issues/36097
Change-Id: Ifd42691524fe41ffe8bb4e2623c5b8c1151de973
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/148539
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Régis Crelier <regis@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Instead of maintaining separate list of static fields which
needs to be flushed into list of retained fields in Iterate()
keep track of which precompilation phase we are in - and add static
fields into the retained set only if we are in the fixpoint
code generation (aka Iterate()) phase.
Apply the same treatment to selectors as well.
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-debug-x64-try
Change-Id: I2c7c7bdf268eaee9623ab1be5cf3eb022991a7c6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/148403
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Previous variant of the code did not handle FutureOr<T> and Comparable<U>
correctly - variables of these types can contain a smi value if T can be a
subclass of num or if U can be num.
Rename HasNonSmiAssignableInterface to CanReceiverBeSmiBasedOnInterfaceTarget
to better conway its meaning.
Fixes https://github.com/flutter/flutter/issues/57398
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try
Change-Id: I67b29908e057632e62c46fb327a5c805fcc78d74
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/149063
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
It might be too late to remove redundant phis in EliminateDeadPhis
because EliminateDeadPhis runs after OptimizeBranches, and
OptimizeBranches may be able to eliminate more branches if redundant
phis are cleaned up.
This change moves elimination of redundant phis into canonicalization
pass which is repeated more frequently.
Fixes recent regressions on several micro-benchmarks after
https://dart-review.googlesource.com/c/sdk/+/139314
Change-Id: Ib0148564615dbd0adb88e93b938ca9f3f59cabfd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/148792
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This saves one instruction for every BoxInt64 overflow check, reducing
the instructions size for Flutter benchmarks by between 0.26% and 1.03%
(0.26% for Flutter Gallery).
Also add OVERFLOW and NO_OVERFLOW condition aliases to arm and arm64.
Change-Id: I82990419b448f21a22ea2cc7a15a9497d3275943
Cq-Do-Not-Cancel-Tryjobs: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/145860
Commit-Queue: Aske Simon Christensen <askesc@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
This is a partial fix for https://github.com/dart-lang/sdk/issues/41939
Let's take one step at a time, but later, we should be able to leave the bound as dynamic, since mutual subtyping of bounds is now implemented.
Change-Id: I57f725ba5b02237a64ae77593f340438f7159ab7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/148515
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Régis Crelier <regis@google.com>
This removes the only stub code with a function owner.
Change-Id: I629eb3a1b231430afaf0a2777032bba8eaddd2aa
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/148124
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Previously, AssertSubtype instructions could only be created with a
compile-time AbstractType value for sub_type and super_type. Relax this
so that AssertSubtype instructions can be created with possibly
non-constant Values instead.
Currently, all AssertSubtype uses still have constant sub- and
supertypes, so for now we check at code generation that we indeed
have constants for these values and only handle the constant case. Thus,
there should be no impact on size or speed of the generated code from
these changes. Follow-up work will add code generation for non-constant
sub- and supertypes and add uses the generalized form.
Bug: https://github.com/dart-lang/sdk/issues/40813
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm_x64-try,vm-kernel-precomp-linux-release-simarm64-try
Change-Id: Ib1512b3e07a016d68a8e0c670ce857b8ac1b2777
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/147520
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>