[JSC] Replace fixup-inserted RegExp primordial `TryGetById` chains with a single `CheckStructure`
a46d2fe
Before the JIT can emit a fast intrinsic for String.prototype.replace, .match, .search, or .split with a RegExp argument, it must prove the argument is "primordial" — that the instance doesn't shadow any prototype methods the spec routes through, since those are observable. The old fixup helpers emitted a TryGetById+CheckIsConstant guard per property (the replace helper checked exec, flags, eight individual flag getters, and @@replace — eleven total). These TryGetByIds are inserted after profiling, so they carry no type information and survive in FTL as expensive opaque IC patchpoints.
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
- void addStringReplacePrimordialChecks(Node* searchRegExp)
+ void addRegExpPrimordialStructureCheck(Node* regExp)
{
Node* node = m_currentNode;
JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
- // ... emitPrimordialCheckFor x11 (exec, flags, 8 flag getters, @@replace)
+ m_insertionSet.insertNode(
+ m_indexInBlock, SpecNone, Check, node->origin,
+ Edge(regExp, RegExpObjectUse));
+ Node* lastIndexProperty = m_insertionSet.insertNode(
+ m_indexInBlock, SpecNone, GetRegExpObjectLastIndex, node->origin,
+ Edge(regExp, RegExpObjectUse));
}
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
+ if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache))
+ return CallOptimizationResult::DidNothing;
This commit replaces up to eleven TryGetById+CheckIsConstant pairs per call site with a single CheckStructure against the original unpatched RegExp structure, and simultaneously adds the previously absent BadCache exit bail to StringPrototypeReplace, StringPrototypeReplaceAll, and RegExpSearchIntrinsic. It exploits two invariants: regExpPrimordialPropertiesWatchpoint fires (invalidating all compiled code) if RegExp.prototype is mutated, and adding any own property transitions an object's structure. So a structure match proves the instance has no shadowing own properties and the prototype is already known clean.
Significance
Hot regexp/string-replace paths run 1.3–1.6x faster because up to 11 opaque IC patchpoints per call site are eliminated from FTL-compiled code; the change also fixes a latent recompilation loop bug exposed by the new guard.
Audit directions
Aaaa Aaaaaaa a Aaaaaaaa Aaaaa Aaaaaaa Aaaa Aaaaaaaaa Aaaaaaaaa Aa a Aaaaaaaaaa Aaa Aaaaaa Aaaaaaaaaaaa Aaaaaaaa Aa a Aaaaa Aaa Aaaaaaaaaa Aaaaaaa Aaaaa Aaaaaaa Aaa Aaa Aaaa Aaa Aaaaa a Aaaaaaaaa Aa Aaa Aaaaaaaa Aaaaaaa Aaa Aaaaaaaa Aaaaaaaaaa a Aaaa Aaaaaaaaaaaaaaa Aaaaaaaaaa Aa Aaaaaaaa Aaaaaa Aaaaaaaaaa Aaaa Aaaaaa Aaa Aaaaaa Aaaaaaaaaa Aaaaaa Aaaaaa Aaaaa Aaaaaaaaaaaa a Aaaaa Aaaa a Aaaaaa Aaaaaaaaa Aaaaa Aaa Aaaaaaaa Aaaaaaaaa Aaa Aaaaaa Aaaa Aaaaaaaa Aaa Aaa Aaaaaaaaaaa Aaaaaaaa Aaaaaaaaa Aaa Aaaaaaa Aaaaaaaaaa Aaaa Aa Aaa Aaaaaaaa Aaaaaa Aaaaa Aa Aaaa Aaa Aaa Aaaaaaaa Aaaaaa Aaaaaaa Aaa Aaaaaaaaaaaaaaaaaa Aaaa Aaa Aaaaaaa Aaaa Aaaaa Aaa Aaa Aaaaaaaaaaa Aa Aa Aaaaa Aaaa Aaaaaaaaa Aaa Aaaaaaaaa Aa Aaaaaaaaaaaaa Aaa Aaaa Aaaaaaaaaaaaa Aaa Aaaaaa Aaaa Aaaa Aaaaaaaaaa Aa a a Aaaaa Aaaaaaa Aaaaaaa Aaaaa Aaaa Aaaaaa Aaaaaaaaaaa Aaaa Aaa Aaaaa Aaaaaaaaa Aa Aaaaaaaaaaaaa Aaa Aaaaaaa Aaaaaaaaa Aaaaa Aa Aaaaaaaaaaaaaaa Aaa Aaa Aaa Aaaaaaaaaaaaaaaa Aaaaa
🔒The narrowed guard and new fast-exit paths raise several edge cases worth security investigation.
Subscribe to read more