/* static */ void * GCRuntime::tryRefillFreeListFromMainThread(JSContext *cx, AllocKind thingKind) { ArenaLists *arenas = cx->arenas(); Zone *zone = cx->zone(); AutoMaybeStartBackgroundAllocation maybeStartBGAlloc; void *thing = arenas->allocateFromArena(zone, thingKind, maybeStartBGAlloc); if (MOZ_LIKELY(thing)) return thing; // Even if allocateFromArena failed due to OOM, a background // finalization or allocation task may be running freeing more memory // or adding more available memory to our free pool; wait for them to // finish, then try to allocate again in case they made more memory // available. cx->runtime()->gc.waitBackgroundSweepOrAllocEnd(); thing = arenas->allocateFromArena(zone, thingKind, maybeStartBGAlloc); if (thing) return thing; return nullptr; }
/* static */ void* GCRuntime::refillFreeListFromMainThread(JSContext* cx, AllocKind thingKind, size_t thingSize) { ArenaLists *arenas = cx->arenas(); Zone *zone = cx->zone(); MOZ_ASSERT(!cx->runtime()->isHeapBusy(), "allocating while under GC"); AutoMaybeStartBackgroundAllocation maybeStartBGAlloc; return arenas->allocateFromArena(zone, thingKind, maybeStartBGAlloc); }
/* static */ void* GCRuntime::refillFreeListOffMainThread(ExclusiveContext* cx, AllocKind thingKind) { ArenaLists* arenas = cx->arenas(); Zone* zone = cx->zone(); JSRuntime* rt = zone->runtimeFromAnyThread(); AutoMaybeStartBackgroundAllocation maybeStartBGAlloc; // If we're off the main thread, we try to allocate once and return // whatever value we get. We need to first ensure the main thread is not in // a GC session. AutoLockHelperThreadState lock; while (rt->isHeapBusy()) HelperThreadState().wait(GlobalHelperThreadState::PRODUCER); return arenas->allocateFromArena(zone, thingKind, maybeStartBGAlloc); }