[M] Change in dart/sdk[main]: [vm/corelib] Optimize building of Maps in JSON decoder.

0 views
Skip to first unread message

Slava Egorov (Gerrit)

unread,
Jul 4, 2024, 10:04:20 AM7/4/24
to Martin Kustermann, Lasse Nielsen, dart-dc-te...@google.com, dart2js-te...@google.com, dart2wasm-t...@google.com, rev...@dartlang.org
Attention needed from Lasse Nielsen and Martin Kustermann

Slava Egorov added 1 comment

File sdk/lib/internal/internal.dart
Line 1058, Patchset 2 (Latest):/// Token type for sharing private functionality between core libraries.
Slava Egorov . unresolved

Currently the only way to share private functionality between two different core libraries (e.g. dart:collection and dart:convert) without exposing it to the users is to move implementation into a private core library and then re-export pieces of it through core libraries.

Doing this with something like `dart:collection` to expose an efficient private method for creating a `Map` from the list key-value pairs is a big refactoring because `dart:collection` has a huge API surface.

So instead I came up with this _hack_. An alternative I considered is doing something like

```
// dart:_internal

// On VM this would redirect `method` to `_privateMethod` which normally can't be
// invoked.
@pragma('vm:redirect', ['dart:collection', '_privateMethod']);
external void method();
```

@l...@google.com Lasse, do you have any opinions on this?

Open in Gerrit

Related details

Attention is currently required from:
  • Lasse Nielsen
  • Martin Kustermann
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedCommit-Message-Has-TEST
  • requirement is not satisfiedCore-Library-Review
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: sdk
Gerrit-Branch: main
Gerrit-Change-Id: Ic3032323143c35c38469d4f5f289daabdf56ecc9
Gerrit-Change-Number: 374564
Gerrit-PatchSet: 2
Gerrit-Owner: Slava Egorov <veg...@google.com>
Gerrit-Reviewer: Lasse Nielsen <l...@google.com>
Gerrit-Reviewer: Martin Kustermann <kuste...@google.com>
Gerrit-Attention: Lasse Nielsen <l...@google.com>
Gerrit-Attention: Martin Kustermann <kuste...@google.com>
Gerrit-Comment-Date: Thu, 04 Jul 2024 14:04:13 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
unsatisfied_requirement
open
diffy

Lasse Nielsen (Gerrit)

unread,
Jul 4, 2024, 11:07:09 AM7/4/24
to Slava Egorov, Martin Kustermann, dart-dc-te...@google.com, dart2js-te...@google.com, dart2wasm-t...@google.com, rev...@dartlang.org
Attention needed from Martin Kustermann and Slava Egorov

Lasse Nielsen added 4 comments

File sdk/lib/_internal/vm/lib/convert_patch.dart
Line 22, Patchset 2 (Latest): coreLibrariesPrivateFunctionality;
Lasse Nielsen . unresolved

Why not just import the function from `dart:_internal` directly.
Is it because the patch uses

