Commit Graph

64 Commits

Author SHA1 Message Date
Alexander Markov 2ee6fcf514 [vm] Remove TypeRef
TypeRef type wraps around another type and it was used to represent
a graph of recursive types. After [0], the only use of TypeRef is
for TypeParameter.bound which may indirectly reference the same
TypeParameter.

This change replaces TypeParameter.bound with TypeParameter.owner and
removes TypeRef entirely. Various parts of the VM no longer need to
handle and support TypeRefs.

TypeParameter.owner can reference a FunctionType, Class,
or, as an optimization, it can be set to null in order to share
class type parameters among different classes.

With the exception of the 'TypeParameter.owner' back pointer,
VM types are now not recursive and can be visited without
additional tracking.

Caveats:

* Generic FunctionType cannot be cloned in a shallow way:
  when copying a FunctionType, type parameters should be cloned too
  and their owners should be updated. For that reason,
  a mapping between 'from' and 'to' function types
  (FunctionTypeMapping) is maintained during type transformations
  such as InstantiateFrom.
  FunctionType::Clone is used instead of Object::Clone where
  appropriate.

* When testing types for subtyping and equivalence, mapping
  between function types is passed to make sure
  type parameters belong to the equivalent function types.

* IL serializer needs to serialize function types as a whole before
  serializing any types potentially pointing into the middle of a
  function type (such as return type 'List<Y0>' pointing into
  the middle of a function type 'List<Y0> Function<Y0>()').

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

TEST=ci

Change-Id: I67c2fd0117c6183a45e183919a7847fd1af70b3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/294165
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
2023-04-28 19:29:36 +00:00
Ryan Macnak 96fd0b2208 [vm, gc] Avoid duplicate pointer visiting functions when compressed pointers are disabled.
This reduces code size ~10k, but more importantly it is easier to read profiling results without duplicate entries.

TEST=ci
Change-Id: I14c4a0d78d856242c5493df6de629ce048753c38
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/294440
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Liam Appelbe <liama@google.com>
2023-04-11 17:36:33 +00:00
Ryan Macnak 1eae028526 [vm] Fix zero-as-null-pointer-constant warnings in the VM.
Unfortunately we cannot enable -Wzero-as-null-pointer-constant because of zlib and icu headers we include.

TEST=build
Change-Id: I9ffd7d7e26f2b3dd616ce54d164b92e60a2366dc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/293882
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
2023-04-10 21:38:57 +00:00
Alexander Aprelev 67683c3973 [vm/isolates] Introduce 'vm:isolate-unsendable' pragma.
Decorate Zone, Future, Completer, Timer and Stream with newly-introduced pragma to make sure that message verification stops earlier, produces shorter retaining path for the user.

BUG=https://github.com/dart-lang/sdk/issues/51722
TEST=send_unsupported_objects_test,isolate_exit_unsendable_test.dart
CoreLibraryReviewExempt: vm-specific pragmas
Change-Id: I499eea542d228ac9cf0797a682664f93f360dc80
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/289027
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2023-03-27 20:54:11 +00:00
Ryan Macnak 63e6041ca9 [vm] Update to variadic FATAL.
TEST=ci
Change-Id: Ic6bc784605e10760bb28ea6df34242336a33b4d0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/286947
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2023-03-06 22:06:59 +00:00
Alexander Aprelev 4f30b5c9b5 [vm/isolates] Include retaining path into an illegal send argument exception.
The exception contains retaining path that looks like this:
```
Invalid argument(s): Illegal argument in isolate message: (object extends NativeWrapper - Library:'dart:io' Class: _RandomAccessFileOpsImpl@14069316)
 <- Library:'dart:io' Class: _RandomAccessFile@14069316
 <- Library:'file:///vm/dart/isolates/send_unsupported_objects_test.dart' Class: SomeLog
 <- Library:'file:///vm/dart/isolates/send_unsupported_objects_test.dart' Class: SomeState
 <-  Class: Context
 <- Library:'dart:core' Class: _Closure@0150898

```

BUG=https://github.com/dart-lang/sdk/issues/51115
BUG=https://github.com/dart-lang/sdk/issues/48592
TEST=send_unsupported_objects_test

Change-Id: I022e693adccf43a7d2c95e1c7283fd7f210cf1d7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/280523
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2023-02-23 03:11:08 +00:00
Martin Kustermann 7db7bd0573 [vm] Simplify is-deeply-immutable check in transitive object copy
Now that we have an immutability bit, we can set the bit in object
header of newly allocated objects if those objects are always
deeply immutable.

That allows only checking for the immutable bit instead of checking
against a whole range of cids when sending objects via
`SendPort.send()` / `Isolate.exit()`.

TEST=ci

