mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-30 13:45:27 +00:00
Bug 726845 - Make Value marking interfaces indirect; r=billm
This will eventually allow the GC to update Values that reference an Object, when moving an object.
This commit is contained in:
parent
063997e021
commit
ba12f349e5
@ -185,8 +185,11 @@ MapObject::mark(JSTracer *trc, JSObject *obj)
|
||||
MapObject *mapobj = static_cast<MapObject *>(obj);
|
||||
if (ValueMap *map = mapobj->getData()) {
|
||||
for (ValueMap::Range r = map->all(); !r.empty(); r.popFront()) {
|
||||
gc::MarkValue(trc, r.front().key, "key");
|
||||
gc::MarkValue(trc, r.front().value, "value");
|
||||
const HeapValue &key = r.front().key;
|
||||
HeapValue tmp(key);
|
||||
gc::MarkValue(trc, &tmp, "key");
|
||||
JS_ASSERT(tmp.get() == key.get());
|
||||
gc::MarkValue(trc, &r.front().value, "value");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -331,8 +334,12 @@ SetObject::mark(JSTracer *trc, JSObject *obj)
|
||||
{
|
||||
SetObject *setobj = static_cast<SetObject *>(obj);
|
||||
if (ValueSet *set = setobj->getData()) {
|
||||
for (ValueSet::Range r = set->all(); !r.empty(); r.popFront())
|
||||
gc::MarkValue(trc, r.front(), "key");
|
||||
for (ValueSet::Range r = set->all(); !r.empty(); r.popFront()) {
|
||||
const HeapValue &key = r.front();
|
||||
HeapValue tmp(key);
|
||||
gc::MarkValue(trc, &tmp, "key");
|
||||
JS_ASSERT(tmp.get() == key.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,8 +134,11 @@ inline void
|
||||
HeapValue::writeBarrierPre(JSCompartment *comp, const Value &value)
|
||||
{
|
||||
#ifdef JSGC_INCREMENTAL
|
||||
if (comp->needsBarrier())
|
||||
js::gc::MarkValueUnbarriered(comp->barrierTracer(), value, "write barrier");
|
||||
if (comp->needsBarrier()) {
|
||||
Value tmp(value);
|
||||
js::gc::MarkValueUnbarriered(comp->barrierTracer(), &tmp, "write barrier");
|
||||
JS_ASSERT(tmp == value);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -319,6 +319,7 @@ class HeapValue
|
||||
inline void set(JSCompartment *comp, const Value &v);
|
||||
|
||||
const Value &get() const { return value; }
|
||||
Value *unsafeGet() { return &value; }
|
||||
operator const Value &() const { return value; }
|
||||
|
||||
bool isUndefined() const { return value.isUndefined(); }
|
||||
|
@ -1270,6 +1270,26 @@ JSContext::sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const
|
||||
return mallocSizeOf(this) + busyArrays.sizeOfExcludingThis(mallocSizeOf);
|
||||
}
|
||||
|
||||
void
|
||||
JSContext::mark(JSTracer *trc)
|
||||
{
|
||||
/* Stack frames and slots are traced by StackSpace::mark. */
|
||||
|
||||
/* Mark other roots-by-definition in the JSContext. */
|
||||
if (globalObject && !hasRunOption(JSOPTION_UNROOTED_GLOBAL))
|
||||
MarkObjectRoot(trc, globalObject, "global object");
|
||||
if (isExceptionPending())
|
||||
MarkValueRoot(trc, &exception, "exception");
|
||||
|
||||
if (autoGCRooters)
|
||||
autoGCRooters->traceAll(trc);
|
||||
|
||||
if (sharpObjectMap.depth > 0)
|
||||
js_TraceSharpMap(trc, &sharpObjectMap);
|
||||
|
||||
MarkValueRoot(trc, &iterValue, "iterValue");
|
||||
}
|
||||
|
||||
namespace JS {
|
||||
|
||||
#if defined JS_THREADSAFE && defined DEBUG
|
||||
|
@ -1121,6 +1121,8 @@ struct JSContext : js::ContextFriendFields
|
||||
return reinterpret_cast<JSContext *>(uintptr_t(link) - offsetof(JSContext, link));
|
||||
}
|
||||
|
||||
void mark(JSTracer *trc);
|
||||
|
||||
private:
|
||||
/*
|
||||
* The allocation code calls the function to indicate either OOM failure
|
||||
@ -1558,18 +1560,18 @@ class AutoShapeVector : public AutoVectorRooter<const Shape *>
|
||||
|
||||
class AutoValueArray : public AutoGCRooter
|
||||
{
|
||||
const js::Value *start_;
|
||||
js::Value *start_;
|
||||
unsigned length_;
|
||||
|
||||
public:
|
||||
AutoValueArray(JSContext *cx, const js::Value *start, unsigned length
|
||||
AutoValueArray(JSContext *cx, js::Value *start, unsigned length
|
||||
JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: AutoGCRooter(cx, VALARRAY), start_(start), length_(length)
|
||||
{
|
||||
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
const Value *start() const { return start_; }
|
||||
Value *start() { return start_; }
|
||||
unsigned length() const { return length_; }
|
||||
|
||||
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
|
@ -416,8 +416,11 @@ JSCompartment::markCrossCompartmentWrappers(JSTracer *trc)
|
||||
{
|
||||
JS_ASSERT(trc->runtime->gcCurrentCompartment);
|
||||
|
||||
for (WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront())
|
||||
MarkValueRoot(trc, e.front().key, "cross-compartment wrapper");
|
||||
for (WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront()) {
|
||||
Value tmp = e.front().key;
|
||||
MarkValueRoot(trc, &tmp, "cross-compartment wrapper");
|
||||
JS_ASSERT(tmp == e.front().key);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -432,9 +432,8 @@ exn_trace(JSTracer *trc, JSObject *obj)
|
||||
vcount += elem->argc;
|
||||
}
|
||||
vp = GetStackTraceValueBuffer(priv);
|
||||
for (i = 0; i != vcount; ++i, ++vp) {
|
||||
MarkValue(trc, *vp, "stack trace argument");
|
||||
}
|
||||
for (i = 0; i != vcount; ++i, ++vp)
|
||||
MarkValue(trc, vp, "stack trace argument");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -530,7 +530,7 @@ args_trace(JSTracer *trc, JSObject *obj)
|
||||
{
|
||||
ArgumentsObject &argsobj = obj->asArguments();
|
||||
ArgumentsData *data = argsobj.data();
|
||||
MarkValue(trc, data->callee, js_callee_str);
|
||||
MarkValue(trc, &data->callee, js_callee_str);
|
||||
MarkValueRange(trc, argsobj.initialLength(), data->slots, js_arguments_str);
|
||||
|
||||
/*
|
||||
|
@ -1855,7 +1855,7 @@ gc_root_traversal(JSTracer *trc, const RootEntry &entry)
|
||||
if (entry.value.type == JS_GC_ROOT_GCTHING_PTR)
|
||||
MarkGCThingRoot(trc, *reinterpret_cast<void **>(entry.key), name);
|
||||
else
|
||||
MarkValueRoot(trc, *reinterpret_cast<Value *>(entry.key), name);
|
||||
MarkValueRoot(trc, reinterpret_cast<Value *>(entry.key), name);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1883,7 +1883,7 @@ AutoGCRooter::trace(JSTracer *trc)
|
||||
{
|
||||
switch (tag) {
|
||||
case JSVAL:
|
||||
MarkValueRoot(trc, static_cast<AutoValueRooter *>(this)->val, "JS::AutoValueRooter.val");
|
||||
MarkValueRoot(trc, &static_cast<AutoValueRooter *>(this)->val, "JS::AutoValueRooter.val");
|
||||
return;
|
||||
|
||||
case PARSER:
|
||||
@ -1905,10 +1905,10 @@ AutoGCRooter::trace(JSTracer *trc)
|
||||
static_cast<AutoPropDescArrayRooter *>(this)->descriptors;
|
||||
for (size_t i = 0, len = descriptors.length(); i < len; i++) {
|
||||
PropDesc &desc = descriptors[i];
|
||||
MarkValueRoot(trc, desc.pd, "PropDesc::pd");
|
||||
MarkValueRoot(trc, desc.value, "PropDesc::value");
|
||||
MarkValueRoot(trc, desc.get, "PropDesc::get");
|
||||
MarkValueRoot(trc, desc.set, "PropDesc::set");
|
||||
MarkValueRoot(trc, &desc.pd, "PropDesc::pd");
|
||||
MarkValueRoot(trc, &desc.value, "PropDesc::value");
|
||||
MarkValueRoot(trc, &desc.get, "PropDesc::get");
|
||||
MarkValueRoot(trc, &desc.set, "PropDesc::set");
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1917,7 +1917,7 @@ AutoGCRooter::trace(JSTracer *trc)
|
||||
PropertyDescriptor &desc = *static_cast<AutoPropertyDescriptorRooter *>(this);
|
||||
if (desc.obj)
|
||||
MarkObjectRoot(trc, desc.obj, "Descriptor::obj");
|
||||
MarkValueRoot(trc, desc.value, "Descriptor::value");
|
||||
MarkValueRoot(trc, &desc.value, "Descriptor::value");
|
||||
if ((desc.attrs & JSPROP_GETTER) && desc.getter)
|
||||
MarkObjectRoot(trc, CastAsObject(desc.getter), "Descriptor::get");
|
||||
if (desc.attrs & JSPROP_SETTER && desc.setter)
|
||||
@ -1996,26 +1996,6 @@ AutoGCRooter::traceAll(JSTracer *trc)
|
||||
|
||||
namespace js {
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
MarkContext(JSTracer *trc, JSContext *acx)
|
||||
{
|
||||
/* Stack frames and slots are traced by StackSpace::mark. */
|
||||
|
||||
/* Mark other roots-by-definition in acx. */
|
||||
if (acx->globalObject && !acx->hasRunOption(JSOPTION_UNROOTED_GLOBAL))
|
||||
MarkObjectRoot(trc, acx->globalObject, "global object");
|
||||
if (acx->isExceptionPending())
|
||||
MarkValueRoot(trc, acx->getPendingException(), "exception");
|
||||
|
||||
if (acx->autoGCRooters)
|
||||
acx->autoGCRooters->traceAll(trc);
|
||||
|
||||
if (acx->sharpObjectMap.depth > 0)
|
||||
js_TraceSharpMap(trc, &acx->sharpObjectMap);
|
||||
|
||||
MarkValueRoot(trc, acx->iterValue, "iterValue");
|
||||
}
|
||||
|
||||
void
|
||||
MarkWeakReferences(GCMarker *gcmarker)
|
||||
{
|
||||
@ -2053,7 +2033,7 @@ MarkRuntime(JSTracer *trc)
|
||||
|
||||
JSContext *iter = NULL;
|
||||
while (JSContext *acx = js_ContextIterator(rt, JS_TRUE, &iter))
|
||||
MarkContext(trc, acx);
|
||||
acx->mark(trc);
|
||||
|
||||
for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
if (c->activeAnalysis)
|
||||
|
@ -45,9 +45,6 @@
|
||||
* scanning functions, but they don't push onto an explicit stack.
|
||||
*/
|
||||
|
||||
using namespace js;
|
||||
using namespace js::gc;
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
|
||||
@ -299,43 +296,43 @@ MarkIdRootRange(JSTracer *trc, size_t len, jsid *vec, const char *name)
|
||||
/*** Value Marking ***/
|
||||
|
||||
static inline void
|
||||
MarkValueInternal(JSTracer *trc, const Value &v)
|
||||
MarkValueInternal(JSTracer *trc, Value *v)
|
||||
{
|
||||
if (v.isMarkable()) {
|
||||
JS_ASSERT(v.toGCThing());
|
||||
return MarkKind(trc, v.toGCThing(), v.gcKind());
|
||||
if (v->isMarkable()) {
|
||||
JS_ASSERT(v->toGCThing());
|
||||
return MarkKind(trc, v->toGCThing(), v->gcKind());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkValue(JSTracer *trc, const js::HeapValue &v, const char *name)
|
||||
MarkValue(JSTracer *trc, HeapValue *v, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkValueInternal(trc, v->unsafeGet());
|
||||
}
|
||||
|
||||
void
|
||||
MarkValueRoot(JSTracer *trc, Value *v, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkValueInternal(trc, v);
|
||||
}
|
||||
|
||||
void
|
||||
MarkValueRoot(JSTracer *trc, const Value &v, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkValueInternal(trc, v);
|
||||
}
|
||||
|
||||
void
|
||||
MarkValueRange(JSTracer *trc, size_t len, const HeapValue *vec, const char *name)
|
||||
MarkValueRange(JSTracer *trc, size_t len, HeapValue *vec, const char *name)
|
||||
{
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
JS_SET_TRACING_INDEX(trc, name, i);
|
||||
MarkValueInternal(trc, vec[i]);
|
||||
MarkValueInternal(trc, vec[i].unsafeGet());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkValueRootRange(JSTracer *trc, size_t len, const Value *vec, const char *name)
|
||||
MarkValueRootRange(JSTracer *trc, size_t len, Value *vec, const char *name)
|
||||
{
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
JS_SET_TRACING_INDEX(trc, name, i);
|
||||
MarkValueInternal(trc, vec[i]);
|
||||
MarkValueInternal(trc, &vec[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -360,17 +357,17 @@ MarkShape(JSTracer *trc, const HeapPtr<const Shape> &thing, const char *name)
|
||||
}
|
||||
|
||||
void
|
||||
MarkValueUnbarriered(JSTracer *trc, const js::Value &v, const char *name)
|
||||
MarkValueUnbarriered(JSTracer *trc, Value *v, const char *name)
|
||||
{
|
||||
JS_SET_TRACING_NAME(trc, name);
|
||||
MarkValueInternal(trc, v);
|
||||
}
|
||||
|
||||
void
|
||||
MarkCrossCompartmentValue(JSTracer *trc, const js::HeapValue &v, const char *name)
|
||||
MarkCrossCompartmentValue(JSTracer *trc, HeapValue *v, const char *name)
|
||||
{
|
||||
if (v.isMarkable()) {
|
||||
js::gc::Cell *cell = (js::gc::Cell *)v.toGCThing();
|
||||
if (v->isMarkable()) {
|
||||
Cell *cell = (Cell *)v->toGCThing();
|
||||
JSRuntime *rt = trc->runtime;
|
||||
if (rt->gcCurrentCompartment && cell->compartment() != rt->gcCurrentCompartment)
|
||||
return;
|
||||
@ -643,7 +640,7 @@ MarkChildren(JSTracer *trc, JSObject *obj)
|
||||
uint32_t nslots = obj->slotSpan();
|
||||
for (uint32_t i = 0; i < nslots; i++) {
|
||||
JS_SET_TRACING_DETAILS(trc, js_PrintObjectSlotName, obj, i);
|
||||
MarkValueInternal(trc, obj->nativeGetSlot(i));
|
||||
MarkValueInternal(trc, obj->nativeGetSlotRef(i).unsafeGet());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -851,6 +848,8 @@ MarkChildren(JSTracer *trc, JSXML *xml)
|
||||
|
||||
} /* namespace gc */
|
||||
|
||||
using namespace js::gc;
|
||||
|
||||
inline void
|
||||
GCMarker::processMarkStackTop()
|
||||
{
|
||||
@ -916,7 +915,7 @@ GCMarker::processMarkStackTop()
|
||||
types::TypeObject *type = obj->typeFromGC();
|
||||
PushMarkStack(this, type);
|
||||
|
||||
js::Shape *shape = obj->lastProperty();
|
||||
Shape *shape = obj->lastProperty();
|
||||
PushMarkStack(this, shape);
|
||||
|
||||
/* Call the trace hook if necessary. */
|
||||
|
@ -97,19 +97,19 @@ MarkIdRootRange(JSTracer *trc, size_t len, jsid *vec, const char *name);
|
||||
/*** Value Marking ***/
|
||||
|
||||
void
|
||||
MarkValue(JSTracer *trc, const js::HeapValue &v, const char *name);
|
||||
MarkValue(JSTracer *trc, HeapValue *v, const char *name);
|
||||
|
||||
void
|
||||
MarkValueRange(JSTracer *trc, size_t len, const HeapValue *vec, const char *name);
|
||||
MarkValueRange(JSTracer *trc, size_t len, HeapValue *vec, const char *name);
|
||||
|
||||
void
|
||||
MarkValueRoot(JSTracer *trc, const Value &v, const char *name);
|
||||
MarkValueRoot(JSTracer *trc, Value *v, const char *name);
|
||||
|
||||
void
|
||||
MarkValueRootRange(JSTracer *trc, size_t len, const Value *vec, const char *name);
|
||||
MarkValueRootRange(JSTracer *trc, size_t len, Value *vec, const char *name);
|
||||
|
||||
inline void
|
||||
MarkValueRootRange(JSTracer *trc, const Value *begin, const Value *end, const char *name)
|
||||
MarkValueRootRange(JSTracer *trc, Value *begin, Value *end, const char *name)
|
||||
{
|
||||
MarkValueRootRange(trc, end - begin, begin, name);
|
||||
}
|
||||
@ -122,14 +122,14 @@ MarkShape(JSTracer *trc, const HeapPtr<const Shape> &thing, const char *name);
|
||||
|
||||
/* Direct value access used by the write barriers and the methodjit */
|
||||
void
|
||||
MarkValueUnbarriered(JSTracer *trc, const js::Value &v, const char *name);
|
||||
MarkValueUnbarriered(JSTracer *trc, Value *v, const char *name);
|
||||
|
||||
/*
|
||||
* Mark a value that may be in a different compartment from the compartment
|
||||
* being GC'd. (Although it won't be marked if it's in the wrong compartment.)
|
||||
*/
|
||||
void
|
||||
MarkCrossCompartmentValue(JSTracer *trc, const js::HeapValue &v, const char *name);
|
||||
MarkCrossCompartmentValue(JSTracer *trc, HeapValue *v, const char *name);
|
||||
|
||||
/*
|
||||
* MarkChildren<JSObject> is exposed solely for preWriteBarrier on
|
||||
@ -153,7 +153,7 @@ MarkCycleCollectorChildren(JSTracer *trc, const Shape *shape);
|
||||
*/
|
||||
|
||||
inline void
|
||||
Mark(JSTracer *trc, const js::HeapValue &v, const char *name)
|
||||
Mark(JSTracer *trc, HeapValue *v, const char *name)
|
||||
{
|
||||
MarkValue(trc, v, name);
|
||||
}
|
||||
@ -171,7 +171,7 @@ Mark(JSTracer *trc, const HeapPtr<JSXML> &xml, const char *name)
|
||||
}
|
||||
|
||||
inline bool
|
||||
IsMarked(const js::Value &v)
|
||||
IsMarked(const Value &v)
|
||||
{
|
||||
if (v.isMarkable())
|
||||
return !IsAboutToBeFinalized(v);
|
||||
|
@ -57,7 +57,7 @@
|
||||
using namespace js;
|
||||
using namespace js::gc;
|
||||
|
||||
static inline const HeapValue &
|
||||
static inline HeapValue &
|
||||
GetCall(JSObject *proxy)
|
||||
{
|
||||
JS_ASSERT(IsFunctionProxy(proxy));
|
||||
@ -72,7 +72,7 @@ GetConstruct(JSObject *proxy)
|
||||
return proxy->getSlot(JSSLOT_PROXY_CONSTRUCT);
|
||||
}
|
||||
|
||||
static inline const HeapValue &
|
||||
static inline HeapValue &
|
||||
GetFunctionProxyConstruct(JSObject *proxy)
|
||||
{
|
||||
JS_ASSERT(IsFunctionProxy(proxy));
|
||||
@ -1246,12 +1246,12 @@ static void
|
||||
proxy_TraceObject(JSTracer *trc, JSObject *obj)
|
||||
{
|
||||
GetProxyHandler(obj)->trace(trc, obj);
|
||||
MarkCrossCompartmentValue(trc, obj->getReservedSlotRef(JSSLOT_PROXY_PRIVATE), "private");
|
||||
MarkCrossCompartmentValue(trc, obj->getReservedSlotRef(JSSLOT_PROXY_EXTRA + 0), "extra0");
|
||||
MarkCrossCompartmentValue(trc, obj->getReservedSlotRef(JSSLOT_PROXY_EXTRA + 1), "extra1");
|
||||
MarkCrossCompartmentValue(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_PRIVATE), "private");
|
||||
MarkCrossCompartmentValue(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_EXTRA + 0), "extra0");
|
||||
MarkCrossCompartmentValue(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_EXTRA + 1), "extra1");
|
||||
if (IsFunctionProxy(obj)) {
|
||||
MarkCrossCompartmentValue(trc, GetCall(obj), "call");
|
||||
MarkCrossCompartmentValue(trc, GetFunctionProxyConstruct(obj), "construct");
|
||||
MarkCrossCompartmentValue(trc, &GetCall(obj), "call");
|
||||
MarkCrossCompartmentValue(trc, &GetFunctionProxyConstruct(obj), "construct");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1259,8 +1259,8 @@ static void
|
||||
proxy_TraceFunction(JSTracer *trc, JSObject *obj)
|
||||
{
|
||||
proxy_TraceObject(trc, obj);
|
||||
MarkCrossCompartmentValue(trc, GetCall(obj), "call");
|
||||
MarkCrossCompartmentValue(trc, GetFunctionProxyConstruct(obj), "construct");
|
||||
MarkCrossCompartmentValue(trc, &GetCall(obj), "call");
|
||||
MarkCrossCompartmentValue(trc, &GetFunctionProxyConstruct(obj), "construct");
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
@ -1903,6 +1903,6 @@ JSScript::markTrapClosures(JSTracer *trc)
|
||||
for (unsigned i = 0; i < length; i++) {
|
||||
BreakpointSite *site = debug->breakpoints[i];
|
||||
if (site && site->trapHandler)
|
||||
MarkValue(trc, site->trapClosure, "trap closure");
|
||||
MarkValue(trc, &site->trapClosure, "trap closure");
|
||||
}
|
||||
}
|
||||
|
@ -1097,7 +1097,7 @@ class TypedArrayTemplate
|
||||
static void
|
||||
obj_trace(JSTracer *trc, JSObject *obj)
|
||||
{
|
||||
MarkValue(trc, obj->getFixedSlotRef(FIELD_BUFFER), "typedarray.buffer");
|
||||
MarkValue(trc, &obj->getFixedSlotRef(FIELD_BUFFER), "typedarray.buffer");
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
@ -91,7 +91,7 @@ namespace js {
|
||||
// bool isMarked(const Type &x)
|
||||
// Return true if x has been marked as live by the garbage collector.
|
||||
//
|
||||
// bool mark(const Type &x)
|
||||
// bool mark(Type &x)
|
||||
// Return false if x is already marked. Otherwise, mark x and return true.
|
||||
//
|
||||
// If omitted, the MarkPolicy parameter defaults to js::DefaultMarkPolicy<Type>,
|
||||
@ -213,7 +213,7 @@ class WeakMap : public HashMap<Key, Value, HashPolicy, RuntimeAllocPolicy>, publ
|
||||
bool markedAny = false;
|
||||
for (Range r = Base::all(); !r.empty(); r.popFront()) {
|
||||
const Key &k = r.front().key;
|
||||
const Value &v = r.front().value;
|
||||
Value &v = r.front().value;
|
||||
/* If the entry is live, ensure its key and value are marked. */
|
||||
if (kp.isMarked(k)) {
|
||||
markedAny |= vp.mark(v);
|
||||
@ -264,10 +264,10 @@ class DefaultMarkPolicy<HeapValue> {
|
||||
return !IsAboutToBeFinalized(x);
|
||||
return true;
|
||||
}
|
||||
bool mark(const HeapValue &x) {
|
||||
bool mark(HeapValue &x) {
|
||||
if (isMarked(x))
|
||||
return false;
|
||||
js::gc::MarkValue(tracer, x, "WeakMap entry");
|
||||
js::gc::MarkValue(tracer, &x, "WeakMap entry");
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -281,7 +281,7 @@ class DefaultMarkPolicy<HeapPtrObject> {
|
||||
bool isMarked(const HeapPtrObject &x) {
|
||||
return !IsAboutToBeFinalized(x);
|
||||
}
|
||||
bool mark(const HeapPtrObject &x) {
|
||||
bool mark(HeapPtrObject &x) {
|
||||
if (isMarked(x))
|
||||
return false;
|
||||
js::gc::MarkObject(tracer, x, "WeakMap entry");
|
||||
@ -298,7 +298,7 @@ class DefaultMarkPolicy<HeapPtrScript> {
|
||||
bool isMarked(const HeapPtrScript &x) {
|
||||
return !IsAboutToBeFinalized(x);
|
||||
}
|
||||
bool mark(const HeapPtrScript &x) {
|
||||
bool mark(HeapPtrScript &x) {
|
||||
if (isMarked(x))
|
||||
return false;
|
||||
js::gc::MarkScript(tracer, x, "WeakMap entry");
|
||||
|
@ -367,7 +367,7 @@ Wrapper::iteratorNext(JSContext *cx, JSObject *wrapper, Value *vp)
|
||||
void
|
||||
Wrapper::trace(JSTracer *trc, JSObject *wrapper)
|
||||
{
|
||||
MarkValue(trc, wrapper->getReservedSlotRef(JSSLOT_PROXY_PRIVATE), "wrappedObject");
|
||||
MarkValue(trc, &wrapper->getReservedSlotRef(JSSLOT_PROXY_PRIVATE), "wrappedObject");
|
||||
}
|
||||
|
||||
JSObject *
|
||||
@ -875,7 +875,7 @@ CrossCompartmentWrapper::iteratorNext(JSContext *cx, JSObject *wrapper, Value *v
|
||||
void
|
||||
CrossCompartmentWrapper::trace(JSTracer *trc, JSObject *wrapper)
|
||||
{
|
||||
MarkCrossCompartmentValue(trc, wrapper->getReservedSlotRef(JSSLOT_PROXY_PRIVATE),
|
||||
MarkCrossCompartmentValue(trc, &wrapper->getReservedSlotRef(JSSLOT_PROXY_PRIVATE),
|
||||
"wrappedObject");
|
||||
}
|
||||
|
||||
|
@ -1963,7 +1963,7 @@ stubs::ConvertToTypedFloat(JSContext *cx, Value *vp)
|
||||
void JS_FASTCALL
|
||||
stubs::WriteBarrier(VMFrame &f, Value *addr)
|
||||
{
|
||||
js::gc::MarkValueUnbarriered(f.cx->compartment->barrierTracer(), *addr, "write barrier");
|
||||
gc::MarkValueUnbarriered(f.cx->compartment->barrierTracer(), addr, "write barrier");
|
||||
}
|
||||
|
||||
void JS_FASTCALL
|
||||
@ -1971,5 +1971,5 @@ stubs::GCThingWriteBarrier(VMFrame &f, Value *addr)
|
||||
{
|
||||
gc::Cell *cell = (gc::Cell *)addr->toGCThing();
|
||||
if (cell && !cell->isMarked())
|
||||
gc::MarkValueUnbarriered(f.cx->compartment->barrierTracer(), *addr, "write barrier");
|
||||
gc::MarkValueUnbarriered(f.cx->compartment->barrierTracer(), addr, "write barrier");
|
||||
}
|
||||
|
@ -275,7 +275,7 @@ StackFrame::mark(JSTracer *trc)
|
||||
}
|
||||
if (IS_GC_MARKING_TRACER(trc))
|
||||
script()->compartment()->active = true;
|
||||
gc::MarkValueUnbarriered(trc, returnValue(), "rval");
|
||||
gc::MarkValueUnbarriered(trc, &returnValue(), "rval");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -485,7 +485,7 @@ StackSpace::markFrameSlots(JSTracer *trc, StackFrame *fp, Value *slotsEnd, jsbyt
|
||||
|
||||
/* Will this slot be synced by the JIT? */
|
||||
if (!analysis->trackSlot(slot) || analysis->liveness(slot).live(offset))
|
||||
gc::MarkValueRoot(trc, *vp, "vm_stack");
|
||||
gc::MarkValueRoot(trc, vp, "vm_stack");
|
||||
else
|
||||
*vp = UndefinedValue();
|
||||
}
|
||||
|
@ -999,7 +999,7 @@ class StackFrame
|
||||
return !!(flags_ & HAS_RVAL);
|
||||
}
|
||||
|
||||
const Value &returnValue() {
|
||||
Value &returnValue() {
|
||||
if (!(flags_ & HAS_RVAL))
|
||||
rval_.setUndefined();
|
||||
return rval_;
|
||||
|
Loading…
Reference in New Issue
Block a user