Commit Graph

891 Commits

Author SHA1 Message Date
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 ed78971d90 [vm/concurrency] Simplify conditions for hot reload and test mode implementation
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: Id32e7d8f95ba0b1fb5bd11179dcd1805d42aba89
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/187083
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
2021-03-02 15:21:22 +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 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 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
Martin Kustermann 02f65fa501 [vm/concurrency] Make clustered snapshot serializer independent of current isolate
Issue https://github.com/dart-lang/sdk/issues/36097

TEST=Mainly refactoring, stress tests for --enable-isolate-groups with JIT will come in the future.

Change-Id: Iebb2fb8bd144cb9abd21916856a04f49f85541c0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/183680
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
2021-02-12 04:32:48 +00:00
Martin Kustermann 92af830255 [vm/concurrency] Move background compiler related state from Isolate to IsolateGroup
As part of making the compiler independent of `Isolate` we have to move
various state from `Isolate` to `IsolateGroup`. This CL moves background
compiler and related state.

One background compiler will be shared for all isolates within a group.

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

TEST=Mainly refactoring, stress tests for --enable-isolate-groups with JIT will come in the future.

Change-Id: I66e863651d0b37c431ce1864e505b5413850cbde
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/183401
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2021-02-12 03:40:14 +00:00
Alexander Aprelev 26c0de0acf [vm/deferred] Keep deferred library prefix status on isolate.
This is to ensure that deferred library status is per isolate, rather than per isolate-group.

TEST=deferred_isolate_test.dart

Issue dartbug.com/36097

Change-Id: I1fb8b8f1830aac688a078fe0a82b06c7daa856fa
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/184040
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2021-02-11 18:00:59 +00:00
Martin Kustermann 0fec35f7df [vm/concurrency] Remove redundant Isolate::shared_class_table_
Issue https://github.com/dart-lang/sdk/issues/36097

TEST=Refactoring of existing implementation.

Change-Id: I4e875ed0996f86a73c712c67da3d261949603512
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/184264
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
2021-02-10 20:48:05 +00:00
Martin Kustermann 75e0837f3e [vm/concurrency] Simplify logic around background compiler, allow concurrent disabling
The logic for background compiler can be simplified due to:

  * we only have one bg compiler
  * it always optimizes
  * it is allocated at isolate startup and freed on isolate shutdown
  * an existing check in the compiler for whether the BG compiler is
    disabled is racy and therefore not helpful
  * when a mutator communicates with BG compiler it will use
    SafepointMutexLocker instead of MutexLocker

This CL also ecapsulates disabling the BG compiler via a
NoBackgroundCompilerScope object. It allows nested disabling and guards
against races.

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

TEST=Refactoring of existing code.

Change-Id: I36ed6592c9a8b91e94181698b7de662b4ee984e9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/183400
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
2021-02-10 19:42:55 +00:00
Martin Kustermann 6a60ed277b [vm/concurrency] Avoid using two different mechanisms to check for single-isolate
During isolate shutdown we remove the isolate from the list of isolates
in a group in one step and decrement a counter in another. Those are not
done atomically.

To avoid races where we use one condition and later on assume the other
holds as well, consistently use the same condition.

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

TEST=Fixes flaky tsan hits of ASSERT.

Change-Id: I41eeb00cd3e341d07cba7571b29aeb4eacdfc458
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/184260
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2021-02-10 16:50:23 +00:00
Alexander Aprelev 6ac90525a0 [vm/concurrency] Allow for background compiler to disable field unboxing.
Issue dartbug.com/36097

TEST=existing test suite
Change-Id: Idd0c26fe9c81a733685105aa944b96ed58bc2765
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/182669
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2021-02-09 16:27:13 +00:00
Martin Kustermann b7ad7a3000 [gardening] Use a read lock instead of a write lock
When accessing the list of isolates in a group to get the first one we
only need a read-lock, not a write-lock.