Change-Id: I4451a9fe11f68c7dd874d49ab632daa3102be19e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/281842
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2023-02-09 00:23:22 +00:00
Martin Kustermann 896e535fe9 [vm] Allow sharing of deeply immutable lists across isolates
We support allocating deeply immutable typed data in the Dart C API
already.
=> This CL adds a test for that.

Furthermore we hook into the already O(n) construction of
`List.unmodifiable(<list>)` and set the objects immutable bit
if all elements of `<list>` are also immutable.
=> This allows then sharing of such lists when sent across isolates.

We do this eagerly to

  - avoid introducing complexity to the deep immutability check in
    transitive copy algorithm

  - avoids re-checking for the subgraph on every send (similar to
    canonicalized bit for constants, we can simply rely on the
    immutable bit)

If we ever optimized `List.unmodifiable()` (which always performs
runtime call atm) we could fold this checking into the place that copies
list elements from `<list>` to the newly allocated list.

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

TEST=vm/dart{,_2}/isolates/fast_object_copy2_test

Change-Id: Ie275e65036a4c53d992804972aae741a9f5ed6dd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/281424
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2023-02-08 19:14:13 +00:00
Martin Kustermann 63b5f5d4b1 [vm] Ensure we copy shallow (but not deeply) immutable lists
The object graph copy code assumed kImmutableCid is used only for
list constants but it turns out our List.immutable([]) implementation
isn't using a wrapper-view, but instead a fixed-length immutable list as
with constants:

  factory List.unmodifiable(Iterable elements) {
    final result = new List<E>.from(elements, growable: false);
    return makeFixedListUnmodifiable(result);
  }

The list constants should already be handled via canonical bit.

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

TEST=vm/dart{,_2}/isolates/regress_51302_test

Change-Id: I5924084ff004dc52bf675897455453d728484d1d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/281421
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2023-02-08 08:58:40 +00:00
Martin Kustermann c9f3aca45b [vm] Ensure we only enqueue maps/sets to be rehashed if we know it got copied successfully
Closes https://github.com/dart-lang/sdk/issues/51226

TEST=vm/dart{,_2}/regress_51226_test

Change-Id: I1da2dfe45863d5f1004efde3a4ecaae89ffd62fa
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/280469
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2023-02-06 11:00:29 +00:00
Ryan Macnak f3067e8740 [vm] Add WeakArray; to be used to create weak canonical sets.
TEST=ci
Bug: https://github.com/dart-lang/sdk/issues/50648
Change-Id: I788a8e3e5e8383c0b8d6f248d64a33dc67013260
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/278860
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2023-01-17 20:33:03 +00:00
Josh Soref 0633041729 Spelling runtime vm
Closes https://github.com/dart-lang/sdk/pull/50786

TEST=ci

GitOrigin-RevId: 781a38e2925ba505f0223ecd578faa9be8e1485c
Change-Id: Ia3c615012d1bac3f0cf64dc01c2ceb40d50d1193
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/276684
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2022-12-29 10:18:02 +00:00
Alexander Markov 3675fd25f4 [vm] Packed representation of record shape
The representation of record shape in record instances and record
types is changed from a pair

  int num_fields
  Array field_names

to a single integer - packed bitfield

  int num_fields(16)
  int field_names_index(kSmiBits-16)

where field names index is an index in the array available from
ObjectStore.

With the new representation of record shapes:
1) Size of record instances is reduced.
2) Number of comparisons for a shape test reduced from 2 to 1
(shape test is used during type checks).
3) A few operations removed from Record.hashCode.
4) Type testing stubs (TTS) are now supported for record types with
named fields. Previously it was not possible to check shape of records
with named fields in TTS as TTS cannot access object pool and cannot
load field names array).

TEST=existing

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

Change-Id: I7cdcbb53938aba5d561cd24dc99530395dbbea7e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/276201
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
2022-12-20 20:11:48 +00:00
Alexander Aprelev 438b81c4f2 [vm/regexp] Share RegExp objects between isolates, keep isolate-specific state in static members.
Revert "[vm/regexp] Copy, rather than share RegExp objects between isolates." is in patchset 1.

Isolate RegEx-sharing benchmarks show 24-100x improvements.

Bug: https://github.com/dart-lang/sdk/issues/50639
TEST=ci
Change-Id: I87943c9b9928869f7a20052cb0dc71d24ad36087
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/276240
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2022-12-20 02:28:04 +00:00
Martin Kustermann 896675c462 [vm] Always share double/float32x4/float64x2/int32x4 in inter-isolate messages
The JIT support for dynamically unboxing has been removed in [0]. As
such all double/float32x4/float64x2/int32x4 objects are immutable and
can therefore be shared across isolates.

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

TEST=ci

Change-Id: Ifd4e7c2444415b2e3b5269d9fbeb6570cc5d6768
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/273680
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
2022-12-07 00:48:28 +00:00
Alexander Aprelev 4275d595b6 [vm/regexp] Copy, rather than share RegExp objects between isolates.
RegExp code objects keep backtracking and registers stacks in object pools, can't be shared between isolates.

