diff --git a/src/objects/objects-inl.h b/src/objects/objects-inl.h index db48ce951c6..2caf54cad37 100644 --- a/src/objects/objects-inl.h +++ b/src/objects/objects-inl.h @@ -1360,8 +1360,17 @@ JSDispatchHandle HeapObject::AllocateAndInstallJSDispatchHandle( DirectHandle host, JSDispatchHandle* location, Isolate* isolate, uint16_t parameter_count, DirectHandle code, WriteBarrierMode mode) { JSDispatchTable::Space* space = isolate->GetJSDispatchTableSpaceFor(location); + // |location| is a raw interior pointer into |*host| computed by the caller. + // NewJSDispatchHandle below may trigger mark-compact GC (via + // RetryCustomAllocateOrFail when the JSDispatchTable is full), which can + // move |*host| and leave |location| dangling. Capture the offset now and + // re-derive |location| through the GC-updated handle afterwards -- mirroring + // the safe overload above. + const ptrdiff_t offset = + reinterpret_cast
(location) - (*host).ptr(); JSDispatchHandle handle = isolate->factory()->NewJSDispatchHandle(parameter_count, code, space); + location = reinterpret_cast((*host).ptr() + offset); // Use a Release_Store to ensure that the store of the pointer into the table // is not reordered after the store of the handle. Otherwise, other threads