← All issues

DFG/FTL: Object.defineProperty descriptor field extraction

93e2909

JSTests/microbenchmarks/object-define-property-put-by-id-direct.js

+function bench() {
+ var sum = 0;
+ for (var i = 0; i < 1000000; i++) {
+ var obj = {};
+ Object.defineProperty(obj, "prop",
+ { value: i, writable: true, enumerable: true, configurable: true });
+ sum += obj.prop;
+ }
+ return sum;
+}

JSC's optimizing JIT has two upper tiers: DFG (mid-tier, dataflow graph) and FTL (top-tier, B3 backend). Object.defineProperty was historically opaque to the JIT because the descriptor is a general object. This commit exploits two watchpoints — the sane-chain watchpoint on Object.prototype and a descriptor-field watchpoint — to prove the descriptor has a known structure at compile time. DFG then inserts GetByOffset nodes that read each descriptor field directly into a new ObjectDefinePropertyFromFields IR node. When all attributes are default and the base object has no existing property for the key, the call collapses further to PutByIdDirect, hitting the inline-cache fast path.

ObjectDefineProperty(obj, key, desc)
        |
        v
ObjectDefinePropertyFromFields(obj, key, e, c, v, w, get, set)
        |
        +--[e=true,c=true,w=true; no existing prop; non-indexed key]
        |       +--> PutByIdDirect(obj, key, value)   ~12x faster
        |
        +--[data desc, any attr differs] --> DefineDataProperty
        |
        +--[accessor desc]                 --> DefineAccessorProperty

Hot Object.defineProperty with a default data descriptor now compiles to a single PutByIdDirect, yielding up to 11.9x speedup on the microbenchmark. The optimization touches watchpoint logic, structure assumptions, property storage semantics, and FTL allocation sinking — every layer where prior DFG bugs have produced exploitable JIT primitives.

🔒

Layered watchpoint guards and multi-stage IR lowering create several audit-worthy edge cases in this new optimization path.

Subscribe to read more