mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1141234 - Part 4: Move off-thread object allocation above unimplementable operations; r=sfink
This commit is contained in:
parent
b2cc60735e
commit
d85cdea52b
@ -57,33 +57,52 @@ TryNewNurseryObject(JSContext *cx, size_t thingSize, size_t nDynamicSlots, const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
GCIfNeeded(ExclusiveContext *cx)
|
||||
template <AllowGC allowGC>
|
||||
inline JSObject *
|
||||
TryNewTenuredObject(ExclusiveContext *cx, AllocKind kind, size_t thingSize, size_t nDynamicSlots)
|
||||
{
|
||||
if (cx->isJSContext()) {
|
||||
JSContext *ncx = cx->asJSContext();
|
||||
JSRuntime *rt = ncx->runtime();
|
||||
HeapSlot *slots = nullptr;
|
||||
if (nDynamicSlots) {
|
||||
slots = cx->zone()->pod_malloc<HeapSlot>(nDynamicSlots);
|
||||
if (MOZ_UNLIKELY(!slots))
|
||||
return nullptr;
|
||||
Debug_SetSlotRangeToCrashOnTouch(slots, nDynamicSlots);
|
||||
}
|
||||
|
||||
JSObject *obj = TryNewTenuredThing<JSObject, allowGC>(cx, kind, thingSize);
|
||||
|
||||
if (obj)
|
||||
obj->setInitialSlotsMaybeNonNative(slots);
|
||||
else
|
||||
js_free(slots);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
GCIfNeeded(JSContext *cx)
|
||||
{
|
||||
JSRuntime *rt = cx->runtime();
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
if (rt->gc.needZealousGC())
|
||||
rt->gc.runDebugGC();
|
||||
if (rt->gc.needZealousGC())
|
||||
rt->gc.runDebugGC();
|
||||
#endif
|
||||
|
||||
// Invoking the interrupt callback can fail and we can't usefully
|
||||
// handle that here. Just check in case we need to collect instead.
|
||||
if (rt->hasPendingInterrupt())
|
||||
rt->gc.gcIfRequested(ncx);
|
||||
// Invoking the interrupt callback can fail and we can't usefully
|
||||
// handle that here. Just check in case we need to collect instead.
|
||||
if (rt->hasPendingInterrupt())
|
||||
rt->gc.gcIfRequested(cx);
|
||||
|
||||
// If we have grown past our GC heap threshold while in the middle of
|
||||
// an incremental GC, we're growing faster than we're GCing, so stop
|
||||
// the world and do a full, non-incremental GC right now, if possible.
|
||||
if (rt->gc.isIncrementalGCInProgress() &&
|
||||
cx->zone()->usage.gcBytes() > cx->zone()->threshold.gcTriggerBytes())
|
||||
{
|
||||
PrepareZoneForGC(cx->zone());
|
||||
AutoKeepAtoms keepAtoms(cx->perThreadData);
|
||||
rt->gc.gc(GC_NORMAL, JS::gcreason::INCREMENTAL_TOO_SLOW);
|
||||
}
|
||||
// If we have grown past our GC heap threshold while in the middle of
|
||||
// an incremental GC, we're growing faster than we're GCing, so stop
|
||||
// the world and do a full, non-incremental GC right now, if possible.
|
||||
if (rt->gc.isIncrementalGCInProgress() &&
|
||||
cx->zone()->usage.gcBytes() > cx->zone()->threshold.gcTriggerBytes())
|
||||
{
|
||||
PrepareZoneForGC(cx->zone());
|
||||
AutoKeepAtoms keepAtoms(cx->perThreadData);
|
||||
rt->gc.gc(GC_NORMAL, JS::gcreason::INCREMENTAL_TOO_SLOW);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -91,20 +110,16 @@ GCIfNeeded(ExclusiveContext *cx)
|
||||
|
||||
template <AllowGC allowGC>
|
||||
static inline bool
|
||||
CheckAllocatorState(ExclusiveContext *cx, AllocKind kind)
|
||||
CheckAllocatorState(JSContext *cx, AllocKind kind)
|
||||
{
|
||||
if (allowGC) {
|
||||
if (!GCIfNeeded(cx))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!cx->isJSContext())
|
||||
return true;
|
||||
|
||||
JSContext *ncx = cx->asJSContext();
|
||||
JSRuntime *rt = ncx->runtime();
|
||||
JSRuntime *rt = cx->runtime();
|
||||
#if defined(JS_GC_ZEAL) || defined(DEBUG)
|
||||
MOZ_ASSERT_IF(rt->isAtomsCompartment(ncx->compartment()),
|
||||
MOZ_ASSERT_IF(rt->isAtomsCompartment(cx->compartment()),
|
||||
kind == AllocKind::STRING ||
|
||||
kind == AllocKind::FAT_INLINE_STRING ||
|
||||
kind == AllocKind::SYMBOL ||
|
||||
@ -119,7 +134,7 @@ CheckAllocatorState(ExclusiveContext *cx, AllocKind kind)
|
||||
|
||||
// For testing out of memory conditions
|
||||
if (js::oom::ShouldFailWithOOM()) {
|
||||
ReportOutOfMemory(ncx);
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -161,14 +176,16 @@ js::Allocate(ExclusiveContext *cx, AllocKind kind, size_t nDynamicSlots, Initial
|
||||
static_assert(sizeof(JSObject_Slots0) >= CellSize,
|
||||
"All allocations must be at least the allocator-imposed minimum size.");
|
||||
|
||||
if (!CheckAllocatorState<allowGC>(cx, kind))
|
||||
// Off-main-thread alloc cannot trigger GC or make runtime assertions.
|
||||
if (!cx->isJSContext())
|
||||
return TryNewTenuredObject<NoGC>(cx, kind, thingSize, nDynamicSlots);
|
||||
|
||||
JSContext *ncx = cx->asJSContext();
|
||||
if (!CheckAllocatorState<allowGC>(ncx, kind))
|
||||
return nullptr;
|
||||
|
||||
if (cx->isJSContext() &&
|
||||
ShouldNurseryAllocateObject(cx->asJSContext()->nursery(), heap))
|
||||
{
|
||||
JSObject *obj = TryNewNurseryObject<allowGC>(cx->asJSContext(), thingSize, nDynamicSlots,
|
||||
clasp);
|
||||
if (ShouldNurseryAllocateObject(ncx->nursery(), heap)) {
|
||||
JSObject *obj = TryNewNurseryObject<allowGC>(ncx, thingSize, nDynamicSlots, clasp);
|
||||
if (obj)
|
||||
return obj;
|
||||
|
||||
@ -181,22 +198,7 @@ js::Allocate(ExclusiveContext *cx, AllocKind kind, size_t nDynamicSlots, Initial
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
HeapSlot *slots = nullptr;
|
||||
if (nDynamicSlots) {
|
||||
slots = cx->zone()->pod_malloc<HeapSlot>(nDynamicSlots);
|
||||
if (MOZ_UNLIKELY(!slots))
|
||||
return nullptr;
|
||||
Debug_SetSlotRangeToCrashOnTouch(slots, nDynamicSlots);
|
||||
}
|
||||
|
||||
JSObject *obj = TryNewTenuredThing<JSObject, allowGC>(cx, kind, thingSize);
|
||||
|
||||
if (obj)
|
||||
obj->setInitialSlotsMaybeNonNative(slots);
|
||||
else
|
||||
js_free(slots);
|
||||
|
||||
return obj;
|
||||
return TryNewTenuredObject<allowGC>(cx, kind, thingSize, nDynamicSlots);
|
||||
}
|
||||
template JSObject *js::Allocate<JSObject, NoGC>(ExclusiveContext *cx, gc::AllocKind kind,
|
||||
size_t nDynamicSlots, gc::InitialHeap heap,
|
||||
@ -215,10 +217,12 @@ js::Allocate(ExclusiveContext *cx)
|
||||
|
||||
AllocKind kind = MapTypeToFinalizeKind<T>::kind;
|
||||
size_t thingSize = sizeof(T);
|
||||
|
||||
MOZ_ASSERT(thingSize == Arena::thingSize(kind));
|
||||
if (!CheckAllocatorState<allowGC>(cx, kind))
|
||||
return nullptr;
|
||||
|
||||
if (cx->isJSContext()) {
|
||||
if (!CheckAllocatorState<allowGC>(cx->asJSContext(), kind))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return TryNewTenuredThing<T, allowGC>(cx, kind, thingSize);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user