BUG=https://github.com/dart-lang/sdk/issues/50082
TEST=one_regexp_many_workers

Change-Id: Ic7db8d7a75a0951178b2f4800f96224d52506545
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/273480
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Aprelev <aam@google.com>
2022-12-02 22:45:21 +00:00
Ryan Macnak a2de36e708 [vm] Rename the default implementation classes of Map and Set.
_InternalLinkedHashMap => _Map
_InternalImmutableLinkedHashMap => _ConstMap
_InternalLinkedHashSet => _Set
_InternalImmutableLinkedHashSet => _ConstSet

This makes things nicer to read in places that display implementation names, such as stack traces, debuggers, profilers and inspectors.

TEST=ci
Change-Id: Iec851c80ea2086cbe79934565dbf35f04809a836
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/266303
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
2022-11-15 17:15:58 +00:00
Alexander Markov 10e9606861 [vm] More efficient 'is' tests for record types
'is' tests against record types are split into series of 'is' tests of
record fields. This is more efficient as record instances cannot be
added to subtype test caches (because type of a record instance
depends on types of its fields).

This change also adds canonicalization and constant evaluation of
LoadFieldInstr for record fields.

Performance on a trivial micro-benchmark (on x64):
JIT (RunTime): 4519104.5 -> 20031.5
AOT (RunTime): 4352583.0 -> 26281.6

TEST=ci
Issue: https://github.com/dart-lang/sdk/issues/49719
Change-Id: I2ed464cd3b31f365b17805f4e7debe1d6d1051fa
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/268080
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
2022-11-07 22:27:31 +00:00
Ryan Macnak 353dc891c8 [vm] Allocate old after isolate messages reach a certain size.
This avoids expensive promotion of large messages.

Cf. 04659de9f05af63d5fe4b8d67d70bb3cdf1c9a7a

TEST=ci
Change-Id: I89d5e560063f7d0c1f791ef299bb74c971f3dccf
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/257801
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-09-26 23:45:07 +00:00
Vyacheslav Egorov 83ab5d5ca3 [vm] Remove dynamic field unboxing in JIT
Instead apply the same approach as we do in AOT: unbox based on the
static type information. There are no TFA results available in JIT,
but we could still unbox fields when running in sound null-safety.

TEST=ci

Cq-Include-Trybots: luci.dart.try:vm-kernel-reload-linux-release-x64-try,vm-kernel-reload-linux-debug-x64-try,vm-kernel-reload-rollback-linux-debug-x64-try,vm-kernel-reload-rollback-linux-release-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-release-simarm64-try,vm-kernel-linux-debug-simriscv64-try,vm-kernel-precomp-linux-debug-simriscv64-try,vm-kernel-nnbd-linux-release-ia32-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-ia32-try,vm-kernel-nnbd-linux-release-simarm-try,vm-kernel-nnbd-linux-release-simarm64-try
Change-Id: Ide2e78c6659261ef8d245a4586cf699ea0fbb459
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/256211
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Slava Egorov <vegorov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
2022-09-20 13:42:45 +00:00
Alexander Markov c94103ae05 [vm] Initial implementation of record instances
TEST=ci

Issue: https://github.com/dart-lang/sdk/issues/49719
Change-Id: I82ba571d1935d616fe3d4d6d579e59eb57d65a43
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/256804
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2022-09-12 22:41:57 +00:00
Alexander Markov 9a023aeae9 [vm] Initial implementation of record types
TEST=language/record_type_test

Issue: https://github.com/dart-lang/sdk/issues/49719
Change-Id: Ib2100c23513395c9fa9c541320eacbb33a2a119e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/256802
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
2022-09-12 22:40:57 +00:00
Vyacheslav Egorov 4a4eedd860 [vm] Clean up ClassTable
* Merge ClassTable and SharedClassTable back together;
* Simplify handling of multiple arrays growing in sync;
* Refactor how reload deals with ClassTable.

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

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

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

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

TEST=ci

Cq-Include-Trybots: luci.dart.try:vm-kernel-reload-linux-release-x64-try,vm-kernel-reload-linux-debug-x64-try,vm-kernel-reload-rollback-linux-debug-x64-try,vm-kernel-reload-rollback-linux-release-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-precomp-tsan-linux-release-x64-try,vm-kernel-tsan-linux-release-x64-try,vm-kernel-precomp-asan-linux-release-x64-try,vm-kernel-asan-linux-release-x64-try
Change-Id: I8b66259fcc474dea7dd2af063e4772df99be06c4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/258361
Commit-Queue: Slava Egorov <vegorov@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
2022-09-10 15:12:35 +00:00
Derek Xu c9f0120220 Reland "[VM - Runtime] Return nullptr when allocating a FinalizablePersistentHandle fails"
This is a reland of commit b8d4e24338

