Commit Graph

637 Commits

Author SHA1 Message Date
Ryan Macnak 1bbb01211d [vm] Fix -Werror=use-after-free in isolate shutdown.
TEST=gcc 12
Change-Id: Ia4aba7b35ee12677799a9aa289a250ae7035ba6d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/259140
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-09-21 17:52:01 +00:00
Vyacheslav Egorov 4a4eedd860 [vm] Clean up ClassTable
* Merge ClassTable and SharedClassTable back together;
* Simplify handling of multiple arrays growing in sync;
* Refactor how reload deals with ClassTable.

The last change is the most important because it makes it
much easier to reason about the code. We move away from
copying bits and pieces of the class table and shared
class table into reload contexts.

Having two class table fields in the isolate group makes
it easier to reason about. One field contains program
class table (one modified by kernel loader and accessed
by various program structure cid lookups) and heap
walk class table (used by GC visitors). Normally these
two fields point to the same class table, but during
hot reload we temporary split them apart: original
class table is kept as a heap walk class table, while
program class table is replaced by a clone and updated
by reload.

If reload succeeds we drop original class table and
set program class table as heap walk one.

If reload fails we drop the program class table and
restore original one from heap walk table.

TEST=ci

Cq-Include-Trybots: luci.dart.try:vm-kernel-reload-linux-release-x64-try,vm-kernel-reload-linux-debug-x64-try,vm-kernel-reload-rollback-linux-debug-x64-try,vm-kernel-reload-rollback-linux-release-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-precomp-tsan-linux-release-x64-try,vm-kernel-tsan-linux-release-x64-try,vm-kernel-precomp-asan-linux-release-x64-try,vm-kernel-asan-linux-release-x64-try
Change-Id: I8b66259fcc474dea7dd2af063e4772df99be06c4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/258361
Commit-Queue: Slava Egorov <vegorov@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2022-09-10 15:12:35 +00:00
Matej Knopp c50869a8cb [VM] trigger message notify callback for each non-service message that came in while message handler was paused.
Closes https://github.com/dart-lang/sdk/pull/49708

TEST=N/A

GitOrigin-RevId: a2a5c2c487daaeb8bd58135e3a011c8e3f1f845e
Change-Id: I9eae4079cdffdb8cd4a07018cfc6efb80a477a2d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/255809
Reviewed-by: Ben Konyi <bkonyi@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2022-09-01 16:17:13 +00:00
Alexander Aprelev f681734aef [vm/send_and_exit] Allow for safepoints when validating exit message.
``` before
$ dart isolate_exit_pause_time_test.dart
.Min(RunTimeRaw): 0.001 ms.
.Avg(RunTimeRaw): 212.399592 ms.
.Percentile50(RunTimeRaw): 49.055 ms.
.Percentile90(RunTimeRaw): 809.049 ms.
.Percentile95(RunTimeRaw): 1009.049 ms.
.Percentile99(RunTimeRaw): 1169.049 ms.
.Max(RunTimeRaw): 1208.049 ms.
```

``` after
$ dart isolate_exit_pause_time_test.dart
.Min(RunTimeRaw): 0.001 ms.
.Avg(RunTimeRaw): 53.87510125 ms.
.Percentile50(RunTimeRaw): 8.05 ms.
.Percentile90(RunTimeRaw): 174.005 ms.
.Percentile95(RunTimeRaw): 217.975 ms.
.Percentile99(RunTimeRaw): 275.033 ms.
.Max(RunTimeRaw): 314.033 ms.
```

Remaining latency after the change is due to large root set formed by pointers_to_verify_at_exit_ that have to be visited during GC.

Fixes https://github.com/dart-lang/sdk/issues/49050
TEST=ci

Change-Id: I1ed7af017f80890900b137a1514e5ffdeb63f53f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/246482
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Aprelev <aam@google.com>
2022-06-08 16:27:22 +00:00
Alexander Markov af4da780be [vm] New async/async* implementation in JIT mode
The new implementation is based on suspend/resume stubs and doesn't
use desugaring of async functions on kernel AST.

Previously, new implementation of async/async* was only supported in
AOT mode. This change adds all necessary bits for the JIT mode:

 * Suspending variable-length frames (for unoptimized code).
 * Handling of Code and pool pointers in Dart stack frames.
 * OSR.
 * Deoptimization.
 * Hot reload.
 * Debugger.

The new implementation is not enabled in JIT mode yet.

Design doc: go/compact-async-await.
TEST=ci

Issue: https://github.com/dart-lang/sdk/issues/48378
Change-Id: I477d6684bdce7cbc1edb179ae2271ff598b7dcc5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/246081
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2022-06-02 23:39:45 +00:00
Ryan Macnak fcc9169885 [vm, gc] Appease TSAN around racy access to IsolateGroup::active_mutators_.
Isolate may be entering or leaving the group while a scavenge is running and using the active mutator count to decide the size of the next to-space. A stale value seen by the scavenger only has performance implications rather than correctness implications, which will get fixed at the next scavenge.

TEST=iso-stress-linux
Bug: https://github.com/dart-lang/sdk/issues/48921
Change-Id: I171e5a460eadba3db6659dccda29c863549d27ea
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/242925
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-04-28 23:27:20 +00:00
Ryan Macnak 57f68b377a [vm, gc] Don't round Scavenger::UsedInWords up to the nearest TLAB.
Rounding usage up to the TLAB causes excessive growth because it gives the growth policy a very inflated view of the survivor ratio.

