Closed
Bug 1398780
Opened 7 years ago
Closed 7 years ago
Add a fast path for copying arguments objects to Array.prototype.slice
Categories
(Core :: JavaScript Engine, enhancement, P3)
Core
JavaScript Engine
Tracking
()
RESOLVED
FIXED
mozilla58
Tracking | Status | |
---|---|---|
firefox58 | --- | fixed |
People
(Reporter: anba, Assigned: anba)
References
Details
Attachments
(2 files, 2 obsolete files)
(deleted),
patch
|
anba
:
review+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
anba
:
review+
|
Details | Diff | Splinter Review |
Adding a fast path for arguments objects to Array.prototype.slice improves this µ-benchmark from ~280ms to 175ms.
var a = Array(3).fill(0).map((v, k) => k + 1);
var args = function(){ return arguments; }.apply(null, a);
var q = 0;
var t = dateNow();
for (var i = 0; i < 1000000; ++i) {
q += Array.prototype.slice.call(args, 0)[0];
}
print(dateNow() - t);
For larger argument counts the relative improvement is even higher, for example when 10 instead of 3 arguments, the test case improves from 540ms to 200ms for me.
Assignee | ||
Comment 1•7 years ago
|
||
This adds a fast path for arguments objects to ArraySliceOrdinary, so we don't fall into the more general CopyArrayElements.
The fast path is only taken when the arguments object has neither an overridden length nor any deleted elements, because then we can directly call ArgumentsObject#element(...) to access the argument values.
For further speed-ups,
1. The result array is created with NewDenseFullyAllocatedArray instead of NewPartlyAllocatedArrayTryReuseGroup (there is no group to re-use and the final array length is known)
2. And the result array elements are set through NativeObject#initDenseElement(), because that allows us to avoid extra barriers when compared to calling NativeObject#ensureDenseElements(...) + NativeObject#setDenseElement[WithType](...). (This correct to do here, right?)
Assignee | ||
Comment 2•7 years ago
|
||
And some more tiny performance improvements to avoid extra rooting.
SpeciesConstructor:
- If |&ctor.toObject() == defaultCtor| holds, we don't actually need to have a separate RootedObject for |ctor|, but instead can reuse |defaultCtor|.
- And the jsid for GetGetterPure doesn't need to be rooted.
IsArraySpecies:
- We don't need to root |ctor| and |speciesId| when calling GetGetterPure.
- And we don't need a RootedValue for GetPropertyPure.
Avoiding extra rooting for IsArraySpecies is nice, because IsArraySpecies is a hot method when Array.prototype.splice is used to remove elements from an array (a usage pattern seen in some of the Speedometer frameworks). For example in this µ-benchmark
var t = dateNow();
for (var i = 0; i < 40000; ++i) {
var a = [1,2,3,4,5,6,7,8,9,0];
while (a.length) a.splice(0, 1);
}
print(dateNow() - t);
We're currently spending about ~30% of our time in IsArraySpecies (according to callgrind).
Attachment #8906622 -
Flags: review?(till)
Updated•7 years ago
|
Priority: -- → P3
Assignee | ||
Comment 3•7 years ago
|
||
Comment on attachment 8906618 [details] [diff] [review]
bug1398780-part1-slice-with-arguments.patch
Switching reviewer because Till doesn't seem to have time right now.
Attachment #8906618 -
Flags: review?(till) → review?(jdemooij)
Assignee | ||
Updated•7 years ago
|
Attachment #8906622 -
Flags: review?(till) → review?(jdemooij)
Comment 4•7 years ago
|
||
Comment on attachment 8906618 [details] [diff] [review]
bug1398780-part1-slice-with-arguments.patch
Review of attachment 8906618 [details] [diff] [review]:
-----------------------------------------------------------------
Nice.
::: js/src/jsarray.cpp
@@ +3229,5 @@
> + result->setDenseInitializedLength(count);
> +
> + for (uint32_t index = 0; index < count; index++) {
> + const Value& v = argsobj->element(begin + index);
> + result->initDenseElement(index, v);
Hm I think it's okay to use this instead of initDenseElementWithType because of [0].
Please add this assert before the loop:
MOZ_ASSERT(result->group()->unknownProperties(), ...some comment explaining this is why it's okay to use initDenseElement instead of initDenseElementWithType...);
[0] http://searchfox.org/mozilla-central/rev/ed1d5223adcdc07e9a2589ee20f4e5ee91b4df10/js/src/jsarray.cpp#3626-3632
Attachment #8906618 -
Flags: review?(jdemooij) → review+
Comment 5•7 years ago
|
||
Comment on attachment 8906622 [details] [diff] [review]
bug1398780-part2-unnecessary-rooting-array.patch
Review of attachment 8906622 [details] [diff] [review]:
-----------------------------------------------------------------
\o/
Attachment #8906622 -
Flags: review?(jdemooij) → review+
Assignee | ||
Comment 6•7 years ago
|
||
Updated part 1 to add the additional assertion per review comments. Carrying r+.
Attachment #8906618 -
Attachment is obsolete: true
Attachment #8919633 -
Flags: review+
Assignee | ||
Comment 7•7 years ago
|
||
Updated part 2 to apply cleanly on inbound, no changes in behaviour.
Attachment #8906622 -
Attachment is obsolete: true
Attachment #8919634 -
Flags: review+
Assignee | ||
Comment 8•7 years ago
|
||
Try: https://treeherder.mozilla.org/#/jobs?repo=try&revision=eab4b5c7828b90e301f153c137c3e506f5bf9c6a
Keywords: checkin-needed
Pushed by ryanvm@gmail.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/f87472bf4efa
Part 1: Add a fast path when Array.prototype.slice is called with an arguments object. r=till
https://hg.mozilla.org/integration/mozilla-inbound/rev/9a67d1a285ce
Part 2: Remove unnecessary rooting in SpeciesConstructor and some Array methods. r=till
Keywords: checkin-needed
Comment 10•7 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/f87472bf4efa
https://hg.mozilla.org/mozilla-central/rev/9a67d1a285ce
Status: ASSIGNED → RESOLVED
Closed: 7 years ago
status-firefox58:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla58
Updated•7 years ago
|
status-firefox57:
affected → ---
You need to log in
before you can comment on or make changes to this bug.
Description
•