Fast path for Array.prototype.indexOf on NodeList
Source/JavaScriptCore/runtime/ArrayPrototype.cpp
Source/JavaScriptCore/runtime/EmbedderArrayLike.h
WebKit's binding layer wraps native C++ DOM objects in JS objects (JSDOMWrapper) on demand. When Array.prototype.indexOf iterates an array-like object like NodeList, it calls [[Get]] on each index, triggering JSNodeList::item() which materializes a full JS wrapper for every Node encountered — just to perform a === comparison. This is pure overhead when the underlying operation is a pointer comparison.
This commit introduces EmbedderArrayLike, a new JSC abstraction that lets embedders implement a native fastIndexOf() bypassing JS wrapper creation. NodeList opts in via a new [EmbedderArrayLike] IDL attribute, so Array.prototype.indexOf on a NodeList now passes the search element directly into a C++ fast path that compares raw Node* pointers.
Before: After:
indexOf(nodeList, searchEl) indexOf(nodeList, searchEl)
└─► for i in 0..length: ├─► JSType == EmbedderArrayLikeType?
nodeList[i] │ yes: fastIndexOf(searchEl)
→ JSDOMWrapper::create(node_i) │ └─► native Node* comparison
→ JSNode* [heap alloc per elem] │ [no alloc]
JSValue(JSNode*) === searchEl └─► no: original slow path
Significance
For large NodeLists, indexOf previously forced GC-pressure-inducing wrapper allocation for each element just to do a pointer comparison — the EmbedderArrayLike abstraction eliminates that entirely and is now open for other array-like DOM types to opt in.