Ensure new-space grows specifically to provide enough TLABs for active mutators.

TEST=golem
Change-Id: Iab01df18c6a8ac996e0f0b2707c9da7e14c7f4a4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/241689
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-04-26 23:35:54 +00:00
Ryan Macnak fd10f5ab28 [vm, gc] Avoid unnecessary nested GcSafepointOperationScopes.
TEST=ci
Change-Id: Ic12d6d1766cf90808716d301abfa216eb597cb1f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/241201
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-04-18 23:14:37 +00:00
Daco Harkes 4b322a398a [vm] Finalizer / NativeFinalizer fixes
1. Run native finalizers before sending isolate exit message. This way
   users can rely on the isolate exit message for both (1) no Dart code
   executing anymore on that isolate _and_ (2) all native finalizers
   having run. Alternatively, we could opt to not provide this second
   guarantee and document this.

2. Fix UBSAN error by making SetArgumentTo42's argument a `void*`.

3. Fix bug in debug mode, stop reading tags from forwarding addresses.

4. Small optimization: Don't promote 0 bytes from new to old space.

5. Skip finalizer_isolate_groups_run_gc_test in optcounter mode.
   In hot reload mode, GC is guaranteed to run. On all other bots GC
   does not run (nothing happens in the other isolate group). However,
   in optcounter mode enough happens in the other isolate group to
   trigger GCs. Alternatively, we could loosen the test to allow either
   a GC to happen or not.

