зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1452982 part 3 - Remove ZoneGroup nursery/storeBuffer methods. r=jonco
This commit is contained in:
Родитель
0ee2315067
Коммит
84ec03bf15
|
@ -92,7 +92,7 @@ DataViewObject::create(JSContext* cx, uint32_t byteOffset, uint32_t byteLength,
|
|||
MOZ_ASSERT(arrayBuffer->byteLength() == 0 &&
|
||||
(uintptr_t(ptr.unwrapValue()) & gc::ChunkMask) == 0);
|
||||
} else {
|
||||
cx->zone()->group()->storeBuffer().putWholeCell(obj);
|
||||
cx->runtime()->gc.storeBuffer().putWholeCell(obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -266,7 +266,7 @@ MapIteratorObject::finalize(FreeOp* fop, JSObject* obj)
|
|||
MOZ_ASSERT(!IsInsideNursery(obj));
|
||||
|
||||
auto range = MapIteratorObjectRange(&obj->as<NativeObject>());
|
||||
MOZ_ASSERT(!obj->zone()->group()->nursery().isInside(range));
|
||||
MOZ_ASSERT(!fop->runtime()->gc.nursery().isInside(range));
|
||||
|
||||
fop->delete_(range);
|
||||
}
|
||||
|
@ -282,7 +282,7 @@ MapIteratorObject::objectMoved(JSObject* obj, JSObject* old)
|
|||
if (!range)
|
||||
return 0;
|
||||
|
||||
Nursery& nursery = iter->zone()->group()->nursery();
|
||||
Nursery& nursery = iter->runtimeFromActiveCooperatingThread()->gc.nursery();
|
||||
if (!nursery.isInside(range)) {
|
||||
nursery.removeMallocedBuffer(range);
|
||||
return 0;
|
||||
|
@ -567,7 +567,8 @@ WriteBarrierPostImpl(ObjectT* obj, const Value& keyValue)
|
|||
if (!keys)
|
||||
return false;
|
||||
|
||||
key->zone()->group()->storeBuffer().putGeneric(OrderedHashTableRef<ObjectT>(obj));
|
||||
JSRuntime* rt = key->runtimeFromActiveCooperatingThread();
|
||||
rt->gc.storeBuffer().putGeneric(OrderedHashTableRef<ObjectT>(obj));
|
||||
}
|
||||
|
||||
if (!keys->append(key))
|
||||
|
@ -1116,7 +1117,7 @@ SetIteratorObject::finalize(FreeOp* fop, JSObject* obj)
|
|||
MOZ_ASSERT(!IsInsideNursery(obj));
|
||||
|
||||
auto range = SetIteratorObjectRange(&obj->as<NativeObject>());
|
||||
MOZ_ASSERT(!obj->zone()->group()->nursery().isInside(range));
|
||||
MOZ_ASSERT(!fop->runtime()->gc.nursery().isInside(range));
|
||||
|
||||
fop->delete_(range);
|
||||
}
|
||||
|
@ -1132,7 +1133,7 @@ SetIteratorObject::objectMoved(JSObject* obj, JSObject* old)
|
|||
if (!range)
|
||||
return 0;
|
||||
|
||||
Nursery& nursery = iter->zone()->group()->nursery();
|
||||
Nursery& nursery = iter->runtimeFromActiveCooperatingThread()->gc.nursery();
|
||||
if (!nursery.isInside(range)) {
|
||||
nursery.removeMallocedBuffer(range);
|
||||
return 0;
|
||||
|
|
|
@ -352,7 +352,7 @@ MinorGC(JSContext* cx, unsigned argc, Value* vp)
|
|||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
if (args.get(0) == BooleanValue(true))
|
||||
cx->zone()->group()->storeBuffer().setAboutToOverflow(JS::gcreason::FULL_GENERIC_BUFFER);
|
||||
cx->runtime()->gc.storeBuffer().setAboutToOverflow(JS::gcreason::FULL_GENERIC_BUFFER);
|
||||
|
||||
cx->minorGC(JS::gcreason::API);
|
||||
args.rval().setUndefined();
|
||||
|
|
|
@ -1434,7 +1434,7 @@ OutlineTypedObject::setOwnerAndData(JSObject* owner, uint8_t* data)
|
|||
// Trigger a post barrier when attaching an object outside the nursery to
|
||||
// one that is inside it.
|
||||
if (owner && !IsInsideNursery(this) && IsInsideNursery(owner))
|
||||
zone()->group()->storeBuffer().putWholeCell(this);
|
||||
owner->storeBuffer()->putWholeCell(this);
|
||||
}
|
||||
|
||||
/*static*/ OutlineTypedObject*
|
||||
|
@ -1634,7 +1634,7 @@ OutlineTypedObject::obj_trace(JSTracer* trc, JSObject* object)
|
|||
typedObj.setData(newData);
|
||||
|
||||
if (trc->isTenuringTracer()) {
|
||||
Nursery& nursery = typedObj.zoneFromAnyThread()->group()->nursery();
|
||||
Nursery& nursery = trc->runtime()->gc.nursery();
|
||||
nursery.maybeSetForwardingPointer(trc, oldData, newData, /* direct = */ false);
|
||||
}
|
||||
}
|
||||
|
@ -2144,7 +2144,7 @@ InlineTypedObject::obj_moved(JSObject* dst, JSObject* src)
|
|||
// but they will not set any direct forwarding pointers.
|
||||
uint8_t* oldData = reinterpret_cast<uint8_t*>(src) + offsetOfDataStart();
|
||||
uint8_t* newData = dst->as<InlineTypedObject>().inlineTypedMem();
|
||||
auto& nursery = dst->zone()->group()->nursery();
|
||||
auto& nursery = dst->runtimeFromActiveCooperatingThread()->gc.nursery();
|
||||
bool direct = descr.size() >= sizeof(uintptr_t);
|
||||
nursery.setForwardingPointerWhileTenuring(oldData, newData, direct);
|
||||
}
|
||||
|
@ -2195,7 +2195,7 @@ InlineTransparentTypedObject::getOrCreateBuffer(JSContext* cx)
|
|||
if (IsInsideNursery(this)) {
|
||||
// Make sure the buffer is traced by the next generational collection,
|
||||
// so that its data pointer is updated after this typed object moves.
|
||||
zone()->group()->storeBuffer().putWholeCell(buffer);
|
||||
storeBuffer()->putWholeCell(buffer);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
|
|
|
@ -207,7 +207,8 @@ class ZoneCellIter<TenuredCell> {
|
|||
|
||||
void init(JS::Zone* zone, AllocKind kind) {
|
||||
MOZ_ASSERT_IF(IsNurseryAllocable(kind),
|
||||
zone->isAtomsZone() || zone->group()->nursery().isEmpty());
|
||||
(zone->isAtomsZone() ||
|
||||
zone->runtimeFromActiveCooperatingThread()->gc.nursery().isEmpty()));
|
||||
initForTenuredIteration(zone, kind);
|
||||
}
|
||||
|
||||
|
|
|
@ -1065,10 +1065,8 @@ GCRuntime::setZeal(uint8_t zeal, uint32_t frequency)
|
|||
}
|
||||
|
||||
ZealMode zealMode = ZealMode(zeal);
|
||||
if (zealMode == ZealMode::GenerationalGC) {
|
||||
for (ZoneGroupsIter group(rt); !group.done(); group.next())
|
||||
group->nursery().enterZealMode();
|
||||
}
|
||||
if (zealMode == ZealMode::GenerationalGC)
|
||||
nursery().enterZealMode();
|
||||
|
||||
// Some modes are mutually exclusive. If we're setting one of those, we
|
||||
// first reset all of them.
|
||||
|
@ -1282,8 +1280,7 @@ GCRuntime::finish()
|
|||
|
||||
FinishTrace();
|
||||
|
||||
for (ZoneGroupsIter group(rt); !group.done(); group.next())
|
||||
group->nursery().printTotalProfileTimes();
|
||||
nursery().printTotalProfileTimes();
|
||||
stats().printTotalProfileTimes();
|
||||
}
|
||||
|
||||
|
@ -6609,7 +6606,7 @@ GCRuntime::compactPhase(JS::gcreason::Reason reason, SliceBudget& sliceBudget,
|
|||
Zone* zone = zonesToMaybeCompact.ref().front();
|
||||
zonesToMaybeCompact.ref().removeFront();
|
||||
|
||||
MOZ_ASSERT(zone->group()->nursery().isEmpty());
|
||||
MOZ_ASSERT(nursery().isEmpty());
|
||||
zone->changeGCState(Zone::Finished, Zone::Compact);
|
||||
|
||||
if (relocateArenas(zone, reason, relocatedArenas, sliceBudget)) {
|
||||
|
@ -6699,18 +6696,6 @@ HeapStateToLabel(JS::HeapState heapState)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static bool
|
||||
AllNurseriesAreEmpty(JSRuntime* rt)
|
||||
{
|
||||
for (ZoneGroupsIter group(rt); !group.done(); group.next()) {
|
||||
if (!group->nursery().isEmpty())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Start a new heap session. */
|
||||
AutoTraceSession::AutoTraceSession(JSRuntime* rt, JS::HeapState heapState)
|
||||
: runtime(rt),
|
||||
|
@ -6720,7 +6705,7 @@ AutoTraceSession::AutoTraceSession(JSRuntime* rt, JS::HeapState heapState)
|
|||
{
|
||||
MOZ_ASSERT(prevState == JS::HeapState::Idle);
|
||||
MOZ_ASSERT(heapState != JS::HeapState::Idle);
|
||||
MOZ_ASSERT_IF(heapState == JS::HeapState::MajorCollecting, AllNurseriesAreEmpty(rt));
|
||||
MOZ_ASSERT_IF(heapState == JS::HeapState::MajorCollecting, rt->gc.nursery().isEmpty());
|
||||
|
||||
// Session always begins with lock held, see comment in class definition.
|
||||
maybeLock.emplace(rt);
|
||||
|
@ -7691,8 +7676,7 @@ GCRuntime::onOutOfMallocMemory()
|
|||
decommitTask.join();
|
||||
|
||||
// Wait for background free of nursery huge slots to finish.
|
||||
for (ZoneGroupsIter group(rt); !group.done(); group.next())
|
||||
group->nursery().waitBackgroundFreeEnd();
|
||||
nursery().waitBackgroundFreeEnd();
|
||||
|
||||
AutoLockGC lock(rt);
|
||||
onOutOfMallocMemory(lock);
|
||||
|
@ -7756,10 +7740,8 @@ JS::AutoDisableGenerationalGC::AutoDisableGenerationalGC(JSContext* cx)
|
|||
|
||||
JS::AutoDisableGenerationalGC::~AutoDisableGenerationalGC()
|
||||
{
|
||||
if (--cx->generationalDisabled == 0) {
|
||||
for (ZoneGroupsIter group(cx->runtime()); !group.done(); group.next())
|
||||
group->nursery().enable();
|
||||
}
|
||||
if (--cx->generationalDisabled == 0)
|
||||
cx->nursery().enable();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
|
@ -7804,8 +7786,7 @@ js::gc::FinishGC(JSContext* cx)
|
|||
JS::FinishIncrementalGC(cx, JS::gcreason::API);
|
||||
}
|
||||
|
||||
for (ZoneGroupsIter group(cx->runtime()); !group.done(); group.next())
|
||||
group->nursery().waitBackgroundFreeEnd();
|
||||
cx->nursery().waitBackgroundFreeEnd();
|
||||
}
|
||||
|
||||
AutoPrepareForTracing::AutoPrepareForTracing(JSContext* cx)
|
||||
|
@ -7858,9 +7839,6 @@ js::NewCompartment(JSContext* cx, JSPrincipals* principals,
|
|||
return nullptr;
|
||||
|
||||
groupHolder.reset(group);
|
||||
|
||||
if (cx->generationalDisabled)
|
||||
group->nursery().disable();
|
||||
}
|
||||
|
||||
if (!zone) {
|
||||
|
@ -8942,7 +8920,7 @@ AutoAssertEmptyNursery::checkCondition(JSContext* cx) {
|
|||
if (!noAlloc)
|
||||
noAlloc.emplace();
|
||||
this->cx = cx;
|
||||
MOZ_ASSERT(AllNurseriesAreEmpty(cx->runtime()));
|
||||
MOZ_ASSERT(cx->nursery().isEmpty());
|
||||
}
|
||||
|
||||
AutoEmptyNursery::AutoEmptyNursery(JSContext* cx)
|
||||
|
@ -8950,7 +8928,7 @@ AutoEmptyNursery::AutoEmptyNursery(JSContext* cx)
|
|||
{
|
||||
MOZ_ASSERT(!cx->suppressGC);
|
||||
cx->runtime()->gc.stats().suspendPhases();
|
||||
EvictAllNurseries(cx->runtime(), JS::gcreason::EVICT_NURSERY);
|
||||
cx->runtime()->gc.evictNursery(JS::gcreason::EVICT_NURSERY);
|
||||
cx->runtime()->gc.stats().resumePhases();
|
||||
checkCondition(cx);
|
||||
}
|
||||
|
|
|
@ -139,12 +139,6 @@ ReallocateObjectBuffer(JSContext* cx, JSObject* obj, T* oldBuffer,
|
|||
return buffer;
|
||||
}
|
||||
|
||||
static inline void
|
||||
EvictAllNurseries(JSRuntime* rt, JS::gcreason::Reason reason = JS::gcreason::EVICT_NURSERY)
|
||||
{
|
||||
rt->gc.evictNursery(reason);
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
|
||||
#endif /* gc_Nursery_inl_h */
|
||||
|
|
|
@ -284,8 +284,8 @@ js::TraceRuntime(JSTracer* trc)
|
|||
MOZ_ASSERT(!trc->isMarkingTracer());
|
||||
|
||||
JSRuntime* rt = trc->runtime();
|
||||
EvictAllNurseries(rt);
|
||||
AutoPrepareForTracing prep(TlsContext.get());
|
||||
rt->gc.evictNursery();
|
||||
AutoPrepareForTracing prep(rt->mainContextFromOwnThread());
|
||||
gcstats::AutoPhase ap(rt->gc.stats(), gcstats::PhaseKind::TRACE_HEAP);
|
||||
rt->gc.traceRuntime(trc, prep.session());
|
||||
}
|
||||
|
|
|
@ -138,8 +138,8 @@ ArenaCellSet*
|
|||
StoreBuffer::WholeCellBuffer::allocateCellSet(Arena* arena)
|
||||
{
|
||||
Zone* zone = arena->zone;
|
||||
Nursery& nursery = zone->group()->nursery();
|
||||
if (!nursery.isEnabled())
|
||||
JSRuntime* rt = zone->runtimeFromActiveCooperatingThread();
|
||||
if (!rt->gc.nursery().isEnabled())
|
||||
return nullptr;
|
||||
|
||||
AutoEnterOOMUnsafeRegion oomUnsafe;
|
||||
|
@ -151,7 +151,7 @@ StoreBuffer::WholeCellBuffer::allocateCellSet(Arena* arena)
|
|||
head_ = cells;
|
||||
|
||||
if (isAboutToOverflow())
|
||||
zone->group()->storeBuffer().setAboutToOverflow(JS::gcreason::FULL_WHOLE_CELL_BUFFER);
|
||||
rt->gc.storeBuffer().setAboutToOverflow(JS::gcreason::FULL_WHOLE_CELL_BUFFER);
|
||||
|
||||
return cells;
|
||||
}
|
||||
|
|
|
@ -582,7 +582,9 @@ struct Zone : public JS::shadow::Zone,
|
|||
// If the cell was in the nursery, hopefully unlikely, then we need to
|
||||
// tell the nursery about it so that it can sweep the uid if the thing
|
||||
// does not get tenured.
|
||||
if (IsInsideNursery(cell) && !group()->nursery().addedUniqueIdToCell(cell)) {
|
||||
if (IsInsideNursery(cell) &&
|
||||
!runtimeFromActiveCooperatingThread()->gc.nursery().addedUniqueIdToCell(cell))
|
||||
{
|
||||
uniqueIds().remove(cell);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -82,12 +82,6 @@ class ZoneGroup
|
|||
explicit ZoneGroup(JSRuntime* runtime);
|
||||
~ZoneGroup();
|
||||
|
||||
inline Nursery& nursery();
|
||||
inline gc::StoreBuffer& storeBuffer();
|
||||
|
||||
inline bool isCollecting();
|
||||
inline bool isGCScheduled();
|
||||
|
||||
// Delete an empty zone after its contents have been merged.
|
||||
void deleteEmptyZone(Zone* zone);
|
||||
|
||||
|
|
|
@ -10488,7 +10488,7 @@ CodeGenerator::link(JSContext* cx, CompilerConstraintList* constraints)
|
|||
for (size_t i = 0; i < graph.numConstants(); i++) {
|
||||
const Value& v = vp[i];
|
||||
if ((v.isObject() || v.isString()) && IsInsideNursery(v.toGCThing())) {
|
||||
cx->zone()->group()->storeBuffer().putWholeCell(script);
|
||||
cx->runtime()->gc.storeBuffer().putWholeCell(script);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -212,21 +212,22 @@ bool
|
|||
CompileZone::canNurseryAllocateStrings()
|
||||
{
|
||||
return nurseryExists() &&
|
||||
zone()->group()->nursery().canAllocateStrings() &&
|
||||
zone()->runtimeFromAnyThread()->gc.nursery().canAllocateStrings() &&
|
||||
zone()->allocNurseryStrings;
|
||||
}
|
||||
|
||||
bool
|
||||
CompileZone::nurseryExists()
|
||||
{
|
||||
return zone()->group()->nursery().exists();
|
||||
return zone()->runtimeFromAnyThread()->gc.nursery().exists();
|
||||
}
|
||||
|
||||
void
|
||||
CompileZone::setMinorGCShouldCancelIonCompilations()
|
||||
{
|
||||
MOZ_ASSERT(CurrentThreadCanAccessZone(zone()));
|
||||
zone()->group()->storeBuffer().setShouldCancelIonCompilations();
|
||||
JSRuntime* rt = zone()->runtimeFromActiveCooperatingThread();
|
||||
rt->gc.storeBuffer().setShouldCancelIonCompilations();
|
||||
}
|
||||
|
||||
JSCompartment*
|
||||
|
|
|
@ -2086,7 +2086,7 @@ IonCompile(JSContext* cx, JSScript* script,
|
|||
if (!builder)
|
||||
return AbortReason::Alloc;
|
||||
|
||||
if (cx->zone()->group()->storeBuffer().cancelIonCompilations())
|
||||
if (cx->runtime()->gc.storeBuffer().cancelIonCompilations())
|
||||
builder->setNotSafeForMinorGC();
|
||||
|
||||
MOZ_ASSERT(recompile == builder->script()->hasIonScript());
|
||||
|
|
|
@ -8647,7 +8647,7 @@ IonBuilder::addTypedArrayLengthAndData(MDefinition* obj,
|
|||
SharedMem<void*> data = tarr->as<TypedArrayObject>().viewDataEither();
|
||||
// Bug 979449 - Optimistically embed the elements and use TI to
|
||||
// invalidate if we move them.
|
||||
bool isTenured = !tarr->zone()->group()->nursery().isInside(data);
|
||||
bool isTenured = !tarr->runtimeFromActiveCooperatingThread()->gc.nursery().isInside(data);
|
||||
if (isTenured && tarr->isSingleton()) {
|
||||
// The 'data' pointer of TypedArrayObject can change in rare circumstances
|
||||
// (ArrayBufferObject::changeContents).
|
||||
|
|
|
@ -975,7 +975,7 @@ TraceBailoutFrame(JSTracer* trc, const JSJitFrameIter& frame)
|
|||
}
|
||||
|
||||
static void
|
||||
UpdateIonJSFrameForMinorGC(const JSJitFrameIter& frame)
|
||||
UpdateIonJSFrameForMinorGC(JSRuntime* rt, const JSJitFrameIter& frame)
|
||||
{
|
||||
// Minor GCs may move slots/elements allocated in the nursery. Update
|
||||
// any slots/elements pointers stored in this frame.
|
||||
|
@ -991,7 +991,7 @@ UpdateIonJSFrameForMinorGC(const JSJitFrameIter& frame)
|
|||
ionScript = frame.ionScriptFromCalleeToken();
|
||||
}
|
||||
|
||||
Nursery& nursery = ionScript->method()->zone()->group()->nursery();
|
||||
Nursery& nursery = rt->gc.nursery();
|
||||
|
||||
const SafepointIndex* si = ionScript->getSafepointIndex(frame.returnAddressToFp());
|
||||
SafepointReader safepoint(ionScript, si);
|
||||
|
@ -1315,7 +1315,7 @@ UpdateJitActivationsForMinorGC(JSRuntime* rt)
|
|||
for (JitActivationIterator activations(cx); !activations.done(); ++activations) {
|
||||
for (OnlyJSJitFrameIter iter(activations); !iter.done(); ++iter) {
|
||||
if (iter.frame().type() == JitFrame_IonJS)
|
||||
UpdateIonJSFrameForMinorGC(iter.frame());
|
||||
UpdateIonJSFrameForMinorGC(rt, iter.frame());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ Linker::newCode(JSContext* cx, CodeKind kind)
|
|||
code->copyFrom(masm);
|
||||
masm.link(code);
|
||||
if (masm.embedsNurseryPointers())
|
||||
cx->zone()->group()->storeBuffer().putWholeCell(code);
|
||||
cx->runtime()->gc.storeBuffer().putWholeCell(code);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
|
@ -962,8 +962,8 @@ jit::IonCompilationCanUseNurseryPointers()
|
|||
// Otherwise, we must be on the active thread during MIR construction. The
|
||||
// store buffer must have been notified that minor GCs must cancel pending
|
||||
// or in progress Ion compilations.
|
||||
JSContext* cx = TlsContext.get();
|
||||
return cx->zone()->group()->storeBuffer().cancelIonCompilations();
|
||||
JSRuntime* rt = TlsContext.get()->zone()->runtimeFromActiveCooperatingThread();
|
||||
return rt->gc.storeBuffer().cancelIonCompilations();
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
||||
|
|
|
@ -579,7 +579,7 @@ NewCallObject(JSContext* cx, HandleShape shape, HandleObjectGroup group)
|
|||
// the initializing writes. The interpreter, however, may have allocated
|
||||
// the call object tenured, so barrier as needed before re-entering.
|
||||
if (!IsInsideNursery(obj))
|
||||
cx->zone()->group()->storeBuffer().putWholeCell(obj);
|
||||
cx->runtime()->gc.storeBuffer().putWholeCell(obj);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
@ -596,7 +596,7 @@ NewSingletonCallObject(JSContext* cx, HandleShape shape)
|
|||
// the call object tenured, so barrier as needed before re-entering.
|
||||
MOZ_ASSERT(!IsInsideNursery(obj),
|
||||
"singletons are created in the tenured heap");
|
||||
cx->zone()->group()->storeBuffer().putWholeCell(obj);
|
||||
cx->runtime()->gc.storeBuffer().putWholeCell(obj);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
|
|
@ -1062,7 +1062,8 @@ CodeGeneratorShared::verifyCompactTrackedOptimizationsMap(JitCode* code, uint32_
|
|||
// decoded. This is disabled for now if the types table might
|
||||
// contain nursery pointers, in which case the types might not
|
||||
// match, see bug 1175761.
|
||||
if (!code->zone()->group()->storeBuffer().cancelIonCompilations()) {
|
||||
JSRuntime* rt = code->runtimeFromActiveCooperatingThread();
|
||||
if (!rt->gc.storeBuffer().cancelIonCompilations()) {
|
||||
IonTrackedOptimizationsTypeInfo typeInfo = typesTable->entry(index);
|
||||
TempOptimizationTypeInfoVector tvec(alloc());
|
||||
ReadTempTypeInfoVectorOp top(alloc(), &tvec);
|
||||
|
|
|
@ -1219,7 +1219,7 @@ void
|
|||
js::DumpHeap(JSContext* cx, FILE* fp, js::DumpHeapNurseryBehaviour nurseryBehaviour)
|
||||
{
|
||||
if (nurseryBehaviour == js::CollectNurseryBeforeDump)
|
||||
EvictAllNurseries(cx->runtime(), JS::gcreason::API);
|
||||
cx->runtime()->gc.evictNursery(JS::gcreason::API);
|
||||
|
||||
DumpHeapTracer dtrc(fp, cx);
|
||||
|
||||
|
|
|
@ -706,7 +706,7 @@ js::RecomputeWrappers(JSContext* cx, const CompartmentFilter& sourceFilter,
|
|||
continue;
|
||||
|
||||
if (!evictedNursery && c->hasNurseryAllocatedWrapperEntries(targetFilter)) {
|
||||
EvictAllNurseries(cx->runtime());
|
||||
cx->runtime()->gc.evictNursery();
|
||||
evictedNursery = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -868,7 +868,7 @@ ArgumentsObject::objectMoved(JSObject* dst, JSObject* src)
|
|||
if (!IsInsideNursery(src))
|
||||
return 0;
|
||||
|
||||
Nursery& nursery = dst->zone()->group()->nursery();
|
||||
Nursery& nursery = dst->runtimeFromActiveCooperatingThread()->gc.nursery();
|
||||
|
||||
size_t nbytesTotal = 0;
|
||||
if (!nursery.isInside(nsrc->data())) {
|
||||
|
|
|
@ -1653,7 +1653,7 @@ ArrayBufferViewObject::trace(JSTracer* trc, JSObject* objArg)
|
|||
// not be enough bytes available, and other views might have data
|
||||
// pointers whose forwarding pointers would overlap this one.
|
||||
if (trc->isTenuringTracer()) {
|
||||
Nursery& nursery = obj->zoneFromAnyThread()->group()->nursery();
|
||||
Nursery& nursery = trc->runtime()->gc.nursery();
|
||||
nursery.maybeSetForwardingPointer(trc, srcData, dstData, /* direct = */ false);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -1558,13 +1558,13 @@ JSObject::fixDictionaryShapeAfterSwap()
|
|||
}
|
||||
|
||||
static MOZ_MUST_USE bool
|
||||
CopyProxyValuesBeforeSwap(ProxyObject* proxy, Vector<Value>& values)
|
||||
CopyProxyValuesBeforeSwap(JSContext* cx, ProxyObject* proxy, Vector<Value>& values)
|
||||
{
|
||||
MOZ_ASSERT(values.empty());
|
||||
|
||||
// Remove the GCPtrValues we're about to swap from the store buffer, to
|
||||
// ensure we don't trace bogus values.
|
||||
StoreBuffer& sb = proxy->zone()->group()->storeBuffer();
|
||||
StoreBuffer& sb = cx->runtime()->gc.storeBuffer();
|
||||
|
||||
// Reserve space for the private slot and the reserved slots.
|
||||
if (!values.reserve(1 + proxy->numReservedSlots()))
|
||||
|
@ -1635,8 +1635,8 @@ JSObject::swap(JSContext* cx, HandleObject a, HandleObject b)
|
|||
* nursery pointers in either object.
|
||||
*/
|
||||
MOZ_ASSERT(!IsInsideNursery(a) && !IsInsideNursery(b));
|
||||
cx->zone()->group()->storeBuffer().putWholeCell(a);
|
||||
cx->zone()->group()->storeBuffer().putWholeCell(b);
|
||||
cx->runtime()->gc.storeBuffer().putWholeCell(a);
|
||||
cx->runtime()->gc.storeBuffer().putWholeCell(b);
|
||||
|
||||
unsigned r = NotifyGCPreSwap(a, b);
|
||||
|
||||
|
@ -1722,11 +1722,11 @@ JSObject::swap(JSContext* cx, HandleObject a, HandleObject b)
|
|||
ProxyObject* proxyB = b->is<ProxyObject>() ? &b->as<ProxyObject>() : nullptr;
|
||||
|
||||
if (aIsProxyWithInlineValues) {
|
||||
if (!CopyProxyValuesBeforeSwap(proxyA, avals))
|
||||
if (!CopyProxyValuesBeforeSwap(cx, proxyA, avals))
|
||||
oomUnsafe.crash("CopyProxyValuesBeforeSwap");
|
||||
}
|
||||
if (bIsProxyWithInlineValues) {
|
||||
if (!CopyProxyValuesBeforeSwap(proxyB, bvals))
|
||||
if (!CopyProxyValuesBeforeSwap(cx, proxyB, bvals))
|
||||
oomUnsafe.crash("CopyProxyValuesBeforeSwap");
|
||||
}
|
||||
|
||||
|
@ -3885,7 +3885,7 @@ JSObject::sizeOfIncludingThisInNursery() const
|
|||
|
||||
MOZ_ASSERT(!isTenured());
|
||||
|
||||
const Nursery& nursery = zone()->group()->nursery();
|
||||
const Nursery& nursery = runtimeFromActiveCooperatingThread()->gc.nursery();
|
||||
size_t size = Arena::thingSize(allocKindForTenure(nursery));
|
||||
|
||||
if (is<NativeObject>()) {
|
||||
|
|
|
@ -124,9 +124,10 @@ NativeObject::elementsRangeWriteBarrierPost(uint32_t start, uint32_t count)
|
|||
for (size_t i = 0; i < count; i++) {
|
||||
const Value& v = elements_[start + i];
|
||||
if ((v.isObject() || v.isString()) && IsInsideNursery(v.toGCThing())) {
|
||||
zone()->group()->storeBuffer().putSlot(this, HeapSlot::Element,
|
||||
unshiftedIndex(start + i),
|
||||
count - i);
|
||||
JSRuntime* rt = runtimeFromActiveCooperatingThread();
|
||||
rt->gc.storeBuffer().putSlot(this, HeapSlot::Element,
|
||||
unshiftedIndex(start + i),
|
||||
count - i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1146,18 +1146,6 @@ SetValueRangeToNull(Value* vec, size_t len)
|
|||
|
||||
extern const JSSecurityCallbacks NullSecurityCallbacks;
|
||||
|
||||
inline Nursery&
|
||||
ZoneGroup::nursery()
|
||||
{
|
||||
return runtime->gc.nursery();
|
||||
}
|
||||
|
||||
inline gc::StoreBuffer&
|
||||
ZoneGroup::storeBuffer()
|
||||
{
|
||||
return runtime->gc.storeBuffer();
|
||||
}
|
||||
|
||||
// This callback is set by JS::SetProcessLargeAllocationFailureCallback
|
||||
// and may be null. See comment in jsapi.h.
|
||||
extern mozilla::Atomic<JS::LargeAllocationFailureCallback> OnLargeAllocationFailure;
|
||||
|
|
|
@ -510,7 +510,7 @@ JSRope::flattenInternal(JSContext* maybecx)
|
|||
left.d.u1.flags = DEPENDENT_FLAGS | LATIN1_CHARS_BIT;
|
||||
left.d.s.u3.base = (JSLinearString*)this; /* will be true on exit */
|
||||
BarrierMethods<JSString*>::postBarrier((JSString**)&left.d.s.u3.base, nullptr, this);
|
||||
Nursery& nursery = zone()->group()->nursery();
|
||||
Nursery& nursery = runtimeFromActiveCooperatingThread()->gc.nursery();
|
||||
if (isTenured() && !left.isTenured())
|
||||
nursery.removeMallocedBuffer(wholeChars);
|
||||
else if (!isTenured() && left.isTenured())
|
||||
|
@ -526,7 +526,7 @@ JSRope::flattenInternal(JSContext* maybecx)
|
|||
}
|
||||
|
||||
if (!isTenured()) {
|
||||
Nursery& nursery = zone()->group()->nursery();
|
||||
Nursery& nursery = runtimeFromActiveCooperatingThread()->gc.nursery();
|
||||
if (!nursery.registerMallocedBuffer(wholeChars)) {
|
||||
js_free(wholeChars);
|
||||
if (maybecx)
|
||||
|
|
|
@ -685,8 +685,8 @@ void
|
|||
ConstraintTypeSet::postWriteBarrier(JSContext* cx, Type type)
|
||||
{
|
||||
if (type.isSingletonUnchecked() && IsInsideNursery(type.singletonNoBarrier())) {
|
||||
cx->zone()->group()->storeBuffer().putGeneric(TypeSetRef(cx->zone(), this));
|
||||
cx->zone()->group()->storeBuffer().setShouldCancelIonCompilations();
|
||||
cx->runtime()->gc.storeBuffer().putGeneric(TypeSetRef(cx->zone(), this));
|
||||
cx->runtime()->gc.storeBuffer().setShouldCancelIonCompilations();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -196,7 +196,7 @@ TypedArrayObject::objectMoved(JSObject* obj, JSObject* old)
|
|||
return 0;
|
||||
}
|
||||
|
||||
Nursery& nursery = obj->zone()->group()->nursery();
|
||||
Nursery& nursery = obj->runtimeFromActiveCooperatingThread()->gc.nursery();
|
||||
void* buf = oldObj->elements();
|
||||
|
||||
if (!nursery.isInside(buf)) {
|
||||
|
@ -494,7 +494,7 @@ class TypedArrayObjectTemplate : public TypedArrayObject
|
|||
MOZ_ASSERT(buffer->byteLength() == 0 &&
|
||||
(uintptr_t(ptr.unwrapValue()) & gc::ChunkMask) == 0);
|
||||
} else {
|
||||
cx->zone()->group()->storeBuffer().putWholeCell(obj);
|
||||
cx->runtime()->gc.storeBuffer().putWholeCell(obj);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -47,54 +47,6 @@ GetUnboxedValue(uint8_t* p, JSValueType type, bool maybeUninitialized)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
SetUnboxedValueNoTypeChange(JSObject* unboxedObject,
|
||||
uint8_t* p, JSValueType type, const Value& v,
|
||||
bool preBarrier)
|
||||
{
|
||||
switch (type) {
|
||||
case JSVAL_TYPE_BOOLEAN:
|
||||
*p = v.toBoolean();
|
||||
return;
|
||||
|
||||
case JSVAL_TYPE_INT32:
|
||||
*reinterpret_cast<int32_t*>(p) = v.toInt32();
|
||||
return;
|
||||
|
||||
case JSVAL_TYPE_DOUBLE:
|
||||
*reinterpret_cast<double*>(p) = v.toNumber();
|
||||
return;
|
||||
|
||||
case JSVAL_TYPE_STRING: {
|
||||
MOZ_ASSERT(!IsInsideNursery(v.toString()));
|
||||
JSString** np = reinterpret_cast<JSString**>(p);
|
||||
if (preBarrier)
|
||||
JSString::writeBarrierPre(*np);
|
||||
*np = v.toString();
|
||||
return;
|
||||
}
|
||||
|
||||
case JSVAL_TYPE_OBJECT: {
|
||||
JSObject** np = reinterpret_cast<JSObject**>(p);
|
||||
|
||||
// Manually trigger post barriers on the whole object. If we treat
|
||||
// the pointer as a HeapPtrObject we will get confused later if the
|
||||
// object is converted to its native representation.
|
||||
JSObject* obj = v.toObjectOrNull();
|
||||
if (IsInsideNursery(obj) && !IsInsideNursery(unboxedObject))
|
||||
unboxedObject->zone()->group()->storeBuffer().putWholeCell(unboxedObject);
|
||||
|
||||
if (preBarrier)
|
||||
JSObject::writeBarrierPre(*np);
|
||||
*np = obj;
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Invalid type for unboxed value");
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool
|
||||
SetUnboxedValue(JSContext* cx, JSObject* unboxedObject, jsid id,
|
||||
uint8_t* p, JSValueType type, const Value& v, bool preBarrier)
|
||||
|
@ -125,7 +77,7 @@ SetUnboxedValue(JSContext* cx, JSObject* unboxedObject, jsid id,
|
|||
if (v.isString()) {
|
||||
JSString** np = reinterpret_cast<JSString**>(p);
|
||||
if (IsInsideNursery(v.toString()) && !IsInsideNursery(unboxedObject))
|
||||
unboxedObject->zone()->group()->storeBuffer().putWholeCell(unboxedObject);
|
||||
v.toString()->storeBuffer()->putWholeCell(unboxedObject);
|
||||
|
||||
if (preBarrier)
|
||||
JSString::writeBarrierPre(*np);
|
||||
|
@ -145,8 +97,8 @@ SetUnboxedValue(JSContext* cx, JSObject* unboxedObject, jsid id,
|
|||
|
||||
// As above, trigger post barriers on the whole object.
|
||||
JSObject* obj = v.toObjectOrNull();
|
||||
if (IsInsideNursery(v.toObjectOrNull()) && !IsInsideNursery(unboxedObject))
|
||||
unboxedObject->zone()->group()->storeBuffer().putWholeCell(unboxedObject);
|
||||
if (IsInsideNursery(obj) && !IsInsideNursery(unboxedObject))
|
||||
obj->storeBuffer()->putWholeCell(unboxedObject);
|
||||
|
||||
if (preBarrier)
|
||||
JSObject::writeBarrierPre(*np);
|
||||
|
|
|
@ -384,7 +384,7 @@ UnboxedPlainObject::ensureExpando(JSContext* cx, Handle<UnboxedPlainObject*> obj
|
|||
// convert the object to its native representation, we will end up with a
|
||||
// corrupted store buffer entry.
|
||||
if (IsInsideNursery(expando) && !IsInsideNursery(obj))
|
||||
cx->zone()->group()->storeBuffer().putWholeCell(obj);
|
||||
expando->storeBuffer()->putWholeCell(obj);
|
||||
|
||||
obj->setExpandoUnsafe(expando);
|
||||
return expando;
|
||||
|
@ -599,7 +599,7 @@ UnboxedPlainObject::convertToNative(JSContext* cx, JSObject* obj)
|
|||
// writes to the expando (see WholeCellEdges::trace), so after conversion
|
||||
// we need to make sure the expando itself will still be traced.
|
||||
if (expando && !IsInsideNursery(expando))
|
||||
cx->zone()->group()->storeBuffer().putWholeCell(expando);
|
||||
cx->runtime()->gc.storeBuffer().putWholeCell(expando);
|
||||
|
||||
obj->setGroup(layout.nativeGroup());
|
||||
obj->as<PlainObject>().setLastPropertyMakeNative(cx, layout.nativeShape());
|
||||
|
|
Загрузка…
Ссылка в новой задаче