Move getters/setters from AccessorShape to object slots
Categories
(Core :: JavaScript Engine, task, P3)
Tracking
()
Tracking | Status | |
---|---|---|
firefox89 | --- | fixed |
People
(Reporter: jandem, Assigned: jandem)
References
(Blocks 2 open bugs)
Details
Attachments
(17 files)
(deleted),
text/x-phabricator-request
|
Details | |
(deleted),
text/x-phabricator-request
|
Details | |
(deleted),
text/x-phabricator-request
|
Details | |
(deleted),
text/x-phabricator-request
|
Details | |
(deleted),
text/x-phabricator-request
|
Details | |
(deleted),
text/x-phabricator-request
|
Details | |
(deleted),
text/x-phabricator-request
|
Details | |
Bug 1700052 part 8 - Add GuardFixedSlotValue and GuardDynamicSlotValue CacheIR instructions. r?iain!
(deleted),
text/x-phabricator-request
|
Details | |
(deleted),
text/x-phabricator-request
|
Details | |
(deleted),
text/x-phabricator-request
|
Details | |
(deleted),
text/x-phabricator-request
|
Details | |
(deleted),
text/x-phabricator-request
|
Details | |
(deleted),
text/x-phabricator-request
|
Details | |
(deleted),
text/x-phabricator-request
|
Details | |
(deleted),
text/x-phabricator-request
|
Details | |
(deleted),
text/x-phabricator-request
|
Details | |
(deleted),
text/x-phabricator-request
|
Details |
Getters/setters are currently stored in the shape tree, in AccessorShape
s. The reasons for doing it this way were mostly historical, as far as I know: we already supported JSGetterOp
and JSSetterOp
getters/setters and that code was reused when implementing ES5 getter/setter objects.
There are a number of problems with this:
- Branchy shape trees when lambdas are used as getters/setters can result in performance cliffs and wasting memory. See the micro-benchmark below for an example of this.
- It complicates the shape code because data properties and accessor properties are so different.
- Certain changes to the object layout we're considering are not possible.
The plan here is as follows:
-
Remove
JSGetterOp/JSSetterOp
(bug 1404885). Today these are only used forarray.length
andArgumentsObject
, and I think we can handle these special cases with a special property attribute instead. -
Add a
GetterSetterPair
GC thing, a tuple holding just the getter/setter objects. Use this inAccessorShape
. -
Store
GetterSetterPair
in an object slot asPrivateGCThingValue
. Remove AccessorShape.
This will require an extra CacheIR guard for getter/setter calls. This is likely acceptable compared to the call overhead, and this could be optimized away in the future if needed (since most getters/setters are on prototype objects, we could use fuses to invalidate code when redefining an accessor property).
Here's a micro-benchmark where a getter property makes accessing a data property much slower (28 ms => 204 ms).
function init() {
var objs = [];
for (var i = 0; i < 128; i++) {
objs.push({get foo() {}, x: 1});
}
return objs;
}
function test(objs) {
var res = 0;
for (var i = 0; i < 10_000_000; i++) {
res += objs[i % 128].x;
}
return res;
}
var objs = init();
var t = dateNow();
var res = test(objs);
print(dateNow() - t);
print(res);
Assignee | ||
Comment 1•4 years ago
|
||
For now these just forward to the equivalent methods on the shape, but that
will change in a later patch.
Assignee | ||
Comment 2•4 years ago
|
||
This way the code will do the right thing when the shape no longer implies a specific
getter object.
A later patch will change this so we store just the slot number instead of the
species property shape.
Depends on D110248
Assignee | ||
Comment 3•4 years ago
|
||
Depends on D110249
Assignee | ||
Comment 4•4 years ago
|
||
This is preparing for a later patch.
Depends on D110250
Assignee | ||
Comment 5•4 years ago
|
||
Also clean up the similar Push method a bit to use PropertyKey instead of jsid.
Depends on D110251
Assignee | ||
Comment 6•4 years ago
|
||
We currently get the jsid from the property's shape, but in a later patch that
Shape* argument will be replaced with a GetterSetter* argument.
I considered using PropertyKey instead of jsid, but this matches similar code
using jsid.
Depends on D110252
Assignee | ||
Comment 7•4 years ago
|
||
This turned out to be a bit more work than expected because we were missing
branch32/branchPtr implementations taking a BaseIndex and a Register.
Depends on D110253
Assignee | ||
Comment 8•4 years ago
|
||
These will be used in a later patch to guard obj[slot] == PrivateGCThingValue(GetterSetter*)
.
Depends on D110254
Assignee | ||
Comment 9•4 years ago
|
||
Depends on D110255
Assignee | ||
Comment 10•4 years ago
|
||
Depends on D110256
Assignee | ||
Comment 11•4 years ago
|
||
There will be additional cleanup of the Shape code in follow-up patches.
Depends on D110257
Assignee | ||
Comment 12•4 years ago
|
||
Depends on D110258
Assignee | ||
Comment 13•4 years ago
|
||
Depends on D110259
Assignee | ||
Comment 14•4 years ago
|
||
Because these methods are now also used for accessor properties.
Depends on D110260
Assignee | ||
Comment 15•4 years ago
|
||
This is a bit faster than getting the slot number from the shape every time.
Depends on D110261
Assignee | ||
Comment 16•4 years ago
|
||
Depends on D110262
Assignee | ||
Updated•4 years ago
|
Comment 17•4 years ago
|
||
Assignee | ||
Comment 18•4 years ago
|
||
Use this instead of checking !isCustomDataProperty
(and before this stack, !isDataProperty
).
Comment 19•4 years ago
|
||
bugherder |
Comment 20•4 years ago
|
||
Comment 21•4 years ago
|
||
bugherder |
Comment 22•4 years ago
|
||
Assignee | ||
Updated•4 years ago
|
Comment 23•4 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/c4825995d926
https://hg.mozilla.org/mozilla-central/rev/40b1b6f502ca
https://hg.mozilla.org/mozilla-central/rev/1bee1c7dabac
https://hg.mozilla.org/mozilla-central/rev/89d1c5483930
https://hg.mozilla.org/mozilla-central/rev/3ad3acac6cf6
https://hg.mozilla.org/mozilla-central/rev/55012db38df0
https://hg.mozilla.org/mozilla-central/rev/b00dca6a4995
Description
•