mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-21 22:57:31 +09:00
Remove unboxed objects from GC
This commit is contained in:
parent
d7714885d1
commit
d73dc74bd1
3 changed files with 3 additions and 118 deletions
|
|
@ -18,6 +18,7 @@
|
||||||
#include "builtin/ModuleObject.h"
|
#include "builtin/ModuleObject.h"
|
||||||
#include "gc/GCInternals.h"
|
#include "gc/GCInternals.h"
|
||||||
#include "gc/Policy.h"
|
#include "gc/Policy.h"
|
||||||
|
#include "gc/StoreBuffer-inl.h"
|
||||||
#include "jit/IonCode.h"
|
#include "jit/IonCode.h"
|
||||||
#include "js/SliceBudget.h"
|
#include "js/SliceBudget.h"
|
||||||
#include "vm/ArgumentsObject.h"
|
#include "vm/ArgumentsObject.h"
|
||||||
|
|
@ -28,7 +29,6 @@
|
||||||
#include "vm/Shape.h"
|
#include "vm/Shape.h"
|
||||||
#include "vm/Symbol.h"
|
#include "vm/Symbol.h"
|
||||||
#include "vm/TypedArrayObject.h"
|
#include "vm/TypedArrayObject.h"
|
||||||
#include "vm/UnboxedObject.h"
|
|
||||||
#include "wasm/WasmJS.h"
|
#include "wasm/WasmJS.h"
|
||||||
|
|
||||||
#include "jscompartmentinlines.h"
|
#include "jscompartmentinlines.h"
|
||||||
|
|
@ -37,7 +37,6 @@
|
||||||
|
|
||||||
#include "gc/Nursery-inl.h"
|
#include "gc/Nursery-inl.h"
|
||||||
#include "vm/String-inl.h"
|
#include "vm/String-inl.h"
|
||||||
#include "vm/UnboxedObject-inl.h"
|
|
||||||
|
|
||||||
using namespace js;
|
using namespace js;
|
||||||
using namespace js::gc;
|
using namespace js::gc;
|
||||||
|
|
@ -1395,14 +1394,6 @@ js::ObjectGroup::traceChildren(JSTracer* trc)
|
||||||
if (maybePreliminaryObjects())
|
if (maybePreliminaryObjects())
|
||||||
maybePreliminaryObjects()->trace(trc);
|
maybePreliminaryObjects()->trace(trc);
|
||||||
|
|
||||||
if (maybeUnboxedLayout())
|
|
||||||
unboxedLayout().trace(trc);
|
|
||||||
|
|
||||||
if (ObjectGroup* unboxedGroup = maybeOriginalUnboxedGroup()) {
|
|
||||||
TraceManuallyBarrieredEdge(trc, &unboxedGroup, "group_original_unboxed_group");
|
|
||||||
setOriginalUnboxedGroup(unboxedGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JSObject* descr = maybeTypeDescr()) {
|
if (JSObject* descr = maybeTypeDescr()) {
|
||||||
TraceManuallyBarrieredEdge(trc, &descr, "group_type_descr");
|
TraceManuallyBarrieredEdge(trc, &descr, "group_type_descr");
|
||||||
setTypeDescr(&descr->as<TypeDescr>());
|
setTypeDescr(&descr->as<TypeDescr>());
|
||||||
|
|
@ -1436,12 +1427,6 @@ js::GCMarker::lazilyMarkChildren(ObjectGroup* group)
|
||||||
if (group->maybePreliminaryObjects())
|
if (group->maybePreliminaryObjects())
|
||||||
group->maybePreliminaryObjects()->trace(this);
|
group->maybePreliminaryObjects()->trace(this);
|
||||||
|
|
||||||
if (group->maybeUnboxedLayout())
|
|
||||||
group->unboxedLayout().trace(this);
|
|
||||||
|
|
||||||
if (ObjectGroup* unboxedGroup = group->maybeOriginalUnboxedGroup())
|
|
||||||
traverseEdge(group, unboxedGroup);
|
|
||||||
|
|
||||||
if (TypeDescr* descr = group->maybeTypeDescr())
|
if (TypeDescr* descr = group->maybeTypeDescr())
|
||||||
traverseEdge(group, static_cast<JSObject*>(descr));
|
traverseEdge(group, static_cast<JSObject*>(descr));
|
||||||
|
|
||||||
|
|
@ -1484,23 +1469,6 @@ CallTraceHook(Functor f, JSTracer* trc, JSObject* obj, CheckGeneration check, Ar
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clasp == &UnboxedPlainObject::class_) {
|
|
||||||
JSObject** pexpando = obj->as<UnboxedPlainObject>().addressOfExpando();
|
|
||||||
if (*pexpando)
|
|
||||||
f(pexpando, mozilla::Forward<Args>(args)...);
|
|
||||||
|
|
||||||
UnboxedPlainObject& unboxed = obj->as<UnboxedPlainObject>();
|
|
||||||
const UnboxedLayout& layout = check == CheckGeneration::DoChecks
|
|
||||||
? unboxed.layout()
|
|
||||||
: unboxed.layoutDontCheckGeneration();
|
|
||||||
if (layout.traceList()) {
|
|
||||||
VisitTraceList(f, layout.traceList(), unboxed.data(),
|
|
||||||
mozilla::Forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
clasp->doTrace(trc, obj);
|
clasp->doTrace(trc, obj);
|
||||||
|
|
||||||
if (!clasp->isNative())
|
if (!clasp->isNative())
|
||||||
|
|
@ -2293,18 +2261,6 @@ static inline void
|
||||||
TraceWholeCell(TenuringTracer& mover, JSObject* object)
|
TraceWholeCell(TenuringTracer& mover, JSObject* object)
|
||||||
{
|
{
|
||||||
mover.traceObject(object);
|
mover.traceObject(object);
|
||||||
|
|
||||||
// Additionally trace the expando object attached to any unboxed plain
|
|
||||||
// objects. Baseline and Ion can write properties to the expando while
|
|
||||||
// only adding a post barrier to the owning unboxed object. Note that
|
|
||||||
// it isn't possible for a nursery unboxed object to have a tenured
|
|
||||||
// expando, so that adding a post barrier on the original object will
|
|
||||||
// capture any tenured->nursery edges in the expando as well.
|
|
||||||
|
|
||||||
if (object->is<UnboxedPlainObject>()) {
|
|
||||||
if (UnboxedExpandoObject* expando = object->as<UnboxedPlainObject>().maybeExpando())
|
|
||||||
expando->traceChildren(&mover);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
|
|
||||||
|
|
@ -201,80 +201,15 @@ gc::TraceCycleCollectorChildren(JS::CallbackTracer* trc, Shape* shape)
|
||||||
} while (shape);
|
} while (shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Object groups can point to other object groups via an UnboxedLayout or the
|
|
||||||
// the original unboxed group link. There can potentially be deep or cyclic
|
|
||||||
// chains of such groups to trace through without going through a thing that
|
|
||||||
// participates in cycle collection. These need to be handled iteratively to
|
|
||||||
// avoid blowing the stack when running the cycle collector's callback tracer.
|
|
||||||
struct ObjectGroupCycleCollectorTracer : public JS::CallbackTracer
|
|
||||||
{
|
|
||||||
explicit ObjectGroupCycleCollectorTracer(JS::CallbackTracer* innerTracer)
|
|
||||||
: JS::CallbackTracer(innerTracer->runtime(), DoNotTraceWeakMaps),
|
|
||||||
innerTracer(innerTracer)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void onChild(const JS::GCCellPtr& thing) override;
|
|
||||||
|
|
||||||
JS::CallbackTracer* innerTracer;
|
|
||||||
Vector<ObjectGroup*, 4, SystemAllocPolicy> seen, worklist;
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
ObjectGroupCycleCollectorTracer::onChild(const JS::GCCellPtr& thing)
|
|
||||||
{
|
|
||||||
if (thing.is<BaseShape>()) {
|
|
||||||
// The CC does not care about BaseShapes, and no additional GC things
|
|
||||||
// will be reached by following this edge.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thing.is<JSObject>() || thing.is<JSScript>()) {
|
|
||||||
// Invoke the inner cycle collector callback on this child. It will not
|
|
||||||
// recurse back into TraceChildren.
|
|
||||||
innerTracer->onChild(thing);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thing.is<ObjectGroup>()) {
|
|
||||||
// If this group is required to be in an ObjectGroup chain, trace it
|
|
||||||
// via the provided worklist rather than continuing to recurse.
|
|
||||||
ObjectGroup& group = thing.as<ObjectGroup>();
|
|
||||||
if (group.maybeUnboxedLayout()) {
|
|
||||||
for (size_t i = 0; i < seen.length(); i++) {
|
|
||||||
if (seen[i] == &group)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (seen.append(&group) && worklist.append(&group)) {
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
// If append fails, keep tracing normally. The worst that will
|
|
||||||
// happen is we end up overrecursing.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TraceChildren(this, thing.asCell(), thing.kind());
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
gc::TraceCycleCollectorChildren(JS::CallbackTracer* trc, ObjectGroup* group)
|
gc::TraceCycleCollectorChildren(JS::CallbackTracer* trc, ObjectGroup* group)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(trc->isCallbackTracer());
|
MOZ_ASSERT(trc->isCallbackTracer());
|
||||||
|
|
||||||
// Early return if this group is not required to be in an ObjectGroup chain.
|
group->traceChildren(trc);
|
||||||
if (!group->maybeUnboxedLayout())
|
|
||||||
return group->traceChildren(trc);
|
|
||||||
|
|
||||||
ObjectGroupCycleCollectorTracer groupTracer(trc->asCallbackTracer());
|
|
||||||
group->traceChildren(&groupTracer);
|
|
||||||
|
|
||||||
while (!groupTracer.worklist.empty()) {
|
|
||||||
ObjectGroup* innerGroup = groupTracer.worklist.popCopy();
|
|
||||||
innerGroup->traceChildren(&groupTracer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*** Traced Edge Printer *************************************************************************/
|
/*** Traced Edge Printer *************************************************************************/
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
|
|
|
||||||
|
|
@ -6190,12 +6190,6 @@ gc::MergeCompartments(JSCompartment* source, JSCompartment* target)
|
||||||
for (auto group = source->zone()->cellIter<ObjectGroup>(); !group.done(); group.next()) {
|
for (auto group = source->zone()->cellIter<ObjectGroup>(); !group.done(); group.next()) {
|
||||||
group->setGeneration(target->zone()->types.generation);
|
group->setGeneration(target->zone()->types.generation);
|
||||||
group->compartment_ = target;
|
group->compartment_ = target;
|
||||||
|
|
||||||
// Remove any unboxed layouts from the list in the off thread
|
|
||||||
// compartment. These do not need to be reinserted in the target
|
|
||||||
// compartment's list, as the list is not required to be complete.
|
|
||||||
if (UnboxedLayout* layout = group->maybeUnboxedLayoutDontCheckGeneration())
|
|
||||||
layout->detachFromCompartment();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fixup zone pointers in source's zone to refer to target's zone.
|
// Fixup zone pointers in source's zone to refer to target's zone.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue