Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: d2af128b149fdd26b795ade265924b8b904afaa1
https://github.com/WebKit/WebKit/commit/d2af128b149fdd26b795ade265924b8b904afaa1
Author: Chris Dumez <[email protected]>
Date: 2026-06-18 (Thu, 18 Jun 2026)
Changed paths:
M Source/WebCore/bindings/js/DOMWrapperWorld.cpp
M Source/WebCore/bindings/js/DOMWrapperWorld.h
M Source/WebCore/bindings/js/JSDOMWrapperCache.h
Log Message:
-----------
Crash when rehashing DOMWrapperWorld::m_wrappers hash map
https://bugs.webkit.org/show_bug.cgi?id=317371
rdar://179144468
Reviewed by Ben Nham.
We are seeing a high volume of crashes in JSC::WeakImpl::clear() while
rehashing DOMWrapperWorld::m_wrappers, caused by a corrupt entry whose
Weak<JSObject> holds a garbage WeakImpl pointer. The same corruption shows
up in other unrelated WTF hash tables (e.g. CodeBlockSet) with the same
reused-memory fingerprint. We have been unable to reproduce it locally,
even with ASAN and stress tests.
This patch adds opt-in diagnostic instrumentation to catch the corrupting
write at its source, with the writer's stack. The m_wrappers hash-table
backing is allocated in its own page(s) and kept read-only except during the
world's own mutating operations (cacheWrapper/uncacheWrapper/clearWrappers),
so any stray write faults immediately at the point of corruption rather than
much later during an unrelated rehash.
Because keeping the backing read-only between mutations costs two mprotect()
calls per mutation (a ~1.2% Speedometer regression when always on), guarding
is sampled per-process: the decision is made once at startup, and in the
common (unguarded) case the allocator falls back to FastMalloc and the
mutation scopes become no-ops, so there is no measurable cost. The sampled
fraction pays the full cost but provides full fidelity, keeping the
fleet-average cost negligible.
This is a temporary diagnostic facility. It should be removed once
the rdar://179144468 root cause is found.
* Source/WebCore/bindings/js/DOMWrapperWorld.cpp:
(WebCore::initializeWrapperMapGuardingOnce):
(WebCore::backingRegistryLock):
(WebCore::backingRegistry):
(WebCore::WrapperMapTableMalloc::allocate):
(WebCore::WrapperMapTableMalloc::malloc):
(WebCore::WrapperMapTableMalloc::zeroedMalloc):
(WebCore::WrapperMapTableMalloc::free):
(WebCore::DOMWrapperWorld::setWrappersTableWritable):
(WebCore::WrapperMutationScope::WrapperMutationScope):
(WebCore::WrapperMutationScope::~WrapperMutationScope):
(WebCore::DOMWrapperWorld::DOMWrapperWorld):
(WebCore::DOMWrapperWorld::~DOMWrapperWorld):
(WebCore::DOMWrapperWorld::clearWrappers):
* Source/WebCore/bindings/js/DOMWrapperWorld.h:
(WebCore::DOMWrapperWorld::noteTableBacking):
(WebCore::DOMWrapperWorld::forgetTableBacking):
* Source/WebCore/bindings/js/JSDOMWrapperCache.h:
(WebCore::cacheWrapper):
(WebCore::uncacheWrapper):
Canonical link: https://commits.webkit.org/315505@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications