Commit graph

19 commits

Author SHA1 Message Date
Martin Kustermann 3c81d992ef [vm/concurrency] Distinguish "gc safepoint operations" from "deopt safepoint operations"
This extends the existing safepoint operation mechanism by allowing to
perform two different operations:

  * "gc safepoint operations": All mutators are stopped at places where
    it's safe to GC. It therefore requires stackmaps to be available for
    all optimized mutator frames.

  * "deopt safepoint operations": All mutators are stopped at places
    where it's safe to GC, but also safe to lazy-deopt mutator frames.
    It therefore requires deopt-id/deopt-info to be available for all
    optimized mutator frames.

Mutators can be asked to block for any of those two safepoint operations.
If a mutator is at a place where its safe to GC it will respond to "gc
safepoint operations" requests, if a mutator is additionally at a place
where it's also safe to lazy-deopt it will respond to "deopt safepoint
operation" requests.

Depending on how the runtime was entered (which is tracked via the
[Thread::runtime_call_deopt_ability_] value) - the mutator might
participate in both or only in gc safepoint operations.

During the start of a "deopt safepoint operation", the safepoint handler
will request all threads to stop at a "deopt safepoint". Some threads
might first want to initiate their own "gc safepoint operation"
(e.g. due to allocation failure) before they reach a "deopt safepoint".

We do allow this by letting the safepoint handler own a "deopt safepoint
operation" but still participate in other thread's "gc safepoint
operation" requests until all mutators are checked into places where
it's safe to lazy-deopt at which point the "deopt safepoint operation"
also owns a "gc safepoint operation".

In order to facilitate this, the Thread's safepoint_state will be
extended to consist of the following bits:

  * AtSafepoint
  * SafepointRequested
  * AtDeoptSafepoint
  * DeoptSafepointRequested
  * BlockedForSafepoint

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

TEST=vm/cc/SafepointOperation_*

Change-Id: Icdc2827718f6780818f99b829a5e806d6bb5b130
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/196927
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2021-05-10 09:13:09 +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
Martin Kustermann f3740ced59 [vm/concurrency] Add SafepointMonitorUnlockScope to allow scoped unlocking of a monitor
In order to simplify code that needs to temporarily give up a monitor
lock, this CL adds a scoped object that releases the monitor on
construction and re-acquires it on destruction.

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

TEST=Refactoring of existing code.

Change-Id: I004a04e54dcdaea009bfbef25d2a946a307e41c6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/187001
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2021-03-02 13:11:42 +00:00
Martin Kustermann 1e114a88d0 [vm/concurrency] Refactor SafepointRwLock to ensure unlocking never causes safepoint transition.
The previous implementation of SafepointRwLock has an issue (discovered
by Slava, see bug) with the following code pattern:

    {
      SafepointReadRwLocker locker(...);
      return Foo(); // <-- Returns raw ptr.
    }

