Weaves the flag `inference-update-4` through to `FlowAnalysis` and updating both the analyzer and CFE point-of-entry to include the flag.
This flag will be used in `flow_analysis.dart` to hide upcoming bug fixes to flow analysis.
Change-Id: Ib0004eb4bcf0b6e579116632b5973fe969e51e90
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/388582
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
This CL changes the CFE's
TypeConstraintGatherer._isNullabilityAwareSubtypeMatch method so that
it is responsible for restoring the constraint state if there is no
match, making it consistent with the contraint gathering methods in
the analyzer and _fe_analyzer_shared.
This made it possible to remove much of the calls to state restoring
logic that _isNullabilityAwareSubtypeMatch previously had to do after
making recursive calls to itself, as well as a lot of state restoring
logic in _fe_analyzer_shared. It also made it possible to eliminate
_tryNullabilityAwareSubtypeMatch from the CFE (since
_isNullabilityAwareSubtypeMatch now has the same behavior).
Making this change now should hopefully simplify the remaining steps
in sharing type variable constraint generation logic, since it will no
longer be necessary to adjust state restoring logic when moving code
between the CFE and _fe_analyzer_shared.
I also took the liberty of rewriting some of the documentation
comments to try to clarify the new conventions.
In the process I also discovered several instances of unnecessary
state restoring logic in the analyzer; I'll make a separate CL to
clean those up (and adjust the analyzer documentation too).
Change-Id: If74c8be06f1d53f61d109e5ea2a8526d5cbcd347
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/388265
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Auto-Submit: Paul Berry <paulberry@google.com>
This CL:
* Makes the incremental compiler copy over the metadata just created for
the libraries compiled into the Component returned.
* Preserves metadata when serializing via the incremental serializer.
* Fixes loading a multi-component with metadata.
* Lets the VM copy all metadata in "_combinePendingDeltas"
when there is only one component to "combine".
It is generally my view, that to do better, metadata has to be redone
(among other things likely has to live on the Library instead).
https://github.com/dart-lang/sdk/issues/39302
With this CL:
```
rm foo.dill ; tools/sdks/dart-sdk/bin/dart pkg/frontend_server/bin/frontend_server_starter.dart --no-print-incremental-dependencies --target=vm --sdk-root=out/ReleaseX64 --platform=vm_platform_strong.dill --output-dill=foo.dill --packages=.dart_tool/package_config.json pkg/compiler/lib/src/dart2js.dart
tools/sdks/dart-sdk/bin/dart pkg/vm/bin/dump_kernel.dart foo.dill foo.dump
grep "@vm.call-site-attributes" foo.dump | wc -l
```
(i.e. a one-shot compile) prints 9500.
```
rm foo.dill ; tools/sdks/dart-sdk/bin/dart pkg/frontend_server/bin/frontend_server_starter.dart --incremental --no-incremental-serialization --no-print-incremental-dependencies --target=vm --sdk-root=out/ReleaseX64 --platform=vm_platform_strong.dill --output-dill=foo.dill --packages=.dart_tool/package_config.json pkg/compiler/lib/src/dart2js.dart
tools/sdks/dart-sdk/bin/dart pkg/vm/bin/dump_kernel.dart foo.dill foo.dump
grep "@vm.call-site-attributes" foo.dump | wc -l
```
(i.e. an incremental compile but without incremental serialization) prints 9500.
and
```
rm foo.dill ; tools/sdks/dart-sdk/bin/dart pkg/frontend_server/bin/frontend_server_starter.dart --incremental --no-print-incremental-dependencies --target=vm --sdk-root=out/ReleaseX64 --platform=vm_platform_strong.dill --output-dill=foo.dill --packages=.dart_tool/package_config.json pkg/compiler/lib/src/dart2js.dart
tools/sdks/dart-sdk/bin/dart pkg/vm/bin/dump_kernel.dart foo.dill foo.dump
grep "@vm.call-site-attributes" foo.dump | wc -l
```
(i.e. an incremental compile with incremental serialization) prints 9500.
If not deleting the dill file first (which will then initialize from it)
metadata might be different though.
If there are no changes and the incremental serializer was and is used
we should still get `9530` (because the bytes are just copied), but
otherwise we might get different results because it's not really
possible to otherwise pick-and-choose and/or merge the metadata.
TEST=Existing tests that it didn't get worse.
Change-Id: I19d530357e7e2a174d7408dbbf0ed7e0248a5b70
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/358444
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
This change combines function-handling logic from the analyzer's
`TypeConstraintGatherer._functionType0` and the CFE's
`TypeConstraintGatherer._isNullabilityAwareSubtypeMatch` methods into
`TypeConstraintGenerator.performSubtypeConstraintGenerationForFunctionTypes`,
which is in `_fe_analyzer_shared`.
The CFE and the analyzer have some pretty significant differences in
how they represent function types:
- In the analyzer, all function parameters are in a single
`parameters` list; each element of this list (of type
`ParameterElement`) can be queried to find out if it is named or
unnamed, and if it is required or optional. A convention enforced
partially by the `FunctionType` constructor is that the `parameters`
list stores reqired unnamed parameters first, then either optional
unnamed parameters or named parameters; named parameters are sorted
by name. The analyzer provides additional getters
`namedParameterTypes`, `normalParameterNames`,
`normalParameterTypes`, `optionalParameterNames`, and
`optionalParameterTypes`, which provide other views of this
information (for example, `namedParameterTypes` contains just the
named parameters, as a map from name to `ParameterElement`).
- In the CFE, unnamed and named parameters are in two separate lists
(`positionalParameters`, of type `List<DartType>`, and
`namedParameters`, of type `List<NamedType>`); in
`positionalParameters`, required parameters come before optional
ones. A single integer (`requiredParameterCount`) indicates how many
elements of `positionalParameters` are required, and by convention,
`namedParameters` is sorted by name.
In order to share logic between these representations, I had to come
up with a common API that these two representations could be easily
adapted to. The analyzer's representation proved to be easier to
adapt, so I based the common API mostly on the CFE's representation,
but with some name changes for clarity. The shared API is:
- `positionalParameterTypes` gets a list of positional parameter types
- `requiredPositionalParameterCount` tells how many entries in
`positionalParameterTypes` are required.
- `returnType` gets the function type's return type.
- `sortedNamedParameters` gets a list of information about named
parameters. The list elements are sorted by name, and each element
of this list is of type `FunctionParameterStructure` (a common
interface implemented both by the analyzer's `ParameterElement` and
the CFE's `NamedType`).
- `typeFormals` gets a list of the function type's formal type
parameters.
To minimize the performance impact of adapting the analyzer to this
API, the analyzer computes `positionalParameterTypes`,
`requiredPositionalParameterCount`, and `sortedNamedParameters` at the
time a `FunctionType` is constructed. Hopefully this should not be too
much of a performance hit, since doing so does not take too much more
effort than checking that the named parameters are sorted (which the
`FunctionType` constructor was already doing).
This is based on previous work by Chloe Stefantsova in
https://dart-review.googlesource.com/c/sdk/+/386480.
Change-Id: Iefe18d72771146399d81747ceab9c929516b0523
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/386322
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
The `unknownFunction` marker object was used to indicate a type of a
function that accepts an unspecified amount of arguments. The uses of
the marker object in the CFE are already replaced by
InvocationTargetType and its subtypes. This CL simply removes the
object itself, which is no longer in use.
Change-Id: I48fe53460d1f96f4fee0a91fb1572e219fbd1502
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/387702
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This moves the prefix builders from the libraryNameSpace to a
separate prefixNameSpace. This is in preparation for the enhanced parts
feature where the prefix scope are handled separately from the library
scopes.
Change-Id: I8fda7529634b70ff511d2aab736d18ed1ad99086
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/387041
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This splits up [computeAmbiguousDeclarationForScope] into
[computeAmbiguousDeclarationForExport], which is moved to [LibraryBuilder], and [computeAmbiguousDeclarationForImport].
Change-Id: I2fad4784904eef6caf731a41300b98c6f172039d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/387080
Reviewed-by: Jens Johansen <jensj@google.com>
These tests cover just the portion of the subtype constraint
generation mechanism that's currently shared between the analyzer and
the CFE. I plan to add more unit tests as more functionality becomes
shared.
Note that as part of this change, I've eliminated the methods
`performSubtypeConstraintGenerationForFutureOrRightSchema` and
`performSubtypeConstraintGenerationForFutureOrLeftSchema`, and instead
made `_performSubtypeConstraintGenerationForFutureOrInternal` public
(renaming it to `performSubtypeConstraintGenerationForFutureOr`). My
rationale for this change is as follows:
- It makes testing easier, since only one method needs to be tested
rather than two.
- Removing these two methods simplifies the call sites in the analyzer
and CFE, since instead of having to use an `if` test to decide which
method to call, they can simply pass in the appropriate boolean
switch for the `leftSchema` argument.
Change-Id: I0911c80fc8e9a4fbdd3dd0063dd203066006c218
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/386861
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
The return type of this method was previously
`TypeDeclarationMatchResult?` (with no explicit type arguments),
meaning that the generic type parameters of
`TypeDeclarationMatchResult` would be filled in by
instantiate-to-bounds as `Object, Object, Object`. But the
implementations always return the more precise type
`TypeDeclarationMatchResult<TypeDeclarationType, TypeDeclaration,
TypeStructure>?`, and the use sites all expect this type. Adding
explicit type arguments improves type safety and probably allows the
compiler to elide some of the type casts involved in pattern matching.
Also, the "mini_ast" implementation of this method contained a subtle
bug: instead of using `unwrappedType.type` for the `typeDeclaration`
Change-Id: Ic7bffc1b0b3e9bfc86c0168d4e6bdf442af8ae39
argument, it should use `unwrappedType.name`. This ensures that if the
type being matched is generic, the generic arguments don't show up in
the `typeDeclaration`.
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/386681
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Short explanation: For whatever reason, when using `identical` on `int`s
the ints are first boxed (`BoxInt64`) before being compared
(`StrictCompare`) whereas just doing `==` just does a compare
(`EqualityCompare`).
Results:
With the CFE compiling (a fixed version of) itself I get these results:
```
instructions:u: -0.5756% +/- 0.0003% (-124825401.80 +/- 64013.17)
```
i.e. almost 125 mio instructions saved.
Another run - with 100 iterations each - I get
```
msec task-clock:u: -0.4927% +/- 0.2585% (-20.85 +/- 10.94)
page-faults:u: 0.0174% +/- 0.0139% (18.80 +/- 15.00)
cycles:u: -0.5233% +/- 0.2683% (-91305451.82 +/- 46815747.30)
instructions:u: -0.5754% +/- 0.0002% (-124793061.49 +/- 37426.30)
branch-misses:u: -1.6903% +/- 1.1207% (-1091410.69 +/- 723627.04)
seconds time elapsed: -0.4863% +/- 0.2581% (-0.02 +/- 0.01)
seconds user: -0.4547% +/- 0.3253% (-0.02 +/- 0.01)
```
In the scanner benchmark with `--string` (i.e. using string scanner) I
get these results:
```
msec task-clock:u: -3.7992% +/- 0.3316% (-190.54 +/- 16.63)
cycles:u: -4.1423% +/- 0.3566% (-836808313.28 +/- 72033424.19)
instructions:u: -3.3524% +/- 0.0000% (-1480262370.08 +/- 828.58)
branch-misses:u: -1.7591% +/- 0.9582% (-1781144.28 +/- 970258.82)
seconds time elapsed: -3.7988% +/- 0.3303% (-0.19 +/- 0.02)
seconds user: -4.0211% +/- 0.4161% (-0.19 +/- 0.02)
```
(Just running the benchmark also sees the characters/µs go from ~93 to
~97).
In the scanner benchmark with `--bytes` (i.e. using the utf8 scanner) I
get these results:
```
msec task-clock:u: -4.2872% +/- 0.4467% (-185.64 +/- 19.34)
cycles:u: -4.2972% +/- 0.4382% (-812955454.92 +/- 82892232.23)
instructions:u: -3.4867% +/- 0.0000% (-1479744935.28 +/- 297.12)
seconds time elapsed: -4.2872% +/- 0.4470% (-0.19 +/- 0.02)
seconds user: -4.2204% +/- 0.4730% (-0.18 +/- 0.02)
```
(Just running the benchmark also sees the bytes/µs go from ~108 to ~113).
In both cases we notice how the actual time, cycles and instructions
agree pretty well.
Combining the data for the compile and the benchmark I assume this CL
actually reduces the runtime of the CFE compiling itself by a about
half a percent.
Change-Id: I67d056837240aef61b6707d02507ab4121b31715
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/385940
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
The parent relation was set up in the SourceFunctionBuilder constructor,
anyway, and this avoids yet another use of the SourceLibraryBuilder in
BuilderFactoryImpl.
Change-Id: Ia0995b6c0a770b205c876eea3a93097337ee39ad
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/386000
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
This change allows to reproduce and minimize the bug in
https://dart-review.googlesource.com/c/sdk/+/385441/2 via this
(mouthful) of a command:
```
out/ReleaseX64/dart pkg/front_end/test/crashing_test_case_minimizer.dart --platform=out/ReleaseX64/vm_platform_strong.dill --invalidate=package:_fe_analyzer_shared/src/messages/codes.dart --invalidate=package:front_end/src/type_inference/assignable_errors.dart --initial-only-outline --load-from-component-before-invalidate --invalidate-all-at-once --packages=.dart_tool/package_config.json pkg/front_end/lib/src/type_inference/assignable_errors.dart
```
Which - after renames - creates a reproduction like this:
```
# Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
# Reproduce a crash.
type: newworld
worlds:
- entry:
- a.dart
sources:
a.dart: |
import 'b.dart';
b.dart: |
export 'c.dart';
c.dart: |
class Message {}
typedef SummaryTemplate = Message Function(int, int, num, num, num);
expectedLibraryCount: 3
- entry:
- a.dart
worldType: updated
expectInitializeFromDill: false
invalidate:
- c.dart
- a.dart
expectedLibraryCount: 3
advancedInvalidation: bodiesOnly
```
(this was already reproduced and fixed in
https://dart-review.googlesource.com/c/sdk/+/385720 but still)
Change-Id: I63d5510b1b848309cc4c74a15cdc1f33400d4861
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/385740
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
References to typedefs were not register in
`fragmentsCreatedWithReferences` and exports would therefore try to
look up the enclosing library through the `Typedef` node. This caused
a crash when the `Typedef` was from a source library, which would not
have had the parent relation set up yet.
Change-Id: I92ace4dd26ed7c357cafeaeebece95b7bd5e68f6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/385720
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
As far as I can tell, these scripts are all only used internally for
formatting generated code, so it should be safe to just parse the code
at the latest language version.
I didn't migrate:
pkg/front_end/test/fasta/textual_outline_suite.dart
I believe that one may need to pass in a specific language version if it
needs to support formatting code from before Dart 3.0. (In particular
if it needs to handle code using old switch constant expressions that
are not supported in Dart 3.0 and later like `case 1 + 2:`.)
Bug: https://github.com/dart-lang/sdk/issues/56687
Change-Id: Ib5cef82c22fc749223095215d3b692e6c27decc7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/385341
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Bob Nystrom <rnystrom@google.com>
Auto-Submit: Bob Nystrom <rnystrom@google.com>