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)

enhancement

Tracking

()

RESOLVED FIXED
mozilla58
Tracking Status
firefox58 --- fixed

People

(Reporter: anba, Assigned: anba)

References

Details

Attachments

(2 files, 2 obsolete files)

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.
Attached patch bug1398780-part1-slice-with-arguments.patch (obsolete) (deleted) — Splinter Review
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: nobody → andrebargull
Status: NEW → ASSIGNED
Attachment #8906618 - Flags: review?(till)
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)
Priority: -- → P3
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)
Attachment #8906622 - Flags: review?(till) → review?(jdemooij)
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 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+
Updated part 1 to add the additional assertion per review comments. Carrying r+.
Attachment #8906618 - Attachment is obsolete: true
Attachment #8919633 - Flags: review+
Updated part 2 to apply cleanly on inbound, no changes in behaviour.
Attachment #8906622 - Attachment is obsolete: true
Attachment #8919634 - Flags: review+
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
Status: ASSIGNED → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla58
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: