Treats async code like function expressions when adding extra
checks for correctness after a hot reload. This is intended to handle
the cases where code that was statically sound and enqueued before the
reload actually runs after a reload when the soundness may no longer
be valid.
Change-Id: I42cd010175126748937d7df830875bc5b850a565
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/444368
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
Refactors the hot reload test suite to support non-FE server based hot reload. Similar to DartPad it uses a DDC process running in '--persistent_worker' mode and sends bazel requests for each reload.
I call this "stateless" mode because the compilation process itself is not maintaining any state. The necessary metadata is passed from one compilation to the other via a delta dill. This differs from the "stateful" mode where the FE server persists a kernel AST in memory from one compilation to the next.
Disregarding the browsers there are effectively 3 run modes now:
- web stateful
- web stateless (new)
- vm stateful
One key difference between the "stateless" and "stateful" modes is the output format of the JS files. In stateful mode DDC emits a file per library being re-compiled. In stateless mode DDC is emitting a single file with all the libraries.
DartPad's workflow is slightly simpler than what's seen in the stateless mode here. It only supports editing a single library so we skip processing any metadata. To simulate this I've added the special 'main_only' which passes a single library for each reload generation. I've verified that this would fail if not for the change recently made to ddc_module_loader.js.
Change-Id: If05da6dbeded4dd20e9e6d9dfaed52151541a19b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/434340
Commit-Queue: Nate Biggs <natebiggs@google.com>
Reviewed-by: Mark Zhou <markzipan@google.com>
Reviewed-by: Kevin Moore <kevmoo@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
d8 tests weren't executing code after a hot restart due to several factors:
1) subsequent calls to `main` after a hot restart weren't being added to an event loop.
2) periodic timers, which use `setInterval` weren't updated to check for the hot restart generation.
3) d8's simulated timers run synchronously, which interacts poorly with our async implementation. Periodic timers never cede to the async task that handles changing hot restart generation, so they would run forever whenever an error was thrown.
Changes:
* Added a helper to d8.js that cancels all timers.
* d8 now cancels all timers if an async main registers an error (via a handler on main).
* `setInterval` is now implemented.
* The embedder now accepts a publicly modifiable config object. `capturedMainHandler` and `mainErrorCallback` can be set via this object.
Change-Id: I523752ea69e8fd1f1ec0f6f585a484b670534cfc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/421680
Commit-Queue: Mark Zhou <markzipan@google.com>
Reviewed-by: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
This removes the 'bind' and 'bindCall' methods in our runtime in favor of extending 'tearoff' to support their behavior. Also introduces 'superTearoff' for invoking torn off super members late.
Change-Id: I52ab797558a225c57cc2c6197c7b1bfa7f05a3c6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/416763
Commit-Queue: Mark Zhou <markzipan@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Bob Nystrom <rnystrom@google.com>
This new update adds fixes + tests for cross-module super mixins. Super getters can refer to mixins compiled in other modules, so we need to expose all mixin names to make them accessible from their enclosing library.
This is a reland of commit e4c4d0f839
Original change's description:
> [ddc] Overhauling tearoff equality and identity.
>
> Hot reload requires DDC to update how its tearoffs are represented. Tearoffs obey the following conventions:
> * Instance tearoffs are never identical
> * Tearoffs with the same object target and name have the same hash code (even if they resolve to different functions across hot reloads)
> * Two separate tearoffs of the same member are equal
>
> To support this, tearoff equality must not depend on the bound object and method but a composite of the bound object, torn off member name, and the exact class/object from which the member was torn off.
>
> Notable changes:
> * Methods' immediately bound targets are emitted with member signatures. This is required to determine the bound targets for instance and dynamic tearoffs. Bound targets are identified by `libraryUri:class` strings.
> * `applyMixin` passes in a 'true' bound target. This is because mixin applications' members are considered children of their 'on' class (not the mixed in class) wrt equality/hashCode.
> * `bind` is modified to pass in its 'true' bound object to support mixins' super getters.
> * `tearoff` and `staticTearoff` are modified to accept a bound target string (only required for static tearoffs, as they are bound at tearoff-creation-time).
> * Static tearoffs avoid using their bound object for hashcode and equality, as these libraries may be wrapped in proxy objects.
> * Tearoff equality and hashCode are updated to consider bound object, bound name, and its bound method's immediate target.
> * 'noSuchMethod' and 'toString' methods are always accessed through their extension property during signature lookups.
>
>
> Change-Id: Ica5501b6860c605db50aa945bafb6802a7317511
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/406723
> Reviewed-by: Nate Biggs <natebiggs@google.com>
> Reviewed-by: Nicholas Shahan <nshahan@google.com>
> Commit-Queue: Mark Zhou <markzipan@google.com>
Change-Id: I645992030f9106c158426412387ddecafc78e3f4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/415102
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
This reverts commit e4c4d0f839.
Reason for revert: Breaks are blocking roll into flutter
https://logs.chromium.org/logs/flutter/buildbucket/cr-buildbucket/8720592021329723649/+/u/run_test.dart_for_web_canvaskit_tests_shard_and_subshard_0/stdout
Original change's description:
> [ddc] Overhauling tearoff equality and identity.
>
> Hot reload requires DDC to update how its tearoffs are represented. Tearoffs obey the following conventions:
> * Instance tearoffs are never identical
> * Tearoffs with the same object target and name have the same hash code (even if they resolve to different functions across hot reloads)
> * Two separate tearoffs of the same member are equal
>
> To support this, tearoff equality must not depend on the bound object and method but a composite of the bound object, torn off member name, and the exact class/object from which the member was torn off.
>
> Notable changes:
> * Methods' immediately bound targets are emitted with member signatures. This is required to determine the bound targets for instance and dynamic tearoffs. Bound targets are identified by `libraryUri:class` strings.
> * `applyMixin` passes in a 'true' bound target. This is because mixin applications' members are considered children of their 'on' class (not the mixed in class) wrt equality/hashCode.
> * `bind` is modified to pass in its 'true' bound object to support mixins' super getters.
> * `tearoff` and `staticTearoff` are modified to accept a bound target string (only required for static tearoffs, as they are bound at tearoff-creation-time).
> * Static tearoffs avoid using their bound object for hashcode and equality, as these libraries may be wrapped in proxy objects.
> * Tearoff equality and hashCode are updated to consider bound object, bound name, and its bound method's immediate target.
> * 'noSuchMethod' and 'toString' methods are always accessed through their extension property during signature lookups.
>
>
> Change-Id: Ica5501b6860c605db50aa945bafb6802a7317511
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/406723
> Reviewed-by: Nate Biggs <natebiggs@google.com>
> Reviewed-by: Nicholas Shahan <nshahan@google.com>
> Commit-Queue: Mark Zhou <markzipan@google.com>
Change-Id: Ic5694976260189f7215dfa3c2318e9a0656f0de6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/415100
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
Hot reload requires DDC to update how its tearoffs are represented. Tearoffs obey the following conventions:
* Instance tearoffs are never identical
* Tearoffs with the same object target and name have the same hash code (even if they resolve to different functions across hot reloads)
* Two separate tearoffs of the same member are equal
To support this, tearoff equality must not depend on the bound object and method but a composite of the bound object, torn off member name, and the exact class/object from which the member was torn off.
Notable changes:
* Methods' immediately bound targets are emitted with member signatures. This is required to determine the bound targets for instance and dynamic tearoffs. Bound targets are identified by `libraryUri:class` strings.
* `applyMixin` passes in a 'true' bound target. This is because mixin applications' members are considered children of their 'on' class (not the mixed in class) wrt equality/hashCode.
* `bind` is modified to pass in its 'true' bound object to support mixins' super getters.
* `tearoff` and `staticTearoff` are modified to accept a bound target string (only required for static tearoffs, as they are bound at tearoff-creation-time).
* Static tearoffs avoid using their bound object for hashcode and equality, as these libraries may be wrapped in proxy objects.
* Tearoff equality and hashCode are updated to consider bound object, bound name, and its bound method's immediate target.
* 'noSuchMethod' and 'toString' methods are always accessed through their extension property during signature lookups.
Change-Id: Ica5501b6860c605db50aa945bafb6802a7317511
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/406723
Reviewed-by: Nate Biggs <natebiggs@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
* Handle inconsistencies in the type of a notice in reload reports.
* Update expected error messages when the type parameters of a class
change.
* Fail reload tests if rejection error was expected but the actual
error is null.
* Cleanup unused imports in tests.
* Delete change_instance_format7 test because it was split into DDC
and VM specific versions.
Change-Id: I3b4d6cb3126d7c1fad688c393677e053a005687f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/408883
Reviewed-by: Mark Zhou <markzipan@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
A new optional suffix to the file names is added: '.restart'.
This allows us to differentiate between hot reload generations
and hot restart generations. All files with the same generation
should either have the suffix or don't. If present, uses the
recompile-request instruction in the frontend server. If not,
uses the recompile instruction. Tests are renamed and a WIP
README is added to document this change.
Change-Id: I2691c5ec0b7336115a76dc0e0369213e74b6ea21
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/406183
Commit-Queue: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
* Normalize white space around source code strings before producing
diffs by trimming and appending a single newline character.
* Write an empty line between the source code and diff text in
generation files.
* Run dart format on all test files.
With these changes you should be able to run the hot reload suite with
`--diff write` and dart format the code multiple times without
introducing changes in the file.
Change-Id: Ifc0b1dd7032bd448f5f6568c5aa3c18dde076c71
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/405247
Reviewed-by: Mark Zhou <markzipan@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
Tearoffs are now represented as a closure that resolves an underlying bound context and property on access. `_boundMethod` and RTI getters must also be evaluated late.
Additionally, we now both canonicalize static methods and tag them with their types at class-declaration time (though lazily) - so that late resolved closures have access to their types.
Some tests have been updated to expect simpler errors. DDC traditionally emits slightly different errors that might aid in debugging.
Change-Id: I1f762b8df45e0766d16dbc8688073768c8bfd233
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/401321
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
Allows tests to define generation files that are expected to be
rejected as invalid for hot reload.
Tests generation files now support the extension `.reject.dart` to
signal a rejection is expected. A corresponding rejection error
message should be added to the map in the config.json file.
- Add new rejection logic to the file discovery and config file
parsing.
- Add new reload receipts that are output by the runtime utils when
running hot reload tests. These receipts are used to verify that
each file generation was visited (not necessarily accepted) at
runtime.
Change-Id: Ifee698f0d6502ecfceba2d5c733a2c88fb5daf7c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/394564
Commit-Queue: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
This is required when a hot reload causes changes to the subtype hierarchy.
This change also adds RTI operations for clearing subtype caches and deleting type rules.
The DDC Embedder also now accesses the RTI library to clear subtype caches on hot reload.
See: #57049
Change-Id: I50a43ce342f23060bc28a3654c2da37c362492b7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/394040
Reviewed-by: Stephen Adams <sra@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
Type changes across hot reloads need to be performed even if the underlying value has already been initialized.
To avoid extraneous type checks, getters replace themselves with a direct access on their value store on first access.
Also updates our builder to support get/set as property descriptor functions.
Adds some extra conditions that will be cleaned up when pragma support is added (#57049).
Change-Id: I44f4a9e1a6fd8a49aca5e629fb21348170a9d80f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/393041
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
The old hot restart tests only tested DDC-internal state changes, not 'true' hot restart. The 'dart.hotRestart' runtime call is due to be deprecated.
Change-Id: I34e32342bca6fabc886d8283e32ae510f8d49874
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/389400
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
Appending a script to the DOM in Chrome causes microtasks to fire. This change makes the `hotRestart` pathway async and inserts an async callback at the hot restart boundary for d8.
Change-Id: Ib05e9e496b6313d861fb5cb691a5894beed62a6e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/389224
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Add a simple implementation that throws out all libraries and runs the
main method again which triggers all libraries to be initialized with
fresh values.
Move the hot reload tests to the ddc canary test configuration
since that is where the support works at this time.
Update frontend server to use the use the new version of the DDC
LibraryCompiler when the emit library bundle option is true.
Change-Id: I6eba613106672536ef8bfcb0ff0a55749e2fb63c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/381902
Reviewed-by: Kevin Moore <kevmoo@google.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
Reviewed-by: Mark Zhou <markzipan@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
* Extends the frontend server controller to validate/reject compile errors in compiles/recompiles.
* Extends the config to permit an 'expectedError' entry.
* Adds a handful of tests to the suite (adapted from the VM's hot reload tests).
Change-Id: I47d814e375c4c72d0406ebf5bdfee3f1975c64f0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/363800
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
VM hot reload are run via:
1) We first emit a dill for every generation ahead of time (full dill on gen 0, incremental deltas subsequently).
2) We start a VM process at generation 0.
3) The VM process runs until it hits a `hotReload` command. It then uses the VM service protocol to connect to itself and reload the next generation.
4) The VM exits when the next generation isn't found.
* Adds config files to reload tests that allow runtime filtering.
* Implements VM-side hot reloading
* Adds several VM-specific hot reload tests
Change-Id: I1c6ad5c4eed426a0189c1b4af31297c9c1dba717
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/359200
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
* Adds tests for the memory filesystem
* Enables hot restart/reload tests
* Adds flags to the hot reload suite
* Makes path resolution logic windows-friendly
* Adds test-reporting logic for trybots to hot reload tests
Change-Id: Ic51a0b8a3c6f8b6de20b58b2ac185dacf444cf47
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/353788
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Nate Bosch <nbosch@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
The hot reload runner currently only supports d8, but I plan to add support for Chrome and VM execution.
Notable changes:
* Creates `package:reload_test` with helpers for running this suite.
* Updates the module loader with D8-specific branches and hooks for hot reload/restart.
* Exposes DDC runtime variables via a `HotReloadTestRuntime` API.
* Ports constant equality hot restart tests from webdev/dwds (validated to fail if either cache-clearing mechanism fails).
* Partially rolls DDC's d8 preamble forward (towards dart2js's).
* Wraps D8's timer implementation with custom timeout logic to better match Chrome's timing semantics when executing with native JS async.
Tests for the framework and matrix updates will be added in an upcoming change.
Change-Id: I2773b29f464cfd0330e4c653c05e117ae150b4a6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/350021
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>