mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Bug 650161 - Add moving GC callback and use it to fix up ipc CPOW tables r=terrence
This commit is contained in:
parent
2e443e6daf
commit
fbd9cb9af7
@ -24,10 +24,16 @@ static void
|
||||
FinalizeChild(JSFreeOp *fop, JSFinalizeStatus status, bool isCompartment, void *data)
|
||||
{
|
||||
if (status == JSFINALIZE_GROUP_START) {
|
||||
static_cast<JavaScriptChild *>(data)->finalize(fop);
|
||||
static_cast<JavaScriptChild *>(data)->finalize();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
FixupChildAfterMovingGC(JSRuntime *rt, void *data)
|
||||
{
|
||||
static_cast<JavaScriptChild *>(data)->fixupAfterMovingGC();
|
||||
}
|
||||
|
||||
JavaScriptChild::JavaScriptChild(JSRuntime *rt)
|
||||
: JavaScriptShared(rt),
|
||||
JavaScriptBase<PJavaScriptChild>(rt)
|
||||
@ -37,6 +43,7 @@ JavaScriptChild::JavaScriptChild(JSRuntime *rt)
|
||||
JavaScriptChild::~JavaScriptChild()
|
||||
{
|
||||
JS_RemoveFinalizeCallback(rt_, FinalizeChild);
|
||||
JS_RemoveMovingGCCallback(rt_, FixupChildAfterMovingGC);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -48,14 +55,15 @@ JavaScriptChild::init()
|
||||
return false;
|
||||
|
||||
JS_AddFinalizeCallback(rt_, FinalizeChild, this);
|
||||
JS_AddMovingGCCallback(rt_, FixupChildAfterMovingGC, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
JavaScriptChild::finalize(JSFreeOp *fop)
|
||||
JavaScriptChild::finalize()
|
||||
{
|
||||
objects_.finalize(fop);
|
||||
objectIds_.finalize(fop);
|
||||
objects_.sweep();
|
||||
objectIds_.sweep();
|
||||
}
|
||||
|
||||
JSObject *
|
||||
|
@ -21,7 +21,7 @@ class JavaScriptChild : public JavaScriptBase<PJavaScriptChild>
|
||||
virtual ~JavaScriptChild();
|
||||
|
||||
bool init();
|
||||
void finalize(JSFreeOp *fop);
|
||||
void finalize();
|
||||
|
||||
void drop(JSObject *obj);
|
||||
|
||||
|
@ -27,6 +27,12 @@ TraceParent(JSTracer *trc, void *data)
|
||||
static_cast<JavaScriptParent *>(data)->trace(trc);
|
||||
}
|
||||
|
||||
static void
|
||||
FixupParentAfterMovingGC(JSRuntime *rt, void *data)
|
||||
{
|
||||
static_cast<JavaScriptParent *>(data)->fixupAfterMovingGC();
|
||||
}
|
||||
|
||||
JavaScriptParent::JavaScriptParent(JSRuntime *rt)
|
||||
: JavaScriptShared(rt),
|
||||
JavaScriptBase<PJavaScriptParent>(rt)
|
||||
@ -36,6 +42,7 @@ JavaScriptParent::JavaScriptParent(JSRuntime *rt)
|
||||
JavaScriptParent::~JavaScriptParent()
|
||||
{
|
||||
JS_RemoveExtraGCRootsTracer(rt_, TraceParent, this);
|
||||
JS_RemoveMovingGCCallback(rt_, FixupParentAfterMovingGC);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -45,6 +52,7 @@ JavaScriptParent::init()
|
||||
return false;
|
||||
|
||||
JS_AddExtraGCRootsTracer(rt_, TraceParent, this);
|
||||
JS_AddMovingGCCallback(rt_, FixupParentAfterMovingGC, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -41,14 +41,12 @@ IdToObjectMap::trace(JSTracer *trc)
|
||||
}
|
||||
|
||||
void
|
||||
IdToObjectMap::finalize(JSFreeOp *fop)
|
||||
IdToObjectMap::sweep()
|
||||
{
|
||||
for (Table::Enum e(table_); !e.empty(); e.popFront()) {
|
||||
DebugOnly<JSObject *> prior = e.front().value().get();
|
||||
if (JS_IsAboutToBeFinalized(&e.front().value()))
|
||||
e.removeFront();
|
||||
else
|
||||
MOZ_ASSERT(e.front().value() == prior);
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,14 +95,14 @@ ObjectToIdMap::init()
|
||||
}
|
||||
|
||||
void
|
||||
ObjectToIdMap::finalize(JSFreeOp *fop)
|
||||
ObjectToIdMap::sweep()
|
||||
{
|
||||
for (Table::Enum e(*table_); !e.empty(); e.popFront()) {
|
||||
JSObject *obj = e.front().key();
|
||||
if (JS_IsAboutToBeFinalizedUnbarriered(&obj))
|
||||
e.removeFront();
|
||||
else
|
||||
MOZ_ASSERT(obj == e.front().key());
|
||||
else if (obj != e.front().key())
|
||||
e.rekeyFront(obj);
|
||||
}
|
||||
}
|
||||
|
||||
@ -596,3 +594,9 @@ JavaScriptShared::Wrap(JSContext *cx, HandleObject aObj, InfallibleTArray<CpowEn
|
||||
return true;
|
||||
}
|
||||
|
||||
void JavaScriptShared::fixupAfterMovingGC()
|
||||
{
|
||||
objects_.sweep();
|
||||
cpows_.sweep();
|
||||
objectIds_.sweep();
|
||||
}
|
||||
|
@ -48,12 +48,14 @@ class IdToObjectMap
|
||||
|
||||
bool init();
|
||||
void trace(JSTracer *trc);
|
||||
void finalize(JSFreeOp *fop);
|
||||
void sweep();
|
||||
|
||||
bool add(ObjectId id, JSObject *obj);
|
||||
JSObject *find(ObjectId id);
|
||||
void remove(ObjectId id);
|
||||
|
||||
void fixupAfterMovingGC();
|
||||
|
||||
private:
|
||||
Table table_;
|
||||
};
|
||||
@ -69,12 +71,14 @@ class ObjectToIdMap
|
||||
~ObjectToIdMap();
|
||||
|
||||
bool init();
|
||||
void finalize(JSFreeOp *fop);
|
||||
void sweep();
|
||||
|
||||
bool add(JSContext *cx, JSObject *obj, ObjectId id);
|
||||
ObjectId find(JSObject *obj);
|
||||
void remove(JSObject *obj);
|
||||
|
||||
void fixupAfterMovingGC();
|
||||
|
||||
private:
|
||||
static void keyMarkCallback(JSTracer *trc, JSObject *key, void *data);
|
||||
|
||||
@ -100,6 +104,8 @@ class JavaScriptShared
|
||||
bool Unwrap(JSContext *cx, const InfallibleTArray<CpowEntry> &aCpows, JS::MutableHandleObject objp);
|
||||
bool Wrap(JSContext *cx, JS::HandleObject aObj, InfallibleTArray<CpowEntry> *outCpows);
|
||||
|
||||
void fixupAfterMovingGC();
|
||||
|
||||
protected:
|
||||
bool toVariant(JSContext *cx, JS::HandleValue from, JSVariant *to);
|
||||
bool fromVariant(JSContext *cx, const JSVariant &from, JS::MutableHandleValue to);
|
||||
|
@ -414,6 +414,8 @@ class GCRuntime
|
||||
void setGCCallback(JSGCCallback callback, void *data);
|
||||
bool addFinalizeCallback(JSFinalizeCallback callback, void *data);
|
||||
void removeFinalizeCallback(JSFinalizeCallback func);
|
||||
bool addMovingGCCallback(JSMovingGCCallback callback, void *data);
|
||||
void removeMovingGCCallback(JSMovingGCCallback func);
|
||||
JS::GCSliceCallback setSliceCallback(JS::GCSliceCallback callback);
|
||||
|
||||
void setValidate(bool enable);
|
||||
@ -797,6 +799,7 @@ class GCRuntime
|
||||
|
||||
Callback<JSGCCallback> gcCallback;
|
||||
CallbackVector<JSFinalizeCallback> finalizeCallbacks;
|
||||
CallbackVector<JSMovingGCCallback> movingCallbacks;
|
||||
|
||||
/*
|
||||
* Malloc counter to measure memory pressure for GC scheduling. It runs
|
||||
|
@ -1888,6 +1888,19 @@ JS_RemoveFinalizeCallback(JSRuntime *rt, JSFinalizeCallback cb)
|
||||
rt->gc.removeFinalizeCallback(cb);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_AddMovingGCCallback(JSRuntime *rt, JSMovingGCCallback cb, void *data)
|
||||
{
|
||||
AssertHeapIsIdle(rt);
|
||||
return rt->gc.addMovingGCCallback(cb, data);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_RemoveMovingGCCallback(JSRuntime *rt, JSMovingGCCallback cb)
|
||||
{
|
||||
rt->gc.removeMovingGCCallback(cb);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_IsAboutToBeFinalized(JS::Heap<JSObject *> *objp)
|
||||
{
|
||||
|
@ -689,6 +689,9 @@ typedef enum JSFinalizeStatus {
|
||||
typedef void
|
||||
(* JSFinalizeCallback)(JSFreeOp *fop, JSFinalizeStatus status, bool isCompartment, void *data);
|
||||
|
||||
typedef void
|
||||
(* JSMovingGCCallback)(JSRuntime *rt, void *data);
|
||||
|
||||
typedef bool
|
||||
(* JSInterruptCallback)(JSContext *cx);
|
||||
|
||||
@ -2025,6 +2028,12 @@ JS_AddFinalizeCallback(JSRuntime *rt, JSFinalizeCallback cb, void *data);
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_RemoveFinalizeCallback(JSRuntime *rt, JSFinalizeCallback cb);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_AddMovingGCCallback(JSRuntime *rt, JSMovingGCCallback cb, void *data);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_RemoveMovingGCCallback(JSRuntime *rt, JSMovingGCCallback cb);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_IsGCMarkingTracer(JSTracer *trc);
|
||||
|
||||
|
@ -1595,6 +1595,25 @@ GCRuntime::removeFinalizeCallback(JSFinalizeCallback callback)
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
GCRuntime::addMovingGCCallback(JSMovingGCCallback callback, void *data)
|
||||
{
|
||||
return movingCallbacks.append(Callback<JSMovingGCCallback>(callback, data));
|
||||
}
|
||||
|
||||
void
|
||||
GCRuntime::removeMovingGCCallback(JSMovingGCCallback callback)
|
||||
{
|
||||
for (Callback<JSMovingGCCallback> *p = movingCallbacks.begin();
|
||||
p < movingCallbacks.end(); p++)
|
||||
{
|
||||
if (p->op == callback) {
|
||||
movingCallbacks.erase(p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JS::GCSliceCallback
|
||||
GCRuntime::setSliceCallback(JS::GCSliceCallback callback) {
|
||||
return stats.setSliceCallback(callback);
|
||||
@ -2426,6 +2445,13 @@ GCRuntime::updatePointersToRelocatedCells()
|
||||
(*op)(&trc, grayRootTracer.data);
|
||||
|
||||
MovingTracer::Sweep(&trc);
|
||||
|
||||
// Call callbacks to get the rest of the system to fixup other untraced pointers.
|
||||
for (Callback<JSMovingGCCallback> *p = rt->gc.movingCallbacks.begin();
|
||||
p < rt->gc.movingCallbacks.end(); p++)
|
||||
{
|
||||
p->op(rt, p->data);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user