This fixes hot-reload bot timeouts where a mutator hits a StackOverflow
slowpath that triggers a reload, which loops over all isolates in a
group to stop BG compiler (takes read lock). The BG compiler in return
will try to acquire write-lock for `FirstIsolate()`, which causes a
deadlock.

TEST=Existing reload timeouts.

Change-Id: Iba9264cc4990a4f00697844c44fad407cebf2e21
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/183003
Reviewed-by: Clement Skau <cskau@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2021-02-05 10:17:22 +00:00
Martin Kustermann 6f90dd22ce [gardening] Small partial revert that enabled validating constants after reload
While addresing a comment in the review of [0], the CL removed a bailout in
`Isolate::ValidateConstants()` that disabled validating of constants
when hot-reload was performed. Apparently there is still an issue with
that. So this CL adds this bailout again.

[0] https://dart-review.googlesource.com/c/sdk/+/182561

TEST=Partial revert, fixes constant validation failures.

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

Change-Id: Iefe9acceb344e73fad97246064e91a32a00dad10
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/183002
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Clement Skau <cskau@google.com>
2021-02-05 10:14:14 +00:00
Martin Kustermann 75a4fa6e23 [vm/concurrency] Move AllClassesFinalized/RemappingCids bits from Isolate to IsolateGroup
Those bits are used by parts of the VM that should be independent of the
current isolate (e.g. class finalizer, compiler).

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

TEST=Refactoring of existing code.

Change-Id: I25c8340304d21fdfa77fa5ab4a5f77a4884d0bba
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/182620
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2021-02-04 18:09:37 +00:00
Martin Kustermann 376bf1826a [vm/concurrency] Move HasAttemptedReload() bool from Isolate to IsolateGroup
As part of making the compiler as well as hot-reload independent of
a particular isolate we move this boolean to `IsolateGroup`.

For hot-reloading isolate groups there are more changes needed that
come in the future. This CL is preparation for making the compiler
independent of current isolate.

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

TEST=Refactoring of existing code.

Change-Id: I434cf1180bc963462e2901dfa83e915df9dc1712
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/182561
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2021-02-04 17:45:57 +00:00
Martin Kustermann 59aa375d22 [vm/concurrency] Make compiler create JitCookie using IsolateGroup::random()
As part of making the compiler independent of the current isolate (since
JITed code will be shared across all isolate) we make the compiler not
depend on `Isolate::random()` but rahter on `IsolateGroup::random()`.

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

TEST=Refactoring of existing code.

Change-Id: I4a7bdd5c3e3d7ca83ef828ad6e38f117b5f2e9ce
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/182560
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2021-02-04 11:12:47 +00:00
Martin Kustermann 3020f7dca2 [vm/concurrency] Remove the unused Isolate::deoptimized_code_array_ and related
Supposedly the intention was to use this in runtime/vm/profiler.cc but
it has been seemingly unused for a while without any issues or test
failures, so this CL removes it.

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

TEST=Removing of code.

Change-Id: I53df5e92e146169b6d8d21c763dd7e8b8f50289a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/182510
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2021-02-04 10:54:12 +00:00
Martin Kustermann 3ce16de628 [vm/concurrency] Move no_reload_scope_depth from Isolate to IsolateGroup
As part of making the compiler and various other systems independent of
the current isolate, we move state from Isolate to IsolateGroup.

There is still follow-up work to do for hot-reloading isolate groups.

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

TEST=Refactoring of existing code.

Change-Id: I4a2cebd06b49696e733adde622217b4de6718260
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/182508
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2021-02-04 10:46:47 +00:00
Martin Kustermann 9f6bc62a39 [vm/concurrency] Move boxed field list form Isolate to IsolateGroup
As part of making the compiler independent of a particular isolate
(since all isolates in a group share the same JITed code) we move the
boxed field list to IsolateGroup.

Any isolate that hits the lazy compile stub will then drain the fields
to be deoptimized and performs that work.

A follow-up investigation can decide whether it's beneficial (or
hurtful) for single vs multi isolate scenarios to deoptimize the field
immediately in BG compiler (and interrupt mutator). It is possibly
disadvantagues for single isolate scenarios to do so, since it causes
more mutator interruptions.

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

TEST=Refactoring of existing code.

Change-Id: I64b42ad99056b43a7264bcc30280b9ba39389a2e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/182505
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2021-02-04 10:46:07 +00:00
Alexander Aprelev 6b3abe0a98 [vm/concurrency] Add --experimental_enable_isolate_groups_jit flag, make --enable_isolate_groups AOT only.
Issue b/177800357.

TEST=existing test suite
Change-Id: Id6b113932ab7014b8fa6c105845c5c490b60f5e8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/181320
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
2021-01-27 17:11:29 +00:00
Martin Kustermann 1b38b85223 [vm/concurrency] Rename IsolateReloadContext -> ProgramReloadContext
As part of making the compiler and other subsystems independent
of `Isolate` we have to move various state from `Isolate` to
`IsolateGroup` (or to another place).

Part of that is `Isolate::reload_context()`. In order to avoid name
conflict of what a `reload_context()` is, we separate it into
`reload_context()` and `program_reload_context()` where the former
contains GC information and the latter contains information about
changes in program structure.

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

TEST=Pure refactoring - relying on existing test coverage.

Change-Id: I7e1b732ce8b34c8842718699d618be542bd59ff6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/177863
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2021-01-16 15:42:53 +00:00
Ryan Macnak b1c09ecd8f [vm] Make naming more consistent when converting between handles, tagged and untagged pointers.
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>
2021-01-15 23:32:02 +00:00
Martin Kustermann 5cd0770c9c [vm/concurrency] Move closure function related state from Isolate to ClosureFunctionsCache
As part of making the compiler and other subsystems independent
of `Isolate` we have to move various state from `Isolate` to
`IsolateGroup` (or to another place).

The access of `ObjectStore::closure_functions()` was spread out over our
codebase, including from `Isolate`. This CL moves it to a centralized
place - ClosureFunctionsCache.

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

TEST=Pure refactoring - relying on existing test coverage.

Change-Id: I3b282623f07614cdc2c2a863bd5b9d6c7748d36f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/177130
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2021-01-07 09:41:27 +00:00
Martin Kustermann 0f76981bb1 [vm/concurrency] Change references to class_table/object_store/heap from Isolate to IsolateGroup
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>
2021-01-06 15:22:11 +00:00
Martin Kustermann 12d7707179 [vm/concurrency] Move null safety related state from Isolate to IsolateGroup
As part of making the compiler independent of `Isolate` we have to move
various state from `Isolate` to `IsolateGroup`.

This CL moves null safety related state.

TEST=Pure refactoring - relying on existing test coverage.

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

Change-Id: Ie0b19b8ef84768c9665326c4f955c956c6ba60bb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/177123
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2021-01-06 12:20:40 +00:00
Martin Kustermann 18971e409f [vm/concurrency] Move obfuscation related state from Isolate to IsolateGroup
As part of making the compiler independent of `Isolate` we have to move
various state from `Isolate` to `IsolateGroup`.

This CL moves obfuscation related state.

TEST=Pure refactoring - relying on existing test coverage.

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

Change-Id: I4b0a74bff9abc200cf8f4ce76b3e1d3d688e664a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/177122
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2021-01-06 11:12:40 +00:00
Martin Kustermann ffac0bcfd5 [vm/concurrency] Remove Dart_IsolateFlags.entry_points / Dart_QualifiedFunctionName from Dart C API
This CL removes the unused entry points in the C API. This is a breaking
API change but we don't promise normal Dart C API stability and existing
known embedders don't specify this flag.

TEST=Pure refactoring - relying on existing test coverage.

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

Change-Id: Ic27662743e48f5f5cfbf770baf2cd255ed3f15b5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/177121
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2021-01-06 10:24:45 +00:00
Martin Kustermann 99db985dfa [vm/concurrency] Remove Isolate::embedder_entry_points_ and related code
The embedder entrypoints stored on the Isolate object are ignored atm.