How the failures were fixed:
1. My ExternalSizeLimit test crashed on msvc because I was using a
0-sized array. I have now changed that array to have size 1.
2. My ExternalSizeLimit test crashed on x64c because
ExternalTypedData::MaxElements(kExternalTypedDataUint8ArrayCid) is much
smaller than kMaxAddrSpaceMB/4 on x64c. I now call
ExternalTypedData::New() with a length argument of 1, and just pretend
that the external allocations are larger when calling
FinalizablePersistentHandle::New().

Original change's description:
> [VM - Runtime] Return nullptr when allocating a
> FinalizablePersistentHandle fails
>
> This CL adds checks to ensure that the tracked total size of
> externally allocated objects never exceeds the amount of memory on the
> system. When the limit is exceeded, then
> FinalizablePersistentHandle::New() will return nullptr.
>
> Resolves https://github.com/dart-lang/sdk/issues/49332
>
> TEST=ci
>
> Change-Id: Ib6cc92325b1d5efcb2965098fa45cfecc90995e3
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/256201
> Reviewed-by: Ben Konyi <bkonyi@google.com>
> Commit-Queue: Derek Xu <derekx@google.com>
> Reviewed-by: Siva Annamalai <asiva@google.com>

TEST=I ran the tryjobs for the configurations that broke CI.

Change-Id: I813aa74667c59a4dbec7f53440ca8d0bf21256ce
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/256973
Reviewed-by: Ben Konyi <bkonyi@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Derek Xu <derekx@google.com>
2022-09-06 15:13:16 +00:00
Ryan Macnak a2d5419f73 Revert "[VM - Runtime] Return nullptr when allocating a FinalizablePersistentHandle fails"
This reverts commit b8d4e24338.

Reason for revert: breaks msvc, msan, x64c builds

Original change's description:
> [VM - Runtime] Return nullptr when allocating a FinalizablePersistentHandle fails
>
> This CL adds checks to ensure that the tracked total size of externally
> allocated objects never exceeds the amount of memory on the system. When
> the limit is exceeded, then FinalizablePersistentHandle::New() will
> return nullptr.
>
> Resolves https://github.com/dart-lang/sdk/issues/49332
>
> TEST=ci
>
> Change-Id: Ib6cc92325b1d5efcb2965098fa45cfecc90995e3
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/256201
> Reviewed-by: Ben Konyi <bkonyi@google.com>
> Commit-Queue: Derek Xu <derekx@google.com>
> Reviewed-by: Siva Annamalai <asiva@google.com>

TBR=bkonyi@google.com,asiva@google.com,dnfield@google.com,derekx@google.com

Change-Id: I934bfbf5dc2e8e2ead5c74fe6b1d84e7b311788c
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/256972
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
2022-08-31 16:41:59 +00:00
Ryan Macnak 3f4db67730 [vm] Avoid pauses from uninterruptible WeakTable::Rehash().
TEST=ci
Change-Id: I39f59931b0607542a76e4b1c64a3126dbd055b74
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/247622
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2022-08-31 16:24:09 +00:00
Derek Xu b8d4e24338 [VM - Runtime] Return nullptr when allocating a FinalizablePersistentHandle fails
This CL adds checks to ensure that the tracked total size of externally
allocated objects never exceeds the amount of memory on the system. When
the limit is exceeded, then FinalizablePersistentHandle::New() will
return nullptr.

Resolves https://github.com/dart-lang/sdk/issues/49332

TEST=ci

Change-Id: Ib6cc92325b1d5efcb2965098fa45cfecc90995e3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/256201
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Derek Xu <derekx@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
2022-08-30 18:51:59 +00:00
Ryan Macnak 938a2c81d2 [vm] Add Dart_NewUnmodifiableExternalTypedDataWithFinalizer.
This foregoes the optimization of removing CheckWritable if the unmodifiable views are not used from Dart code.

TEST=ci
Bug: https://github.com/dart-lang/sdk/issues/49784
Change-Id: I18f3c36437ef136daf875358278caca4e3e0faa0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/255816
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-08-23 16:36:10 +00:00
Ryan Macnak 234128e8d3 Revert "[vm] Allocate old in object-graph-copy's slow path."
This reverts commit d0a60d67c9.

Reason for revert: Slow path transition seems to occur earlier than I expected

Original change's description:
> [vm] Allocate old in object-graph-copy's slow path.
>
> If we have reached the slow path, the message's subgraph is very likely to be large.
>
> TEST=ci
> Change-Id: Ie8a18c78936ae8a53f30dd61da3650e684c09dfa
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/249081
> Commit-Queue: Ryan Macnak <rmacnak@google.com>
> Reviewed-by: Martin Kustermann <kustermann@google.com>

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

