This CL implements `NativeFinalizer` in the GC.
`FinalizerEntry`s are extended to track `external_size` and in which
`Heap::Space` the finalizable value is.
On attaching a native finalizer, the external size is added to the
relevant heap. When the finalizable value is promoted from new to old
space, the external size is promoted as well. And when a native
finalizer is run or is detached, the external size is removed from the
relevant heap again.
In contrast to Dart `Finalizer`s, `NativeFinalizer`s are run on isolate
shutdown.
When the `NativeFinalizer`s themselves are collected, the finalizers are
not run. Users should stick the native finalizer in a global variable to
ensure finalization. We will revisit this design when we add send and
exit support, because there is a design space to explore what to do in
that case. This current solution promises the least to users.
In this implementation native finalizers have a Dart entry to clean up
the entries from the `all_entries` field of the finalizer. We should
consider using another data structure that avoids the need for this Dart
entry. See the TODO left in the code.
Bug: https://github.com/dart-lang/sdk/issues/47777
TEST=runtime/tests/vm/dart(_2)/isolates/fast_object_copy_test.dart
TEST=runtime/vm/object_test.cc
TEST=tests/ffi(_2)/vmspecific_native_finalizer_*
Change-Id: I8f594c80c3c344ad83e1f2de10de028eb8456121
Cq-Include-Trybots: luci.dart.try:vm-kernel-reload-rollback-linux-debug-x64-try,vm-kernel-reload-linux-debug-x64-try,vm-ffi-android-debug-arm64c-try,dart-sdk-mac-arm64-try,vm-kernel-mac-release-arm64-try,pkg-mac-release-arm64-try,vm-kernel-precomp-nnbd-mac-release-arm64-try,vm-kernel-win-debug-x64c-try,vm-kernel-win-debug-x64-try,vm-kernel-precomp-win-debug-x64c-try,vm-kernel-nnbd-win-release-ia32-try,vm-ffi-android-debug-arm-try,vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-mac-debug-x64-try,vm-kernel-nnbd-mac-debug-x64-try,vm-kernel-nnbd-linux-debug-ia32-try,benchmark-linux-try,flutter-frontend-try,pkg-linux-debug-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-gcc-linux-try,vm-kernel-optcounter-threshold-linux-release-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-obfuscate-linux-release-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64c-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/236320
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
The order of operations for type inference of a generic invocation is
now:
1. Create some constraints on type parameters by trying to match the
return type of the invocation target as a subtype of the incoming
type context. (For a constructor invocation, the return type of
the invocation target is considered the raw uninstantiated type of
the class enclosing the constructor declaration.)
2. Downwards inference: partially solve the set of type constraints
accumulated in step 1, to produce a preliminary mapping of type
parameters to type schemas.
3. Recursively infer all arguments to the invocation, except that if
experimental feature `inference-update-1` is enabled, skip any
arguments that are function literals (a.k.a. "closures"). Obtain
the type contexts for the recursive inference by substituting the
preliminary mapping (from step 2) into the corresponding parameter
types of the invocation target. For each argument that is
recursively inferred, create additional constraints on type
parameters using the resulting static type.
4. If no arguments were skipped during step 3, go to step 7 (this
always happens if `inference-update-1` is disabled).
5. Horizontal inference: partially solve the set of type constraints
accumulated so far, to produce an updated preliminary mapping of
type parameters to type schemas.
6. Recursively infer all of the invocation arguments that were
previously skipped. As in step 3, obtain the type contexts for the
recursive inference by substituting the preliminary mapping (this
time from step 5) into the corresponding parameter types of the
invocation target. Again, for each argument that is recursively
inferred, create additional constraints on type parameters using
the resulting static type.
7. Upwards inference: solve the set of type constraints accumulated so
far, to produce a final mapping of type parameters to types. Check
that each type is a subtype of the bound of its corresponding type
parameter.
8. Check that the static type of each argument is assignable to the
type obtained by substituting the final mapping (from step 7) into
the corresponding parameter type of the invocation target.
9. Finally, obtain the static type of the invocation by substituting
the final mapping (from step 7) into the return type of the
invocation target.
This addresses simpler cases of
https://github.com/dart-lang/language/issues/731. Note that if
experimental flag `inference-update-1` is disabled, the behavior is
unchanged.
Note that steps 2 and 5 use the same algorithm as each other (they
only differ in how many type constraints have been accumulated so
far), so I've renamed the function that performs it from
`downwardsInfer` to `partialInfer`.
Change-Id: I10d3288d4f4ba9e2b6bc18409186ddc67ca2ee9d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/238881
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
In order to address https://github.com/dart-lang/language/issues/731
(improved type inference for `fold` etc.) we're going to need to
sometimes defer analysis of invocation arguments that are closures, so
that closure parameters can have their types inferred based on other
parameters. To avoid annoying the user with inconsistent behaviors,
we defer analysis of closures in all circumstances, even if it's not
necessary to do so for type inference purposes.
This has a minor user-visible effect: if an invocation contains some
closures and some non-closures, any demotions that happen due to write
captures in the closures are postponed until the end of the
invocation; this means that the write-captured variables remain
promoted for other invocation arguments, even if those arguments
appear after the closure. This is safe because there is no way for
the closure to be called until after all of the other invocation
arguments are evaluated. See the language tests in this CL for
details.
Note that this change only has an effect when the experimental feature
`inference-update-1` is enabled.
Change-Id: I283fc5eb07af2aeca0a06d523011d8c4617fbad7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/237720
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This allows us to avoid some redundant computation (we don't have to
match up arguments to the corresponding parameters twice). It also
paves the way for supporting improved type inference of `fold`
(https://github.com/dart-lang/language/issues/731) because it will
allow us to resolve some arguments (gathering more constraints), then
compute a new set of inferred types, then resolve more arguments, and
so on, rather than forcing us to do all the constraint gathering at
the end.
Change-Id: I67d8b8228390ced14281145a4614f66c8e3c7e73
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/238622
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
In the process, I removed 'useFastaParser' from both the public API and
the implementation class. I also removed 'enableTiming' from the public
API.
The other getters were left because they seem like reasonable options
for plugins to want to query. If you disagree, we can address them in a
future CL.
Change-Id: Ia5630b71190dd68bcd66199baa0c05846fcc37b8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/238661
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
We don't need to call this method from
`InvocationInferrer.resolveInvocation`, because resolution of a call
to `identical` always uses the derived class
`MethodInvocationInferrer`, which inherits proper handling of
`identicalInfo` from `FullInvocationInferrer.FullInvocationInferrer`.
Change-Id: Ic511befee498bd241d2d33240b4b388a0ed74be4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/238601
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Rather than compute a preliminary `invokeType` prior to calling
`_visitArguments`, we just compute the necessary substitution to go
from `rawType` to `invokeType`, and let `_visitArguments` apply it
when needed. This will improve efficiency when I add support for
better type inference of `fold` (see
https://github.com/dart-lang/language/issues/731), because it will
allow multiple passes of type inference without having to recompute
`invokeType` each time. Also, it gives `_visitArguments` access to
the `rawType`, which I will take advantage of in a follow-up CL to
make constraint generation happen at a more reasonable time.
Change-Id: I2ecabac10c0ec91fc994b4cf2d8f33a5b532a99e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/238600
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
`_visitArguments` handles walking through the argument list,
recursively performing type inference on each argument.
`_recordIdenticalInfo` handles the necessary integration with flow
analysis to support type promotion via `identical(variable, null)`
tests.
We no longer call `super.resolveInvocation` from the overriden method
`FullInvocationInferrer.resolveInvocation`, but instead call
`_visitArguments` and `recordIdenticalInfo` directly.
This is part of a larger arc of work to enable better type inference
of `fold` and similar methods (see
https://github.com/dart-lang/language/issues/731). It will allow me
to add some additional parameters to `_visitArguments` that relate to
type inference, without complicating the API of `resolveInvocation`.
Change-Id: I6d8ac1af4cfbadf86d5fbfd4ba1b4652707ecfdf
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/238505
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
All of the changes here should be non-breaking; they should only result
in _fewer_ diagnostics.
New cases of "check the parent": parent is
* BinaryExpression
* ForElement
* IfElement
* IndexedExpression
* PostfixExpression
* SpreadElement
New cases of a "real use": parent is
* AssertInitializer
* AssertStatement
* ConstructorFieldInitializer
* ForEachParts
* ForEachPartsWithDeclaration
* ForLoopParts
* IfStatement
* ThrowExpression
* WhileStatement
* YieldStatement
Bug: https://github.com/dart-lang/sdk/issues/47685
Change-Id: Ib3fa216d45d01a728f73795b32b52f204eb140e5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/238264
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
This means we no longer need the _getArgumentList method, which in
turn means we can remove three derived classes whose only purpose was
to provide implementations of it.
Change-Id: Ia2fc14fdd27871cb70279a13cc8b6ca27f97ac8c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/238360
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
`FullInvocationInferrer.resolveInvocation` only sets `inferrer` to
non-null in the event that `rawType` is non-null. So inside an `if
(inferrer != null)` block we can safely assume `rawType` is non-null.
Change-Id: I05a56cd2f54d9658877cf24ed8ec4493eabc42d8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/238381
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Rather than have a separate subclass of `MethodInvocationInferrer` to
handle `identical`, with a method override for `_iterateArguments`
that makes calls to flow analysis in between handling arguments, we
now have an `_isIdentical` method to determine whether the flow
analysis calls are needed, and the logic for calling into flow
analysis is directly in the base class implementation of
`resolveInvocation`.
This change will be necessary to support
https://github.com/dart-lang/language/issues/731 (improved type
inference for functions like `Iterable.fold`) because it will require
changing the order in which we visit arguments sometimes, so the
technique of overriding `_iterateArguments` won't work anymore.
Bug: https://github.com/dart-lang/language/issues/731
Change-Id: I77bd20b10494da941a1bc8b5fc63968c6c2c68cc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/238120
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
* Make `MicroContextObjects` constructor private, which is not used
outside the library.
* Remove unused `analysisContext2` constructor parameter.
* Make `tryMatchSubtypeOf` private, which requires a parameter of
private type.
* Make `_FileStateFiles` public, as it is used outside the library.
* Return empty for void-typed functions.
Change-Id: If67a69effdbbaed2eb364788e52eeb60270a0c19
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/237855
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>