TEST=Pure refactoring - relying on existing test coverage.

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

Change-Id: I4098461c6ee649dffd0f662362cb4f0ae54e88f1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/177120
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2021-01-06 10:23:10 +00:00
Alexander Aprelev fce355b8b0 [vm/fields] Always clone fields when running an optimizing compiler, even when it runs on the mutator thread.
Attempts to run class finalizaton on background thread revealed the problem where during optimization(which could run on mutator thread too) we might need to finalize previously unseen class, load annotatons for it, load and set some constant fields. This could result in updating Fields guarded_cid, requires check during installation of newly produced optimized code. Because mutator thread is currently exempt from cloning and validating fields guards, that could result in invalid optimized code installation.

This CL ensures that fields are always cloned in optimizing compiler even when it runs on mutator thread.

Ability to run multiple optimizing compilers is also needed for dartbug.com/36097.

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

TEST=existing test suite with ltw isolate groups enabled, https://dart-review.googlesource.com/c/sdk/+/176300 mocked up test(still to be improved).

Change-Id: I608f4abff30b468cb9d0ab270221a0ba72c32470
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175341
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2020-12-17 00:22:13 +00:00
Alexander Aprelev e45e4cad50 [vm/service] Fix calculation of heap size numbers for isolate groups
TEST=benchmarks/IsolateSpawnMemory with/without --enable-isolate-groups

Change-Id: Id8349839248323b84cbc743217cd4a380504c8b7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175520
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Alexander Aprelev <aam@google.com>
2020-12-09 17:36:20 +00:00
Martin Kustermann 425780f410 [vm/concurrency] Share program structure and JITed code with --enable-isolate-groups
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>
2020-12-09 09:39:59 +00:00
Ryan Macnak e3a9d70591 [vm, service] Remove unsafe querying across threads during Isolate::PrintJSON.
Note this would be unsafe even if under a safepoint operation because not all of the queried threads participate in safepoints.

TEST=tsan
Bug: https://github.com/dart-lang/sdk/issues/44304
Bug: https://github.com/dart-lang/sdk/issues/44385
Change-Id: I8156e8c6049165e5c53b66c3391f3e8a496ddaaf
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175000
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ben Konyi <bkonyi@google.com>
2020-12-08 00:36:38 +00:00
Martin Kustermann f30675a29f [vm/concurrency] Ensure static field registration is done under programlock
Also prepare for being able to grow field table of other isolates when
registering a new static field.

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

TEST=Tests using --enable-isolate-groups.

Change-Id: If1bc272e71da5cc89f962cfcac04d72c9314cf51
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175066
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2020-12-04 19:38:52 +00:00
Martin Kustermann b6c28bb0c9 [vm/concurrency] Move various JIT compiler related locks from Isolate to IsolateGroup
Once we enable sharing of JITed code with --enable-isolate-groups, we
need to ensure all isolates use the same locks to for their shared data.

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

TEST=Tests running with --enable-lightweight-isolates.

Change-Id: Ie6e928c5505b39c93e086dfac379bd22034a0028
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/174640
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2020-12-02 20:30:48 +00:00
Martin Kustermann 759caec558 [vm/concurrency] Add patchable_call_mutex and take it in miss handlers
We serialize all changes to patchable call state to ensure we always
make progress (e.g. transition from Monomorphic -> Polymorphic).

Only if the miss handler actually needs to patch the patchable call do
we stop mutators - if it only updates ICData we don't have to do that.
=> In the future we might introduce a more clever mechanism to avoid
   stopping mutators.

The CL also moves some locks from Isolate to IsolateGroup to ensure
all mutators use the same lock, since they operate on shared data
structures.

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

TEST=Existing isolate tests that --enable-isolate-groups.

