This adds serialization of the new local variables, VariableStatement and VariableDeclaration. This prepares for replacing LegacyVariable with the new variables in all backends.
TEST=existing
Change-Id: I9bbebfbfd372042d6b7027f0fabd24c165699832
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/506240
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Call sites targeting a procedure annotated with `external-effect` will
not produce any code, including the argument which will not be
evaluated.
However, the single parameter will be treated as 'live' for the purposes
of any global analysis the backends do. This is useful for things like
protobuf shaking where a user may want to retain certain protobuf
messages without actually emitting the code that retains those messages.
Today this functionality is available internally in the vm and wasm SDK
libraries. dart2js has similar functionality represented via the
opaqueTrue and opaqueFalse booleans (which will cause conditional
branches to get shaken after analysis). This will replace dart2js's
opaque(True/False).
This also adds validation to the frontend to ensure a method annotated
with 'external-effect' is well-formed.
Change-Id: If1c4096673e655c58fe7638840a16125003e7809
Tested: Backend tests for codegen were added. A frontend test was added for the validation. A language test was added to confirm the behavior.
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/476020
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Nate Biggs <natebiggs@google.com>
StreamingFlowGraphBuilder::BuildTryFinally talks about 5 different
cases where a finally block needs to be executed:
1) break/continue in a loop
2) continue in a switch
3) return statement
4) try body is an open fragment
5) exception is thrown inside try
StreamingFlowGraphBuilder::BuildTryFinally itself only handles cases
4 and 5. So when we added branch coverage to the finally inside
BuildTryFinally, we missed cases 1, 2, and 3, which go through
TranslateFinallyFinalizers instead.
Bug: https://github.com/dart-lang/tools/issues/2241
Change-Id: I02b38a18452be709d5fabd9945d6570a2f1b5120
Fixes: https://github.com/dart-lang/tools/issues/2241
TEST=SourceReport_BranchCoverage_finallyEdgeCases
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/463220
Commit-Queue: Liam Appelbe <liama@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
When TFA is able to infer type arguments, write _exact type_ into
the inferred types metadata.
Use inferred exact type in the VM: load it from metadata and
attach to a field if necessary. CompileType is extended to hold
exact type if it is known.
In the instruction canonicalizer, if type arguments are loaded from
a value which has a known exact type, then replace this LoadField with
Constant type arguments from exact type.
This allows VM to use inferred type arguments to remove parameter
type checks.
TEST=runtime/tests/vm/dart/eliminate_type_check_using_exact_type_il_test.dart
Closes https://github.com/dart-lang/sdk/issues/61083
Change-Id: I766c5e8c49be406f3e12d38e8d966e5813500c4d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/440064
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Since Dart 2, assert statements only accept bool conditions,
so evaluation of the assert condition can be simplified in the VM.
TEST=existing
Change-Id: I0f54ad66b9d9aef707fef4eac192128a3994e7c9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/425920
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Change core library '_throwNew' helpers to return Never.
Since https://dart-review.googlesource.com/c/sdk/+/405604 flow graph
builder automatically appends Stop and closes fragment after appending
a call with return type Never. So additional 'throw' after calling
'_throwNew' are no longer needed and can be removed.
Also, cleanup unused FlowGraphBuilder::ThrowTypeError() and
replace 'throw' with shorter Stop at the end of 'case'.
TEST=ci
Change-Id: I0a5109fd693c0463c53e70e5dd261f8080bf1132
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/406080
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Previously catch blocks were hanging off the function entry blocks being effectively an alternative entry-point into the function. Now catch blocks are hanging off the try-entry blocks.
Previously all the variables that are used in the catch block and beyond were declared as parameters to catch block. Now only those that have their definitions not dominating catch entry will become parameters (for example, if a variable is assigned in the try-block, it becomes a parameter to catch block).
During OSR, if OSR target entry point is inside some try-blocks, then all of corresponding try-entry/catch-blocks are pulled up to the OSR entry forming a chain that ends with a jump to the OSR target entry.
TEST=vm/dart/trycatch*, ci
Change-Id: Iae20c6548d5d65c63be6d7a53c1b0d2adac7ac31
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/356311
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
With sound null safety front-end guarantees that all logical
expressions have a non-nullable bool type, so legacy AssertBoolean
checks are no longer needed and can be removed.
TEST=ci
Change-Id: If952da7bd0ac83c43de3e5d98845c5e5d8d29f6a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/382744
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This CL changes compounds (structs, unions, and arrays) to be backed
by a TypedDataBase and an int offset.
Before this CL, the compounds where only backed by a TypedDataBase.
This leads to the following issues:
1. Access to nested structs required code for allocating new typed data
views or pointers, which the optimizer then had to prevent from
being allocated after inlining.
2. Runtime branching on whether the TypedDataBase was a Pointer or
TypedData increased code size and prevented inlining.
https://github.com/dart-lang/sdk/issues/54892
This could not be properly optimized if in AOT both typed
data and pointer were flowing into the same compound.
3. Constructing TypedData views required calculating the length of the
view.
After this CL, accessing nested compounds will lead to accesses on the
original TypedDataBase with an extra offset.
This removes the polymorphism on TypedData vs Pointer, because the
final int/float/Pointer accesses in nested compounds operate on
TypedDataBase.
Also, it simplifies creating an `offsetBy` accessor, because it will
no longer have to be polymorphic in typed data vs pointer, nor will it
have to calculate the length of the field.
Implementation details:
* The changes in the CFE and patch files are straightforward.
* VM: Struct-by-value returns (or callback params) are initialized
with an offsetInBytes of 0.
* VM: Struct-by-value arguments (and callback return) need to read out
the offsetInBytes. Before this CL we were passing in the TypedData
as tagged value. With this CL we are passing the TypedData as tagged
value and the offset as unboxed int, from 1 IL input to 2 IL
inputs. (The alternative would have been to take the compound as
a tagged value, but that would have prevented optimizations from not
allocating the compound object in the optimizer.
The FfiCallInstr is updated to have two definitions for the case
where we were passing in the TypedData previously.
The NativeReturnInstr is refactored to be able to take two inputs
instead of 1. (Note that we don't have VariadicInstr only
VariadicDefinition in the code base. So the instruction is _not_
implemented as variadic, rather as having a fixed length of 2.)
* dart2wasm does no longer support nested compounds due to the
compound implementation only storing a pointer address.
https://github.com/dart-lang/sdk/issues/55083
Intending to land this after
https://dart-review.googlesource.com/c/sdk/+/353101.
TEST=test/ffi
CoreLibraryReviewExempt: VM and WASM-only implementation change.
Closes: https://github.com/dart-lang/sdk/issues/54892
Bug: https://github.com/dart-lang/sdk/issues/44589
Change-Id: I8749e21094bf8fa2d5ff1e48b6b002c375232eb5
Cq-Include-Trybots: dart-internal/g3.dart-internal.try:g3-cbuild-try
Cq-Include-Trybots: dart/try:vm-aot-android-release-arm64c-try,vm-aot-android-release-arm_x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try,vm-aot-mac-release-arm64-try,vm-aot-mac-release-x64-try,vm-aot-obfuscate-linux-release-x64-try,vm-aot-optimization-level-linux-release-x64-try,vm-aot-win-debug-arm64-try,vm-aot-win-debug-x64-try,vm-aot-win-debug-x64c-try,vm-appjit-linux-debug-x64-try,vm-asan-linux-release-x64-try,vm-checked-mac-release-arm64-try,vm-eager-optimization-linux-release-ia32-try,vm-eager-optimization-linux-release-x64-try,vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64c-try,vm-ffi-qemu-linux-release-arm-try,vm-ffi-qemu-linux-release-riscv64-try,vm-fuchsia-release-x64-try,vm-linux-debug-ia32-try,vm-linux-debug-x64-try,vm-linux-debug-x64c-try,vm-mac-debug-arm64-try,vm-mac-debug-x64-try,vm-msan-linux-release-x64-try,vm-reload-linux-debug-x64-try,vm-reload-rollback-linux-debug-x64-try,vm-ubsan-linux-release-x64-try,vm-win-debug-arm64-try,vm-win-debug-x64-try,vm-win-debug-x64c-try,vm-win-release-ia32-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/354226
Reviewed-by: Tess Strickland <sstrickl@google.com>
Previously, method extractors (getter functions which return
tear-offs) where implemented in the following way:
Method extractor body is an asm intrinsic which loads a few registers
and jumps to BuildMethodExtractor stubs.
BuildMethodExtractor stub loads more registers, calls AllocateClosure
stub and initializes a few fields of a closure (this stub also used
to call AllocateContext but it is no longer needed for tear-offs).
AllocateClosure allocates a closure object and initializes closure
fields.
Instead of doing 2 hops to the object allocation, method extractor
body now calls AllocateClosure stubs directly which initializes
all closure fields. This saves a jump and a handful of instructions
to load certain things on registers and set closure fields.
Assembler intrinsic for method extractor body and
architecture-specific BuildMethodExtractor stubs are now removed.
Also, as method extractors are really tiny, they are now always
inlined.
TEST=ci
Change-Id: Icfeed18414659a76c7d24d3f6f53a76c91e5bbd3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/356302
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
FFI loads and stores via structs can have a TypedData as receiver,
so this CL updates those loads to `kMayBeInnerPointer`.
This CL adds an IL test to verify that for `Pointer` loads the untagged
value is treated correctly as `kCannotBeInnerPointer`.
(And adds some prefer-inline pragmas to make some common operations
be inlined to avoid allocating `Pointer` objects.)
This CL updates the load in the FFI closures to use a load-field.
This can also potentially enable not allocating a pointer object when
this closure is inlined.
TEST=tests/ffi/unwrap_typeddata_generated_test.dart
TEST=tests/ffi
CoreLibraryReviewExempt: Only adding some pragmas.
Change-Id: If687e54c676f275cc849b3fed526a13766ab331a
Cq-Include-Trybots: luci.dart.try:vm-aot-android-release-arm64c-try,vm-aot-android-release-arm_x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try,vm-aot-mac-release-arm64-try,vm-aot-mac-release-x64-try,vm-aot-obfuscate-linux-release-x64-try,vm-aot-optimization-level-linux-release-x64-try,vm-aot-win-debug-arm64-try,vm-aot-win-debug-x64-try,vm-appjit-linux-debug-x64-try,vm-asan-linux-release-x64-try,vm-checked-mac-release-arm64-try,vm-eager-optimization-linux-release-ia32-try,vm-eager-optimization-linux-release-x64-try,vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64c-try,vm-ffi-qemu-linux-release-arm-try,vm-ffi-qemu-linux-release-riscv64-try,vm-fuchsia-release-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-linux-debug-ia32-try,vm-linux-debug-x64-try,vm-linux-debug-x64c-try,vm-mac-debug-arm64-try,vm-mac-debug-x64-try,vm-msan-linux-release-x64-try,vm-reload-linux-debug-x64-try,vm-reload-rollback-linux-debug-x64-try,vm-ubsan-linux-release-x64-try,vm-win-debug-arm64-try,vm-win-debug-x64-try,vm-win-release-ia32-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/349241
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Instead of implicitly creating closures for FFI
asFunction/lookupFunction APIs in the VM, now they are explicitly expressed in the kernel AST. That makes it possible to analyze
them in TFA.
FFI calls from Dart code into native are now performed in the following way:
```
block {
Pointer #ffiTarget0 = target;
@pragma('vm:ffi:call-closure', _FfiCall<Int32 Function(Int32)>(isLeaf: false))
#ffiClosure0(int arg1) {
_nativeEffect(arg1);
return _ffiCall<int>(#ffiTarget0);
}
} =>#ffiClosure0;
```
_ffiCall method is recognized by the VM and its call is replaced
directly with FFI calling sequence. _ffiCall uses closure
parameters implicitly. No extra trampolines are generated for FFI calls.
TEST=existing
Fixes https://github.com/dart-lang/sdk/issues/54172
Issue https://github.com/dart-lang/sdk/issues/39692
CoreLibraryReviewExempt: Implementation change only.
Change-Id: I92b3ff7391470686151ad0807e2cdbbf1a69d256
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/339662
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
This adds the `Native.addressOf` function, which takes a constant tear-
off of a method annotated with `@Native` as a parameter and returns a
pointer to the underlying C function.
The CFE will resolve these calls in two steps: First, the existing
transformer for `@Native` methods adds a pragma describing the fully-
resolved native annotation (with the asset id inferred from the library
if not given explicitly). Then, the FFI use sites transformer rewrites
calls to `Native.addressOf` by searching for this pragma on the passed
function and passing the `Native` constants to `Native._addressOf`. The
latter method is implemented in the VM, which can re-use existing parts
already used for `@Native` calls.
An alternative implementation strategy would have been to forward
`addressOf` calls to `Native.ffi_resolver_function` directly without
any special consideration in the VM. However, the chosen approach makes
it easier to support static linking in the future, as this requires
unresolved symbols in the generated assembly.
Closes https://github.com/dart-lang/sdk/issues/50552
TEST=pkg/vm/testcases/transformations/ffi/ffinative.dart
TEST=tests/ffi/native_assets/asset_*_test.dart
TEST=tests/ffi/vmspecific_static_checks_ffinative_test.dart
TEST=pkg/analyzer/test/src/diagnostics/ffi_native_test.dart
Cq-Include-Trybots: luci.dart.try:vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try,vm-aot-mac-release-arm64-try,vm-aot-mac-release-x64-try,vm-aot-obfuscate-linux-release-x64-try,vm-aot-optimization-level-linux-release-x64-try,vm-aot-win-debug-arm64-try,vm-aot-win-debug-x64c-try,vm-aot-win-release-x64-try,vm-kernel-precomp-linux-release-x64-try
CoreLibraryReviewExempt: VM & dart2wasm only feature
Change-Id: Ic8e3a390146dffd44c95578f975a4472db79a0ee
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/333920
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Adds a `CachableIdempotentCallInstr` that can be invoked via
`@pragma('vm:cachable-idempotent')` if the call-sites is force
optimized.
The object pool is not visited by the scavenger. So, we store the
results as unboxed integers. Consequently, only dart functions that
return integers can be cached.
Cachable idempotent calls should never be inlined. After the first
call the function not be called again.
The call itself is on a slow path to avoid register spilling on the
fast path.
TEST=vm/cc/IRTest_CachableIdempotentCall
TEST=runtime/tests/vm/dart/cachable_idempotent_test.dart
Bug: https://github.com/dart-lang/sdk/issues/51618
Change-Id: I612e896f27add76f57796c060157e14cc687a0fd
Cq-Include-Trybots: luci.dart.try:vm-aot-android-release-arm64c-try,vm-aot-android-release-arm_x64-try,vm-aot-asan-linux-release-x64-try,vm-aot-linux-debug-simarm_x64-try,vm-aot-linux-debug-simriscv64-try,vm-aot-mac-release-arm64-try,vm-aot-mac-release-x64-try,vm-aot-msan-linux-release-x64-try,vm-aot-obfuscate-linux-release-x64-try,vm-aot-tsan-linux-release-x64-try,vm-aot-ubsan-linux-release-x64-try,vm-aot-win-debug-arm64-try,vm-aot-win-debug-x64c-try,vm-aot-win-release-x64-try,vm-appjit-linux-debug-x64-try,vm-asan-linux-release-x64-try,vm-checked-mac-release-arm64-try,vm-eager-optimization-linux-release-ia32-try,vm-eager-optimization-linux-release-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-linux-debug-ia32-try,vm-linux-debug-simriscv64-try,vm-linux-debug-x64-try,vm-mac-debug-arm64-try,vm-mac-debug-x64-try,vm-msan-linux-release-x64-try,vm-reload-linux-debug-x64-try,vm-reload-rollback-linux-debug-x64-try,vm-tsan-linux-release-x64-try,vm-ubsan-linux-release-x64-try,vm-win-debug-arm64-try,vm-win-debug-x64-try,vm-win-debug-x64c-try,vm-win-release-ia32-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/301601
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
FunctionTearOff node represents a tear-off of the 'call' method of
a Function, so it is basically a no-op:
FunctionTearOff(receiver) == receiver
So we can remove this node early, during lowering transformation on
kernel AST and clean up handling of FunctionTearOff nodes from the VM
and dart2wasm compilation pipelines.
TEST=ci
Change-Id: Ia1500a066a0261076162e018ff0ab502258f606f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/325924
Reviewed-by: Ömer Ağacan <omersa@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This change is almost trivial. The closure is stored on the callback's
RawReceivePort, not in the VM. So we can basically just remove the CFE
check and it pretty much works. The only problem is that we can't set
function.FfiCallbackTarget anymore, so most of the CL is dealing with
that.
A few places were deciding whether an FFI trampoline was a call or a
callback based on whether function.FfiCallbackTarget() was null. But
now the target will be null for async callbacks. So instead I've added
a new value to the FfiCallbackKind enum (and renamed it), and changed
those checks.
Sync callback closures will be a separate CL, because they're more
complicated.
Bug: https://github.com/dart-lang/sdk/issues/52689
Change-Id: I8e5dfb557362e679f66195b735c3c382e6792840
TEST=async_void_function_callbacks_test.dart
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/316160
Commit-Queue: Liam Appelbe <liama@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
a) Remove 2 fields in our object representation:
* PatchClass::library_data_
* Library::kernel_data_
=> This saves O(#libraries + #patch-classes) which can amount up to
10+ MB for big apps, as we save not just the slots but the
[ExternalTypedData] objects they used to reference.
Instead we'll compute the KernelLibraryData when we need it by making a
[TypedDataView] of sub parts of the component.
b) We make a kernel binary be represented by a single [ExternalTypedData].
Whenever we need a sub-part of a kernel binary (e.g. one for each
component for concatinated kernels, or one for a library inside a
component) we use proper [TypedDataView]s for that.
c) As we sometimes need to create a view of only a particular library
within a component we need to find start/end of a library based on
index.
=> We store the library index instead of the library offset on
Library/PatchClass.
=> We can easily derive the start/end of a library from it's index by
looking at the kernel component encoding.
d) We make the [Reader] object work purely based on a pointer - instead
of making it have if/else when reading bytes (either from pointer or
from a view).
e) We make the [KernelProgramInfo] store the kernel_component and
various TD views into it.
TEST=ci
Change-Id: Ibe160881ff48635e834c3d647a977a144b5d0565
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/313561
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
** KernelProgramInfo
The VM can load multiple kernel files into an isolate. Each kernel file
is represented as a [KernelProgramInfo] object. Loading a kernel blob
will result in a tree of objects
Library
- TopLevelClass
+ Field
+ Function
+ Class
+ Field
+ Function
+ ... closure functions ...
The entire tree belongs to one [KernelProgramInfo] object. There are
two exceptions
* after a hot-reload we inject [PatchClass]es (as owners of
old [Field]/[Function] objects) that identify the old kernel data
* expression evaluation functions will get a special data array with
information about the expression evaluation kernel data
=> We attach the [KernelProgramInfo] to the root of the tree, namely
the [Library]
=> We introduce `{Field,Function,Class,Library}::KernelProgramInfo()`
that will get that object - by walking up the chain.
=> We introduce `UntaggedPatchClass::kernel_program_info_` field that
allows saving the old [KernelProgramInfo] (on which the old
[Field]/[Function] objects are based upon) in the [PatchClass].
=> We include the [KernelProgramInfo] in the expression evaluation
data array.
** Scripts
A [Script] object should represent a .dart source file. It contains the
source, line offsets, etc. of that dart source file. The contents of a
dart source file may be used by many classes/libraries or even many
kernel blobs (e.g. via our copying mixin application).
When we build a tree like above, we'll attach a reference to a
[Script] object to [Class] objects. But members of a class may come from
a different script, in which case we inject an intermediary [PatchClass]
that references that other script.
When the compiler frontend loads kernel, builds flow graph, etc we walk
down the kernel binary (the tree above) - all belonging to the same
[KernelProgramInfo] object, but sub-parts may belong to different
[Script]s.
=> We use the existing [ActiveClass] class that keeps track of the
current class & member inside the class we're operating on.
=> Whenever we need the script we get it from the active member
function/class.
** Misc
We make kernel related classes (e.g. [KernelReaderHelper]) independent
of [Script].
We make the [Script] objects hold on to the [KernelProgramInfo] they are
based upon (e.g. for lazy source reading). But since a given [Script]
doesn't belong to a particular kernel blob (multiple kernel blobs may
contain information about the same script) we don't expose this in the
public API.
=> In the future we could have a unique [Script] object per url (instead
of having several as we do now)
TEST=ci
Change-Id: I7bd698f497b0bd8ab8e546540bb1dad5b5a6dd48
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/313381
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
This adds FileUriConstantExpression, a subclass of ConstantExpression, to support correct file offset of annotations for augmentations and patches.
The FileUriExpression is used to carry the file uri of the expression
before constant evaluation.
TEST=general/patch_annotations
Change-Id: I0dc8a0cb97dd530fd1960785d38c2d5e4883c3dd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/311660
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
This CL replaces `late Finalizable` variables with the original and
a nullable non-late variable. Every assignment is done first to the
late variable, and the immediately to the nullable non-late shadow
variable. The reachability fences are then inserted only for the
nullable non-late shadow variable.
The advantage of this is that the semantics are fully valid and none
of the further compiler pipeline has to know about late Finalizables.
(1) We remove the special casing in the VM.
(2) The TFA logic with finalizables is no longer blocked.
The downside of this approach is that we use more memory, we need
two fields at runtime, one storing a null and the other storing a
sentinel on initiazation. Moreover, we get some extra store
instructions.
TEST=pkg/vm/testcases/transformations/ffi/finalizable_late.dart
TEST=pkg/vm/testcases/transformations/ffi/finalizable_late_2.dart
TEST=tests/language/vm/regress_49005_test.dart
Closes: https://github.com/dart-lang/sdk/issues/51511
Change-Id: Ifedd3387a368233a2d01e1bcaa9f5e3eceb76856
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/286782
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
This is follow up to 65f4a733bb,
which switched optimized code to use fixed frame for outgoing
arguments.
Change Kernel to IL translation to handle null-checks in
invocations differently: this code used to duplicate receiver on
the stack to accomodate for PushArgument in unoptimized code, but
PushArgument has not been inserted since f4e61eacfd,
which means duplication of the receiver is no longer necessary.
TEST=ci
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-dwarf-linux-product-x64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-debug-simarm_x64-try,vm-kernel-precomp-nnbd-linux-release-simarm64-try
Change-Id: I6c1f1e8c354f9ea92424b6602b83b9e9ebce8b69
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/284184
Commit-Queue: Slava Egorov <vegorov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
'is' tests against record types are split into series of 'is' tests of
record fields. This is more efficient as record instances cannot be
added to subtype test caches (because type of a record instance
depends on types of its fields).
This change also adds canonicalization and constant evaluation of
LoadFieldInstr for record fields.
Performance on a trivial micro-benchmark (on x64):
JIT (RunTime): 4519104.5 -> 20031.5
AOT (RunTime): 4352583.0 -> 26281.6
TEST=ci
Issue: https://github.com/dart-lang/sdk/issues/49719
Change-Id: I2ed464cd3b31f365b17805f4e7debe1d6d1051fa
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/268080
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This is a reland of commit e2d6cb69fb
Original change's description:
> Reland "[vm/compiler] Optimize switch statements"
>
> This is a reland of commit f5228127f8
>
> Original change's description:
> > [vm/compiler] Optimize switch statements
> >
> > Switch statements that either contain only integers or only enum values of the same type can be optimized.
> >
> > Depending on the number of switch expressions and the number of holes that the range of switch expressions contains, either a binary search or a jump table is used.
> >
> > TEST=runtime/test/vm/dart{,_2}/optimized_switch
> > TEST=tests/language{,_2}/switch
> >
> > Fixes: https://github.com/dart-lang/sdk/issues/49585
> >
> > Co-authored-by: Gabriel Terwesten gabriel@terwesten.net
> >
> > Change-Id: I62dcdb7843107f03de7e468c60b4db52ec78f676
> > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/253787
> > Reviewed-by: Alexander Markov <alexmarkov@google.com>
> > Commit-Queue: Alexander Markov <alexmarkov@google.com>
>
> TEST=runtime/test/vm/dart{,_2}/optimized_switch
> TEST=tests/language{,_2}/switch
>
> Change-Id: Ie96e5ff41dce33e2425ba9ad15ecd931d09bec6e
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/255700
> Reviewed-by: Alexander Markov <alexmarkov@google.com>
> Commit-Queue: Alexander Markov <alexmarkov@google.com>
TEST=runtime/test/vm/dart{,_2}/optimized_switch
TEST=tests/language{,_2}/switch
Change-Id: I56f8d25a88bb856115550c5da3f02c80c7547802
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/256180
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This is a reland of commit f5228127f8
Original change's description:
> [vm/compiler] Optimize switch statements
>
> Switch statements that either contain only integers or only enum values of the same type can be optimized.
>
> Depending on the number of switch expressions and the number of holes that the range of switch expressions contains, either a binary search or a jump table is used.
>
> TEST=runtime/test/vm/dart{,_2}/optimized_switch
> TEST=tests/language{,_2}/switch
>
> Fixes: https://github.com/dart-lang/sdk/issues/49585
>
> Co-authored-by: Gabriel Terwesten gabriel@terwesten.net
>
> Change-Id: I62dcdb7843107f03de7e468c60b4db52ec78f676
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/253787
> Reviewed-by: Alexander Markov <alexmarkov@google.com>
> Commit-Queue: Alexander Markov <alexmarkov@google.com>
TEST=runtime/test/vm/dart{,_2}/optimized_switch
TEST=tests/language{,_2}/switch
Change-Id: Ie96e5ff41dce33e2425ba9ad15ecd931d09bec6e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/255700
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Switch statements that either contain only integers or only enum values of the same type can be optimized.
Depending on the number of switch expressions and the number of holes that the range of switch expressions contains, either a binary search or a jump table is used.
TEST=runtime/test/vm/dart{,_2}/optimized_switch
TEST=tests/language{,_2}/switch
Fixes: https://github.com/dart-lang/sdk/issues/49585
Co-authored-by: Gabriel Terwesten gabriel@terwesten.net
Change-Id: I62dcdb7843107f03de7e468c60b4db52ec78f676
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/253787
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
The kernel builder relied on only seeing expressions emitted by the
finalizable transform (variable get and this) as arguments to the fence.
However, other transforms can run later. In this case the expression
was turned into a constant.
This CL changes the implementation to accept any expression rather than
accepting a subset of expressions.
TEST=tests/ffi/regress_49402_test.dart
Closes: https://github.com/dart-lang/sdk/issues/49402
Change-Id: I1a962a5b7a38099eb5c3bbf5a5a8145b16727d97
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/250744
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
This CL changes the IL building for reachability fences to their call
sites. This enables us to catch the field load and tell it to not emit
an initialization check for late fields.
The sentinel value will now flow into the ReachabilityFenceInstr, where
it will be discarded.
TEST=tests/language/vm/regress_49005_test.dart
Closes: https://github.com/dart-lang/sdk/issues/49005
Change-Id: Ic21c9905290925eb83860d8394b13be7dd7592c1
Cq-Include-Trybots: luci.dart.try:vm-ffi-android-debug-arm64c-try,vm-ffi-android-debug-arm-try,vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-reload-rollback-linux-debug-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/244628
Reviewed-by: Liam Appelbe <liama@google.com>
Commit-Queue: Daco Harkes <dacoharkes@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>
Previously, compiler looked at the size of Dart source code when
deciding that the method is huge and needs to be compiled
with less optimizations. That size includes comments and nested
closures, so it is very inaccurate and the heuristic had
false positives seen in practice.
This change revises the heuristic to look at number of kernel
AST nodes, which are counted during building of flow graph.
This change also introduces --print_huge_methods option which
shows the warning if method is huge and compiled with less
optimizations.
TEST=manually verified that huge method from
https://github.com/flutter/flutter/issues/94461 is printed
when --print_huge_methods option is specified.
Issue: https://github.com/dart-lang/sdk/issues/48495
Issue: https://github.com/dart-lang/sdk/issues/48284
Change-Id: I81188b0cc3c147423e9cee91f2a6f544d60d319b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/235173
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>