Change-Id: I61faddd37e424a742427ae7c270cdb8b0a13c418
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/255300
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-08-16 16:23:47 +00:00
Ryan Macnak a8a94dcc4d [vm] Fix leak of forwarding tables when isolate message sending fails.
TEST=ci
Change-Id: I644834dcb49f197390dd71468b42b74c68a3cdb7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/255180
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-08-16 16:19:07 +00:00
Ryan Macnak d0a60d67c9 [vm] Allocate old in object-graph-copy's slow path.
If we have reached the slow path, the message's subgraph is very likely to be large.

TEST=ci
Change-Id: Ie8a18c78936ae8a53f30dd61da3650e684c09dfa
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/249081
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2022-08-15 20:32:56 +00:00
Ryan Macnak c1e67ac84f [vm] Recognize unmodifiable typed data views.
These types now work with Dart_TypedDataAcquireData.

The presence of these types no longer degrades the performance of typed data indexed loads.

The presence of these types degrades the performance of typed data indexed stores much less. The performance of indexed stores is somewhat regressed if these types were not used.

TEST=ci
Bug: https://github.com/dart-lang/sdk/issues/32028
Bug: https://github.com/dart-lang/sdk/issues/40924
Bug: https://github.com/dart-lang/sdk/issues/42785
Change-Id: Iffad865708501acf96db418985cd5a69bd9afa55
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/254501
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-08-11 18:10:48 +00:00
Ryan Macnak 10bf1cfe58 Revert "[vm] Recognize unmodifiabled typed data views."
This reverts commit d1112d37bd.

Reason for revert: b/242043014

Original change's description:
> [vm] Recognize unmodifiabled typed data views.
>
> These types now work with Dart_TypedDataAcquireData.
>
> The presence of these types no longer degrades the performance of typed data indexed loads.
>
> The presence of these types degrades the performance of typed data indexed stores much less. The performance of indexed stores is somewhat regressed if these types were not used.
>
> TEST=ci
> Bug: https://github.com/dart-lang/sdk/issues/32028
> Bug: https://github.com/dart-lang/sdk/issues/40924
> Bug: https://github.com/dart-lang/sdk/issues/42785
> Change-Id: I05ac5c9543f6f61ac37533b9efe511254778caed
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/253700
> Reviewed-by: Aske Simon Christensen <askesc@google.com>
> Reviewed-by: Martin Kustermann <kustermann@google.com>
> Commit-Queue: Ryan Macnak <rmacnak@google.com>

TBR=kustermann@google.com,rmacnak@google.com,askesc@google.com

TEST=ci
Change-Id: I32c1c460fc30c51bc0d42e7cfaafe72bf5630069
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: https://github.com/dart-lang/sdk/issues/32028
Bug: https://github.com/dart-lang/sdk/issues/40924
Bug: https://github.com/dart-lang/sdk/issues/42785
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/254560
Reviewed-by: Siva Annamalai <asiva@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-08-10 20:08:22 +00:00
Ryan Macnak d1112d37bd [vm] Recognize unmodifiabled typed data views.
These types now work with Dart_TypedDataAcquireData.

The presence of these types no longer degrades the performance of typed data indexed loads.

The presence of these types degrades the performance of typed data indexed stores much less. The performance of indexed stores is somewhat regressed if these types were not used.

TEST=ci
Bug: https://github.com/dart-lang/sdk/issues/32028
Bug: https://github.com/dart-lang/sdk/issues/40924
Bug: https://github.com/dart-lang/sdk/issues/42785
Change-Id: I05ac5c9543f6f61ac37533b9efe511254778caed
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/253700
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-08-09 20:57:05 +00:00
Ryan Macnak 88ca1e95b8 [vm, gc] Evaluate old-gen GC on each new-gen page.
This gives starting or finalizing concurrent marking a chance to run not-immediately-after-a-scavenge.

TEST=ci
Change-Id: Iec1ba7b7440045cc18e01637af1f865d588b24c2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/246163
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-06-07 21:56:41 +00:00
Ryan Macnak c588224163 [vm] Represent the slow object copy from_to table with a heap array.
- Greatly reduces the size of the root set, thus reducing pauses for scavenges or marking that occur during a copy.
 - Reduces the memory overhead of the from_to table from 6 words per object to 2 words per object.

TEST=ci
Change-Id: Icf81f4b25adff22590a9c84c40068e35dd4d502b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/246305
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2022-06-01 17:52:28 +00:00
Martin Kustermann b83b89a900 [vm/concurrency] Add number of objects / bytes copied to timeline events for inter-isolate messages
Closes https://github.com/dart-lang/sdk/issues/48591

TEST=vm/dart{,_2}/isolates/fast_object_copy_timeline_test

Change-Id: I1de3a6f0d8a31450e45f689e0d67358285204a71
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/245167
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
2022-05-20 08:16:41 +00:00
Martin Kustermann 31ae00fb13 [vm] Ensure transitive object copy allows low safepoint latencies
To make responsiveness to safepointing requests better when a thread
does a transitive object copy we add safepoint checkins.