After the return expression has been evaluated to a raw pointer
the destructor might enter safepoint and cause GC, which leaves
the raw pointer unchanged (since it's not in a handle).

This CL refactors the implementation to ensure we don't perform any
state transition in the destructor, therefore eliminate the
possibility of GC moving the object we return.

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

TEST=Relying on existing SafepointRwLock.

Change-Id: Ib7a62b36838edd4b39ad67a8c58f048aa05aa144
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/185062
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
2021-02-17 09:53:49 +00:00
Martin Kustermann a55b0137e9 [vm/concurrency] Make SafepointMutexLocker inherit from StackResource
The SafepointMutexLocker class already has a virtual destructor and was
therefore probably intended to be called when a longjmp() crosses it.

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

TEST=Added vm/cc tests in the CL.

Change-Id: Ifcfe51db733c4451be5be688df0c34004b98c3cc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/174644
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
2020-12-02 14:59:13 +00:00
Martin Kustermann dae308461c [vm/concurrency] Share [Heap] and [SharedClassTable] between all isolates within one isolate group
This CL:

  * Moves [Heap]/[SharedClassTable] from [Isolate] to [IsolateGroup], which
    will make all isolates in the group use the same heap. The GC will use
    the shared class table for object size information.

  * Adds support for entering/leaving an isolate group as a helper thread
    (e.g. via [Thread::EnterIsolateGroupAsHelper]). The current active
    isolate group can be accessed via TLS `IsolateGroup::Current()` or
    `Thread::isolate_group_`. When entering as a helper thread there will be
    no current isolate.

  * Changes the GC to use the above mechanism and ensures GC works without
    a currently active isolate. The GC will use information purely available via
    [IsolateGroup]. The GC will iterate all isolates within an isolate
    group e.g. for scanning roots.

  * Makes spawning of new isolates start in their own isolate group.
    Once the isolate is fully functional it's heap will be merged into
    the original isolate group

  * Moves ApiState, containing persistent and weak persistent handles,
    from [Isolate] to [IsolateGroup], plus adds appropriate locking.

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

Change-Id: Ia8e1d8aa78750e8400864200f4825395a182c004
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/126646
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2020-02-20 21:08:35 +00:00
Martin Kustermann 7339b27f7f [vm/concurrency] Fix bug in Safepoint{Mutex,Monitor}Locker which can cause a deadlock
While a thread is outside a safepoint it should not perform any
long blocking operation and it must not acquire a Mutex/Monitor which
can be held while being inside a safepoint.

Right now we can have this situation

   GC wants to safepoint
   T1 is in a safepoint, acquires lock L and wants to leave safepoint (waits for GC to finish)
   T2 is not in a safepoint and tries to acquire lock L

With this CL, we ensure to always transition to a safepoint before
performing Lock/Enter/Wait.

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

Change-Id: I79c55c79bfe828a319f5b035880f578ef62d913a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134323
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2020-02-05 23:17:59 +00:00
Martin Kustermann 38c6152884 [vm/concurrency] Add IsolateGroup::RunWithStoppedMutators and use it in various places
When installing new code, we need to ensure the mutator is stopped for a
variety of reasons.

Right now we only need to distuinguish mutator and background compiler
when installing code: The mutator can install code without any
synchronization whereas the bg compiler needs to get the mutator to a safepoint.

Yet once all isolates within one isolate group share a heap, a mutator
might need to stop all other mutators before installing code (since they
operate on pages on which we flip page protection bits)

This CL adds IsolateGroup::RunWithStoppedMutators which will get other
mutators to a safepoint (if there are multiple or we are on a bg
compiler thread).

Along with this we add a read-write lock and use it for the protection
of the IsolateGroup::isolate_: While we make assumptions about the
number of isolates in a group we force all pending additions of new
isolates to wait. Later on this will also be used to allow iterating the
list of isolates during GC and prevent new isolates from being added at
the same time.

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

Change-Id: I6e761fa51d36b2f2b4b67995cac954898ce7fd69
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-android-release-arm-try,vm-dartkb-linux-release-x64-abi-try,vm-kernel-precomp-bare-linux-release-x64-try,vm-kernel-precomp-mac-debug-simarm_x64-try,vm-kernel-precomp-win-release-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/116767
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2019-09-18 12:24:31 +00:00
Ryan Macnak 54b197ccc2 [vm] Prevent GC when there are outstanding pointers from Dart_TypedDataAcquireData.
Bug: https://github.com/dart-lang/sdk/issues/37256
Change-Id: I1dcd2e32d8308c5a7169731169a048b8f1bfcc79
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/106023
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
2019-06-19 21:31:31 +00:00
Ryan Macnak 8da46d35f5 [vm] Move heap-related code to its own subdirectory (cf. compiler).
Remove some dead includes.

Change-Id: I31f3e739e5ee46dcbba5d6a2f091491b46402943
Reviewed-on: https://dart-review.googlesource.com/60146
Reviewed-by: Zach Anderson <zra@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2018-06-20 00:39:49 +00:00
Ryan Macnak 28399608e3 [vm] Remove some unnecessary OFFSET_OF.
Change-Id: Iaed6cbae7717b7fb5d3c22d8c35a2ba489569e73
Reviewed-on: https://dart-review.googlesource.com/18461
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2017-11-09 22:20:02 +00:00
Zachary Anderson 6cd8a79078 VM: Re-format to use at most one newline between functions
R=asiva@google.com

Review-Url: https://codereview.chromium.org/2974233002 .
2017-07-13 08:08:37 -07:00
Zachary Anderson a1bcf051d8 clang-format runtime/vm
R=johnmccutchan@google.com

Review URL: https://codereview.chromium.org/2481873005 .
2016-11-08 13:54:47 -08:00
Ryan Macnak bb85b32d51 Fix --verify-on-transition for OSR and concurrent sweep.
Wait for concurrent sweep tasks before verifying points, as building the allocation set expects unmarked objects.

Make assertion okay with a missing stack map at entry, which transiently exists for OSR, as the frame looks the same as unoptimized code here.

Fixes #13608
Fixes #23683
Reproduces issue #26927

R=fschneider@google.com

Review URL: https://codereview.chromium.org/2411453003 .
2016-10-11 15:03:09 -07:00
Siva Annamalai 79e4792dd6 Fix for issue 26511 (VM hangs waiting for all threads that are not already at
a safepoint to check-in)

BUG=26511
R=rmacnak@google.com

Review URL: https://codereview.chromium.org/2018673003 .
2016-05-27 15:30:34 -07:00
Siva Annamalai 1ba14b5b1d Check for Thread::Current being non NULL as in some situations (shutdown) it could be NULL.
R=johnmccutchan@google.com

Review URL: https://codereview.chromium.org/1751913003 .
2016-03-01 14:06:26 -08:00
Siva Annamalai e83151cc77 - Add assertions in MutexLocker/MonitorLocker to ensure that the code enclosed
in these blocks will not have a safepoint operation
- changed boxed_field_list_monitor_ to boxed_field_list_mutex_ as we only
  need a mutex for guarding access to boxed_field_list_ as changed the
  lock to use SafepointMutexLocker as the list addition code could potentially
  allocate and result in GC (safepoint operation)
- Added a SafepointMonitorLocker as we have a function Isolate::VisitIsolates
  which could potentially have safepoints in the enclosed block.
- Make the lock around MegamorphicCacheTable::Lookup a SafepointMutexLocker
  as the look up code seems to be allocating memory while the lock is held.
- Changed the ThreadPool and MessageHandler code to account for the new
  MonitorLocker usage standard
- Fixed PortMap::PrintPortsForMessageHandler to use SafepointMutexLocker as
  the code it encloses calls into Dart
- Removed profiler_ field in class Profiler as it doesn't seem to be used.

R=johnmccutchan@google.com, srdjan@google.com

Review URL: https://codereview.chromium.org/1748953003 .
2016-03-01 12:33:50 -08:00
Siva Annamalai 5322692506 Add a SafepointMutexLocker class so that it is possible to have scopes inside the MutexLocker which could potentially trigger safepoints.
R=srdjan@google.com

Review URL: https://codereview.chromium.org/1717803002 .
2016-02-19 16:03:52 -08:00
Siva Annamalai e72c1fb47d Implement safepointing of threads :
- uses thread execution status transition to track when a thread is in a safepoint or needs to block for a safepoint
 - introduces a monitor per Thread object
 - uses a per thread safepoint handshake between the thread requesting a safepoint and the requested thread.

The ThreadRegistry class now contains only the thread list for an isolate and the functionality of scheduling a thread onto an Isolate and unscheduling it from teh isolate. We could fold this functionality into the Isolate class in a different CL.

R=rmacnak@google.com, zra@google.com

Review URL: https://codereview.chromium.org/1541073002 .
2016-02-01 10:57:34 -08:00