Bug 234990 - JSArray::fastSlice() should not convert the source from CoW
Summary: JSArray::fastSlice() should not convert the source from CoW
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: All All
: P2 Enhancement
Assignee: Alexey Shvayka
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2022-01-07 14:58 PST by Alexey Shvayka
Modified: 2022-01-14 15:50 PST (History)
8 users (show)

See Also:


Attachments
Patch (4.62 KB, patch)
2022-01-10 14:31 PST, Alexey Shvayka
mark.lam: review-
Details | Formatted Diff | Diff
Patch (3.15 KB, patch)
2022-01-10 15:53 PST, Alexey Shvayka
no flags Details | Formatted Diff | Diff
Patch (3.32 KB, patch)
2022-01-10 16:10 PST, Alexey Shvayka
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Alexey Shvayka 2022-01-07 14:58:12 PST
... since we aren't modifying it.
Comment 1 Alexey Shvayka 2022-01-10 14:31:03 PST
Created attachment 448801 [details]
Patch
Comment 2 Mark Lam 2022-01-10 15:06:15 PST
Comment on attachment 448801 [details]
Patch

r=me if EWS is happy.
Comment 3 Yusuke Suzuki 2022-01-10 15:41:15 PST
Comment on attachment 448801 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=448801&action=review

> Source/JavaScriptCore/runtime/JSArray.cpp:747
> +        Structure* resultStructure = globalObject->arrayStructureForIndexingTypeDuringAllocation(sourceIndexingMode | IsArray);

Doesn't it accidentally propagate CoW state if source is CoW?
The result of slice should not be CoW array.
Comment 4 Alexey Shvayka 2022-01-10 15:53:11 PST
Created attachment 448806 [details]
Patch

Unset CopyOnWrite from indexing mode.
Comment 5 Mark Lam 2022-01-10 15:54:46 PST
(In reply to Yusuke Suzuki from comment #3)
> Comment on attachment 448801 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=448801&action=review
> 
> > Source/JavaScriptCore/runtime/JSArray.cpp:747
> > +        Structure* resultStructure = globalObject->arrayStructureForIndexingTypeDuringAllocation(sourceIndexingMode | IsArray);
> 
> Doesn't it accidentally propagate CoW state if source is CoW?
> The result of slice should not be CoW array.

You are right.  I actually checked for that during my review, and then got distracted and forgot to follow thru on it.  Thanks for catching this.
Comment 6 Alexey Shvayka 2022-01-10 15:55:15 PST
Comment on attachment 448806 [details]
Patch

(In reply to Mark Lam from comment #2)
> Comment on attachment 448801 [details]
> Patch
> 
> r=me if EWS is happy.

Thanks Mark!
Needs another review I guess.

(In reply to Yusuke Suzuki from comment #3)
> Comment on attachment 448801 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=448801&action=review
> 
> > Source/JavaScriptCore/runtime/JSArray.cpp:747
> > +        Structure* resultStructure = globalObject->arrayStructureForIndexingTypeDuringAllocation(sourceIndexingMode | IsArray);
> 
> Doesn't it accidentally propagate CoW state if source is CoW?
> The result of slice should not be CoW array.

My bad, it does, I didn't look into arrayStructureForIndexingTypeDuringAllocation() close enough.
JSTests/microbenchmarks/lazy-array-species-watchpoints.js nicely covers the case.
I very much appreciate the tip!
Comment 7 Yusuke Suzuki 2022-01-10 15:56:23 PST
Comment on attachment 448806 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=448806&action=review

r=me with comment.

> JSTests/stress/array-slice-cow.js:11
> +    return slice;

Can we have a test checking slice is non CoW?

> JSTests/stress/array-slice-cow.js:20
> +    return slice;

Ditto

> JSTests/stress/array-slice-cow.js:29
> +    return slice;

Ditto.

> Source/JavaScriptCore/runtime/JSArray.cpp:736
> +    auto arrayType = (source->indexingMode() & ~CopyOnWrite) | IsArray;

We should take indexingType() instead of indexingMode(). The difference between IndexingType and IndexingMode is CoW bit.
Comment 8 Alexey Shvayka 2022-01-10 16:01:50 PST
(In reply to Yusuke Suzuki from comment #7)
> > Source/JavaScriptCore/runtime/JSArray.cpp:736
> > +    auto arrayType = (source->indexingMode() & ~CopyOnWrite) | IsArray;
> 
> We should take indexingType() instead of indexingMode(). The difference
> between IndexingType and IndexingMode is CoW bit.

I'm likely missing something, but in

  inline IndexingType JSCell::indexingType() const
  {
      return indexingTypeAndMisc() & AllWritableArrayTypes;
  }

doesn't `& AllWritableArrayTypes` bit exclude both non-JSArrays and CoW?
Comment 9 Alexey Shvayka 2022-01-10 16:03:26 PST
(In reply to Alexey Shvayka from comment #8)
> (In reply to Yusuke Suzuki from comment #7)
> > > Source/JavaScriptCore/runtime/JSArray.cpp:736
> > > +    auto arrayType = (source->indexingMode() & ~CopyOnWrite) | IsArray;
> > 
> > We should take indexingType() instead of indexingMode(). The difference
> > between IndexingType and IndexingMode is CoW bit.
> 
> I'm likely missing something, but in
> 
>   inline IndexingType JSCell::indexingType() const
>   {
>       return indexingTypeAndMisc() & AllWritableArrayTypes;
>   }
> 
> doesn't `& AllWritableArrayTypes` bit exclude both non-JSArrays and CoW?

Oh no it doesn't, please disregard.
Comment 10 Alexey Shvayka 2022-01-10 16:10:02 PST
Created attachment 448810 [details]
Patch

Assert that result of fastSlice() is non-CoW and leverage indexingType().
Comment 11 Radar WebKit Bug Importer 2022-01-14 14:59:18 PST
<rdar://problem/87620060>
Comment 12 Alexey Shvayka 2022-01-14 15:31:06 PST
Comment on attachment 448810 [details]
Patch

Thanks again for review, Yusuke! indexingType() is neat.
Comment 13 EWS 2022-01-14 15:49:59 PST
Committed r288036 (246062@main): <https://commits.webkit.org/246062@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 448810 [details].