In the fast object copy implementation - which runs inside
NoSafepointScope - we bail out to the slow path if there's a safepoint
requested.

The slow path is safe to GC at any point due to having all objects
inside handles / GC-visible objects.

TEST=Existing test suite.

Change-Id: Ie2c37e2f618506ab62a592aa9ff9ab266a02b64b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/245166
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2022-05-19 12:22:24 +00:00
Alexander Markov bf4bb95308 [vm] New async/await implementation in the VM, part 2 - vm
The new implementation moves away from desugaring of async
functions on kernel AST, state machine generated in the flow graph and
capturing all local variables in the context.

Instead, async/await is implemented using a few stubs
(InitSuspendableFunction, Suspend, Resume, Return and
AsyncExceptionHandler). The stubs are implemented in a
platform-independent way using (macro-)assembler helpers.
When suspending a function, its frame is copied into a SuspendState
object, and when resuming a function it is copied back onto the stack.
No extra code is generated for accessing local variables.
Callback closures are created lazily on the first await.

Design doc: go/compact-async-await.

Part 1 (kernel): https://dart-review.googlesource.com/c/sdk/+/241842

TEST=ci

Issue: https://github.com/dart-lang/sdk/issues/48378
Change-Id: Ibad757035b7cc438ebdff80b460728b1d3eff1f5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/242000
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2022-04-29 01:03:50 +00:00
Daco Harkes 532c116cd2 [vm] Implement NativeFinalizer
This CL implements `NativeFinalizer` in the GC.

`FinalizerEntry`s are extended to track `external_size` and in which
`Heap::Space` the finalizable value is.

On attaching a native finalizer, the external size is added to the
relevant heap. When the finalizable value is promoted from new to old
space, the external size is promoted as well. And when a native
finalizer is run or is detached, the external size is removed from the
relevant heap again.

In contrast to Dart `Finalizer`s, `NativeFinalizer`s are run on isolate
shutdown.

When the `NativeFinalizer`s themselves are collected, the finalizers are
not run. Users should stick the native finalizer in a global variable to
ensure finalization. We will revisit this design when we add send and
exit support, because there is a design space to explore what to do in
that case. This current solution promises the least to users.

In this implementation native finalizers have a Dart entry to clean up
the entries from the `all_entries` field of the finalizer. We should
consider using another data structure that avoids the need for this Dart
entry. See the TODO left in the code.

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

TEST=runtime/tests/vm/dart(_2)/isolates/fast_object_copy_test.dart
TEST=runtime/vm/object_test.cc
TEST=tests/ffi(_2)/vmspecific_native_finalizer_*

Change-Id: I8f594c80c3c344ad83e1f2de10de028eb8456121
Cq-Include-Trybots: luci.dart.try:vm-kernel-reload-rollback-linux-debug-x64-try,vm-kernel-reload-linux-debug-x64-try,vm-ffi-android-debug-arm64c-try,dart-sdk-mac-arm64-try,vm-kernel-mac-release-arm64-try,pkg-mac-release-arm64-try,vm-kernel-precomp-nnbd-mac-release-arm64-try,vm-kernel-win-debug-x64c-try,vm-kernel-win-debug-x64-try,vm-kernel-precomp-win-debug-x64c-try,vm-kernel-nnbd-win-release-ia32-try,vm-ffi-android-debug-arm-try,vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-mac-debug-x64-try,vm-kernel-nnbd-mac-debug-x64-try,vm-kernel-nnbd-linux-debug-ia32-try,benchmark-linux-try,flutter-frontend-try,pkg-linux-debug-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-gcc-linux-try,vm-kernel-optcounter-threshold-linux-release-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-obfuscate-linux-release-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64c-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/236320
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
2022-03-26 09:41:21 +00:00
Daco Harkes e151a81108 Reland "[vm] Implement Finalizer"
Original CL in patchset 1.
Split-off https://dart-review.googlesource.com/c/sdk/+/238341
And pulled in fix https://dart-review.googlesource.com/c/sdk/+/238582
(Should merge cleanly when this lands later.)

This CL implements the `Finalizer` in the GC.

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

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

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

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

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

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

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

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

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

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

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

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

