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>
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>
Currently we have things called XPtr which are not what you get from ptr().
Old world:
handle->raw() returns RawObject* (tagged)
raw_obj->ptr() returns RawObject* (untagged)
After 6fe15f6df9:
handle->raw() returns ObjectPtr
obj_ptr->ptr() returns ObjectLayout*
New world:
handle->ptr() returns ObjectPtr
obj_ptr->untag() returns UntaggedObject*
TEST=ci
Change-Id: I6c7f34014cf20737607caaf84979838300d12df2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/149367
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
As part of making the compiler and other subsystems independent
of `Isolate` we have to move various state from `Isolate` to
`IsolateGroup`.
The class_table and object_store were already moved to `IsolateGroup`.
This CL only replaces usages of `Isolate::{object_store,class_table}`
with the equivalent in `IsolateGroup`.
Issue https://github.com/dart-lang/sdk/issues/36097
TEST=Pure refactoring - relying on existing test coverage.
Change-Id: I34a0682d715b054d6c5faff077a513980f59a348
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/177126
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
This removes our temporary scaffolding support for JIT isolate groups
(which was implemented by creating a new isolate group, loading the
application kernel into it and then merging the heap into the original
isolate group - maintaining a different object store)
It makes all isolates within a group share the same object store, same
libraries and JITed code. It will be conservative to start with, only
allow running unoptimized code, etc.
We will gradually remove the restrictions imposed by this CL:
https://dart-review.googlesource.com/c/sdk/+/173970
Issue https://github.com/dart-lang/sdk/issues/36097
TEST=Tests using --enable-isolate-groups with JIT sharing.
Change-Id: I2bf69a6fe3c905067c4cec2e81613f731c52e5ee
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175302
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
The former calls the latter with the same arguments, so we could call
the latter directly, though we prefer to use `_startIsolate()` as the
entrypoint.
This fixes test failures in obfuscated mode, where the runtime cannot
find the `_delayEntrypointInvocation` function.
TEST=Fixes -n dartkp-obfuscate-linux-release-x64 ffi_2/dylib_isolates_test
Change-Id: I062fc16658f90750439f304849daa3911d3a1b89
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/171946
Reviewed-by: Tess Strickland <sstrickl@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
The Isolate.spawn() is part of our dart:isolate library implementation,
it should therefore preferrably live under runtime/lib folder.
This CL does that as well as removing some special message handling
logic by using the new `Dart_RunLoopAsync()` C API, which results in
net removal of code.
As a nice side-effect it also makes isolate spawning slightly faster due
to avoiding extra safepoint/vm<->native transitions.
Issue https://github.com/dart-lang/sdk/issues/44088
TEST=Changes existing implementation, have existing test coverage for it.
Change-Id: I00607a1436946552bbe12e8e23062e8f743d4f11
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/171731
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Dart_CreateLightweightIsolate API:
This API can be used by embedders to create a lightweight isolate
(inside an existing isolate group).
It is the analogous to Dart_CreateIsolateGroup - though taking a
parent isolate as parameter (inside whose IG we create a new isolate)
instead of taking kernel/snapshot data.
Right now this API works on AOT and returns an error in JIT, both cases
are covered by the test.
Dart_RunLoopAsync:
The API can be used by embedders to transfer ownership of an isolate to
the VM, which will take care of running the message handling loop and
shuts the isolate down once the last receive port has been closed.
It does allow listening to error/exit events generated by the message
loop implementation as well as allows setting errors-are-fatal,
effectively the same event-loop related parameters from the
`Isolate.spawn()` API, just in Dart.
It's the embedders responsibility to first launch initial dart code
which will take care of responding to events (i.e. directly/indirectly
open a receive port) - otherwise the isolate cannot be talked to and
would immediately shut down.
Since our vm/cc tests do support running in AOT, we use a hybrid
approach to test the functionality: We let a normal Dart test call a
small C wrapper using FFI, to create a lightweight isolate, run it on a
new thread and join that thread.
TEST=vm/dart{,_2}/isolates/dart_api_create_lightweight_isolate_test
Issue https://github.com/dart-lang/sdk/issues/36097
Closes https://github.com/dart-lang/sdk/issues/44088
Change-Id: Id77ba928793fdb517f6cb7e8130df98a0366ddd6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/170983
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
When Dart invokes Isolate.spawn the Dart VM calls out to the embedder to
create an isolate (group) or initialize it (in case of lightweight
isolates).
* If the embedder doesn't implement this functionality or fails to
perform the creation/initialization, it will signal this failure
via the return value it gives to the VM in the call back
implementation (i.e. Dart_InitializeParams.create_group and
Dart_InitializeParams.initialize_isolate}).
* If the embeder sucessfully completed it's work, the VM owns the
isolate after the embedder call returns. The VM is then responsible
for running it.
It is an undocumented invariant atm that the embedder is responsible
to make the isolate runnable if it signals the VM that isolate was
sucessfully created/initialized.
=> If it does not do that, we have effectively an isolate leak.
=> Though right now seemingly all of our embedders to that correctly.
To avoid this unintentional isolate leak we make the isolate runnable
ourselves if embedder callback was successful but did not make it
runnable itself.
=> This also avoids unnecessary ceremony code in the embedders that
look like this:
Dart_ExitIsolate();
Dart_IsolateMakeRunnable(child);
Dart_EnterIsolate(child);
The implementation of `Dart_IsolateMakeRunnable()` had an untested and
unused code path that caused running the isolate (on a thread pool).
This is not documented and can lead to bugs because often the
embedders enter the isolate right after making it runnable (e.g. above
code sequence) - which would be racing with the spawned message handler
thread.
=> Furtunately our embedders are well behaved and make the isolate
runnable during the callback.
=> As a safeguard we'll make `Dart_IsolateMakeRunnable()` return an
error if it's called outside the callback (which we can detect by
the presense of a spawn state)
Issue https://github.com/dart-lang/sdk/issues/44088
Issue https://github.com/dart-lang/sdk/issues/36097
TEST=Changes internal details of implementation which is already covered by tests.
Change-Id: Ieef316cc0807d99f2fcb1fbd56bbc9c41e904ba8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/170882
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
prevent repeated port allocations
Flutter makes heavy use of short-lived Timers which currently causes
repeated opening/closing of the Timer port. This change allows for
RawReceivePorts to be set active / inactive, allowing for a port to be
kept open but not considered alive.
Flutter benchmark changes:
Before dart-lang/sdk@d5118d5: "notifyListener2_iteration": 545.0
After dart-lang/sdk@d5118d5: "notifyListener2_iteration": 1639.0
With fix: "notifyListener2_iteration": 629.0
Fixes https://github.com/flutter/flutter/issues/69583
TEST=Updated port state tests and verified change against Flutter's microbenchmarks
Change-Id: I50ff1a1b0f1f29bcdac958e41c66429e9586fba2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/171628
Commit-Queue: Ben Konyi <bkonyi@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
This reverts commit 5bf9163e1b.
Reason for revert: Tests failing on bots.
Original change's description:
> [ Service / dart:isolate ] Added getPorts RPC and 'debugName' optional
> parameter for ReceivePort and RawReceivePort
>
> This change collects additional information related to ReceivePort
> allocation locations and an optional debug name that will be displayed
> by tooling. ReceivePort is now a special InstanceKind and a ReceivePort
> @Instance will include the port ID, allocation stack trace, and debug
> name.
>
> Change-Id: I003cfff2b7649218e37d9b653c0e953df5d992e7
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/167902
> Reviewed-by: Ryan Macnak <rmacnak@google.com>
TBR=bkonyi@google.com,rmacnak@google.com,asiva@google.com
Change-Id: I39c3abb07c8c40c158eb4549749b076399bccce9
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/169160
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
parameter for ReceivePort and RawReceivePort
This change collects additional information related to ReceivePort
allocation locations and an optional debug name that will be displayed
by tooling. ReceivePort is now a special InstanceKind and a ReceivePort
@Instance will include the port ID, allocation stack trace, and debug
name.
Change-Id: I003cfff2b7649218e37d9b653c0e953df5d992e7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/167902
Reviewed-by: Ryan Macnak <rmacnak@google.com>
This was originally added to prevent fork bombs in our test suite. Early versions of AOT for the standalone VM loaded the AOT program based on LD_LIBRARY_PATH instead of the command line arguments, so tests the tried to spawn a second script spawned themselves. The VM snapshot has since also been changed to be the same for every app, and some embedders already load multiple apps into the same process using the C API.
Embedders can still block any Isolate.spawn or spawnUri in the C callbacks if they don't want to implement loading for secondary isolates.
Change-Id: I4a4beda2a797ce26367350298eaafd7e53256b3b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/152592
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Introduces Dart_NewFinalizableHandle which does auto delete itself,
but does not allow accessing the weak referenced object.
Issue: https://github.com/dart-lang/sdk/issues/42312
Change-Id: I24ea732925122c453213c4fa3f629761c352f838
Cq-Include-Trybots:dart/try:vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64-try,app-kernel-linux-debug-x64-try,vm-kernel-linux-debug-ia32-try,vm-kernel-win-debug-x64-try,vm-kernel-win-debug-ia32-try,vm-kernel-precomp-linux-debug-x64-try,vm-dartkb-linux-release-x64-abi-try,vm-kernel-precomp-android-release-arm64-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-msan-linux-release-x64-try,vm-kernel-precomp-msan-linux-release-x64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-simarm64-try,vm-kernel-precomp-android-release-arm_x64-try,vm-kernel-precomp-obfuscate-linux-release-x64-try,dart-sdk-linux-try,analyzer-analysis-server-linux-try,analyzer-linux-release-try,front-end-linux-release-x64-try,vm-kernel-precomp-win-release-x64-try,vm-kernel-mac-debug-x64-try,vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-nnbd-linux-debug-x64-try,analyzer-nnbd-linux-release-try,front-end-nnbd-linux-release-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/154695
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
To enable our tests to spawn a new isolate in a new group, this CL
adds a `{bool newIsolateGroup}` parameter to the internal
`Isolate._spawnFunction` native and moves that native to
`dart:_internal`, thereby allowing runtime/tests/vm/dart/* to access it.
It also adds various tests for lightweight AOT isolates, exercising
GC, communication, spawning, ...
Issue https://github.com/dart-lang/sdk/issues/36097
Change-Id: I3940c30fb43d2475c58e6be78507da74ce64b60d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/145941
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Our TLAB sizes and maximum new space size constrain the number of
parallel mutator threads we can have. Having too many mutator threads
would cause constant races between threads to acquire TLABs.
In reality we should constrain the number of threads to be at most the
number of cores, since at most that many threads can run in parallel
(i.e. at the same time).
This CL extends the TreadPool implementation to be constrained by a
maximum size. Furthermore it makes each isolate group's have it's own
pool with constrained size and schedule all group member
mutator / message handler tasks on that pool.
Issue https://github.com/dart-lang/sdk/issues/36097
Change-Id: I095c749adad827ab892f33713a32be594d7606d1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/145382
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
We have accumulated almost 69 commits. Please see issue
https://github.com/dart-lang/sdk/issues/41739
for details of why these CLs had to be reverted.
Revert "Reland "[vm] Make VM support .dart_tool/package_config.json""
This reverts commit fa6cc57a32.
Revert "[VM] - Fix hang when no package config or .packages exist"
This reverts commit 31be795457.
Revert "[vm/isolate] Make Isolate.resolveUri() work for both `.packages` and `dart_tool/package_config.json`"
This reverts commit a99f7aef6e.
Revert "[vm] Skip (newly enabled) isolate tests on simarm* and hot-reload configs"
This reverts commit 7082e99c28.
Revert "[vm] Remove ../0 postfix from status file entries (test framework does not recognize those multitests)"
This reverts commit 708468684a.
Change-Id: Id6b951bde4f379fdcfac3cc23e0057a77a7e6db0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/146041
Reviewed-by: Ben Konyi <bkonyi@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Siva Annamalai <asiva@google.com>
This reverts commit 922ea3e9b6 in patchset 1, fix for assertion triggered in https://ci.chromium.org/b/8883214567628884960 in patchset 2, fix for deadlock around symbols table mutex in patchset 4.
Original commit description:
Speed up is achieved by sharing most of the dart code, object store
and class table between isolates in single isolate group. So
instead of bootstrapping isolate from the snapshot, isolate is
initialized by setting pointers to existing data structures already
set up for first isolate, and only few isolate-specific structures (moved
to newly introducted isolate_object_store) are created.
To allow for safe cross-isolate switchable call site, type test cache
mutations additional synchronization via RunWithStoppedMutators(that
relies on safepoints) was added.
Besides switchable call sites, no other mutation to the dart code is
done in AOT, which allows such sharing.
Bug: https://github.com/dart-lang/sdk/issues/37835
Bug: https://github.com/dart-lang/sdk/issues/36097
Change-Id: I655e337198214c9dfacbe76f7852b941b5a7e910
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/143462
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Original revert in patchset 1, fix for deadlock issue in patchset 2: avoid reentrant calls to RunWithStoppedMutator.
Further review comments addressed in successive patchsets.
This reverts commit 8ef508ba36.
Original commit description:
Speed up is achieved by sharing most of the dart code, object store
and class table between isolates in single isolate group. So
instead of bootstrapping isolate from the snapshot, isolate is
initialized by setting pointers to existing data structures already
set up for first isolate, and only few isolate-specific structures (moved
to newly introducted isolate_object_store) are created.
To allow for safe cross-isolate switchable call site, type test cache
mutations additional synchronization via RunWithStoppedMutators(that
relies on safepoints) was added.
Besides switchable call sites, no other mutation to the dart code is
done in AOT, which allows such sharing.
Change-Id: I6a0279d9812020ad7a5c2b7851980b6a29b95b9a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/143327
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Speed up is achieved by sharing most of the dart code, object store
and class table between isolates in single isolate group. So
instead of bootstrapping isolate from the snapshot, isolate is
initialized by setting pointers to existing data structures already
set up for first isolate, and only few isolate-specific structures (moved
to newly introducted isolate_object_store) are created.
To allow for safe cross-isolate switchable call site, type test cache
mutations additional synchronization via RunWithStoppedMutators(that
relies on safepoints) was added.
Besides switchable call sites, no other mutation to the dart code is
done in AOT, which allows such sharing.
Bug: https://github.com/dart-lang/sdk/issues/37835
Bug: https://github.com/dart-lang/sdk/issues/36097
Change-Id: I64c86525f4ef9cb30567a49a106bfe700355942b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/136780
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Similar to the split of ClassTable into ClassTable/SharedClassTable,
this CL splits up the IsolateReloadContext into:
* IsolateGroupReloadContext: Consists of reload-related information across all
isolates. The [Reload()] method is split up in phases that are
performed on all isolates before the next phase is started.
=> This allows each isolate to add reasons for rolling back, if no
reasons are found the reload will be accepted atomically.
* IsolateReloadContext: Constists of reload-related information for a
particular isolate (e.g. mappings of old to new classes)
The assumption is that all isolates have the same source (and therefore
the same libraries). For certain things, e.g. discovering which libraries
changed, it is necessary to examine the object store. We use the first
isolate in a group (but could use any of them) to do so, since the
isolate group does not have this information atm.
This is a preparation CL for supporting hot-reloading multiple isolates
within one isolate group. Though the support in this CL stays at having
only a single isolate in a group.
=> This CL turns off FLAG_enable_isolate_groups in JIT mode.
Issue https://github.com/dart-lang/sdk/issues/36097
Change-Id: I7f4d536d4f5ab4a2a73fb0c7618ba967c9b77234
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/123254
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
The isolate group object will keep a doubly-linked list of all isolates
within it's group. This will allow us to later on iterate all isolates
within a group for e.g. GC purposes.
The isolate group object will eventually hold the shared heap, thread registry
and other resources. This CL is only the start.
Issue https://github.com/dart-lang/sdk/issues/36097
Change-Id: I32103bbb4830cd4f16665c4032d47dabdf3594dd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/108407
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
This reverts commit 3d14b75f97.
An Isolate Group (IG) is a collection of isolates which were spawned from the
same source. This allows the VM to:
* have a guarantee that all isolates within one IG can safely exchange
structured objects (currently we rely on embedder for this
guarantee)
* hot-reload all isolates together (currently we only reload one
isolate, leaving same-source isolates in inconsistent state)
* make a shared heap for all isolates from the same IG, which paves
the way for faster communication and sharing of immutable objects.
All isolates within one IG will share the same IsolateGroupSource.
**Embedder changes**
This change makes breaking embedder API changes to support this new
concept of Isolate Groups: The existing isolate lifecycle callbacks
given to Dart_Initialize will become Isolate Group lifecycle callbacks.
A new callback `initialize_isolate` callback will be added which can
initialize a new isolate within an existing IG.
Existing embedders can be updated by performing the following renames
Dart_CreateIsolate -> Dart_CreateIsolateGroup
Dart_IsolateCreateCallback -> Dart_IsolateGroupCreateCallback
Dart_IsolateCleanupCallback -> Dart_IsolateGroupShutdownCallback
Dart_CreateIsolateFromKernel -> Dart_CreateIsolateGroupFromKernel
Dart_CurrentIsolateData -> Dart_CurrentIsolateGroupData
Dart_IsolateData -> Dart_IsolateGroupData
Dart_GetNativeIsolateData -> Dart_GetNativeIsolateGroupData
Dart_InitializeParams.create -> Dart_InitializeParams.create_group
Dart_InitializeParams.cleanup -> Dart_InitializeParams.shutdown_group
Dart_InitializeParams.shutdown -> Dart_InitializeParams.shutdown_isolate
By default `Isolate.spawn` will cause the creation of a new IG.
Though an embedder can opt-into supporting multiple isolates within one IG by
providing a callback to the newly added `Dart_InitializeParams.initialize_isolate`.
The responsibility of this new callback is to initialize an existing
isolate (which was setup by re-using source code from the spawning
isolate - i.e. the one which used `Isolate.spawn`) by setting native
resolvers, initializing global state, etc.
Issue https://github.com/dart-lang/sdk/issues/36648
Issue https://github.com/dart-lang/sdk/issues/36097
Original review: https://dart-review.googlesource.com/c/sdk/+/105241
Difference to original review:
* Give each isolate it's own [Loader] (for now)
* Sort classes during initialization for spawned isolates if app-jit is used (to match main isolate)
* Fix IsolateData memory leak if isolate startup fails
Difference to first reland(Patchset 2):
* Fix typo where memory was freed twice.
Change-Id: Ib1c83fe83b629cd50ae6af90ee99fdd44da882d4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/108367
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
This reverts commit 67ab3be10d.
Reason for revert: Causes non-deterministic failures on front-end bots on Windows with "Isolate creation failed" error. See https://logs.chromium.org/logs/dart/buildbucket/cr-buildbucket.appspot.com/8909292129328681248/+/steps/unit_tests/0/stdout
Original change's description:
> Reland "[vm/concurrency] Introduce concept of Isolate Groups"
>
> An Isolate Group (IG) is a collection of isolates which were spawned from the
> same source. This allows the VM to:
>
> * have a guarantee that all isolates within one IG can safely exchange
> structured objects (currently we rely on embedder for this
> guarantee)
>
> * hot-reload all isolates together (currently we only reload one
> isolate, leaving same-source isolates in inconsistent state)
>
> * make a shared heap for all isolates from the same IG, which paves
> the way for faster communication and sharing of immutable objects.
>
> All isolates within one IG will share the same IsolateGroupSource.
>
> **Embedder changes**
>
> This change makes breaking embedder API changes to support this new
> concept of Isolate Groups: The existing isolate lifecycle callbacks
> given to Dart_Initialize will become Isolate Group lifecycle callbacks.
> A new callback `initialize_isolate` callback will be added which can
> initialize a new isolate within an existing IG.
>
> Existing embedders can be updated by performing the following renames
>
> Dart_CreateIsolate -> Dart_CreateIsolateGroup
> Dart_IsolateCreateCallback -> Dart_IsolateGroupCreateCallback
> Dart_IsolateCleanupCallback -> Dart_IsolateGroupShutdownCallback
> Dart_CreateIsolateFromKernel -> Dart_CreateIsolateGroupFromKernel
> Dart_CurrentIsolateData -> Dart_CurrentIsolateGroupData
> Dart_IsolateData -> Dart_IsolateGroupData
> Dart_GetNativeIsolateData -> Dart_GetNativeIsolateGroupData
> Dart_InitializeParams.create -> Dart_InitializeParams.create_group
> Dart_InitializeParams.cleanup -> Dart_InitializeParams.shutdown_group
> Dart_InitializeParams.shutdown -> Dart_InitializeParams.shutdown_isolate
>
> By default `Isolate.spawn` will cause the creation of a new IG.
>
> Though an embedder can opt-into supporting multiple isolates within one IG by
> providing a callback to the newly added `Dart_InitializeParams.initialize_isolate`.
> The responsibility of this new callback is to initialize an existing
> isolate (which was setup by re-using source code from the spawning
> isolate - i.e. the one which used `Isolate.spawn`) by setting native
> resolvers, initializing global state, etc.
>
> Issue https://github.com/dart-lang/sdk/issues/36648
> Issue https://github.com/dart-lang/sdk/issues/36097
>
> Original review: https://dart-review.googlesource.com/c/sdk/+/105241
>
> Difference to original review:
>
> * Give each isolate it's own [Loader] (for now)
> * Sort classes during initialization for spawned isolates if app-jit is used (to match main isolate)
> * Fix IsolateData memory leak if isolate startup fails
>
> Change-Id: I98277d3d10fe275aa9b8a16b6bdd446bbea0b100
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/107506
> Commit-Queue: Martin Kustermann <kustermann@google.com>
> Reviewed-by: Ryan Macnak <rmacnak@google.com>
TBR=kustermann@google.com,aam@google.com,rmacnak@google.com
# Not skipping CQ checks because original CL landed > 1 day ago.
Change-Id: Ia4e0f4f9fc317499d3570a371c5bdf9aed799e77
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/108101
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
An Isolate Group (IG) is a collection of isolates which were spawned from the
same source. This allows the VM to:
* have a guarantee that all isolates within one IG can safely exchange
structured objects (currently we rely on embedder for this
guarantee)
* hot-reload all isolates together (currently we only reload one
isolate, leaving same-source isolates in inconsistent state)
* make a shared heap for all isolates from the same IG, which paves
the way for faster communication and sharing of immutable objects.
All isolates within one IG will share the same IsolateGroupSource.
**Embedder changes**
This change makes breaking embedder API changes to support this new
concept of Isolate Groups: The existing isolate lifecycle callbacks
given to Dart_Initialize will become Isolate Group lifecycle callbacks.
A new callback `initialize_isolate` callback will be added which can
initialize a new isolate within an existing IG.
Existing embedders can be updated by performing the following renames
Dart_CreateIsolate -> Dart_CreateIsolateGroup
Dart_IsolateCreateCallback -> Dart_IsolateGroupCreateCallback
Dart_IsolateCleanupCallback -> Dart_IsolateGroupShutdownCallback
Dart_CreateIsolateFromKernel -> Dart_CreateIsolateGroupFromKernel
Dart_CurrentIsolateData -> Dart_CurrentIsolateGroupData
Dart_IsolateData -> Dart_IsolateGroupData
Dart_GetNativeIsolateData -> Dart_GetNativeIsolateGroupData
Dart_InitializeParams.create -> Dart_InitializeParams.create_group
Dart_InitializeParams.cleanup -> Dart_InitializeParams.shutdown_group
Dart_InitializeParams.shutdown -> Dart_InitializeParams.shutdown_isolate
By default `Isolate.spawn` will cause the creation of a new IG.
Though an embedder can opt-into supporting multiple isolates within one IG by
providing a callback to the newly added `Dart_InitializeParams.initialize_isolate`.
The responsibility of this new callback is to initialize an existing
isolate (which was setup by re-using source code from the spawning
isolate - i.e. the one which used `Isolate.spawn`) by setting native
resolvers, initializing global state, etc.
Issue https://github.com/dart-lang/sdk/issues/36648
Issue https://github.com/dart-lang/sdk/issues/36097
Original review: https://dart-review.googlesource.com/c/sdk/+/105241
Difference to original review:
* Give each isolate it's own [Loader] (for now)
* Sort classes during initialization for spawned isolates if app-jit is used (to match main isolate)
* Fix IsolateData memory leak if isolate startup fails
Change-Id: I98277d3d10fe275aa9b8a16b6bdd446bbea0b100
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/107506
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
This reverts commit b75057b687.
Reason for revert: Caused some failures on app-jit builders
Original change's description:
> [vm/concurrency] Introduce concept of Isolate Groups
>
> An Isolate Group (IG) is a collection of isolates which were spawned from the
> same source. This allows the VM to:
>
> * have a guarantee that all isolates within one IG can safely exchange
> structured objects (currently we rely on embedder for this
> guarantee)
>
> * hot-reload all isolates together (currently we only reload one
> isolate, leaving same-source isolates in inconsistent state)
>
> * make a shared heap for all isolates from the same IG, which paves
> the way for faster communication and sharing of immutable objects.
>
> All isolates within one IG will share the same IsolateGroupSource.
>
> **Embedder changes**
>
> This change makes breaking embedder API changes to support this new
> concept of Isolate Groups: The existing isolate lifecycle callbacks
> given to Dart_Initialize will become Isolate Group lifecycle callbacks.
> A new callback `initialize_isolate` callback will be added which can
> initialize a new isolate within an existing IG.
>
> Existing embedders can be updated by performing the following renames
>
> Dart_CreateIsolate -> Dart_CreateIsolateGroup
> Dart_IsolateCreateCallback -> Dart_IsolateGroupCreateCallback
> Dart_IsolateCleanupCallback -> Dart_IsolateGroupShutdownCallback
> Dart_CreateIsolateFromKernel -> Dart_CreateIsolateGroupFromKernel
> Dart_CurrentIsolateData -> Dart_CurrentIsolateGroupData
> Dart_IsolateData -> Dart_IsolateGroupData
> Dart_GetNativeIsolateData -> Dart_GetNativeIsolateGroupData
> Dart_InitializeParams.create -> Dart_InitializeParams.create_group
> Dart_InitializeParams.cleanup -> Dart_InitializeParams.shutdown_group
> Dart_InitializeParams.shutdown -> Dart_InitializeParams.shutdown_isolate
>
> By default `Isolate.spawn` will cause the creation of a new IG.
>
> Though an embedder can opt-into supporting multiple isolates within one IG by
> providing a callback to the newly added `Dart_InitializeParams.initialize_isolate`.
> The responsibility of this new callback is to initialize an existing
> isolate (which was setup by re-using source code from the spawning
> isolate - i.e. the one which used `Isolate.spawn`) by setting native
> resolvers, initializing global state, etc.
>
> Issue https://github.com/dart-lang/sdk/issues/36648
> Issue https://github.com/dart-lang/sdk/issues/36097
>
> Change-Id: I82437ac017ca33018d45e02f353b0672db155f6a
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/105241
> Commit-Queue: Martin Kustermann <kustermann@google.com>
> Reviewed-by: Ryan Macnak <rmacnak@google.com>
> Reviewed-by: Alexander Aprelev <aam@google.com>
TBR=kustermann@google.com,aam@google.com,rmacnak@google.com
Change-Id: Ibd90992a01d61188f27b445c21532e0c46f996ea
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/107405
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
An Isolate Group (IG) is a collection of isolates which were spawned from the
same source. This allows the VM to:
* have a guarantee that all isolates within one IG can safely exchange
structured objects (currently we rely on embedder for this
guarantee)
* hot-reload all isolates together (currently we only reload one
isolate, leaving same-source isolates in inconsistent state)
* make a shared heap for all isolates from the same IG, which paves
the way for faster communication and sharing of immutable objects.
All isolates within one IG will share the same IsolateGroupSource.
**Embedder changes**
This change makes breaking embedder API changes to support this new
concept of Isolate Groups: The existing isolate lifecycle callbacks
given to Dart_Initialize will become Isolate Group lifecycle callbacks.
A new callback `initialize_isolate` callback will be added which can
initialize a new isolate within an existing IG.
Existing embedders can be updated by performing the following renames
Dart_CreateIsolate -> Dart_CreateIsolateGroup
Dart_IsolateCreateCallback -> Dart_IsolateGroupCreateCallback
Dart_IsolateCleanupCallback -> Dart_IsolateGroupShutdownCallback
Dart_CreateIsolateFromKernel -> Dart_CreateIsolateGroupFromKernel
Dart_CurrentIsolateData -> Dart_CurrentIsolateGroupData
Dart_IsolateData -> Dart_IsolateGroupData
Dart_GetNativeIsolateData -> Dart_GetNativeIsolateGroupData
Dart_InitializeParams.create -> Dart_InitializeParams.create_group
Dart_InitializeParams.cleanup -> Dart_InitializeParams.shutdown_group
Dart_InitializeParams.shutdown -> Dart_InitializeParams.shutdown_isolate
By default `Isolate.spawn` will cause the creation of a new IG.
Though an embedder can opt-into supporting multiple isolates within one IG by
providing a callback to the newly added `Dart_InitializeParams.initialize_isolate`.
The responsibility of this new callback is to initialize an existing
isolate (which was setup by re-using source code from the spawning
isolate - i.e. the one which used `Isolate.spawn`) by setting native
resolvers, initializing global state, etc.
Issue https://github.com/dart-lang/sdk/issues/36648
Issue https://github.com/dart-lang/sdk/issues/36097
Change-Id: I82437ac017ca33018d45e02f353b0672db155f6a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/105241
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>