TEST=runtime/tests/vm/dart(_2)/finalizer/*
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_*

Closes: https://github.com/dart-lang/sdk/issues/48740
Closes: https://github.com/dart-lang/sdk/issues/48715
Closes: https://github.com/dart-lang/sdk/issues/48674

Change-Id: I5e260e087aef48524f2214f5b332caeda18f2e37
Cq-Include-Trybots: luci.dart.try:vm-kernel-ubsan-linux-release-x64-try,vm-kernel-precomp-ubsan-linux-release-x64-try,vm-canary-linux-debug-try,vm-kernel-optcounter-threshold-linux-release-x64-try,vm-kernel-optcounter-threshold-linux-release-ia32-try,app-kernel-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/240043
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
2022-04-07 07:05:27 +00:00
Daco Harkes 532c116cd2 [vm] Implement NativeFinalizer
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>
2022-03-26 09:41:21 +00:00
Daco Harkes e151a81108 Reland "[vm] Implement Finalizer"
Original CL in patchset 1.
Split-off https://dart-review.googlesource.com/c/sdk/+/238341
And pulled in fix https://dart-review.googlesource.com/c/sdk/+/238582
(Should merge cleanly when this lands later.)

This CL implements the `Finalizer` in the GC.

The GC is specially aware of two types of objects for the purposes of
running finalizers.

1) `FinalizerEntry`
2) `Finalizer` (`FinalizerBase`, `_FinalizerImpl`)

A `FinalizerEntry` contains the `value`, the optional `detach` key, and
the `token`, and a reference to the `finalizer`.
An entry only holds on weakly to the value, detach key, and finalizer.
(Similar to how `WeakReference` only holds on weakly to target).

A `Finalizer` contains all entries, a list of entries of which the value
is collected, and a reference to the isolate.

When a the value of an entry is GCed, the enry is added over to the
collected list.
If any entry is moved to the collected list, a message is sent that
invokes the finalizer to call the callback on all entries in that list.

When a finalizer is detached by the user, the entry token is set to the
entry itself and is removed from the all entries set.
This ensures that if the entry was already moved to the collected list,
the finalizer is not executed.

To speed up detaching, we use a weak map from detach keys to list of
entries. This ensures entries can be GCed.

Both the scavenger and marker tasks process finalizer entries in
parallel.
Parallel tasks use an atomic exchange on the head of the collected
entries list, ensuring no entries get lost.
The mutator thread is guaranteed to be stopped when processing entries.
This ensures that we do not need barriers for moving entries into the
finalizers collected list.
Dart reads and replaces the collected entries list also with an atomic
exchange, ensuring the GC doesn't run in between a load/store.

When a finalizer gets posted a message to process finalized objects, it
is being kept alive by the message.
An alternative design would be to pre-allocate a `WeakReference` in the
finalizer pointing to the finalizer, and send that itself.
This would be at the cost of an extra object.

Send and exit is not supported in this CL, support will be added in a
follow up CL. Trying to send will throw.

Bug: https://github.com/dart-lang/sdk/issues/47777

TEST=runtime/tests/vm/dart/finalizer/*
TEST=runtime/tests/vm/dart_2/isolates/fast_object_copy_test.dart
TEST=runtime/vm/object_test.cc

Change-Id: Ibdfeadc16d5d69ade50aae5b9f794284c4c4dbab
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-analyze-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/+/238086
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
2022-03-25 10:29:30 +00:00
Daco Harkes 37526fc8d7 Revert "[vm] Implement Finalizer"
This reverts commit 7dca34c235.

Reason for revert: b/226085355 dart_vm_test crashing. Unclear what
the cause is. Reverting so we can triage the issue.

TEST=This is a revert.

Original change's description:
> [vm] Implement `Finalizer`
>
> This CL implements the `Finalizer` in the GC.
>
> (This CL does not yet implement `NativeFinalizer`.)
>
> The GC is specially aware of two types of objects for the purposes of
> running finalizers.
>
> 1) `FinalizerEntry`
> 2) `Finalizer` (`FinalizerBase`, `_FinalizerImpl`)
>
> A `FinalizerEntry` contains the `value`, the optional `detach` key, and
> the `token`, and a reference to the `finalizer`.
> An entry only holds on weakly to the value, detach key, and finalizer.
> (Similar to how `WeakReference` only holds on weakly to target).
>
> A `Finalizer` contains all entries, a list of entries of which the value
> is collected, and a reference to the isolate.
>
> When a the value of an entry is GCed, the enry is added over to the
> collected list.
> If any entry is moved to the collected list, a message is sent that
> invokes the finalizer to call the callback on all entries in that list.
>
> When a finalizer is detached by the user, the entry token is set to the
> entry itself and is removed from the all entries set.
> This ensures that if the entry was already moved to the collected list,
> the finalizer is not executed.
>
> To speed up detaching, we use a weak map from detach keys to list of
> entries. This ensures entries can be GCed.
>
> Both the scavenger and marker tasks process finalizer entries in
> parallel.
> Parallel tasks use an atomic exchange on the head of the collected
> entries list, ensuring no entries get lost.
> The mutator thread is guaranteed to be stopped when processing entries.
> This ensures that we do not need barriers for moving entries into the
> finalizers collected list.
> Dart reads and replaces the collected entries list also with an atomic
> exchange, ensuring the GC doesn't run in between a load/store.
>
> When a finalizer gets posted a message to process finalized objects, it
> is being kept alive by the message.
> An alternative design would be to pre-allocate a `WeakReference` in the
> finalizer pointing to the finalizer, and send that itself.
> This would be at the cost of an extra object.
>
> Send and exit is not supported in this CL, support will be added in a
> follow up CL. Trying to send will throw.
>
> Bug: https://github.com/dart-lang/sdk/issues/47777
>
> TEST=runtime/tests/vm/dart/finalizer/*
> TEST=runtime/tests/vm/dart_2/isolates/fast_object_copy_test.dart
> TEST=runtime/vm/object_test.cc
>
> Change-Id: I03e6b4a46212316254bf46ba3f2df333abaa686c
> 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-analyze-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/+/229544
> Reviewed-by: Lasse Nielsen <lrn@google.com>
> Reviewed-by: Slava Egorov <vegorov@google.com>
> Reviewed-by: Martin Kustermann <kustermann@google.com>
> Reviewed-by: Ryan Macnak <rmacnak@google.com>
> Commit-Queue: Daco Harkes <dacoharkes@google.com>

TBR=lrn@google.com,vegorov@google.com,kustermann@google.com,rmacnak@google.com,dacoharkes@google.com

Change-Id: I991f6e49896d18a8d70210cf315d858b462d66c9
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: https://github.com/dart-lang/sdk/issues/47777
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-analyze-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/+/238080
Reviewed-by: Slava Egorov <vegorov@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
2022-03-22 11:55:38 +00:00
Daco Harkes 7dca34c235 [vm] Implement Finalizer
This CL implements the `Finalizer` in the GC.

(This CL does not yet implement `NativeFinalizer`.)

The GC is specially aware of two types of objects for the purposes of
running finalizers.

1) `FinalizerEntry`
2) `Finalizer` (`FinalizerBase`, `_FinalizerImpl`)

A `FinalizerEntry` contains the `value`, the optional `detach` key, and
the `token`, and a reference to the `finalizer`.
An entry only holds on weakly to the value, detach key, and finalizer.
(Similar to how `WeakReference` only holds on weakly to target).

A `Finalizer` contains all entries, a list of entries of which the value
is collected, and a reference to the isolate.

When a the value of an entry is GCed, the enry is added over to the
collected list.
If any entry is moved to the collected list, a message is sent that
invokes the finalizer to call the callback on all entries in that list.

When a finalizer is detached by the user, the entry token is set to the
entry itself and is removed from the all entries set.
This ensures that if the entry was already moved to the collected list,
the finalizer is not executed.

To speed up detaching, we use a weak map from detach keys to list of
entries. This ensures entries can be GCed.

Both the scavenger and marker tasks process finalizer entries in
parallel.
Parallel tasks use an atomic exchange on the head of the collected
entries list, ensuring no entries get lost.
The mutator thread is guaranteed to be stopped when processing entries.
This ensures that we do not need barriers for moving entries into the
finalizers collected list.
Dart reads and replaces the collected entries list also with an atomic
exchange, ensuring the GC doesn't run in between a load/store.

When a finalizer gets posted a message to process finalized objects, it
is being kept alive by the message.
An alternative design would be to pre-allocate a `WeakReference` in the
finalizer pointing to the finalizer, and send that itself.
This would be at the cost of an extra object.

Send and exit is not supported in this CL, support will be added in a
follow up CL. Trying to send will throw.

Bug: https://github.com/dart-lang/sdk/issues/47777

TEST=runtime/tests/vm/dart/finalizer/*
TEST=runtime/tests/vm/dart_2/isolates/fast_object_copy_test.dart
TEST=runtime/vm/object_test.cc

Change-Id: I03e6b4a46212316254bf46ba3f2df333abaa686c
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-analyze-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/+/229544
Reviewed-by: Lasse Nielsen <lrn@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
2022-03-22 10:30:18 +00:00
Ryan Macnak 81143e16c4 [vm, gc] Don't perform blocking compactions in response to Dart_NotifyLowMemory.
These GCs usually did not free very much memory but did consume a lot of CPU. They would on low-powered, low-memory devices often take ~1s, during which time the OS might decide the OOM signal wasn't working and kill us before the compaction can complete and free pages. Instead, only release pooled memory.

Also use more appropriate GCReasons in calls of CollectMost/AllGarbage.

TEST=ci
Bug: b/216333343
Change-Id: Ia56b9ca409410f17d40508c69fb1bc9df0ce4028
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/235300
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-03-08 22:42:46 +00:00
Alexander Markov 211da364be [vm] Experimental ability to spawn isolate from kernel blob in memory
TEST=runtime/tests/vm/dart/spawn_uri_from_kernel_blob_test.dart

Change-Id: Ieb327f0350d5d8ea1d344c64aa3dd217125da5fe
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/232682
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
2022-02-23 16:55:52 +00:00
Liam Appelbe 9d79a890f3 [vm] Adding branch coverage RPC to source report
TEST=Unit tests and an integration test
Bug: https://github.com/dart-lang/coverage/issues/141
Change-Id: I84958091dc6f9753f5e9446bb3517a8099019981
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/222541
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Liam Appelbe <liama@google.com>
2022-01-12 19:12:04 +00:00
Ryan Macnak 28e522ed97 [vm] Don't include an isolate in getVM until it has been registered with the service isolate routing.
TEST=low probability Collected error on all uses of vm service
Bug: https://github.com/dart-lang/sdk/issues/33747
Bug: https://github.com/dart-lang/sdk/issues/46450
Change-Id: I7b8d08a734033d0678a539230d13ec3d66413961
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/63645
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-01-11 18:19:15 +00:00
Liam Appelbe ac7bca37a8 [vm] Add an isolate group flag for branch coverage.
Branch coverage can't be enabled by a simple global flag, because this
causes problems when functions in an app-jit snapshot that didn't have
the flag enabled are compiled by a VM that has the flag enabled. In
particular, the coverage array will see a different set of token
positions, causing some important asserts to fail.

Change-Id: I35227252b5d271f20b01de99466c06708ec83ed8
TEST=CI
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/223360
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Liam Appelbe <liama@google.com>
2021-12-14 22:53:36 +00:00
Ben Konyi bea5dfdb08 [ VM / Service ] Allow for system isolates to register service extensions
System isolates should be able to register service extensions with the
exception of a few special isolates:
  - Kernel isolate
  - Service isolate
  - VM isolate

Required to help resolve b/203694081

TEST=CQ

Change-Id: I1f11acd89132636039a817a5dfddb6189817a7fe
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/222032
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
2021-12-08 22:09:08 +00:00
Ryan Macnak 9b89231e1e [vm] Broadcast the low-memory interrupt to only one member of each isolate group.
When this mechanism was first added, each isolate had its own heap that needed to GC on low memory. Now that isolates share a heap with other members of the group, broadcasting to each isolate does redundant work in groups that have more than one isolate.

TEST=ci
Bug: https://github.com/dart-lang/sdk/issues/47672
Change-Id: I3b71c19a2362f5a3274238e590bbf73e37aa2b4e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/220064
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2021-11-15 17:35:43 +00:00
Liam Appelbe 00cb9514cf [vm] Fix coverage for assert statements
Use RecordCoverageInstr to properly track coverage for assert
statements.

Fixes: https://github.com/dart-lang/sdk/issues/47017
Change-Id: Ic9c35afe3f0ba1eaa581953d4961ca57f5f6a64d
TEST=Added unit test
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/219907
Commit-Queue: Liam Appelbe <liama@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
2021-11-11 00:09:44 +00:00
Ryan Macnak 985824de50 [vm] Ask the OS to release the memory for the clustered portion of the snapshot.
This region is mostly unused after loading, but it may be accessed again if
 - Isolate.spawn is invoke with isolate groups disabled
 - A secondary snapshot produced by splitting is loaded
 - An external typed data in the snapshot is accessed (usually a kernel file)
 - Likely other cases

Even if these cases did not exist, the region is often part of a shared library and so unable to be released independently.

madvise(DONT_NEED) on this region will cause the OS to release the memory in this region but keep the address space reservation and mapping. If it is touched again, it will be brought back in from the file. If it is not backed by a file, such as malloc memory, it will be brought back in as zeros and the program will likely fail.

TEST=ci
Bug: https://github.com/dart-lang/sdk/issues/44019
Bug: https://github.com/flutter/flutter/issues/92120
Change-Id: I315a049b0f7d440e181d0a5e87fa6770a2fd4f79
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/216580
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
2021-10-25 17:30:50 +00:00
Martin Kustermann bcedf9f99a [gardening] Fix benign nullptr-dereference reported by UBSAN
Fixes https://github.com/dart-lang/sdk/issues/47341

TEST=Fixes service_2/break_on_function_many_child_isolates_test/service in UBSAN

Change-Id: I4de303e99604b9ffeca36a8e62bbaac421b1e7ca
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/215547
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2021-10-05 15:11:00 +00:00
Ryan Macnak 8e17ac781b [vm, gc] Avoid unnecessary intermediate maps, handles and arrays in setting up a become operation.
TEST=ci
Change-Id: Ib014fc544dcab54258d2102ee87d8f35f609594a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/211940
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
2021-09-28 18:30:52 +00:00
Martin Kustermann 9615af4635 [vm] Cleanup some workaround due to native extensions (which got removed)
Now that support for native extensions (aka dart-ext:*) has been
removed, the kernel loader is guaranteed not to call out to embedder
anymore (it did so before for loading shared libraries).

This allos us to clean up some code as well as extend the scope of our
NoActiveIsolateScope.

TEST=ci

Change-Id: I5c8c9ee47298fdd316583ba3aed74772c1c7783f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/212296
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2021-09-03 10:55:37 +00:00
Ben Konyi c7fe9ada2f Reland "[ package:dds ] Add support for caching CPU samples based on UserTag"
This reverts commit ada4278fd5.

TEST=pkg/dds/test/get_cached_cpu_samples_test.dart

Change-Id: I771410c8647fc1eb721c5aeb325c7a595430435c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/209120
Commit-Queue: Ben Konyi <bkonyi@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
2021-08-25 00:04:04 +00:00
Ryan Macnak d9048340ba [vm, service] Include each isolate a separate synthetic object in heap snapshots.
Fix labels for sentinel, transition_sentinel, ImmutableArray, LinkedHashMap and LinkedHashSet.

Display unlimited children when look at successors, as the worst case is the size of the field table. For predecessors and dominators, the worst case is the whole heap.

TEST=ci
Change-Id: I6fcfdfb0833d58c9ac4f586b823244d817aeba27
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/209841
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
2021-08-17 16:49:32 +00:00
Alexander Aprelev 94a40a6b09 [vm/concurrency] Do symbol table lookup without read lock.
Instead use acq/rel atomics for symbol table read/write.

Symbol lock read and write acquisition time(per simple lock acquisition time tracking from https://github.com/dart-lang/sdk/issues/46252#issue-910738294) reduced from
===
IsolateGroup main shutting down:
RWlock read: 1211 ms, write: 151
===
to
===
IsolateGroup main shutting down:
RWlock read: 7 ms, write: 63
===

Bug: https://github.com/dart-lang/sdk/issues/46252

TEST=IsolateSpawn on tsan

Change-Id: Ic8605c18511eba08a21202ca030b527af0a0fbc9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/207340
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2021-07-27 20:54:07 +00:00
Ben Konyi 4c9e322dd4 [ VM / Service ] Allow for CpuSamples to be streamed when samples are about to be overwritten.
TEST=pkg/vm_service/test/cpu_samples_stream_test.dart

Change-Id: I1fcb49b6a79cde725a1f0622d1327b9a86165ae9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/206920
Commit-Queue: Ben Konyi <bkonyi@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2021-07-16 20:50:58 +00:00
Martin Kustermann 627292bcc0 [vm] Remove --experimental-enable-isolate-groups-jit, only guard via --enable-isolate-groups
The JIT support has progressed and is no longer unstable. We'll
therefore remove the experimental flag and rely on the same
--enable-isolate-groups flag as in AOT mode.

Issue https://github.com/dart-lang/sdk/issues/36097

TEST=Existing test suite.

Change-Id: Iff0dd5b64d9b6ab91ad9ffc0ae445efc802d3908
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/207122
Auto-Submit: Martin Kustermann <kustermann@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
Commit-Queue: Slava Egorov <vegorov@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
2021-07-16 09:13:28 +00:00
Martin Kustermann 91ac6475cb [vm/concurrency] Enable more isolate tests, remove outdated TODOs, fix 2 tests
This CL

  * Removes conditional Skip markers in status files
  * Removes some outdated TODOs in the code
  * Deletes tests/lib_2/isolate/isolate_stress_test
    => It's skipped everywhere, we no longer support isolates on web
  * Fixes standalone{,_2}/io/directory_list_sync_test:
    => Instead of relying on the Platform.script which could be an ELF
       file lying somewhere else, use Platform.executable instead
  * Fixes standalone{,_2}/io/unix_socket_test:
    => The server used `sub.cancel()` to close it's reading end while
       the client tried to write to it. This is racy.
       If the server goes first, the write on client will throw (since
       no error listener was installed on socket.done)
       Avoid the race by coordinating client/server.

Issue https://github.com/dart-lang/sdk/issues/36097

TEST=Enables more tests.

Change-Id: I0464f81f540f2eda23ef4199cc536e53e6a809b9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/207120
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2021-07-16 07:51:58 +00:00
Ryan Macnak 09cc09cb85 [vm] Don't block OOB messages or reload during field initialization; make interrupts lock-free.
- Account for initialization-in-progress sentinel when checking static field types for reload.
 - Don't read the true stack limit when setting or clearing interrupts.

TEST=ci
Bug: https://github.com/dart-lang/sdk/issues/46596
Change-Id: I80adb4d7d69f01125b7eae8215b5da4d2e467bda
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/206662
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2021-07-14 00:09:10 +00:00
Daco Harkes 21af69a7a5 Revert "[vm] Don't block OOB messages during field initialization; make interrupts lock-free."
This reverts commit 4d789f60d1.

Reason for revert: TSAN races
https://github.com/dart-lang/sdk/issues/46596

Original change's description:
> [vm] Don't block OOB messages during field initialization; make interrupts lock-free.
>
> TEST=ci
> Change-Id: I51d0f51995e197ab71c059f17d22259eea19c286
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/206566
> Commit-Queue: Ryan Macnak <rmacnak@google.com>
> Reviewed-by: Ben Konyi <bkonyi@google.com>

TBR=bkonyi@google.com,rmacnak@google.com

Change-Id: I777f5a0bbeb3cd60e03aff46183b19ab4e286664
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/206545
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
2021-07-13 11:30:08 +00:00
Ryan Macnak 4d789f60d1 [vm] Don't block OOB messages during field initialization; make interrupts lock-free.
TEST=ci
Change-Id: I51d0f51995e197ab71c059f17d22259eea19c286
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/206566
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Ben Konyi <bkonyi@google.com>
2021-07-13 00:43:05 +00:00
Martin Kustermann b3b2abb9eb [vm/concurrency] Store persistent handle in [Message]s instead of [Bequest] object
Storing a persistent handle in [Message] objects instead of the
[Bequest] (which is just a wrapper around a persistent handle) will
allow us to use the same mechanism for sending copies of transitive
object graphs.

Since messages can have maps inside them that need rehashing, we'll
make the persistent handle point to an array of length 2 of the format:

    array = [<message>, <array-of-objects-in-message-to-rehash>]

The sendAndExit doesn't use the second part atm (since it preserves
identities and therefore avoids the need for rehashing).

Though sending transitive copies of object graphs will require this
functionality (a follow-up CL which will land with this one).

For ease of reviewing this CL was split out.

Issue https://github.com/dart-lang/sdk/issues/36097

TEST=Refactoring, relying on existing test coverage.

Change-Id: I2afa78b42ef82d46477579623fd54f027136333f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203769
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
2021-06-18 06:55:11 +00:00
Alexander Markov 00d6b8972a [vm] Separate class for sentinel objects
This change adds a new VM-internal class for sentinel objects.
Previously sentinel objects used class Never.

TEST=existing tests

Issue: https://github.com/dart-lang/sdk/issues/46141
Change-Id: Ibb3361092967132f4f1952d64fe0168659f3075e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/202870
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2021-06-11 18:44:56 +00:00
Alexander Aprelev 9302a7427b [vm/concurrency] Assert that no SafepointRwLocks are acquired while in SafepointOperationScope.
Attempts to acquire safepoint lock while in SafepointOperationScope could result
in deadlocks if somebody else was holding that lock when they were forced to a safepoint.
Clean up few places where locks were acquired in SafepointOperationScope.

Introduce StoppedMutatorsScope and GroupDebugger::RunUnderReadLockIfNeeded that acquires
a lock only if it runs outside of StoppedMutatorsScope - to prevent such deadlocks.

Also fix tsan warning about data race around message_notify_callback by making it atomic.

TEST=tsan runs of debugger CI tests

Fixes https://github.com/dart-lang/sdk/issues/45527
Fixes https://github.com/dart-lang/sdk/issues/45549

Issue https://github.com/dart-lang/sdk/issues/36097

Change-Id: Ibb53d9ce760d869e044e17075aeebf20fc0016a5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193582
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Ben Konyi <bkonyi@google.com>
2021-04-03 03:36:32 +00:00
Alexander Aprelev 4baf7e5e3d [vm/concurrency] Introduce GroupDebugger that takes CodeBreakpoints management away from isolate Debugger.
CodeBreakpoint class tracks patching of the call targets for the purpose of routing the call to the debugger runtime.
With this CL CodeBreakpoint instance is managed by GroupDebugger, debugger class owned by IsolateGroup, and can be associated with multiple BreakpointLocation, one location per isolate that set a breakpoint at particular code location.

TEST=observatory/tests/service/break_on_function_child_isolate_test

Issue https://github.com/dart-lang/sdk/issues/36097

Change-Id: I3b3d0974a0fb9668742e5c1e2a2ce13b84b1d630
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/190732
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2021-03-17 18:03:14 +00:00
Alexander Aprelev 182d0dd156 [vm/concurrency] Ensure updates to Isolate::isolate_flags_ are atomic and thread-safe.
Fixes https://github.com/dart-lang/sdk/issues/45169.

TEST=flaky vm/dart_2/isolates/reload_many_isolates_live_and_die_test

Change-Id: I3a378aef76a91de49611f7debe9cbc2c9335e872
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/189160
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2021-03-05 15:24:49 +00:00
Martin Kustermann 700ba716cd [vm/concurrency] Avoid O(n) traversal of isolates to find pending deopt
To avoid a O(n) traversal of isolates in order to find pending deopts,
we'll move the pending deopt state to the Thread. It's really a property
of a thread: when the thread's stack gets unwound - via return or
exceptional flow - we remove pending deopts.

This CL also encapsulates the pending deopt logic into a [PendingDeopts]
class - thereby avoiding logic around manipulating this array being
spread around. It simplifies the already very big [Isolate] class.

TEST=Refactoring of existing code.

Issue https://github.com/dart-lang/sdk/issues/36097
Closes https://github.com/dart-lang/sdk/issues/45168

Change-Id: I5a9b18c577f21a0f2a88332b1bc26641ec39d2af
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/188521
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
2021-03-03 09:31:53 +00:00
Martin Kustermann 91c628d63a [vm/concurrency] Final support for hot-reload of multi-isolate groups
This is the initial implementation of hot reload with multi-isolate
groups.

Implementation:

As before, when a service API call triggers a reload it will be routed
as an OOB message to a specific isolate (**). As opposed to before, that
isolate has now to coordinate with all other isolates, ensuring that it
"owns" the reload and all other isolates are waiting in a state that
allows reload.

This is implemented as a [ReloadOperationScope] which first participates
in other reloads (if there are any) and then owns the reload. It will
send a new kind of service message to all other registered isolates. All
of them have to check in before reload can proceed. If a new isolate
is about to join the group, it will participate when registering the
isolate. If an old isolate wants to die, it will participate when
unregistering the isolate.

This means that in addition to the existing StackOverFlow checks that
can process OOB messages and therefore reload, we'll have isolate
registration and unregistration as well as a new
Isolate::kCheckForReload OOB message handler where an isolate can
participate in a reload.

We consider the isolate group to be reloadable if the main isolate has
loaded the program and set the root library. Helper isolates don't need
to load any more kernel code and only initialize core libraries, so it's
fine to reload them during this time.

(**) The reason we continue to send reload service API calls to any
isolate in an isolate group is that re-loading might involve calling out
to the embedder's tag handler. Doing so currently requires an active
isolate.

If we allowed a subset of dart_api.h (the subset needed by the tag
handler) to be used only with an active IsolateGroup instead of an
active Isolate we could remove this requirement.

Edge cases:

There's various edge cases to consider: The main edge case is, we currently
maintain an upper limit to the number of isolates executing in parallel
(to ensure each can have big enough chunk of new space, i.e. TLAB).

If there are more isolates with active work they are waiting until one
of the exiting ones "yields". To ensure progress, if any such actively
running isolate gets a request to participate in a reload, it will mark
its own thread as "blocked" and therefore "yields", so another isolate
can make progress until all isolates are participating and the reload
can start.

Marking an isolate as "blocked" happens by exiting that isolate. It will
free up it's TLAB, decrease active mutator count and (if running on VM's
thread pool) also temporarily increase the thread pool size.

The side-effect of this is that it will use one pthread per isolate
during reload. In the future we can extend this first implementation, by
specially handling isolates that don't have a message handler running.
Doing so would require careful consideration to avoid races.

Testing:

In order to test this we use a small helper framework for reload tests.
The helper framework will, similar to real world reload e.g. in flutter,
will spawn a subprocess. It will use the service API to trigger reloads
in this subproces.

To synchronize between the reload driver and the application being
reloaded it allows watching for events to be printed to stdout/stderr.

The reload test itself can be written - similar to multitests - with
annotations such as `// @include-in-relload-0` in them. The testing
framework will then generate multiple application versions that all get
compiled to kernel.

For simplicity we generate the kernel using the standalone VM with
`--snapshot-kind=kernel` and avoid using the incremental compiler.

There are 4 different tests exercising different aspects of
multi-isolate reload:

  vm/dart_2/isolates/reload_active_stack_test:
    Performs a reload while a fixed number of isolates have an active
    stack, thereby ensuring e.g. that all frames of all isolate mutator
    stacks get deoptimized, ...

  vm/dart_2/isolates/reload_no_active_stack_test:
    Similar to the test above, but instead of having an active stack the
    isolates can yield to the event loop, possibly be even descheduled

  vm/dart_2/isolates/reload_many_isolates_test:
    Similar to the test above, but this test uses many more isolates.

  vm/dart_2/isolates/reload_many_isolates_live_and_die_test:
    Performs a reload where isolates get spawned and die all the time.
    There are always P isolates alive at any given point in time, each
    of them spawns children when their parent has died.
    Performing a reload catches isolates as various stages of their
    lifecycle and can therefore cover a lot of corner cases.

TEST=vm/dart_2/isolates/reload_*_test.dart

Issue https://github.com/dart-lang/sdk/issues/36097

Change-Id: I97039b4084de040b7f2e22f5832a40d57ba398d5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/187461
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
2021-03-02 18:57:02 +00:00
Martin Kustermann 29268ba7d2 [vm/concurrency] Move no-reload-scope counter to Thread
Whether a given isolate allows reloading is really a property of the
thread not the isolate (where it was before) or isolate group (where
it was moved to), so this CL moves it to Thread.

As the thread's stack is going down and up, NoReloadScope's might be
entered or exited, just as with our many other scopes, such as
NoOOBMessageScope/...

Longer term we might need to find a better mechanism to deal with
different OOB messages. For example: Reload as well as OOB messages
are disabled during static field initialization. Though that means *all*
OOB messages cannot reach the isolate during initialization of a static
field (which can do arbitrary amount of work).

This is part of making hot-reload work with isolate groups.

Issue https://github.com/dart-lang/sdk/issues/36097

TEST=Refactoring of existing code.

Change-Id: I9e80c6d4a184c54c0373fef13af3264cc3f27ece
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/187002
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2021-03-02 14:11:42 +00:00
Martin Kustermann c78f12c550 [vm/concurrency] Allow caller of Thread::{Exit,Enter}Isolate to specify nesting
It's mainly hoisting an expression out of
IsolateGroup::{Increase,Decrease}MutatorCount to callers of it.

Right now we consider a Thread::{Exit,Enter} to be nested if there are
existing Dart frames on the stack. A future CL will have a case where
there's a nested exit&re-enter without Dart frames on the stack.

Trying to do this automatically by checking whether there's an
active api scope / zone on the thread fails due to some
asymmetry in our codebase.

Issue https://github.com/dart-lang/sdk/issues/36097

TEST=Refactoring of existing code.

Change-Id: Id70eda03efb2099487c5f0c8affd25ddff926553
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/186287
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2021-02-25 18:44:16 +00:00
Martin Kustermann 2e2d542969 [vm/concurrency] Use isolate group id as key for incremental compiler for reload
As part of implementing hot-reload for isolate groups, we have to ensure
reloads on a group are performed using the same state of incremental
compiler.

This means we cannot use a specific isolate's information (such as it's
main port) for reloading purposes. Instead we use the unqiue isolate
group id when communicating with the kernel service.

Issue https://github.com/dart-lang/sdk/issues/36097

TEST=Existing test coverage, future test when hot-reload is fully
     implemented with isolate groups.

Change-Id: Ifab39cd2ba689c08507dfab4091cd26951ed54e5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/185320
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2021-02-18 06:59:24 +00:00
Martin Kustermann 5b4349de54 [vm/concurrency] Make main hot-reload implementation independent of current isolate
Since hot-reloading will affect all isolates within a group, there
should be nothing isolate-specific inside it. We therefore add a
NoActiveIsolateScope to the main part of the reloading
implementation.

Issue https://github.com/dart-lang/sdk/issues/36097

TEST=Refactoring of existing implementation.

Change-Id: I1c8db00e6a016c77c68c2c04448de056a76d42c5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/184782
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2021-02-17 09:38:29 +00:00
Martin Kustermann 2439c412f0 [vm/concurrency] Make main Kernel loading independent of current isolate
Since loading kernel will affect all isolates within a group, there
should be nothing isolate-specific inside the kernel loader. To ensure
we don't have (or introduce) any accidental uses, we add a
NoActiveIsolateScope to the main parts of kernel loading.

Only loading of native extensions - done by the kernel loader -
currently requires an active isolate. The reason for this is that
loading native extensions happen by calling out to embedder, which calls
back into the VM using the our embedding API (which currently requires
an active isolate)

Issue https://github.com/dart-lang/sdk/issues/36097

TEST=Refactoring of existing implementation.

Change-Id: I96e64dbfe7148b76b8fa006fe5dbde8c1f904504
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/184269
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
2021-02-12 19:45:05 +00:00
Martin Kustermann 461fb4ec8e [vm/concurrency] Remove redundant fields in Isolate
The object store related fields in [Isolate] are not needed anymore:

  Isolate::object_store_
  Isolate::cached_object_store_
  Isolate::object_store_shared_ptr_

and can be directly accessed from [IsolateGroup].

Issue https://github.com/dart-lang/sdk/issues/36097

TEST=Refactoring of existing implementation.

Change-Id: Ia01da92cbb4e7cf5862c8419e27578ea07d4bdf2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/184268
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
2021-02-12 13:14:37 +00:00
Martin Kustermann b80ab44a53 [vm/concurrency] Move class registration from Isolate to IsolateGroup
We share the program across all isolates within a group. So hot-reload
should not depend on a particular isolate. This CL moves class
registration (which hot reload triggers) from Isolate to IsolateGroup.

Issue https://github.com/dart-lang/sdk/issues/36097

TEST=Refactoring of existing implementation.

Change-Id: Ibdb4e67a095c7f2f3e3c1a8f8194bd0ca936b140
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/184266
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
2021-02-12 07:53:46 +00:00
Martin Kustermann c95714d069 [vm/concurrency] Add NoActiveIsolateScope to precompiler & bg compiler
With --enable-isolate-groups we will start sharing JITed code. The JITed
code - which will be executed by all isolates - should therefore not
depend on a particular isolate's state, flags or any other
isolate-specific information.

To avoid accidental bugs where the compiler starts using
isolate-specific information, we ensure the compiler runs without a
current isolate.

This CL doesn't add NoActiveIsolateScope because on unoptimized compiles
of natives, the compiler calls out to embedder for eager native
resolution of native functions. This API forces embedder to callback
into VM atm.

Issue https://github.com/dart-lang/sdk/issues/36097

TEST=Adds more checking.

Change-Id: I6c86674c010b74c15855652415706dbaa8749d33
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/183692
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
2021-02-12 05:59:05 +00:00
Martin Kustermann 8e887672f4 [vm/concurrency] First changes for hot-reloading with isolate gropus.
This CL moves the [ProgramReloadContext] from [Isolate] to
[IsolateGroup] - since the program is shared across isolates. Amongst
other things, it also deoptimizes stacks of all isolate mutators.

There is still future work to do for hot-reloading multiple isolates
within a group, this is only the first change.

Issue https://github.com/dart-lang/sdk/issues/36097

TEST=Refactoring of existing implementation.

Change-Id: Ic394de265e3922f84657de2da25a46179b624647
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/183693
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
2021-02-12 05:48:15 +00:00