Bug 1792228: Use LoadObject instead of LoadProto for proto shape guards r=jandem

We noticed this while looking at the CacheIR generated for an add-slot stub.

The depth threshold of 4 was picked by browsing around on the web and dumping the observed depth. 4 is enough to cover 95%+ of the cases I saw.

There are a couple of other places where we use LoadProto: the no-teleporting case in `GeneratePrototypeGuards`, and `ShapeGuardPrototypeChainForCrossCompartmentHolder`. They didn't show up in my experiments, so I left them alone for now.

Differential Revision: https://phabricator.services.mozilla.com/D158037
This commit is contained in:
Iain Ireland 2022-10-26 20:40:03 +00:00
parent babfa4a3b5
commit e8e72a84cc

View File

@ -761,6 +761,9 @@ static void TestMatchingHolder(CacheIRWriter& writer, NativeObject* obj,
// Note: this relies on shape implying proto.
static void ShapeGuardProtoChain(CacheIRWriter& writer, NativeObject* obj,
ObjOperandId objId) {
uint32_t depth = 0;
static const uint32_t MAX_CACHED_LOADS = 4;
while (true) {
JSObject* proto = obj->staticPrototype();
if (!proto) {
@ -768,7 +771,18 @@ static void ShapeGuardProtoChain(CacheIRWriter& writer, NativeObject* obj,
}
obj = &proto->as<NativeObject>();
objId = writer.loadProto(objId);
// After guarding the shape of an object, we can safely bake that
// object's proto into the stub data. Compared to LoadProto, this
// takes one load instead of three (object -> shape -> baseshape
// -> proto). We cap the depth to avoid bloating the size of the
// stub data.
if (depth < MAX_CACHED_LOADS) {
objId = writer.loadObject(obj);
} else {
objId = writer.loadProto(objId);
}
depth++;
writer.guardShape(objId, obj->shape());
}