Closed Bug 1696178 Opened 3 years ago Closed 3 years ago

Optimize Object.assign more

Categories

(Core :: JavaScript Engine, task, P3)

task

Tracking

()

RESOLVED FIXED
89 Branch
Tracking Status
firefox89 --- fixed

People

(Reporter: jandem, Assigned: jandem)

References

(Blocks 1 open bug)

Details

Attachments

(8 files)

Object.assign({}, ...) is very hot on Reddit, Slack and other modern websites.

This is related to bug 1648546, but there's more we can do in the C++ implementation before adding IC stubs for this.

Depends on: 1697143

I have some patches for this. For the micro-benchmark below, I get (best of 3 runs):

before:        2351 ms
+ bug 1697143: 1732 ms
+ parts 1-4:   1653 ms
+ parts 5-6:    885 ms
+ part 7:       756 ms
function f() {
    var from1 = {a: 1, b: 2, c: 3};
    var from2 = {};
    var from3 = {b: 4};
    for (var i = 0; i < 10_000_000; i++) {
        Object.assign({}, from1, from2, from3);
    }
}
var t = dateNow();
f();
print(dateNow() - t);

When we had unboxed objects, not every object had a shape, but now we can just
do a shape check without checking it's a NativeObject first.

Checking for proxies was slowing us down for no good reason. Non-native objects
already manage their own layout; slotSpan only applies to native objects.

Depends on D108403

One of the advantages of the Shape/BaseShape overhaul is that non-dictionary
shapes never change their BaseShape, because the BaseShape no longer contains
the ShapeTable and "owned" BaseShapes don't exist anymore.

This lets us simplify some comments and code.

Depends on D108404

NativeObject::addEnumerableDataProperty is very hot and this is a measurable speedup
because it's not as branchy as setLastProperty.

Depends on D108405

This will be used by the next patch to optimize Object.assign.

Depends on D108406

Websites like Reddit and Slack call Object.assign thousands of times. The vast majority
of these calls (more than 95%) are with plain objects. This patch adds a fast path for
this case.

This lets us bypass the generic SetProperty code and some of the JSClass checks
that aren't relevant for PlainObject.

Depends on D108407

These are all setting newly added slots so we can avoid the pre-barrier.

Attachment #9209053 - Attachment description: Bug 1696178 part 1 - Simplify and optimize shape check in TryAssignNative. r?anba! → Bug 1696178 part 1 - Simplify/optimize shape check in TryAssignNative and TryEnumerableOwnPropertiesNative. r?anba!
Pushed by jdemooij@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/6b91b2e87f18
part 1 - Simplify/optimize shape check in TryAssignNative and TryEnumerableOwnPropertiesNative. r=anba
https://hg.mozilla.org/integration/autoland/rev/4ca97ae7f9ce
part 2 - Don't handle proxies in Shape::slotSpan. r=jonco
https://hg.mozilla.org/integration/autoland/rev/aa7ea7bda43e
part 3 - Remove Shape::slotSpan overload with JSClass argument. r=jonco
https://hg.mozilla.org/integration/autoland/rev/12574c8b209d
part 4 - Add NativeObject::setLastPropertyForNewDataProperty. r=jonco
https://hg.mozilla.org/integration/autoland/rev/bad57461dcc4
part 5 - Add ObjectFlag::HasNonWritableOrAccessorExcludingProto. r=jonco
https://hg.mozilla.org/integration/autoland/rev/f16ed78f5471
part 6 - Add a fast path for Object.assign with plain objects. r=anba
https://hg.mozilla.org/integration/autoland/rev/c9bb3660abd3
part 7 - Add a faster path for when the shape can be reused directly. r=jonco
https://hg.mozilla.org/integration/autoland/rev/ecf43b0add73
part 8 - Use initSlot instead of setSlot in a few places. r=jonco
Regressions: 1700525
Regressions: 1701899
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: