← All issues

[JSC] Map/Set iterator next must not touch JSMapIterator/JSSetIterator directly

7937fd7

ObjectAllocationSinking is a DFG optimization that replaces heap-allocated objects with virtual SSA fields when the object doesn't escape; for it to work, every write to the object must appear as an explicit PutInternalField node. OSR exits transfer control from a JIT frame back to the interpreter mid-execution, at which point any already-mutated object state is permanent. The old MapIteratorNext advanced the iterator's internal storage pointer and bucket index as an implicit side effect hidden inside the node.

Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

- Node* storage = addToGraph(MapIteratorNext, Edge(iterator, MapIteratorObjectUse));
- setResult(storage);
+ Node* tuple = addToGraph(MapIteratorNext, Edge(storageField), Edge(iteratedObjectField, MapObjectUse), Edge(entryField));
+ Node* newStorage = addToGraph(ExtractFromTuple, OpInfo(0), tuple);
+ newStorage->setResult(NodeResultJS);
+ Node* newEntry = addToGraph(ExtractFromTuple, OpInfo(1), tuple);
+ newEntry->setResult(NodeResultInt32);
+ addToGraph(PutInternalField, OpInfo(storageFieldIndex), mapIterator, newStorage);
+ addToGraph(PutInternalField, OpInfo(entryFieldIndex), mapIterator, newEntry);
+ FrozenValue* sentinelConst = m_graph.freezeStrong(m_graph.m_vm.orderedHashTableSentinel());
+ Node* done = addToGraph(CompareEqPtr, OpInfo(sentinelConst), newStorage);
+ setResult(done);

The refactor turns MapIteratorNext into a stateless read returning a (storage, entry) tuple; ByteCodeParser then emits explicit PutInternalField nodes to commit the new storage and entry index after all dependent key/value loads succeed, exposing the full write set to both optimizations.

Iterator sinking eliminates heap allocation on every hot for-of loop over Maps and Sets, and the deferred commit closes a real correctness gap around mid-iteration tier transitions where an OSR exit previously left the iterator in an unknown intermediate state.

🔒

Several edge cases in the new deferred-commit and iterator-sinking paths are worth security investigation.

Subscribe to read more