Flow analysis implements field promotion using an extension of SSA
(static single assignment) analysis.
In traditional SSA, an analysis phase assigns a collection of SSA
nodes to each local variable in the program, such that each SSA node
represents a region of control flow in which there are no assignments
to the variable, and no control flow joins that might affect the
variable's value. Each local variable read expression is therefore
associated with an SSA node, establishing the invariant that two reads
that share the same SSA node are known to produce identical results.
In flow analysis, SSA nodes are also assigned to property get
expressions, with a similar invariant: two property gets that share
the same SSA node are known to produce identical results. To ensure
soundness, flow analysis generally only considers a property get
expression to be promoted if the get has the same SSA node as a
previous type test.
There's an exception, though: if a property get is associated with an
SSA node that arose from a control flow join, it may be appropriate to
consider it promoted, if the SSA nodes that were joined are both
considered to be promoted. For example, consider the code below:
class C {
final int? _i;
C(this._i);
}
f(bool b, C c1, C c2) {
C c3;
if (b) {
c3 = c1;
if (c3._i == null) return;
} else {
c3 = c2;
if (c3._i == null) return;
} // (1)
print(c3._i + 1); // (2)
}
At (2), it makes sense to consider `c3._i` to be promoted, because
`c3._i` was type checked in both control flow paths leading up to the
join point at (1). However, since those two control flow paths contain
different assignments to `c3`, at the time that the join point (1) is
analyzed, flow analysis assigns a fresh SSA node to `c3._i`, distinct
from the two SSA nodes that were type checked.
To ensure that the promotion is preserved, a new method is introduced,
`SsaNode._join`, which creates the fresh SSA node and updates the
newly created flow model to preserve the promotion. The bulk of the
heavy lifting is done by `SsaNode._joinProperties`, which recursively
walks the `_promotableProperties` maps of the two SSA nodes being
joined, creating fresh promotions for all the properties that should
have their promotions preserved.
This required plumbing some new parameters through
`VariableModel.join` (which calls `SsaNode._join`), so that
`SsaNode._joinProperties` can find the promotion information along the
two incoming control flow paths, and can create fresh promotions for
the outgoing control flow path.
Fixes https://github.com/dart-lang/sdk/issues/53146.
Change-Id: I6e53b3363ab5d769bef1b96f0ccd380fa2ca39df
Bug: https://github.com/dart-lang/sdk/issues/53146
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/320580
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
This reverts commit 7bdbc0560e as it makes dart crash on Windows 7 and earlier.
Bug: https://github.com/flutter/flutter/issues/130554
Change-Id: I61224ea89aec968465e2bc4fa1dafe0eca215677
TEST=ci
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/320620
Auto-Submit: Alexander Aprelev <aam@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Alexander Aprelev <aam@google.com>
Commit-Queue: Siva Annamalai <asiva@google.com>
- Initial and final marking no longer visit all of new-space, reducing the STW pause for major GC.
- A scavenge during concurrent marking must forward / filter objects in the marking worklist that are moved / collected, increasing the STW pause for minor GC.
- Unreachable intergenerational cycles and weak references are collected in the next mark-sweep instead of first requiring enough scavenges to promote the whole cycle or weak target into old-space.
- Artificial minor GCs are no longer needed to avoid memory leaks from back-to-back major GCs.
- reachabilityBarrier is now just a count of major GCs.
TEST=ci
Change-Id: I8c2c64b120766571b62d3bd8dab37ae81c2dca98
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319583
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
Clarify that the diagnostic applies to optional named parameters, that support is already removed, and showcase the symbols themselves for extra clarity.
Change-Id: I0920793452bb8b0aaba04cbc96e89bb8acd571c0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/320442
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Previously we had started to move core patch files to libraries for
better code organization.
However moving implementation classes to separate libraries required
making the implementation types and internal members public.
This has two problems:
1. The members can be accessed by end users via `dynamic`.
2. More importantly, because those public internal members can impact
TFA results.
We don't care about (1) too much, but (2) is important.
So in this CL we make the libraries part of `core` again, while keeping
the file structure the same when possible.
With implementation files listed as "patches" they can still have their
own imports, but hey won't be importing each other as they're all part
of the same library.
This is the first CL in series that merges `_boxed_int` and
`_boxed_double` libraries back to `core`, and `_typed_data` back to
`typed_data`. Follow-up CLs will merge the other libraries back to
`core`.
The conventions for files is:
- Files that patch core types are named `..._patch.dart`.
- Implementation classes are in separate files. Names of the
implementation files is either the implementation class name (e.g.
`boxed_double.dart` for `_BoxedDouble`), or when implementing multiple
class, name of the library being implemented (e.g. `typed_data.dart`).
Following these conventions, `double.dart` is renamed to
`double_patch.dart`.
Because we lose namespacing for helpers, the helper intrinsics like
`double` `_toInt` are moved to class members, as before.
One problem in the current CL is that in `libraries.yaml`, when I
`include` a target, I can't add more `core` patches to the included
target, the patch section overrides the included patches. I don't know
if this is a bug yet. If it is, we can refactor `libraries.yaml` after
it's fixed.
Tested: Changes covered by existing tests.
Change-Id: Iba7d81d383deff61aad521000f0ca9cf9276dcfb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319500
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
This add support for patterns in textual outline by requiring callers
to pass an 'enablePatterns' flags. For incremental compilation this is
derive from the previously built library. For the textual outline suite
this is derived from the experimental flags.
Change-Id: Iebf420162c83808e2d0e2acb6e7fc147fec5c617
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/320520
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This extracts the FolderOptions and TestOptions logic from suite.dart
to be shared with other test suites. The former is used to allow
the textual outline suite to have a formatter crash while a feature
is not yet released. These crashes have caused quite a bit of churn
in the early development of new features.
Change-Id: Iac607ea8fc1c8ae0ba9dd0397bccb9a11fbae9a0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319982
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
This change is intended to be a temporary fix until the broken
internal test is fixed.
Change-Id: I0f6c334bd54c605306318b95836e91755252580f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/320340
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
This should fix one of the issues turning the bots red.
Change-Id: I5729e1f4cb8dd12b33391113166581d5d6618e67
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/320260
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Avoids the VM later failing with a misleading "Out of Memory" message when allocation fails for lack of available file descriptors.
Cf. 78732b243e
TEST=ulimit
Change-Id: I2edbcf98cc8e30f70e6b0efe63b2d301fb03e191
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/320180
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
There are many failing Dart2JS language/library tests due to differences in backend implementations.
We want to adopt a strategy that allows us to make explicit the different expectations we have of each backend.
This adds logic for the 2 most common causes of these backend related failures (numbers and implicit checks) but we can add more of these as we discover more use cases.
This is an iteration on https://dart-review.googlesource.com/c/sdk/+/293463 attempting to integrate feedback from that change.
Change-Id: Ie3a1954066199695d92881497e940385467c9a12
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/311780
Commit-Queue: Nate Biggs <natebiggs@google.com>
Reviewed-by: Stephen Adams <sra@google.com>
Reviewed-by: Lasse Nielsen <lrn@google.com>
Revisions updated by `dart tools/rev_sdk_deps.dart`.
dartdoc (e8d00c0..5cfb1f3):
5cfb1f36 2023-08-07 Sam Rawlins Bump to analyzer 6.1.0 (#3474)
ffi (f01dfca..e2c01a9):
e2c01a9 2023-08-08 Slava Egorov Expose pointer to free from allocators (#203)
http (7e9ed12..9f167a7):
9f167a7 2023-08-08 Alex James Remove example test from java_http (#1001)
test (5d571d6..9b1828f):
9b1828f4 2023-08-09 Nate Bosch Send a MessagePort to host on frame startup (#2072)
ae2ab1ee 2023-08-08 Jacob MacDonald publish test_core v0.5.6 (#2076)
2e9bba21 2023-08-08 Jacob MacDonald fix failing casts when talking to minified apps from the host (#2075)
tools (f14bf2e..295ff92):
295ff92 2023-08-10 Elias Yishak Fix empty string for `CLIENT_ID` from being sent when user decides to opt in (#144)
bc6c9f0 2023-08-09 Elias Yishak Clean up on dart docs across all dart files under lib (#142)
Change-Id: I75147259ce51f240c1dc359896ec7709bada288f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319783
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Auto-Submit: Devon Carew <devoncarew@google.com>
- This causes inconsistency between AppJIT trained kernel service including eliminating barriers but the runtime compensation being disabled.
- The barrier elimination in the SuspendState stubs cannot be disabled.
TEST=ci
Bug: https://github.com/dart-lang/sdk/issues/52990
Change-Id: I4c5c7817a51f303d6f3bdbea8c15ad23a3e57735
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319906
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Previously, the flow control logic for patterns didn't use the
`FlowModel.split` or `FlowModel.unsplit` methods at all. This meant
that if a control flow join point occurred in pattern logic, flow
analysis would consider the split point to be whatever split point was
established by the enclosing expression or statement. In the case of
an if-case statement, it would consider the split point to be at the
beginning of the scrutinee expression.
Split points are used by flow analysis for the sole purpose of
ensuring that joins propagate type promotions the same way in dead
code as they do in live code (so that users introducing temporary
`throw` expressions or `return` statements into their code do not have
to deal with nuisance compile errors in the (now dead) code that
follows. The consequence of flow analysis considering the split point
to be at the beginning of the scrutinee expression is that if the
scrutinee expression is proven to always throw, then joins that arise
from the pattern or guard may not behave consistently with how they
would have behaved otherwise. For example:
int getInt(Object o) => ...;
void consumeInt(int i) { ... }
test(int? i) {
if (
// (1)
getInt('foo')
case
// (2)
int()
// (3)
when i == null) {
} else {
// (4)
consumeInt(i);
}
}
In the above code, there is a join point at (4), joining control flows
from (a) the situation where the pattern `int()` failed to match, and
(b) the situation where `i == null` evaluated to `false` (and hence
`i` is promoted to non-nullable `int`). Since the return type of
`getInt` is `int`, it's impossible for the pattern `int()` to fail, so
at the join point, control flow path (a) is considered
unreacable. Therefore the promotion from control flow path (b) is
kept, and so the call to `consumeInt` is valid.
In order to decide whether to preserve promotions from one of the
control flow paths leading up to a join, flow analysis only considers
reachability relative to the corresponding split point. Prior to this
change, the split point in question occurred at (1), so if the
expression `getInt('foo')` had been replaced with `getInt(throw
UnimplementedError())`, flow analysis would have considered both
control flow paths (a) and (b) to be unreachable relative to the split
point, so it would not have preserved the promotion from (b), and
there would have been a compile time error in the (now dead) call to
`consumeInt`.
This change moves the split point from (1) to (2), so that changing
`getInt('foo')` to `getInt(throw UnimplementedError())` no longer
causes any change in type promotion behavior.
The implementation of this change is to add calls to `FlowModel.split`
and `FlowModel.unsplit` around all top-level patterns. At first glance
this might appear to affect the behavior of all patterns, but actually
the only user-visible effect is on patterns in if-case statements,
because:
- In switch statements and switch expressions, there is already a
split point before each case.
- In irrefutable patterns, there is no user-visible effect, because
irrefutable patterns cannot fail to match, and therefore don't do
any control flow joins.
This change allows the split points for patterns to be determined by a
simple syntactic rule, which will facilitate some refactoring of split
points that I am currently working on.
Change-Id: I55573ba5c28b2f2e6bba8731f9e3b02613b6beb2
Bug: https://github.com/dart-lang/sdk/issues/53167
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319381
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Incremental compiler only runs procedure transformations during expression compilation, as opposed to modular library transformations
that are run during initial compilation stage on libraries (including JS interop-related transformations).
In this CL:
- Add implementation of `performTransformationsOnProcedure` to dev compiler target
- runs JS interop-related transformations on a procedure.
- Add related expression evaluation tests
- expressions using JS interop and extension types.
Closes: https://github.com/dart-lang/sdk/issues/53048
Change-Id: I085920db9c3af4c680283c574087d8901c99dfcf
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319585
Commit-Queue: Anna Gringauze <annagrin@google.com>
Reviewed-by: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
While our benchmarks don't involve overlapping memory between source
and destination, general methods for copying between TypedData must.
Thus, our benchmark for using the C interface via FFI must use memmove
instead of memcpy.
To avoid having to update our benchmark configurations, the name of
that benchmark is unchanged.
In addition, this CL adds filtering for benchmark names and turning on
and off specific outputs for quick comparisons when running manually.
Change-Id: I20616549d8bc9ab481884846d3f13df20a3c854e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319981
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
This reverts commit 58f4b3a7a6.
Reason for revert: Causes build failures in google3 - b/295404395
Original change's description:
> [dart2js] Use symbols for isolate tags
>
> All supported browsers have JavaScript Symbols so use Symbols.
> Avoiding string property names should fix a bug where separate
> programs running in separate iframes arrive at using the same
> property.
>
> Issue: #53154
> Change-Id: I470dc47de3ad381aeab670cf62d62e53f2e72873
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319865
> Reviewed-by: Sigmund Cherem <sigmund@google.com>
> Commit-Queue: Stephen Adams <sra@google.com>
Issue: #53154
Change-Id: I581fe08aee6ac9e2d74e813641a942223553cf5d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319980
Auto-Submit: Oleh Prypin <oprypin@google.com>
Commit-Queue: Alexander Thomas <athom@google.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Reviewed-by: Alexander Thomas <athom@google.com>
Commit-Queue: Oleh Prypin <oprypin@google.com>
Adds special representations of runtime types for the interface types
`Object`, `Function` and `Record`. With this change, all types with
non-interface subtypes have special representations, which avoids some
special cases down the line.
Change-Id: I61b4da20fa1cc62d42e1770278a3272028c9e2a0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/318681
Reviewed-by: Joshua Litt <joshualitt@google.com>
All supported browsers have JavaScript Symbols so use Symbols.
Avoiding string property names should fix a bug where separate
programs running in separate iframes arrive at using the same
property.
Issue: #53154
Change-Id: I470dc47de3ad381aeab670cf62d62e53f2e72873
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319865
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Commit-Queue: Stephen Adams <sra@google.com>