-
Notifications
You must be signed in to change notification settings - Fork 653
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Faster caching of prototype accesses.
Summary: We have a kind of "prototype caching" for properties found on an object's prototype chain, but it is only used after a dictionary lookup ensures that the property is not an own property of the object, which decreases it's effectiveness as an optimization. This diff changes prototype caching. A PropertyCache entry gains a new field: the "negMatchClazz". When we find a property in the (immediate) prototype (and therefore not in the object), we set the "clazz" field of the PropertyCache to the HC of the prototype object, and the "slot" field to the slot index of the property in the prototype. This is not sufficient, however: between one access and the next, the property might get added to the object, and then it would then be incorrect to retrieve it from the prototype. To guard against this, we record the HC of the object in "negMatchClazz" -- when the object had this HC, the property was not in the object. Both HC's must match to get a prototype cache hit. But when they do, we avoid doing a dictionary lookup in the object. Follow-ons planned: Implement this optimization for shermes, and for the JIT. The structure of the optimization is such that things still work correctly, but they may be slightly slower. Currently, the prototype cache path checks that the current object is not lazy, a proxy, or a host object. The latter two, at least, would be unnecessary if we ensured that proxy and host objects had an HC distinct from that of an empty object. Hopefully, something similar would apply for lazy objects. Reviewed By: neildhar Differential Revision: D65297624 fbshipit-source-id: a7dce0e17944d11b75950306eb1666894e43665b
- Loading branch information
1 parent
685b9b0
commit c2c12b9
Showing
8 changed files
with
133 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/** | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
// RUN: %hermes -O -target=HBC %s | %FileCheck --match-full-lines %s | ||
|
||
// Exercise the proto cache. | ||
print(function () { | ||
var proto = {x: 7}; | ||
var o = {}; | ||
Object.setPrototypeOf(o, proto); | ||
|
||
function access(o) { | ||
'noinline' | ||
return o.x; | ||
} | ||
|
||
// o.x in second call to "access" should get a proto cache hit. | ||
return access(o) + access(o); | ||
}()); | ||
// CHECK: 14 | ||
|
||
// Show that the proto cache doesn't get improper cache hits | ||
// if the object changes to have the queried property. | ||
print(function () { | ||
var proto = {x: 7}; | ||
var o = {}; | ||
Object.setPrototypeOf(o, proto); | ||
|
||
function access(o) { | ||
'noinline' | ||
return o.x; | ||
} | ||
|
||
// o.x in second call to "access" should get a proto cache hit. | ||
var sum = access(o); | ||
o.x = 700; | ||
sum += access(o); | ||
return sum; | ||
}()); | ||
// CHECK: 707 | ||
|