Change-Id: Ibdfeadc16d5d69ade50aae5b9f794284c4c4dbab
Cq-Include-Trybots: luci.dart.try:vm-kernel-reload-rollback-linux-debug-x64-try,vm-kernel-reload-linux-debug-x64-try,vm-ffi-android-debug-arm64c-try,dart-sdk-mac-arm64-try,vm-kernel-mac-release-arm64-try,pkg-mac-release-arm64-try,vm-kernel-precomp-nnbd-mac-release-arm64-try,vm-kernel-win-debug-x64c-try,vm-kernel-win-debug-x64-try,vm-kernel-precomp-win-debug-x64c-try,vm-kernel-nnbd-win-release-ia32-try,vm-ffi-android-debug-arm-try,vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-mac-debug-x64-try,vm-kernel-nnbd-mac-debug-x64-try,vm-kernel-nnbd-linux-debug-ia32-try,benchmark-linux-try,flutter-analyze-try,flutter-frontend-try,pkg-linux-debug-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-gcc-linux-try,vm-kernel-optcounter-threshold-linux-release-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-obfuscate-linux-release-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64c-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/238086
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
2022-03-25 10:29:30 +00:00
Daco Harkes c7c7a17adf [vm] Refactor delayed lists in GC
This refactors the delayed lists in the marker and scavenger, but does
not have any behavior changes.

Split off https://dart-review.googlesource.com/c/sdk/+/238086

TEST=running test suites will trigger GC.

Change-Id: I82ca4c3dca3351b6543bafaee1318b8e0da75f1f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/238341
Reviewed-by: Slava Egorov <vegorov@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
2022-03-23 19:26:11 +00:00
Daco Harkes 37526fc8d7 Revert "[vm] Implement Finalizer"
This reverts commit 7dca34c235.

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

TEST=This is a revert.

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

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

Change-Id: I991f6e49896d18a8d70210cf315d858b462d66c9
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: https://github.com/dart-lang/sdk/issues/47777
Cq-Include-Trybots: luci.dart.try:vm-kernel-reload-rollback-linux-debug-x64-try,vm-kernel-reload-linux-debug-x64-try,vm-ffi-android-debug-arm64c-try,dart-sdk-mac-arm64-try,vm-kernel-mac-release-arm64-try,pkg-mac-release-arm64-try,vm-kernel-precomp-nnbd-mac-release-arm64-try,vm-kernel-win-debug-x64c-try,vm-kernel-win-debug-x64-try,vm-kernel-precomp-win-debug-x64c-try,vm-kernel-nnbd-win-release-ia32-try,vm-ffi-android-debug-arm-try,vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-mac-debug-x64-try,vm-kernel-nnbd-mac-debug-x64-try,vm-kernel-nnbd-linux-debug-ia32-try,benchmark-linux-try,flutter-analyze-try,flutter-frontend-try,pkg-linux-debug-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-gcc-linux-try,vm-kernel-optcounter-threshold-linux-release-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-obfuscate-linux-release-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64c-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/238080
Reviewed-by: Slava Egorov <vegorov@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
2022-03-22 11:55:38 +00:00
Daco Harkes 7dca34c235 [vm] Implement Finalizer
This CL implements the `Finalizer` in the GC.

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

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

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

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

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

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

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

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

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

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

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

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

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

Change-Id: I03e6b4a46212316254bf46ba3f2df333abaa686c
Cq-Include-Trybots: luci.dart.try:vm-kernel-reload-rollback-linux-debug-x64-try,vm-kernel-reload-linux-debug-x64-try,vm-ffi-android-debug-arm64c-try,dart-sdk-mac-arm64-try,vm-kernel-mac-release-arm64-try,pkg-mac-release-arm64-try,vm-kernel-precomp-nnbd-mac-release-arm64-try,vm-kernel-win-debug-x64c-try,vm-kernel-win-debug-x64-try,vm-kernel-precomp-win-debug-x64c-try,vm-kernel-nnbd-win-release-ia32-try,vm-ffi-android-debug-arm-try,vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-mac-debug-x64-try,vm-kernel-nnbd-mac-debug-x64-try,vm-kernel-nnbd-linux-debug-ia32-try,benchmark-linux-try,flutter-analyze-try,flutter-frontend-try,pkg-linux-debug-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-gcc-linux-try,vm-kernel-optcounter-threshold-linux-release-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-obfuscate-linux-release-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64c-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/229544
Reviewed-by: Lasse Nielsen <lrn@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
2022-03-22 10:30:18 +00:00
Ryan Macnak 81143e16c4 [vm, gc] Don't perform blocking compactions in response to Dart_NotifyLowMemory.
These GCs usually did not free very much memory but did consume a lot of CPU. They would on low-powered, low-memory devices often take ~1s, during which time the OS might decide the OOM signal wasn't working and kill us before the compaction can complete and free pages. Instead, only release pooled memory.

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

TEST=ci
Bug: b/216333343
Change-Id: Ia56b9ca409410f17d40508c69fb1bc9df0ce4028
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/235300
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-03-08 22:42:46 +00:00
Daco Harkes 828dcd00e8 [vm] Implement WeakReference in the VM
This CL implements `WeakReference` in the VM.

* This reduces the size of weak references from 2 objects using 8 words
  to 1 object using 4 words.
* This makes loads of weak reference targets a single load instead of
  two.
* This avoids the fix-point in the GC and message object copying for
  weak references. (N.b. Weak references need to be processed _after_
  the fix-point for weak properties.)

