mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-30 05:35:31 +00:00
Bug 1107639 - Remove public Add/RemoveRoot API r=terrence
This commit is contained in:
parent
56abdc7b9a
commit
fbac697693
@ -272,6 +272,11 @@ class ChainedIter
|
||||
T operator->() const { return get(); }
|
||||
};
|
||||
|
||||
typedef js::HashMap<Value *,
|
||||
const char *,
|
||||
js::DefaultHasher<Value *>,
|
||||
js::SystemAllocPolicy> RootedValueMap;
|
||||
|
||||
class GCRuntime
|
||||
{
|
||||
public:
|
||||
@ -284,8 +289,8 @@ class GCRuntime
|
||||
inline bool upcomingZealousGC();
|
||||
inline bool needZealousGC();
|
||||
|
||||
template <typename T> bool addRoot(T *rp, const char *name, JSGCRootType rootType);
|
||||
void removeRoot(void *rp);
|
||||
bool addRoot(Value *vp, const char *name);
|
||||
void removeRoot(Value *vp);
|
||||
void setMarkStackLimit(size_t limit);
|
||||
|
||||
void setParameter(JSGCParamKey key, uint32_t value);
|
||||
@ -665,7 +670,7 @@ class GCRuntime
|
||||
// so as to reduce the cost of operations on the available lists.
|
||||
ChunkPool fullChunks_;
|
||||
|
||||
js::RootedValueMap rootsHash;
|
||||
RootedValueMap rootsHash;
|
||||
|
||||
size_t maxMallocBytes;
|
||||
|
||||
|
@ -445,21 +445,7 @@ js::gc::GCRuntime::markRuntime(JSTracer *trc,
|
||||
|
||||
for (RootRange r = rootsHash.all(); !r.empty(); r.popFront()) {
|
||||
const RootEntry &entry = r.front();
|
||||
const char *name = entry.value().name ? entry.value().name : "root";
|
||||
JSGCRootType type = entry.value().type;
|
||||
void *key = entry.key();
|
||||
if (type == JS_GC_ROOT_VALUE_PTR) {
|
||||
MarkValueRoot(trc, reinterpret_cast<Value *>(key), name);
|
||||
} else if (*reinterpret_cast<void **>(key)){
|
||||
if (type == JS_GC_ROOT_STRING_PTR)
|
||||
MarkStringRoot(trc, reinterpret_cast<JSString **>(key), name);
|
||||
else if (type == JS_GC_ROOT_OBJECT_PTR)
|
||||
MarkObjectRoot(trc, reinterpret_cast<JSObject **>(key), name);
|
||||
else if (type == JS_GC_ROOT_SCRIPT_PTR)
|
||||
MarkScriptRoot(trc, reinterpret_cast<JSScript **>(key), name);
|
||||
else
|
||||
MOZ_CRASH("unexpected js::RootInfo::type value");
|
||||
}
|
||||
MarkValueRoot(trc, entry.key(), entry.value());
|
||||
}
|
||||
|
||||
MarkPersistentRootedChains(trc);
|
||||
|
124
js/src/jsapi.cpp
124
js/src/jsapi.cpp
@ -1500,130 +1500,6 @@ JS_strdup(JSRuntime *rt, const char *s)
|
||||
|
||||
#undef JS_AddRoot
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::AddValueRoot(JSContext *cx, JS::Heap<JS::Value> *vp)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
return AddValueRoot(cx, vp->unsafeGet(), nullptr);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::AddStringRoot(JSContext *cx, JS::Heap<JSString *> *rp)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
return AddStringRoot(cx, rp->unsafeGet(), nullptr);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::AddObjectRoot(JSContext *cx, JS::Heap<JSObject *> *rp)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
return AddObjectRoot(cx, rp->unsafeGet(), nullptr);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::AddNamedValueRoot(JSContext *cx, JS::Heap<JS::Value> *vp, const char *name)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
return AddValueRoot(cx, vp->unsafeGet(), name);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::AddNamedValueRootRT(JSRuntime *rt, JS::Heap<JS::Value> *vp, const char *name)
|
||||
{
|
||||
return AddValueRootRT(rt, vp->unsafeGet(), name);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::AddNamedStringRoot(JSContext *cx, JS::Heap<JSString *> *rp, const char *name)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
return AddStringRoot(cx, rp->unsafeGet(), name);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::AddNamedObjectRoot(JSContext *cx, JS::Heap<JSObject *> *rp, const char *name)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
return AddObjectRoot(cx, rp->unsafeGet(), name);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::AddNamedScriptRoot(JSContext *cx, JS::Heap<JSScript *> *rp, const char *name)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
return AddScriptRoot(cx, rp->unsafeGet(), name);
|
||||
}
|
||||
|
||||
/* We allow unrooting from finalizers within the GC */
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS::RemoveValueRoot(JSContext *cx, JS::Heap<JS::Value> *vp)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
RemoveRoot(cx->runtime(), (void *)vp);
|
||||
*vp = UndefinedValue();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS::RemoveStringRoot(JSContext *cx, JS::Heap<JSString *> *rp)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
RemoveRoot(cx->runtime(), (void *)rp);
|
||||
*rp = nullptr;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS::RemoveObjectRoot(JSContext *cx, JS::Heap<JSObject *> *rp)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
RemoveRoot(cx->runtime(), (void *)rp);
|
||||
*rp = nullptr;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS::RemoveScriptRoot(JSContext *cx, JS::Heap<JSScript *> *rp)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
RemoveRoot(cx->runtime(), (void *)rp);
|
||||
*rp = nullptr;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS::RemoveValueRootRT(JSRuntime *rt, JS::Heap<JS::Value> *vp)
|
||||
{
|
||||
RemoveRoot(rt, (void *)vp);
|
||||
*vp = UndefinedValue();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS::RemoveStringRootRT(JSRuntime *rt, JS::Heap<JSString *> *rp)
|
||||
{
|
||||
RemoveRoot(rt, (void *)rp);
|
||||
*rp = nullptr;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS::RemoveObjectRootRT(JSRuntime *rt, JS::Heap<JSObject *> *rp)
|
||||
{
|
||||
RemoveRoot(rt, (void *)rp);
|
||||
*rp = nullptr;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS::RemoveScriptRootRT(JSRuntime *rt, JS::Heap<JSScript *> *rp)
|
||||
{
|
||||
RemoveRoot(rt, (void *)rp);
|
||||
*rp = nullptr;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_AddExtraGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data)
|
||||
{
|
||||
|
@ -1996,83 +1996,6 @@ JS_strdup(JSContext *cx, const char *s);
|
||||
extern JS_PUBLIC_API(char *)
|
||||
JS_strdup(JSRuntime *rt, const char *s);
|
||||
|
||||
namespace JS {
|
||||
|
||||
/*
|
||||
* A GC root is a pointer to a jsval, JSObject * or JSString * that itself
|
||||
* points into the GC heap. JS_AddValueRoot takes a pointer to a jsval and
|
||||
* JS_AddGCThingRoot takes a pointer to a JSObject * or JString *.
|
||||
*
|
||||
* Note that, since JS_Add*Root stores the address of a variable (of type
|
||||
* jsval, JSString *, or JSObject *), that variable must live until
|
||||
* JS_Remove*Root is called to remove that variable. For example, after:
|
||||
*
|
||||
* void some_function() {
|
||||
* jsval v;
|
||||
* JS_AddNamedValueRoot(cx, &v, "name");
|
||||
*
|
||||
* the caller must perform
|
||||
*
|
||||
* JS_RemoveValueRoot(cx, &v);
|
||||
*
|
||||
* before some_function() returns.
|
||||
*
|
||||
* Also, use JS_AddNamed*Root(cx, &structPtr->memberObj, "structPtr->memberObj")
|
||||
* in preference to JS_Add*Root(cx, &structPtr->memberObj), in order to identify
|
||||
* roots by their source callsites. This way, you can find the callsite while
|
||||
* debugging if you should fail to do JS_Remove*Root(cx, &structPtr->memberObj)
|
||||
* before freeing structPtr's memory.
|
||||
*/
|
||||
extern JS_PUBLIC_API(bool)
|
||||
AddValueRoot(JSContext *cx, JS::Heap<JS::Value> *vp);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
AddStringRoot(JSContext *cx, JS::Heap<JSString *> *rp);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
AddObjectRoot(JSContext *cx, JS::Heap<JSObject *> *rp);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
AddNamedValueRoot(JSContext *cx, JS::Heap<JS::Value> *vp, const char *name);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
AddNamedValueRootRT(JSRuntime *rt, JS::Heap<JS::Value> *vp, const char *name);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
AddNamedStringRoot(JSContext *cx, JS::Heap<JSString *> *rp, const char *name);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
AddNamedObjectRoot(JSContext *cx, JS::Heap<JSObject *> *rp, const char *name);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
AddNamedScriptRoot(JSContext *cx, JS::Heap<JSScript *> *rp, const char *name);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
RemoveValueRoot(JSContext *cx, JS::Heap<JS::Value> *vp);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
RemoveStringRoot(JSContext *cx, JS::Heap<JSString *> *rp);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
RemoveObjectRoot(JSContext *cx, JS::Heap<JSObject *> *rp);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
RemoveScriptRoot(JSContext *cx, JS::Heap<JSScript *> *rp);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
RemoveValueRootRT(JSRuntime *rt, JS::Heap<JS::Value> *vp);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
RemoveStringRootRT(JSRuntime *rt, JS::Heap<JSString *> *rp);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
RemoveObjectRootRT(JSRuntime *rt, JS::Heap<JSObject *> *rp);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
RemoveScriptRootRT(JSRuntime *rt, JS::Heap<JSScript *> *rp);
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
/*
|
||||
* Register externally maintained GC roots.
|
||||
*
|
||||
|
@ -1495,10 +1495,6 @@ GCRuntime::setMarkStackLimit(size_t limit)
|
||||
marker.setMaxCapacity(limit);
|
||||
}
|
||||
|
||||
template <typename T> struct BarrierOwner {};
|
||||
template <typename T> struct BarrierOwner<T *> { typedef T result; };
|
||||
template <> struct BarrierOwner<Value> { typedef HeapValue result; };
|
||||
|
||||
bool
|
||||
GCRuntime::addBlackRootsTracer(JSTraceDataOp traceOp, void *data)
|
||||
{
|
||||
@ -1596,9 +1592,8 @@ GCRuntime::setSliceCallback(JS::GCSliceCallback callback) {
|
||||
return stats.setSliceCallback(callback);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
GCRuntime::addRoot(T *rp, const char *name, JSGCRootType rootType)
|
||||
GCRuntime::addRoot(Value *vp, const char *name)
|
||||
{
|
||||
/*
|
||||
* Sometimes Firefox will hold weak references to objects and then convert
|
||||
@ -1607,87 +1602,33 @@ GCRuntime::addRoot(T *rp, const char *name, JSGCRootType rootType)
|
||||
* cases.
|
||||
*/
|
||||
if (isIncrementalGCInProgress())
|
||||
BarrierOwner<T>::result::writeBarrierPre(*rp);
|
||||
HeapValue::writeBarrierPre(*vp);
|
||||
|
||||
return rootsHash.put((void *)rp, RootInfo(name, rootType));
|
||||
return rootsHash.put(vp, name);
|
||||
}
|
||||
|
||||
void
|
||||
GCRuntime::removeRoot(void *rp)
|
||||
GCRuntime::removeRoot(Value *vp)
|
||||
{
|
||||
rootsHash.remove(rp);
|
||||
rootsHash.remove(vp);
|
||||
poke();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static bool
|
||||
AddRoot(JSRuntime *rt, T *rp, const char *name, JSGCRootType rootType)
|
||||
{
|
||||
return rt->gc.addRoot(rp, name, rootType);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static bool
|
||||
AddRoot(JSContext *cx, T *rp, const char *name, JSGCRootType rootType)
|
||||
{
|
||||
bool ok = cx->runtime()->gc.addRoot(rp, name, rootType);
|
||||
if (!ok)
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool
|
||||
js::AddValueRoot(JSContext *cx, Value *vp, const char *name)
|
||||
{
|
||||
return AddRoot(cx, vp, name, JS_GC_ROOT_VALUE_PTR);
|
||||
}
|
||||
|
||||
extern bool
|
||||
js::AddValueRootRT(JSRuntime *rt, js::Value *vp, const char *name)
|
||||
{
|
||||
return AddRoot(rt, vp, name, JS_GC_ROOT_VALUE_PTR);
|
||||
}
|
||||
|
||||
extern bool
|
||||
js::AddStringRoot(JSContext *cx, JSString **rp, const char *name)
|
||||
{
|
||||
return AddRoot(cx, rp, name, JS_GC_ROOT_STRING_PTR);
|
||||
}
|
||||
|
||||
extern bool
|
||||
js::AddObjectRoot(JSContext *cx, JSObject **rp, const char *name)
|
||||
{
|
||||
return AddRoot(cx, rp, name, JS_GC_ROOT_OBJECT_PTR);
|
||||
}
|
||||
|
||||
extern bool
|
||||
js::AddObjectRoot(JSRuntime *rt, JSObject **rp, const char *name)
|
||||
{
|
||||
return AddRoot(rt, rp, name, JS_GC_ROOT_OBJECT_PTR);
|
||||
}
|
||||
|
||||
extern bool
|
||||
js::AddScriptRoot(JSContext *cx, JSScript **rp, const char *name)
|
||||
{
|
||||
return AddRoot(cx, rp, name, JS_GC_ROOT_SCRIPT_PTR);
|
||||
}
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
js::AddRawValueRoot(JSContext *cx, Value *vp, const char *name)
|
||||
{
|
||||
return AddRoot(cx, vp, name, JS_GC_ROOT_VALUE_PTR);
|
||||
MOZ_ASSERT(vp);
|
||||
MOZ_ASSERT(name);
|
||||
bool ok = cx->runtime()->gc.addRoot(vp, name);
|
||||
if (!ok)
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return ok;
|
||||
}
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
js::RemoveRawValueRoot(JSContext *cx, Value *vp)
|
||||
{
|
||||
RemoveRoot(cx->runtime(), vp);
|
||||
}
|
||||
|
||||
void
|
||||
js::RemoveRoot(JSRuntime *rt, void *rp)
|
||||
{
|
||||
rt->gc.removeRoot(rp);
|
||||
cx->runtime()->gc.removeRoot(vp);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -832,46 +832,6 @@ const size_t MAX_EMPTY_CHUNK_AGE = 4;
|
||||
|
||||
} /* namespace gc */
|
||||
|
||||
typedef enum JSGCRootType {
|
||||
JS_GC_ROOT_VALUE_PTR,
|
||||
JS_GC_ROOT_STRING_PTR,
|
||||
JS_GC_ROOT_OBJECT_PTR,
|
||||
JS_GC_ROOT_SCRIPT_PTR
|
||||
} JSGCRootType;
|
||||
|
||||
struct RootInfo {
|
||||
RootInfo() {}
|
||||
RootInfo(const char *name, JSGCRootType type) : name(name), type(type) {}
|
||||
const char *name;
|
||||
JSGCRootType type;
|
||||
};
|
||||
|
||||
typedef js::HashMap<void *,
|
||||
RootInfo,
|
||||
js::DefaultHasher<void *>,
|
||||
js::SystemAllocPolicy> RootedValueMap;
|
||||
|
||||
extern bool
|
||||
AddValueRoot(JSContext *cx, js::Value *vp, const char *name);
|
||||
|
||||
extern bool
|
||||
AddValueRootRT(JSRuntime *rt, js::Value *vp, const char *name);
|
||||
|
||||
extern bool
|
||||
AddStringRoot(JSContext *cx, JSString **rp, const char *name);
|
||||
|
||||
extern bool
|
||||
AddObjectRoot(JSContext *cx, JSObject **rp, const char *name);
|
||||
|
||||
extern bool
|
||||
AddObjectRoot(JSRuntime *rt, JSObject **rp, const char *name);
|
||||
|
||||
extern bool
|
||||
AddScriptRoot(JSContext *cx, JSScript **rp, const char *name);
|
||||
|
||||
extern void
|
||||
RemoveRoot(JSRuntime *rt, void *rp);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
extern bool
|
||||
|
Loading…
Reference in New Issue
Block a user