Change-Id: I4a11a8b8bb65581c6aba11cdf73acdea0f24a502
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/174469
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2020-12-02 18:14:18 +00:00
Martin Kustermann e74d01007e [vm/concurrency] Make updates to MegamorphicCache use type_feedback_mutex to prevent concurrent access
With lightweights isolates enabled we need to ensure to update entries
in MetamorphicCache in sequence with mutual exclusion.

This CL adds appropriate locking for the MegamorphicCache.

Right now this is safe in AOT because the entire SwitchableCallMiss
handler runs with stopped mutators. A future CL will relax this. That
future CL will also move the megamorphic mutex from Isolate to
IsolateGroup, since the megamoprhic caches are shared within an isolate
group.

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

TEST=CL is purely a refactoring.

Change-Id: I30305b04027d2bf9b4d5f6b1700bf158d38bdba7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/174467
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
2020-12-02 14:52:47 +00:00
Martin Kustermann 83e460ab6d [vm/concurrency] Make ICData use new type_feeback_mutex to prevent duplicate entries
Dart mutator threads cause update to runtime type feedback information
(e.g. ICData, MegamorphicCache). With multiple lightweight isolates
sharing JITed code, they will share the type feedback as well. That also
means multiple mutators can try to update type feedback at the same time
with the same (or different) feedback.

This means we can run into situations where we're trying to update type
feedback with information that's already there.
=> At a minimum we want to avoid adding duplicate entries to the ICData,
   so we have to guard against that.

Since the actual backing store to ICData is immutable, we have two
choices:

  * Let each thread read the current backing store, make a
    copy-on-write, add the new entry and update ICData with new backing
    store.
    => This can lead to an successful update being visible for a short
       period and then disappearing.

  * We can can ensure mutual exclusion when updating the backing store
    of ICData, thereby making read+grow+write appear atomic.
    => This requires taking a lock but ensures we never hit the same
       IC miss multiple times.

=> We take the latter approach for now.

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

TEST=CL is purely a refactoring.

Change-Id: Ic3b2de61e25de0210323edd732424cc7d1178771
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/174465
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
2020-12-02 14:51:07 +00:00
Martin Kustermann dab1efeb5d [vm/concurrency] Make the IGs own the initial static field value table
As part of making lightweight isolates work in JIT, we will need to
ensure that whenever a new isolate is spawned it will get it's initial
global field table populated.

In order to achieve this we make the isolate groups initial field table
the authoritive place where we

  a) register initial static field values
  b) serializer reads them from, deserializer writes them to

This allows us to also remove the `FieldLayout::initial_saved_value_`
that was present for both static and non-static fields. In reality this
initial saved value is only meaningful for static fields though it was
kept in memory as well as (de)serialized even for non-static fields.

The one place where it was actually used for non-static fields was
incorrect and should instead use `null`.

The removal of this field results in net removal of code in this CL.

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

TEST=Internal refactoring, relying on existing test coverage.

Change-Id: I088a87e2ea159bac7fa7f1f360da553d752e6569
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/173263
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
2020-11-24 11:25:58 +00:00
Martin Kustermann b4773ae496 [vm/concurrency] Move static field registration out of Field::New() methods
As part of making lightweight isolates work in JIT, we will need to
ensure that whenever a new static field is loaded, it will get a new
slot on every isolate and the possibly initial static value is set in
all isolates's field state.

In order to achieve this we first move field registration out of
Field::New*() - to the place where the field is created and the initial
static field value is known.

In a future CL we will make a field registration be performed on all
isolates in a group.

TEST=CL is internal refactoring, existing test coverage.

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

Change-Id: I802ae55b841be173733dbd0ad3dbffeebd5c1889
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/173260
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-11-21 07:36:53 +00:00
Martin Kustermann d9561e5a1d [vm/concurrency] Move Isolate.spawn()-related logic out of runtime/vm/ into runtime/lib
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>
2020-11-15 13:31:47 +00:00
Martin Kustermann bf4280ff75 [vm/concurrency] Add Dart_CreateLightweightIsolate/Dart_RunLoopAsync APIs
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>
2020-11-12 10:22:16 +00:00