The semantics of weak references in messages is that their target gets
set to `null` if the target is not included in the message by a strong
reference.

The tests take particular care to exercise the case where a weak
reference's target is only kept alive because a weak property key is
alive and it refers to the target in its value. This exercises the fact
that weak references need to be processed last.

Does not add support for weak references in the app snapshot. It would
be dead code until we start using weak references in for example the
CFE.

This CL does not try to unify weak references and weak properties in
the GC or messaging (as proposed in go/dart-vm-weakreference), because
their semantics differ enough.

Closes: https://github.com/dart-lang/sdk/issues/48162

TEST=runtime/tests/vm/dart/finalizer/weak_reference_run_gc_test.dart
TEST=runtime/tests/vm/dart/isolates/fast_object_copy_test.dart
TEST=runtime/vm/object_test.cc
TEST=tests/lib/isolate/weak_reference_message_1_test.dart
TEST=tests/lib/isolate/weak_reference_message_2_test.dart

Change-Id: I3810e919a5866f3ae8a95bd9aa23a880a0b0921c
Cq-Include-Trybots: luci.dart.try:app-kernel-linux-debug-x64-try,dart-sdk-mac-arm64-try,vm-canary-linux-debug-try,vm-fuchsia-release-x64-try,vm-kernel-gcc-linux-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-linux-debug-x64c-try,vm-kernel-linux-debug-x64-try,vm-kernel-linux-debug-simriscv64-try,vm-kernel-mac-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-nnbd-linux-release-ia32-try,vm-kernel-nnbd-linux-release-simarm64-try,vm-kernel-nnbd-linux-release-simarm-try,vm-kernel-nnbd-mac-debug-arm64-try,vm-kernel-nnbd-mac-debug-x64-try,vm-kernel-nnbd-win-release-ia32-try,vm-kernel-nnbd-win-release-x64-try,vm-kernel-optcounter-threshold-linux-release-x64-try,vm-kernel-precomp-android-release-arm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64c-try,vm-kernel-precomp-win-debug-x64c-try,vm-kernel-reload-rollback-linux-debug-x64-try,vm-kernel-reload-linux-debug-x64-try,vm-kernel-win-debug-ia32-try,vm-kernel-win-debug-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/232087
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
2022-02-10 21:59:41 +00:00
Martin Kustermann dc7e082336 [vm/concurrency] Ensure rehashing of maps correctly resets [_deletedKeys]
When we rehash a linked hash map, we rebuild the index but keep the
existing data array. The [_deletedKeys] specifies the number of entries in the
[_index] which were marked as deleted. The Dart code that triggers
rehashing and initializes a new [_index] didn't initialize
[_deletedKeys].

=> We'll fix this in the Dart code and as a precaution also in the
   transitive object copy code.

Furthermore we add a missing optimization: In the example from the bug
report we shouldn't even have attempted to re-hash, because the maps
have only primitive keys (which do not rely on identity or user-defined
hashcodes).

=> We'll change the existing optimization to ignore deleted entries when
   determining whether a rehash is needed.

The rehashing code for Sets works differently and takes this already
into account.

Closes https://github.com/dart-lang/sdk/issues/47598

TEST=vm/dart{,_2}/isolates/fast_object_copy_test

Change-Id: I3529ecbf500009ab0c72b98e6c427b8840a69371
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/219000
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2021-11-03 13:36:35 +00:00
Martin Kustermann b7909e132a [vm/concurrency] Allow StackTrace objects to be shared
The existing lib/isolate/stacktrace_message_test was failing and also
incorrectly written due to "!" in front of the expected stringification
of the stacktrace.

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

TEST=vm/dart{,_2}/isolates/fast_object_copy2_test, lib{,_2}/isolate/stacktrace_message_test

Change-Id: I169d8fd7a7c3cb3b8c57e00287565e3a5c622acf
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/216041
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
2021-10-11 09:01:44 +00:00
Ryan Macnak 5da8050f86 [vm, gc] Move GCType and GCReason out of Heap, making them accessible to Scavenger and PageSpace.
Add a GCReason for store buffer overflow instead of using a separate print.

This is a pure refactoring that doesn't change GC policy.

TEST=ci
Change-Id: Idcd95b0701a36f45ebaa02db2c2fac9a9081d7c6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/215102
Reviewed-by: Liam Appelbe <liama@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2021-10-04 18:57:19 +00:00
Ryan Macnak 78b9f54957 [vm] Fix initialization of Contexts in object graph copy's fast-path bailout.
Cf. 179c96cd60.

TEST=ci
Bug: https://github.com/dart-lang/sdk/issues/47235
Change-Id: I9f6aef564286f6b239d697072ed5405085269add
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/213681
Reviewed-by: Liam Appelbe <liama@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2021-09-16 22:17:24 +00:00