[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.
Significance
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.
Audit directions
Aaaa Aaaaaaaaaaaaaaaaaaaaaaa Aaaaa a Aaaaaaaaaaaaaaa Aaaa Aaaaa Aaaaaaaa Aaa Aaaaaaa Aaaa Aaaaaaaaaaa Aaa Aaaa Aaaaaa Aaaa Aaaaaaa Aaa Aaaaaa Aa Aaa Aaaaa Aaaaaaaaaaa Aaaaa a a Aaaaa Aaaaa Aaaaaa Aaaaaaa Aaaaaa Aa Aaaaaaaaa Aaaaaaa Aaaaaaa Aa Aaaa Aaa Aaaaaaaaaaaaaaa Aaaa Aaaaa Aaaaaaa Aa Aaaaaaaa Aaaaaaaa Aaaa Aaaaa Aa Aaaaa Aaaaaa Aaaaaaa a Aaaaaaaaaaaaaa Aa Aaa Aaaaaaaaaa Aaa Aaaaaaaa Aaaaaa Aaaaa Aa Aaa Aaaa Aaaaaa Aaa Aaaaaaaaaaaaaaaaaaa Aaaaaaaaaaa Aaa Aaaa Aa Aaaaaaaaa Aa Aaaaaaaaaa Aa Aaaaa Aaaaa Aaa Aaaaaaa Aaaaaa Aaa Aaaaa Aaa Aaaaaa Aaaaa Aaaaaaaa Aaaa Aa Aaaaaaaaaaaa Aaaaaaaa Aaaaaaa Aaaaa Aaaa Aaaaaaaaaaa Aaaaa Aaaa Aaaaaaaaaa Aaaaa Aaaaaaa Aaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaa Aaaaaa Aaa Aaaaaaaaaaaaa Aaaa Aaaaaa Aa Aaaaaa Aaaaaaa a a Aaaaaaaaaaaaa Aaaaaaa Aa Aaa Aaaa Aaaaaa Aaaaa Aaaaaaaaaa Aaaaaa Aaa Aaaaaaaaaaaaaaa Aaaaaa Aa Aaaaa Aaaaaaa Aaaaaaa Aaaa Aaa Aaa Aaaaaaaaaaa Aaa Aaa Aaa Aa Aaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaa Aaa Aaaaaaaaaaaaaaaaaaaaaaaaa Aa Aaaaaa Aaaaaaaaa Aaaaaaaaa Aa Aaaaa Aaaaaa Aaa Aaaaaa Aaaaaaaaa Aaa Aaaa Aaa Aaaaaaaa Aaaaaa Aaaaaaaaa Aaaaaa Aaaa Aaaaaaaaa Aaaaa Aaaaaa Aaaaaaaa Aaaaa Aa Aaaaaaa
🔒Several edge cases in the new deferred-commit and iterator-sinking paths are worth security investigation.
Subscribe to read more