File sdk/lib/_internal/vm_shared/lib/compact_hash.dart
Line 435, Patchset 2 (Latest): void _populateUnsafe(List<Object?> kvPairs) {
Lasse Nielsen . unresolved

(Aboid abbreviations, `keyValuePairs` isn't that long.)

File sdk/lib/collection/collection.dart
Line 77, Patchset 2 (Latest):extension CollectionInternals on InternalFunctionalityToken {
Lasse Nielsen . unresolved

This declaration is publicly visible.
It may not be possible to create an object implementing `InternalFunctionalityToken`, but the extension exists in the public namespace and shows that `InternalFunctionalityToken` exists.

It's possible to name complete `CollectionInternals`, and write
`CollectionInternals(throw "banana").createMapFromKeyValuyeListUnsafe(...)`.

It should be hidden better.

If the functionality only needs to be used from inside `dart:` libraries, then just put it into `dart:_internal`, which they can all import, instead of putting it in `dart:collection`.

If it's used by non-`dart:` libraries ... why? And who? And like, don't. 😊

File sdk/lib/internal/internal.dart
Line 1058, Patchset 2 (Latest):/// Token type for sharing private functionality between core libraries.
Slava Egorov . unresolved

Currently the only way to share private functionality between two different core libraries (e.g. dart:collection and dart:convert) without exposing it to the users is to move implementation into a private core library and then re-export pieces of it through core libraries.

Doing this with something like `dart:collection` to expose an efficient private method for creating a `Map` from the list key-value pairs is a big refactoring because `dart:collection` has a huge API surface.

So instead I came up with this _hack_. An alternative I considered is doing something like

```
// dart:_internal

// On VM this would redirect `method` to `_privateMethod` which normally can't be
// invoked.
@pragma('vm:redirect', ['dart:collection', '_privateMethod']);
external void method();
```

@l...@google.com Lasse, do you have any opinions on this?

Lasse Nielsen

Yep. Don't like visible hacks. (No matter how clever, the goal is to not expose any public names to users.)

I like the idea of allowing platform libraries to redirect to each other.
(I've been very tempted to just combine all the core libraries into on `dart:_impl` and export the individual libraries from there. It's not like they're not strongly connected anyway.)

I'll think about it and see if I can find an invisible alternative.

(Maybe we can have some small shared stub in `dart:_internal` that classes can opt in to being compatible with in some way. I hope, but no concrete idea yet.)

Open in Gerrit

Related details

Attention is currently required from:
  • Martin Kustermann
  • Slava Egorov
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedCommit-Message-Has-TEST
  • requirement is not satisfiedCore-Library-Review
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: sdk
Gerrit-Branch: main
Gerrit-Change-Id: Ic3032323143c35c38469d4f5f289daabdf56ecc9
Gerrit-Change-Number: 374564
Gerrit-PatchSet: 2
Gerrit-Owner: Slava Egorov <veg...@google.com>
Gerrit-Reviewer: Lasse Nielsen <l...@google.com>
Gerrit-Reviewer: Martin Kustermann <kuste...@google.com>
Gerrit-Attention: Slava Egorov <veg...@google.com>
Gerrit-Attention: Martin Kustermann <kuste...@google.com>
Gerrit-Comment-Date: Thu, 04 Jul 2024 15:07:04 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Slava Egorov <veg...@google.com>
unsatisfied_requirement
open
diffy

Slava Egorov (Gerrit)

unread,
Jul 4, 2024, 3:28:00 PM7/4/24
to Martin Kustermann, Lasse Nielsen, dart-dc-te...@google.com, dart2js-te...@google.com, dart2wasm-t...@google.com, rev...@dartlang.org
Attention needed from Lasse Nielsen and Martin Kustermann

Slava Egorov added 4 comments

File sdk/lib/_internal/vm/lib/convert_patch.dart
Line 22, Patchset 2: coreLibrariesPrivateFunctionality;
Lasse Nielsen . resolved

Why not just import the function from `dart:_internal` directly.
Is it because the patch uses

Slava Egorov

That's because the function actually resides in `dart:collection` (which contains both public classes and their private implementations).

I have tried to move private implementations into `dart:_internal` but that does not work - because we have declared public interfaces `final`. :)

Anyway, new patch does VM specific redirection instead.

File sdk/lib/_internal/vm_shared/lib/compact_hash.dart
Line 435, Patchset 2: void _populateUnsafe(List<Object?> kvPairs) {
Lasse Nielsen . resolved

(Aboid abbreviations, `keyValuePairs` isn't that long.)

Slava Egorov

Done

File sdk/lib/collection/collection.dart
Line 77, Patchset 2:extension CollectionInternals on InternalFunctionalityToken {
Lasse Nielsen . resolved

This declaration is publicly visible.
It may not be possible to create an object implementing `InternalFunctionalityToken`, but the extension exists in the public namespace and shows that `InternalFunctionalityToken` exists.

It's possible to name complete `CollectionInternals`, and write
`CollectionInternals(throw "banana").createMapFromKeyValuyeListUnsafe(...)`.

It should be hidden better.

If the functionality only needs to be used from inside `dart:` libraries, then just put it into `dart:_internal`, which they can all import, instead of putting it in `dart:collection`.

If it's used by non-`dart:` libraries ... why? And who? And like, don't. 😊

Slava Egorov

You can write that but it will not execute :)

Anyway, I agree it is too ugly. Implemented `@pragma('vm:redirect', ...)` instead.

File sdk/lib/internal/internal.dart
Line 1058, Patchset 2:/// Token type for sharing private functionality between core libraries.
Slava Egorov . resolved

Currently the only way to share private functionality between two different core libraries (e.g. dart:collection and dart:convert) without exposing it to the users is to move implementation into a private core library and then re-export pieces of it through core libraries.

Doing this with something like `dart:collection` to expose an efficient private method for creating a `Map` from the list key-value pairs is a big refactoring because `dart:collection` has a huge API surface.

So instead I came up with this _hack_. An alternative I considered is doing something like

```
// dart:_internal

// On VM this would redirect `method` to `_privateMethod` which normally can't be
// invoked.
@pragma('vm:redirect', ['dart:collection', '_privateMethod']);
external void method();
```

@l...@google.com Lasse, do you have any opinions on this?

Lasse Nielsen

Yep. Don't like visible hacks. (No matter how clever, the goal is to not expose any public names to users.)

I like the idea of allowing platform libraries to redirect to each other.
(I've been very tempted to just combine all the core libraries into on `dart:_impl` and export the individual libraries from there. It's not like they're not strongly connected anyway.)

I'll think about it and see if I can find an invisible alternative.

(Maybe we can have some small shared stub in `dart:_internal` that classes can opt in to being compatible with in some way. I hope, but no concrete idea yet.)

Slava Egorov

Implemented pragma based solution instead.

Open in Gerrit

Related details

Attention is currently required from:
  • Lasse Nielsen
  • Martin Kustermann
Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedCommit-Message-Has-TEST
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: sdk
    Gerrit-Branch: main
    Gerrit-Change-Id: Ic3032323143c35c38469d4f5f289daabdf56ecc9
    Gerrit-Change-Number: 374564
    Gerrit-PatchSet: 3
    Gerrit-Owner: Slava Egorov <veg...@google.com>
    Gerrit-Reviewer: Lasse Nielsen <l...@google.com>
    Gerrit-Reviewer: Martin Kustermann <kuste...@google.com>
    Gerrit-Attention: Lasse Nielsen <l...@google.com>
    Gerrit-Attention: Martin Kustermann <kuste...@google.com>
    Gerrit-Comment-Date: Thu, 04 Jul 2024 19:27:57 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Lasse Nielsen <l...@google.com>
    Comment-In-Reply-To: Slava Egorov <veg...@google.com>
    unsatisfied_requirement
    open
    diffy

    Lasse Nielsen (Gerrit)

    unread,
    Jul 5, 2024, 7:10:26 AM7/5/24
    to Slava Egorov, Commit Queue, Martin Kustermann, dart-dc-te...@google.com, dart2js-te...@google.com, dart2wasm-t...@google.com, rev...@dartlang.org
    Attention needed from Martin Kustermann and Slava Egorov

    Lasse Nielsen voted and added 19 comments

    Votes added by Lasse Nielsen

    Code-Review+1

    19 comments

    Patchset-level comments
    File-level comment, Patchset 4 (Latest):
    Lasse Nielsen . resolved

    LGTM, with only small nits.

    Lots of ideas for different ways to do the same thing, but if this is an improvement, then ship it. We can always improve more.

    File pkg/vm/lib/modular/transformations/lowering.dart
    Line 85, Patchset 4 (Latest): inCoreLibrary = node.importUri.scheme == 'dart';
    Lasse Nielsen . unresolved

    Use `.isScheme('dart')` instead of `.scheme == 'dart`. (It avoids allocation for `_SimpleUri`s. And is case insensitive.)

    ```dart
    inCoreLibrary = node.importUri.isScheme('dart');
    ```
    Line 103, Patchset 4 (Latest): // Resolve redirection supplied via vm:redirect pragma if applicable.
    Lasse Nielsen . unresolved

    Maybe worth mentioning that it always stores a value in the `_redirectionCache`. If there is no redirection, it stores the target itself, so it's cheaper to look up a second time.
    (Or insert a comment line in the code saying that. I had to read the code twice to notice that detail, which I think is fairly important.)

    Line 130, Patchset 4 (Latest): final [libraryUri, functionName] = targetName.split('#');
    Lasse Nielsen . unresolved

    This pattern match throws if the option string has more or less than one `#`. I'm not sure throwing is the best way to report an error.
    Obviously that should never happen because we only end here for declarations inside `dart:_internal`, and we (surely) won't have typos in those, and users can't introduce bugs.

    Line 135, Patchset 4 (Latest): throw StateError(
    Lasse Nielsen . unresolved

    Doesn't sound like a *state* error.
    A state error means an object is currently in a state where the requested functionality is not supported, but could at other times allow it.

    I'm not sure which object/state this state error is referring to, and what is wrong with it.

    Could it be reported as a compilation error or context relevant exception?
    A format exception?

    (Generally `ArgumentError`, `StateError` and `UnsupportedError` are used to report that the caller of a method has made a mistake. Here the mistake is not in the call to `_resolveRedirection`, it's in the input, which the caller is not expected to check before calling. So `FormatException` would be an option that matches.)

    Line 150, Patchset 4 (Latest): throw StateError('$target is redirecting to $redirectionTarget but '
    Lasse Nielsen . unresolved

    Also not a `StateError`. Not an error *in this call*, so something that should probably be reported as a compilation error by the framework doing the lowering.

    Line 150, Patchset 4 (Latest): throw StateError('$target is redirecting to $redirectionTarget but '
    Lasse Nielsen . unresolved

    Super-nit: Comma before "but".

    File runtime/docs/compiler/pragmas_recognized_by_compiler.md
    Line 163, Patchset 4 (Latest):- it is only recognized when applied to methods declared in `dart:internal`;
    Lasse Nielsen . unresolved

    ... applied to static methods ...?

    (I guess it's ignored on everything that is not a static function, but then it's actually not recognized on non-static methods.)

    Line 164, Patchset 4 (Latest):- it only rewrites static invocations of those methods;
    Lasse Nielsen . unresolved

    Aka: Not tear-offs.
    (Can the invocation be, fx, a static getter invocation, or only function declarations?)

    Line 173, Patchset 4 (Latest):external int foo(int x);
    Lasse Nielsen . unresolved

    (Should not introduce public names in patches. I guess it's "safe" for `dart:_internal`. I'd still suggest putting it as `external` in `dart:_internal` itself, and provide a patch for it on all platforms, even if most throw `UnsupportedError`. Then it's clear from the source of `dart:internal` which members it has.)

    File sdk/lib/_internal/vm/lib/convert_patch.dart
    Line 26, Patchset 4 (Latest):import "dart:collection" show CollectionInternals;
    Lasse Nielsen . unresolved

    No `CollectionInternals` any more.

    Line 99, Patchset 4 (Latest): /** Contents of the current container being built, or null if not building a
    Lasse Nielsen . resolved

    (Do consider switching to `///` comments at some point.)

    Line 104, Patchset 4 (Latest): List? currentContainer;
    Lasse Nielsen . unresolved

    Consider making this an explicit `List<dynamic>`.
    (Just to be explicit.)

    Line 147, Patchset 4 (Latest): final kvPairs = unsafeCast<List>(currentContainer);
    Lasse Nielsen . unresolved

    Name it `keyValuePairs`.

    Consider `assert(keyValuePairs.length.isOdd);`

    Line 148, Patchset 4 (Latest): if (reviver case final reviver?) {
    Lasse Nielsen . unresolved
    Are you absolutely sure this is as efficient as:
    ```dart
    var revivier = this.revivier;
    if (reviever != null) {
    ```
    on all platforms?
    (If so, I'm happy. If not, let's keep the simple code.)
    Line 159, Patchset 4 (Latest): value = createMapFromKeyValueListUnsafe<String, dynamic>(
    Lasse Nielsen . unresolved

    (If we only ever use this method for `<String, dynamic>`, then it could be named something with `Json` and not need to take type argumens, or unsafely cast its values).

    File sdk/lib/_internal/vm_shared/lib/compact_hash.dart
    Line 451, Patchset 4 (Latest): internal.unsafeCast<V>(keyValuePairs[i + 1]);
    Lasse Nielsen . unresolved

    This call calls `operator []=(K key, V value)` call which is coviariant by generics. Will that do `K`/`V` checks on entry, or are those optimized away when the call is on `this` (or the receiver type is otherwise known to be exact)?


    If I read `[]=` correctly, it ends up copying the key/value pairs
    into `_data` in exactly the same order (unless the original JSON had duplicate keys, which it never does).

    Could you just take the backing array of `keyValuePairs` and use it as `_data`, and then compute the hashes and validate that there are no duplicate entries. (If there is, move the value to the earlier one if and tombstone the latter, but again, that never hapens in practice.)

    Or at least do `_data.setRange(0, keyValuePairs.length, keyValuePairs);` and then do what I suggest above?

    Line 453, Patchset 4 (Latest): }
    Lasse Nielsen . unresolved

    Alternatively, we could keep the current behavior of the JSON parser, storing maps for maps, and just expose a `_Map._unsafeSet(Map map, Object? key, Object? value)` which adds the entry to the map, like the `this[...] = ...` call above, without allocating an intermediate list.

    File sdk/lib/internal/internal.dart
    Line 1058, Patchset 2:/// Token type for sharing private functionality between core libraries.
    Slava Egorov . resolved

    Currently the only way to share private functionality between two different core libraries (e.g. dart:collection and dart:convert) without exposing it to the users is to move implementation into a private core library and then re-export pieces of it through core libraries.

    Doing this with something like `dart:collection` to expose an efficient private method for creating a `Map` from the list key-value pairs is a big refactoring because `dart:collection` has a huge API surface.

    So instead I came up with this _hack_. An alternative I considered is doing something like

    ```
    // dart:_internal

    // On VM this would redirect `method` to `_privateMethod` which normally can't be
    // invoked.
    @pragma('vm:redirect', ['dart:collection', '_privateMethod']);
    external void method();
    ```

    @l...@google.com Lasse, do you have any opinions on this?

    Lasse Nielsen

    Yep. Don't like visible hacks. (No matter how clever, the goal is to not expose any public names to users.)

    I like the idea of allowing platform libraries to redirect to each other.
    (I've been very tempted to just combine all the core libraries into on `dart:_impl` and export the individual libraries from there. It's not like they're not strongly connected anyway.)

    I'll think about it and see if I can find an invisible alternative.

    (Maybe we can have some small shared stub in `dart:_internal` that classes can opt in to being compatible with in some way. I hope, but no concrete idea yet.)

    Slava Egorov

    Implemented pragma based solution instead.

    Lasse Nielsen

    Copying all of `dart:collection` into `dart:_collection` and exporting it from `dart:collection`, minus anything we don't want to share, would be a valid approach. Maybe we should just do it for all the core libraries, once and for all.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Martin Kustermann
    • Slava Egorov
    Submit Requirements:
    • requirement satisfiedCode-Review
    • requirement is not satisfiedCommit-Message-Has-TEST
    • requirement satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: sdk
    Gerrit-Branch: main
    Gerrit-Change-Id: Ic3032323143c35c38469d4f5f289daabdf56ecc9
    Gerrit-Change-Number: 374564
    Gerrit-PatchSet: 4
    Gerrit-Owner: Slava Egorov <veg...@google.com>
    Gerrit-Reviewer: Lasse Nielsen <l...@google.com>
    Gerrit-Reviewer: Martin Kustermann <kuste...@google.com>
    Gerrit-Reviewer: Slava Egorov <veg...@google.com>
    Gerrit-Attention: Slava Egorov <veg...@google.com>
    Gerrit-Attention: Martin Kustermann <kuste...@google.com>
    Gerrit-Comment-Date: Fri, 05 Jul 2024 11:10:21 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Martin Kustermann (Gerrit)

    unread,
    Jul 8, 2024, 3:33:38 AM7/8/24
    to Slava Egorov, Lasse Nielsen, Commit Queue, dart-dc-te...@google.com, dart2js-te...@google.com, dart2wasm-t...@google.com, rev...@dartlang.org
    Attention needed from Lasse Nielsen and Slava Egorov

    Martin Kustermann added 6 comments

    File pkg/vm/lib/modular/transformations/lowering.dart
    Line 83, Patchset 4 (Latest): TreeNode visitLibrary(Library node) {
    Martin Kustermann . unresolved

    We can remove this `isCoreLibrary` specific code.

    If only `dart:_internal` can declare externals with redirecting pragmas, then we're already guaranteed that all callers are in `dart:*` libraries - because one cannot really import `dart:_internal` anywhere else

    Line 121, Patchset 4 (Latest): for (var annotation in target.annotations) {
    Martin Kustermann . unresolved

    nit: final

    File sdk/lib/_internal/vm/lib/convert_patch.dart
    Line 148, Patchset 4 (Latest): if (reviver case final reviver?) {
    Lasse Nielsen . unresolved
    Are you absolutely sure this is as efficient as:
    ```dart
    var revivier = this.revivier;
    if (reviever != null) {
    ```
    on all platforms?
    (If so, I'm happy. If not, let's keep the simple code.)
    Martin Kustermann

    Much prefer lasses code than `if (case final reviver?)`

    I wouldn't have guessed that `if (reviver case final reviver?)` would effectively be a `reviver != null` check - in fact the `reviver?` would indicate to me we allow matching null). This new pattern match syntax is IMHO overused and often makes code much less readable!

    File sdk/lib/_internal/vm_shared/lib/compact_hash.dart
    Line 436, Patchset 4 (Latest): int size = _roundUpToPowerOfTwo(keyValuePairs.length);
    Martin Kustermann . unresolved

    `assert(keyValuePairs.length % 2 == 0)`

    Would it make sense to check for `keyValuePairs.length == 0` and do something faster?

    Line 451, Patchset 4 (Latest): internal.unsafeCast<V>(keyValuePairs[i + 1]);
    Lasse Nielsen . unresolved

    This call calls `operator []=(K key, V value)` call which is coviariant by generics. Will that do `K`/`V` checks on entry, or are those optimized away when the call is on `this` (or the receiver type is otherwise known to be exact)?


    If I read `[]=` correctly, it ends up copying the key/value pairs
    into `_data` in exactly the same order (unless the original JSON had duplicate keys, which it never does).

    Could you just take the backing array of `keyValuePairs` and use it as `_data`, and then compute the hashes and validate that there are no duplicate entries. (If there is, move the value to the earlier one if and tombstone the latter, but again, that never hapens in practice.)

    Or at least do `_data.setRange(0, keyValuePairs.length, keyValuePairs);` and then do what I suggest above?

    Martin Kustermann

    👍 to lasse's 2 comments

    We can steal the backing store of the array and use existing logic to create the index, see:
    ```
    void _createIndex() {
    final size =
    _roundUpToPowerOfTwo(max(_data.length, _HashBase._INITIAL_INDEX_SIZE));
    final newIndex = new Uint32List(size);
    final hashMask = _HashBase._indexSizeToHashMask(size);
    assert(_hashMask == hashMask);
        for (int j = 0; j < _usedData; j += 2) {
    final key = _data[j] as K;
          final fullHash = _hashCode(key);
    final hashPattern = _HashBase._hashPattern(fullHash, hashMask, size);
    final d =
    _findValueOrInsertPoint(key, fullHash, hashPattern, size, newIndex);
    // We just allocated the index, so we should not find this key in it yet.
    assert(d <= 0);
          final i = -d;
          assert(1 <= hashPattern && hashPattern < (1 << 32));
    final index = j >> 1;
    assert((index & hashPattern) == 0);
    newIndex[i] = hashPattern | index;
    }
        // Publish new index, uses store release semantics.
    _index = newIndex;
    }
    ```
    Lasse Nielsen . unresolved

    Alternatively, we could keep the current behavior of the JSON parser, storing maps for maps, and just expose a `_Map._unsafeSet(Map map, Object? key, Object? value)` which adds the entry to the map, like the `this[...] = ...` call above, without allocating an intermediate list.

    Martin Kustermann

    That will cause unnecessary work if the map has to resize while json parser is adding more properties. By collecting all key/values first, we ensure that we have to do hashing & index creation only once.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Lasse Nielsen
    • Slava Egorov
    Submit Requirements:
    • requirement satisfiedCode-Review
    • requirement is not satisfiedCommit-Message-Has-TEST
    • requirement satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: sdk
    Gerrit-Branch: main
    Gerrit-Change-Id: Ic3032323143c35c38469d4f5f289daabdf56ecc9
    Gerrit-Change-Number: 374564
    Gerrit-PatchSet: 4
    Gerrit-Owner: Slava Egorov <veg...@google.com>
    Gerrit-Reviewer: Lasse Nielsen <l...@google.com>
    Gerrit-Reviewer: Martin Kustermann <kuste...@google.com>
    Gerrit-Reviewer: Slava Egorov <veg...@google.com>
    Gerrit-Attention: Lasse Nielsen <l...@google.com>
    Gerrit-Attention: Slava Egorov <veg...@google.com>
    Gerrit-Comment-Date: Mon, 08 Jul 2024 07:33:33 +0000
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Lasse Nielsen (Gerrit)

    unread,
    Jul 15, 2024, 7:21:38 AM7/15/24
    to Slava Egorov, Commit Queue, Martin Kustermann, dart-dc-te...@google.com, dart2js-te...@google.com, dart2wasm-t...@google.com, rev...@dartlang.org
    Attention needed from Martin Kustermann and Slava Egorov

    Lasse Nielsen added 1 comment

    File pkg/vm/lib/modular/transformations/lowering.dart
    Line 83, Patchset 4 (Latest): TreeNode visitLibrary(Library node) {
    Martin Kustermann . unresolved

    We can remove this `isCoreLibrary` specific code.

    If only `dart:_internal` can declare externals with redirecting pragmas, then we're already guaranteed that all callers are in `dart:*` libraries - because one cannot really import `dart:_internal` anywhere else

    Lasse Nielsen

    I like defense in depth. (I have once removed what I thought was one of two things preventing some possible misuse, only to discover that someone else had removed the other.)
    It's not an expensive check, I'd keep it.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Martin Kustermann
    • Slava Egorov
    Submit Requirements:
    • requirement satisfiedCode-Review
    • requirement is not satisfiedCommit-Message-Has-TEST
    • requirement satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: sdk
    Gerrit-Branch: main
    Gerrit-Change-Id: Ic3032323143c35c38469d4f5f289daabdf56ecc9
    Gerrit-Change-Number: 374564
    Gerrit-PatchSet: 4
    Gerrit-Owner: Slava Egorov <veg...@google.com>
    Gerrit-Reviewer: Lasse Nielsen <l...@google.com>
    Gerrit-Reviewer: Martin Kustermann <kuste...@google.com>
    Gerrit-Reviewer: Slava Egorov <veg...@google.com>
    Gerrit-Attention: Martin Kustermann <kuste...@google.com>
    Gerrit-Attention: Slava Egorov <veg...@google.com>
    Gerrit-Comment-Date: Mon, 15 Jul 2024 11:21:33 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Martin Kustermann <kuste...@google.com>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Stephen Adams (Gerrit)

    unread,
    Jul 15, 2024, 7:18:23 PM7/15/24
    to Slava Egorov, Lasse Nielsen, Commit Queue, Martin Kustermann, dart-dc-te...@google.com, dart2js-te...@google.com, dart2wasm-t...@google.com, rev...@dartlang.org
    Attention needed from Martin Kustermann and Slava Egorov

    Stephen Adams added 2 comments

    Patchset-level comments
    Stephen Adams . resolved

    I would like the redirect to be solved at the language level.
    I have needed this kind of thing for other runtimes and ended up adding a new `dart:_foo` library.

    Failing that, can the transform be refactored so it is easy to use from js_runtime, js_dev_runtime etc?

    File sdk/lib/_internal/vm_shared/lib/compact_hash.dart
    Line 436, Patchset 4 (Latest): int size = _roundUpToPowerOfTwo(keyValuePairs.length);
    Martin Kustermann . unresolved

    `assert(keyValuePairs.length % 2 == 0)`

    Would it make sense to check for `keyValuePairs.length == 0` and do something faster?

    Stephen Adams

    nit: `assert(keyValuePairs.length.isEven)`

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Martin Kustermann
    • Slava Egorov
    Submit Requirements:
    • requirement satisfiedCode-Review
    • requirement is not satisfiedCommit-Message-Has-TEST
    • requirement satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: sdk
    Gerrit-Branch: main
    Gerrit-Change-Id: Ic3032323143c35c38469d4f5f289daabdf56ecc9
    Gerrit-Change-Number: 374564
    Gerrit-PatchSet: 4
    Gerrit-Owner: Slava Egorov <veg...@google.com>
    Gerrit-Reviewer: Lasse Nielsen <l...@google.com>
    Gerrit-Reviewer: Martin Kustermann <kuste...@google.com>
    Gerrit-Reviewer: Slava Egorov <veg...@google.com>
    Gerrit-CC: Stephen Adams <s...@google.com>
    Gerrit-Attention: Martin Kustermann <kuste...@google.com>
    Gerrit-Attention: Slava Egorov <veg...@google.com>
    Gerrit-Comment-Date: Mon, 15 Jul 2024 23:18:17 +0000
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Ömer Ağacan (Gerrit)

    unread,
    Aug 5, 2024, 8:01:58 AM8/5/24
    to Slava Egorov, Stephen Adams, Lasse Nielsen, Commit Queue, Martin Kustermann, dart-dc-te...@google.com, dart2js-te...@google.com, dart2wasm-t...@google.com, rev...@dartlang.org
    Attention needed from Martin Kustermann, Slava Egorov and Stephen Adams

    Ömer Ağacan added 1 comment

    Patchset-level comments
    Stephen Adams . resolved

    I would like the redirect to be solved at the language level.
    I have needed this kind of thing for other runtimes and ended up adding a new `dart:_foo` library.

    Failing that, can the transform be refactored so it is easy to use from js_runtime, js_dev_runtime etc?

    Ömer Ağacan

    There's a pattern we use in dart2wasm that allows having internally-public top-level members that are not available to users.

    We implement internal types in underscored libraries, like `dart:_string`, `dart:_boxed_int`, `dart:_typed_data`.

    Since underscored libraries are not available to the users, these libraries can export unsafe things at the top-level that accesses internals of the types. These top-level things can then be used by other underscored libraries.

    This design worked great for dart2wasm, we basically have unrestricted access to internals of internal data structures in the entire standard library, without exposing anything extra to users.

    Since `compact_hash.dart` is a part of a public library (`dart:collection`) this can't be done for `_populateUnsafe` (that would mean injecting a public member to the library).

    So for dart2wasm we will either need to support the `vm:redirect` pragma, or copy `compact_hash.dart` and make it a libarary (e.g. `dart:_compact_hash`) and add a public member `createMapFromKeyValueListUnsafe`.

    I'm not sure if we can avoid copying the file here. Maybe we can have something like:

    ```
    wasm_common:
    libraries:
    _compact_hash:
    uri: _internal/vm_shared/lib/compact_hash.dart
    patches:
    - _internal/wasm/lib/compact_hash_public_members.dart
    ```

    where `compact_hash_public_members.dart` will just add a public top-level `populateUnsafe` member.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Martin Kustermann
    • Slava Egorov
    • Stephen Adams
    Submit Requirements:
    • requirement satisfiedCode-Review
    • requirement is not satisfiedCommit-Message-Has-TEST
    • requirement satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: sdk
    Gerrit-Branch: main
    Gerrit-Change-Id: Ic3032323143c35c38469d4f5f289daabdf56ecc9
    Gerrit-Change-Number: 374564
    Gerrit-PatchSet: 4
    Gerrit-Owner: Slava Egorov <veg...@google.com>
    Gerrit-Reviewer: Lasse Nielsen <l...@google.com>
    Gerrit-Reviewer: Martin Kustermann <kuste...@google.com>
    Gerrit-Reviewer: Slava Egorov <veg...@google.com>
    Gerrit-CC: Stephen Adams <s...@google.com>
    Gerrit-CC: Ömer Ağacan <ome...@google.com>
    Gerrit-Attention: Martin Kustermann <kuste...@google.com>
    Gerrit-Attention: Slava Egorov <veg...@google.com>
    Gerrit-Attention: Stephen Adams <s...@google.com>
    Gerrit-Comment-Date: Mon, 05 Aug 2024 12:01:54 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Stephen Adams <s...@google.com>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Ömer Ağacan (Gerrit)

    unread,
    Aug 5, 2024, 8:16:37 AM8/5/24
    to Slava Egorov, Stephen Adams, Lasse Nielsen, Commit Queue, Martin Kustermann, dart-dc-te...@google.com, dart2js-te...@google.com, dart2wasm-t...@google.com, rev...@dartlang.org
    Attention needed from Martin Kustermann, Slava Egorov and Stephen Adams

    Ömer Ağacan added 1 comment

    File pkg/vm/lib/modular/transformations/lowering.dart
    Line 89, Patchset 4 (Latest): }
    Ömer Ağacan . unresolved

    I'm not suggesting changing it, but I'm just curious if this `finally` block is necessary. I'd think that when the call site is done with one library and visits another it calls `visitLibrary` as the first thing, which will update `inCoreLibrary`. Is this not the case? Can this class visit a member (or another kind of AST node) without visiting its library first?

    Gerrit-Comment-Date: Mon, 05 Aug 2024 12:16:31 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Lasse Nielsen (Gerrit)

    unread,
    Aug 5, 2024, 1:24:47 PM8/5/24
    to Slava Egorov, Ömer Ağacan, Stephen Adams, Commit Queue, Martin Kustermann, dart-dc-te...@google.com, dart2js-te...@google.com, dart2wasm-t...@google.com, rev...@dartlang.org
    Attention needed from Martin Kustermann, Slava Egorov and Stephen Adams

    Lasse Nielsen added 1 comment

    File sdk/lib/_internal/vm/lib/internal_patch.dart
    Line 447, Patchset 4 (Latest):external Map<K, V> createMapFromKeyValueListUnsafe<K, V>(
    Lasse Nielsen . unresolved

    Consider adding another VM-specific internal library for this, instead of stuffing everything into `dart:_internal`.

    Patch files should generally not add public members that are not in the cross-platform source.

    Gerrit-Comment-Date: Mon, 05 Aug 2024 17:24:42 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Slava Egorov (Gerrit)

    unread,
    Aug 13, 2024, 7:32:14 AM8/13/24
    to Ömer Ağacan, Stephen Adams, Lasse Nielsen, Commit Queue, Martin Kustermann, dart-dc-te...@google.com, dart2js-te...@google.com, dart2wasm-t...@google.com, rev...@dartlang.org
    Attention needed from Martin Kustermann, Stephen Adams and Ömer Ağacan

    Slava Egorov added 22 comments

    Patchset-level comments
    File-level comment, Patchset 6 (Latest):
    Slava Egorov . resolved

    Removed redirection pragma. Can now access necessary internals via `dart:_compact_hash` publics instead.

    File pkg/vm/lib/modular/transformations/lowering.dart
    Line 83, Patchset 4: TreeNode visitLibrary(Library node) {
    Martin Kustermann . resolved

    We can remove this `isCoreLibrary` specific code.

    If only `dart:_internal` can declare externals with redirecting pragmas, then we're already guaranteed that all callers are in `dart:*` libraries - because one cannot really import `dart:_internal` anywhere else

    Lasse Nielsen

    I like defense in depth. (I have once removed what I thought was one of two things preventing some possible misuse, only to discover that someone else had removed the other.)
    It's not an expensive check, I'd keep it.

    Slava Egorov

    Reverted these changes.

    Line 85, Patchset 4: inCoreLibrary = node.importUri.scheme == 'dart';
    Lasse Nielsen . resolved

    Use `.isScheme('dart')` instead of `.scheme == 'dart`. (It avoids allocation for `_SimpleUri`s. And is case insensitive.)

    ```dart
    inCoreLibrary = node.importUri.isScheme('dart');
    ```
    Slava Egorov

    Reverted these changes.

    Line 89, Patchset 4: }
    Ömer Ağacan . resolved

    I'm not suggesting changing it, but I'm just curious if this `finally` block is necessary. I'd think that when the call site is done with one library and visits another it calls `visitLibrary` as the first thing, which will update `inCoreLibrary`. Is this not the case? Can this class visit a member (or another kind of AST node) without visiting its library first?

    Slava Egorov

    Reverted these changes.

    (`finally` was here just to keep the state consistent even if we throw an exception and then catch and resume traversal - not that it would actually ever happen, but just in case.)

    Line 103, Patchset 4: // Resolve redirection supplied via vm:redirect pragma if applicable.
    Lasse Nielsen . resolved

    Maybe worth mentioning that it always stores a value in the `_redirectionCache`. If there is no redirection, it stores the target itself, so it's cheaper to look up a second time.
    (Or insert a comment line in the code saying that. I had to read the code twice to notice that detail, which I think is fairly important.)

    Slava Egorov

    Reverted these changes.

    Line 121, Patchset 4: for (var annotation in target.annotations) {
    Martin Kustermann . resolved

    nit: final

    Slava Egorov

    Reverted these changes.

    Line 130, Patchset 4: final [libraryUri, functionName] = targetName.split('#');
    Lasse Nielsen . resolved

    This pattern match throws if the option string has more or less than one `#`. I'm not sure throwing is the best way to report an error.
    Obviously that should never happen because we only end here for declarations inside `dart:_internal`, and we (surely) won't have typos in those, and users can't introduce bugs.

    Slava Egorov

    Reverted these changes.

    Line 135, Patchset 4: throw StateError(
    Lasse Nielsen . resolved

    Doesn't sound like a *state* error.
    A state error means an object is currently in a state where the requested functionality is not supported, but could at other times allow it.

    I'm not sure which object/state this state error is referring to, and what is wrong with it.

    Could it be reported as a compilation error or context relevant exception?
    A format exception?

    (Generally `ArgumentError`, `StateError` and `UnsupportedError` are used to report that the caller of a method has made a mistake. Here the mistake is not in the call to `_resolveRedirection`, it's in the input, which the caller is not expected to check before calling. So `FormatException` would be an option that matches.)

    Slava Egorov

    Reverted these changes.

    Line 150, Patchset 4: throw StateError('$target is redirecting to $redirectionTarget but '
    Lasse Nielsen . resolved

    Also not a `StateError`. Not an error *in this call*, so something that should probably be reported as a compilation error by the framework doing the lowering.

    Slava Egorov

    Reverted these changes.

    Line 150, Patchset 4: throw StateError('$target is redirecting to $redirectionTarget but '
    Lasse Nielsen . resolved

    Super-nit: Comma before "but".

    Slava Egorov

    Reverted these changes.

    File runtime/docs/compiler/pragmas_recognized_by_compiler.md
    Line 163, Patchset 4:- it is only recognized when applied to methods declared in `dart:internal`;
    Lasse Nielsen . resolved

    ... applied to static methods ...?

    (I guess it's ignored on everything that is not a static function, but then it's actually not recognized on non-static methods.)

    Slava Egorov

    Reverted these changes.

    Line 164, Patchset 4:- it only rewrites static invocations of those methods;
    Lasse Nielsen . resolved

    Aka: Not tear-offs.
    (Can the invocation be, fx, a static getter invocation, or only function declarations?)

    Slava Egorov

    Reverted these changes.

    Line 173, Patchset 4:external int foo(int x);
    Lasse Nielsen . resolved

    (Should not introduce public names in patches. I guess it's "safe" for `dart:_internal`. I'd still suggest putting it as `external` in `dart:_internal` itself, and provide a patch for it on all platforms, even if most throw `UnsupportedError`. Then it's clear from the source of `dart:internal` which members it has.)

    Slava Egorov

    Reverted these changes.

    File sdk/lib/_internal/vm/lib/convert_patch.dart
    Line 26, Patchset 4:import "dart:collection" show CollectionInternals;
    Lasse Nielsen . resolved

    No `CollectionInternals` any more.

    Slava Egorov

    Done

    Line 104, Patchset 4: List? currentContainer;
    Lasse Nielsen . resolved

    Consider making this an explicit `List<dynamic>`.
    (Just to be explicit.)

    Slava Egorov

    Done

    Line 147, Patchset 4: final kvPairs = unsafeCast<List>(currentContainer);
    Lasse Nielsen . resolved

    Name it `keyValuePairs`.

    Consider `assert(keyValuePairs.length.isOdd);`

    Slava Egorov

    Done

    Line 148, Patchset 4: if (reviver case final reviver?) {
    Lasse Nielsen . resolved
    Are you absolutely sure this is as efficient as:
    ```dart
    var revivier = this.revivier;
    if (reviever != null) {
    ```
    on all platforms?
    (If so, I'm happy. If not, let's keep the simple code.)
    Martin Kustermann

    Much prefer lasses code than `if (case final reviver?)`

    I wouldn't have guessed that `if (reviver case final reviver?)` would effectively be a `reviver != null` check - in fact the `reviver?` would indicate to me we allow matching null). This new pattern match syntax is IMHO overused and often makes code much less readable!

    Slava Egorov

    Kernel for `if (a case final a?)`

    ```
    {
    final synthesized T? #0#0 = this.{test::A::a}{T?};
    {
    final hoisted T a;
    if(!(#0#0 == null)) {
    a = #0#0{T};
    {
    return a;
    }
    }
    }
    }
    ```
     so it is basically the same code.
    Line 159, Patchset 4: value = createMapFromKeyValueListUnsafe<String, dynamic>(
    Lasse Nielsen . resolved

    (If we only ever use this method for `<String, dynamic>`, then it could be named something with `Json` and not need to take type argumens, or unsafely cast its values).

    Slava Egorov

    We might want to reuse this in other places.

    File sdk/lib/_internal/vm/lib/internal_patch.dart
    Line 447, Patchset 4:external Map<K, V> createMapFromKeyValueListUnsafe<K, V>(
    Lasse Nielsen . resolved

    Consider adding another VM-specific internal library for this, instead of stuffing everything into `dart:_internal`.

    Patch files should generally not add public members that are not in the cross-platform source.

    Slava Egorov

    Done

    File sdk/lib/_internal/vm_shared/lib/compact_hash.dart
    Line 436, Patchset 4: int size = _roundUpToPowerOfTwo(keyValuePairs.length);
    Martin Kustermann . resolved

    `assert(keyValuePairs.length % 2 == 0)`

    Would it make sense to check for `keyValuePairs.length == 0` and do something faster?

    Stephen Adams

    nit: `assert(keyValuePairs.length.isEven)`

    Slava Egorov

    I doubt it makes sense to optimize for empty collections.

    Line 451, Patchset 4: internal.unsafeCast<V>(keyValuePairs[i + 1]);
    Lasse Nielsen . resolved
    Slava Egorov

    We can make this optimization in a separate CL.

    It requires much bigger changes - because there are assumptions about the length of `data` baked into the implementation, so if you want to just steal the backing store then you need to make sure it is of the right size.

    And you need to filter duplicates, so you can't just reuse `_createIndex` logic.

    Line 453, Patchset 4: }
    Lasse Nielsen . resolved

    Alternatively, we could keep the current behavior of the JSON parser, storing maps for maps, and just expose a `_Map._unsafeSet(Map map, Object? key, Object? value)` which adds the entry to the map, like the `this[...] = ...` call above, without allocating an intermediate list.

    Martin Kustermann

    That will cause unnecessary work if the map has to resize while json parser is adding more properties. By collecting all key/values first, we ensure that we have to do hashing & index creation only once.

    Slava Egorov

    Martin's explanation is correct.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Martin Kustermann
    • Stephen Adams
    • Ömer Ağacan
    Submit Requirements:
    • requirement satisfiedCode-Review
    • requirement satisfiedCommit-Message-Has-TEST
    • requirement satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: sdk
    Gerrit-Branch: main
    Gerrit-Change-Id: Ic3032323143c35c38469d4f5f289daabdf56ecc9
    Gerrit-Change-Number: 374564
    Gerrit-PatchSet: 6
    Gerrit-Owner: Slava Egorov <veg...@google.com>
    Gerrit-Reviewer: Lasse Nielsen <l...@google.com>
    Gerrit-Reviewer: Martin Kustermann <kuste...@google.com>
    Gerrit-Reviewer: Slava Egorov <veg...@google.com>
    Gerrit-CC: Stephen Adams <s...@google.com>
    Gerrit-CC: Ömer Ağacan <ome...@google.com>
    Gerrit-Attention: Martin Kustermann <kuste...@google.com>
    Gerrit-Attention: Stephen Adams <s...@google.com>
    Gerrit-Attention: Ömer Ağacan <ome...@google.com>
    Gerrit-Comment-Date: Tue, 13 Aug 2024 11:32:08 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Lasse Nielsen <l...@google.com>
    Comment-In-Reply-To: Martin Kustermann <kuste...@google.com>
    Comment-In-Reply-To: Stephen Adams <s...@google.com>
    Comment-In-Reply-To: Ömer Ağacan <ome...@google.com>
    satisfied_requirement
    open
    diffy

    Slava Egorov (Gerrit)

    unread,
    Aug 13, 2024, 7:32:16 AM8/13/24
    to Ömer Ağacan, Stephen Adams, Lasse Nielsen, Commit Queue, Martin Kustermann, dart-dc-te...@google.com, dart2js-te...@google.com, dart2wasm-t...@google.com, rev...@dartlang.org
    Attention needed from Martin Kustermann, Stephen Adams and Ömer Ağacan

    Slava Egorov voted Commit-Queue+2

    Commit-Queue+2
    Gerrit-Comment-Date: Tue, 13 Aug 2024 11:32:11 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: Yes
    satisfied_requirement
    open
    diffy

    Commit Queue (Gerrit)

    unread,
    Aug 13, 2024, 8:00:55 AM8/13/24
    to Slava Egorov, Ömer Ağacan, Stephen Adams, Lasse Nielsen, Martin Kustermann, dart-dc-te...@google.com, dart2js-te...@google.com, dart2wasm-t...@google.com, rev...@dartlang.org

    Commit Queue submitted the change with unreviewed changes

    Unreviewed changes

    4 is the latest approved patch-set.
    The change was submitted with unreviewed changes in the following files:

    ```
    The name of the file: sdk/lib/_internal/vm/lib/internal_patch.dart
    Insertions: 3, Deletions: 3.

    The diff is too large to show. Please review the diff.
    ```
    ```
    The name of the file: runtime/docs/compiler/pragmas_recognized_by_compiler.md
    Insertions: 0, Deletions: 35.

    The diff is too large to show. Please review the diff.
    ```
    ```
    The name of the file: sdk/lib/_internal/vm/lib/hash_factories.dart
    Insertions: 0, Deletions: 4.

    The diff is too large to show. Please review the diff.
    ```
    ```
    The name of the file: sdk/lib/_internal/vm_shared/lib/compact_hash.dart
    Insertions: 38, Deletions: 25.

    The diff is too large to show. Please review the diff.
    ```
    ```
    The name of the file: runtime/docs/pragmas.md
    Insertions: 0, Deletions: 1.

    The diff is too large to show. Please review the diff.
    ```
    ```
    The name of the file: sdk/lib/_internal/vm/lib/convert_patch.dart
    Insertions: 7, Deletions: 13.

    The diff is too large to show. Please review the diff.
    ```
    ```
    The name of the file: pkg/vm/lib/modular/transformations/lowering.dart
    Insertions: 1, Deletions: 79.

    The diff is too large to show. Please review the diff.
    ```

    Change information

    Commit message:
    [vm/corelib] Optimize building of Maps in JSON decoder.

    Instead of gradually adding key-value pairs into the Map as JSON
    is being parsed collect all key values first and then allocate
    the map with appropriate capacity.

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

    TEST=ci
    Change-Id: Ic3032323143c35c38469d4f5f289daabdf56ecc9
    Commit-Queue: Slava Egorov <veg...@google.com>
    Reviewed-by: Lasse Nielsen <l...@google.com>
    Files:
    • M sdk/lib/_internal/vm/lib/convert_patch.dart
    • M sdk/lib/_internal/vm_shared/lib/compact_hash.dart
    Change size: M
    Delta: 2 files changed, 53 insertions(+), 28 deletions(-)
    Branch: refs/heads/main
    Submit Requirements:
    • requirement satisfiedCode-Review: +1 by Lasse Nielsen
    Open in Gerrit
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: merged
    Gerrit-Project: sdk
    Gerrit-Branch: main
    Gerrit-Change-Id: Ic3032323143c35c38469d4f5f289daabdf56ecc9
    Gerrit-Change-Number: 374564
    Gerrit-PatchSet: 7
    Gerrit-Owner: Slava Egorov <veg...@google.com>
    Gerrit-Reviewer: Lasse Nielsen <l...@google.com>
    Gerrit-Reviewer: Martin Kustermann <kuste...@google.com>
    Gerrit-Reviewer: Slava Egorov <veg...@google.com>
    open
    diffy
    satisfied_requirement

    Martin Kustermann (Gerrit)

    unread,
    Aug 13, 2024, 1:30:01 PM8/13/24
    to Commit Queue, Slava Egorov, Ömer Ağacan, Stephen Adams, Lasse Nielsen, dart-dc-te...@google.com, dart2js-te...@google.com, dart2wasm-t...@google.com, rev...@dartlang.org

    Martin Kustermann voted Code-Review+1

    Code-Review+1
    Open in Gerrit

    Related details

    Attention set is empty
    Submit Requirements:
    • requirement satisfiedCode-Review
    • requirement satisfiedCommit-Message-Has-TEST
    • requirement satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: sdk
    Gerrit-Branch: main
    Gerrit-Change-Id: Ic3032323143c35c38469d4f5f289daabdf56ecc9
    Gerrit-Change-Number: 374564
    Gerrit-PatchSet: 7
    Gerrit-Owner: Slava Egorov <veg...@google.com>
    Gerrit-Reviewer: Lasse Nielsen <l...@google.com>
    Gerrit-Reviewer: Martin Kustermann <kuste...@google.com>
    Gerrit-Reviewer: Slava Egorov <veg...@google.com>
    Gerrit-CC: Stephen Adams <s...@google.com>
    Gerrit-CC: Ömer Ağacan <ome...@google.com>
    Gerrit-Comment-Date: Tue, 13 Aug 2024 17:29:56 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: Yes
    satisfied_requirement
    open
    diffy
    Reply all
    Reply to author
    Forward
    0 new messages