inline void AutoGCRooter::trace(JSTracer *trc) { switch (tag_) { case PARSER: frontend::MarkParser(trc, this); return; case IDARRAY: { JSIdArray *ida = static_cast<AutoIdArray *>(this)->idArray; MarkIdRange(trc, ida->length, ida->vector, "JS::AutoIdArray.idArray"); return; } case DESCRIPTORS: { PropDescArray &descriptors = 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_"); } return; } case ID: MarkIdRoot(trc, &static_cast<AutoIdRooter *>(this)->id_, "JS::AutoIdRooter.id_"); return; case VALVECTOR: { AutoValueVector::VectorImpl &vector = static_cast<AutoValueVector *>(this)->vector; MarkValueRootRange(trc, vector.length(), vector.begin(), "js::AutoValueVector.vector"); return; } case STRING: if (static_cast<AutoStringRooter *>(this)->str_) MarkStringRoot(trc, &static_cast<AutoStringRooter *>(this)->str_, "JS::AutoStringRooter.str_"); return; case IDVECTOR: { AutoIdVector::VectorImpl &vector = static_cast<AutoIdVector *>(this)->vector; MarkIdRootRange(trc, vector.length(), vector.begin(), "js::AutoIdVector.vector"); return; } case SHAPEVECTOR: { AutoShapeVector::VectorImpl &vector = static_cast<js::AutoShapeVector *>(this)->vector; MarkShapeRootRange(trc, vector.length(), const_cast<Shape **>(vector.begin()), "js::AutoShapeVector.vector"); return; } case OBJVECTOR: { AutoObjectVector::VectorImpl &vector = static_cast<AutoObjectVector *>(this)->vector; MarkObjectRootRange(trc, vector.length(), vector.begin(), "js::AutoObjectVector.vector"); return; } case FUNVECTOR: { AutoFunctionVector::VectorImpl &vector = static_cast<AutoFunctionVector *>(this)->vector; MarkObjectRootRange(trc, vector.length(), vector.begin(), "js::AutoFunctionVector.vector"); return; } case STRINGVECTOR: { AutoStringVector::VectorImpl &vector = static_cast<AutoStringVector *>(this)->vector; MarkStringRootRange(trc, vector.length(), vector.begin(), "js::AutoStringVector.vector"); return; } case NAMEVECTOR: { AutoNameVector::VectorImpl &vector = static_cast<AutoNameVector *>(this)->vector; MarkStringRootRange(trc, vector.length(), vector.begin(), "js::AutoNameVector.vector"); return; } case VALARRAY: { AutoValueArray *array = static_cast<AutoValueArray *>(this); MarkValueRootRange(trc, array->length(), array->start(), "js::AutoValueArray"); return; } case SCRIPTVECTOR: { AutoScriptVector::VectorImpl &vector = static_cast<AutoScriptVector *>(this)->vector; MarkScriptRootRange(trc, vector.length(), vector.begin(), "js::AutoScriptVector.vector"); return; } case OBJOBJHASHMAP: { AutoObjectObjectHashMap::HashMapImpl &map = static_cast<AutoObjectObjectHashMap *>(this)->map; for (AutoObjectObjectHashMap::Enum e(map); !e.empty(); e.popFront()) { MarkObjectRoot(trc, &e.front().value(), "AutoObjectObjectHashMap value"); JS_SET_TRACING_LOCATION(trc, (void *)&e.front().key()); JSObject *key = e.front().key(); MarkObjectRoot(trc, &key, "AutoObjectObjectHashMap key"); if (key != e.front().key()) e.rekeyFront(key); } return; } case OBJU32HASHMAP: { AutoObjectUnsigned32HashMap *self = static_cast<AutoObjectUnsigned32HashMap *>(this); AutoObjectUnsigned32HashMap::HashMapImpl &map = self->map; for (AutoObjectUnsigned32HashMap::Enum e(map); !e.empty(); e.popFront()) { JSObject *key = e.front().key(); MarkObjectRoot(trc, &key, "AutoObjectUnsignedHashMap key"); if (key != e.front().key()) e.rekeyFront(key); } return; } case OBJHASHSET: { AutoObjectHashSet *self = static_cast<AutoObjectHashSet *>(this); AutoObjectHashSet::HashSetImpl &set = self->set; for (AutoObjectHashSet::Enum e(set); !e.empty(); e.popFront()) { JSObject *obj = e.front(); MarkObjectRoot(trc, &obj, "AutoObjectHashSet value"); if (obj != e.front()) e.rekeyFront(obj); } return; } case HASHABLEVALUE: { AutoHashableValueRooter *rooter = static_cast<AutoHashableValueRooter *>(this); rooter->trace(trc); return; } case IONMASM: { #ifdef JS_ION static_cast<js::jit::MacroAssembler::AutoRooter *>(this)->masm()->trace(trc); #endif return; } case IONALLOC: { #ifdef JS_ION static_cast<js::jit::AutoTempAllocatorRooter *>(this)->trace(trc); #endif return; } case WRAPPER: { /* * We need to use MarkValueUnbarriered here because we mark wrapper * roots in every slice. This is because of some rule-breaking in * RemapAllWrappersForObject; see comment there. */ MarkValueUnbarriered(trc, &static_cast<AutoWrapperRooter *>(this)->value.get(), "JS::AutoWrapperRooter.value"); return; } case WRAPVECTOR: { AutoWrapperVector::VectorImpl &vector = static_cast<AutoWrapperVector *>(this)->vector; /* * We need to use MarkValueUnbarriered here because we mark wrapper * roots in every slice. This is because of some rule-breaking in * RemapAllWrappersForObject; see comment there. */ for (WrapperValue *p = vector.begin(); p < vector.end(); p++) MarkValueUnbarriered(trc, &p->get(), "js::AutoWrapperVector.vector"); return; } case JSONPARSER: static_cast<js::JSONParser *>(this)->trace(trc); return; case CUSTOM: static_cast<JS::CustomAutoRooter *>(this)->trace(trc); return; } JS_ASSERT(tag_ >= 0); if (Value *vp = static_cast<AutoArrayRooter *>(this)->array) MarkValueRootRange(trc, tag_, vp, "JS::AutoArrayRooter.array"); }
inline void AutoGCRooter::trace(JSTracer* trc) { switch (tag_) { case PARSER: frontend::MarkParser(trc, this); return; case VALVECTOR: { AutoValueVector::VectorImpl& vector = static_cast<AutoValueVector*>(this)->vector; TraceRootRange(trc, vector.length(), vector.begin(), "JS::AutoValueVector.vector"); return; } case IDVECTOR: { AutoIdVector::VectorImpl& vector = static_cast<AutoIdVector*>(this)->vector; TraceRootRange(trc, vector.length(), vector.begin(), "JS::AutoIdVector.vector"); return; } case OBJVECTOR: { AutoObjectVector::VectorImpl& vector = static_cast<AutoObjectVector*>(this)->vector; TraceRootRange(trc, vector.length(), vector.begin(), "JS::AutoObjectVector.vector"); return; } case VALARRAY: { /* * We don't know the template size parameter, but we can safely treat it * as an AutoValueArray<1> because the length is stored separately. */ AutoValueArray<1>* array = static_cast<AutoValueArray<1>*>(this); TraceRootRange(trc, array->length(), array->begin(), "js::AutoValueArray"); return; } case IONMASM: { static_cast<js::jit::MacroAssembler::AutoRooter*>(this)->masm()->trace(trc); return; } case WRAPPER: { /* * We need to use TraceManuallyBarrieredEdge here because we mark * wrapper roots in every slice. This is because of some rule-breaking * in RemapAllWrappersForObject; see comment there. */ TraceManuallyBarrieredEdge(trc, &static_cast<AutoWrapperRooter*>(this)->value.get(), "JS::AutoWrapperRooter.value"); return; } case WRAPVECTOR: { AutoWrapperVector::VectorImpl& vector = static_cast<AutoWrapperVector*>(this)->vector; /* * We need to use TraceManuallyBarrieredEdge here because we mark * wrapper roots in every slice. This is because of some rule-breaking * in RemapAllWrappersForObject; see comment there. */ for (WrapperValue* p = vector.begin(); p < vector.end(); p++) TraceManuallyBarrieredEdge(trc, &p->get(), "js::AutoWrapperVector.vector"); return; } case CUSTOM: static_cast<JS::CustomAutoRooter*>(this)->trace(trc); return; } MOZ_ASSERT(tag_ >= 0); if (Value* vp = static_cast<AutoArrayRooter*>(this)->array) TraceRootRange(trc, tag_, vp, "JS::AutoArrayRooter.array"); }
inline void AutoGCRooter::trace(JSTracer* trc) { switch (tag_) { case PARSER: frontend::MarkParser(trc, this); return; case IDARRAY: { JSIdArray* ida = static_cast<AutoIdArray*>(this)->idArray; TraceRange(trc, ida->length, ida->begin(), "JS::AutoIdArray.idArray"); return; } case DESCVECTOR: { AutoPropertyDescriptorVector::VectorImpl& descriptors = static_cast<AutoPropertyDescriptorVector*>(this)->vector; for (size_t i = 0, len = descriptors.length(); i < len; i++) descriptors[i].trace(trc); return; } case VALVECTOR: { AutoValueVector::VectorImpl& vector = static_cast<AutoValueVector*>(this)->vector; TraceRootRange(trc, vector.length(), vector.begin(), "JS::AutoValueVector.vector"); return; } case IDVECTOR: { AutoIdVector::VectorImpl& vector = static_cast<AutoIdVector*>(this)->vector; TraceRootRange(trc, vector.length(), vector.begin(), "JS::AutoIdVector.vector"); return; } case IDVALVECTOR: { AutoIdValueVector::VectorImpl& vector = static_cast<AutoIdValueVector*>(this)->vector; for (size_t i = 0; i < vector.length(); i++) { TraceRoot(trc, &vector[i].id, "js::AutoIdValueVector id"); TraceRoot(trc, &vector[i].value, "js::AutoIdValueVector value"); } return; } case SHAPEVECTOR: { AutoShapeVector::VectorImpl& vector = static_cast<js::AutoShapeVector*>(this)->vector; TraceRootRange(trc, vector.length(), const_cast<Shape**>(vector.begin()), "js::AutoShapeVector.vector"); return; } case OBJVECTOR: { AutoObjectVector::VectorImpl& vector = static_cast<AutoObjectVector*>(this)->vector; TraceRootRange(trc, vector.length(), vector.begin(), "JS::AutoObjectVector.vector"); return; } case STRINGVECTOR: { AutoStringVector::VectorImpl& vector = static_cast<AutoStringVector*>(this)->vector; TraceRootRange(trc, vector.length(), vector.begin(), "js::AutoStringVector.vector"); return; } case NAMEVECTOR: { AutoNameVector::VectorImpl& vector = static_cast<AutoNameVector*>(this)->vector; TraceRootRange(trc, vector.length(), vector.begin(), "js::AutoNameVector.vector"); return; } case VALARRAY: { /* * We don't know the template size parameter, but we can safely treat it * as an AutoValueArray<1> because the length is stored separately. */ AutoValueArray<1>* array = static_cast<AutoValueArray<1>*>(this); TraceRootRange(trc, array->length(), array->begin(), "js::AutoValueArray"); return; } case SCRIPTVECTOR: { AutoScriptVector::VectorImpl& vector = static_cast<AutoScriptVector*>(this)->vector; TraceRootRange(trc, vector.length(), vector.begin(), "js::AutoScriptVector.vector"); return; } case HASHABLEVALUE: { AutoHashableValueRooter* rooter = static_cast<AutoHashableValueRooter*>(this); rooter->trace(trc); return; } case IONMASM: { static_cast<js::jit::MacroAssembler::AutoRooter*>(this)->masm()->trace(trc); return; } case WRAPPER: { /* * We need to use TraceManuallyBarrieredEdge here because we mark * wrapper roots in every slice. This is because of some rule-breaking * in RemapAllWrappersForObject; see comment there. */ TraceManuallyBarrieredEdge(trc, &static_cast<AutoWrapperRooter*>(this)->value.get(), "JS::AutoWrapperRooter.value"); return; } case WRAPVECTOR: { AutoWrapperVector::VectorImpl& vector = static_cast<AutoWrapperVector*>(this)->vector; /* * We need to use TraceManuallyBarrieredEdge here because we mark * wrapper roots in every slice. This is because of some rule-breaking * in RemapAllWrappersForObject; see comment there. */ for (WrapperValue* p = vector.begin(); p < vector.end(); p++) TraceManuallyBarrieredEdge(trc, &p->get(), "js::AutoWrapperVector.vector"); return; } case JSONPARSER: static_cast<js::JSONParserBase*>(this)->trace(trc); return; case CUSTOM: static_cast<JS::CustomAutoRooter*>(this)->trace(trc); return; } MOZ_ASSERT(tag_ >= 0); if (Value* vp = static_cast<AutoArrayRooter*>(this)->array) TraceRootRange(trc, tag_, vp, "JS::AutoArrayRooter.array"); }
inline void AutoGCRooter::trace(JSTracer *trc) { switch (tag_) { case PARSER: frontend::MarkParser(trc, this); return; case IDARRAY: { JSIdArray *ida = static_cast<AutoIdArray *>(this)->idArray; MarkIdRange(trc, ida->length, ida->vector, "JS::AutoIdArray.idArray"); return; } case DESCVECTOR: { AutoPropDescVector::VectorImpl &descriptors = static_cast<AutoPropDescVector *>(this)->vector; for (size_t i = 0, len = descriptors.length(); i < len; i++) descriptors[i].trace(trc); return; } case VALVECTOR: { AutoValueVector::VectorImpl &vector = static_cast<AutoValueVector *>(this)->vector; MarkValueRootRange(trc, vector.length(), vector.begin(), "js::AutoValueVector.vector"); return; } case IDVECTOR: { AutoIdVector::VectorImpl &vector = static_cast<AutoIdVector *>(this)->vector; MarkIdRootRange(trc, vector.length(), vector.begin(), "js::AutoIdVector.vector"); return; } case SHAPEVECTOR: { AutoShapeVector::VectorImpl &vector = static_cast<js::AutoShapeVector *>(this)->vector; MarkShapeRootRange(trc, vector.length(), const_cast<Shape **>(vector.begin()), "js::AutoShapeVector.vector"); return; } case OBJVECTOR: { AutoObjectVector::VectorImpl &vector = static_cast<AutoObjectVector *>(this)->vector; MarkObjectRootRange(trc, vector.length(), vector.begin(), "js::AutoObjectVector.vector"); return; } case FUNVECTOR: { AutoFunctionVector::VectorImpl &vector = static_cast<AutoFunctionVector *>(this)->vector; MarkObjectRootRange(trc, vector.length(), vector.begin(), "js::AutoFunctionVector.vector"); return; } case STRINGVECTOR: { AutoStringVector::VectorImpl &vector = static_cast<AutoStringVector *>(this)->vector; MarkStringRootRange(trc, vector.length(), vector.begin(), "js::AutoStringVector.vector"); return; } case NAMEVECTOR: { AutoNameVector::VectorImpl &vector = static_cast<AutoNameVector *>(this)->vector; MarkStringRootRange(trc, vector.length(), vector.begin(), "js::AutoNameVector.vector"); return; } case VALARRAY: { /* * We don't know the template size parameter, but we can safely treat it * as an AutoValueArray<1> because the length is stored separately. */ AutoValueArray<1> *array = static_cast<AutoValueArray<1> *>(this); MarkValueRootRange(trc, array->length(), array->begin(), "js::AutoValueArray"); return; } case SCRIPTVECTOR: { AutoScriptVector::VectorImpl &vector = static_cast<AutoScriptVector *>(this)->vector; MarkScriptRootRange(trc, vector.length(), vector.begin(), "js::AutoScriptVector.vector"); return; } case OBJOBJHASHMAP: { AutoObjectObjectHashMap::HashMapImpl &map = static_cast<AutoObjectObjectHashMap *>(this)->map; for (AutoObjectObjectHashMap::Enum e(map); !e.empty(); e.popFront()) { MarkObjectRoot(trc, &e.front().value(), "AutoObjectObjectHashMap value"); trc->setTracingLocation((void *)&e.front().key()); JSObject *key = e.front().key(); MarkObjectRoot(trc, &key, "AutoObjectObjectHashMap key"); if (key != e.front().key()) e.rekeyFront(key); } return; } case OBJU32HASHMAP: { AutoObjectUnsigned32HashMap *self = static_cast<AutoObjectUnsigned32HashMap *>(this); AutoObjectUnsigned32HashMap::HashMapImpl &map = self->map; for (AutoObjectUnsigned32HashMap::Enum e(map); !e.empty(); e.popFront()) { JSObject *key = e.front().key(); MarkObjectRoot(trc, &key, "AutoObjectUnsignedHashMap key"); if (key != e.front().key()) e.rekeyFront(key); } return; } case OBJHASHSET: { AutoObjectHashSet *self = static_cast<AutoObjectHashSet *>(this); AutoObjectHashSet::HashSetImpl &set = self->set; for (AutoObjectHashSet::Enum e(set); !e.empty(); e.popFront()) { JSObject *obj = e.front(); MarkObjectRoot(trc, &obj, "AutoObjectHashSet value"); if (obj != e.front()) e.rekeyFront(obj); } return; } case HASHABLEVALUE: { AutoHashableValueRooter *rooter = static_cast<AutoHashableValueRooter *>(this); rooter->trace(trc); return; } case IONMASM: { static_cast<js::jit::MacroAssembler::AutoRooter *>(this)->masm()->trace(trc); return; } case WRAPPER: { /* * We need to use MarkValueUnbarriered here because we mark wrapper * roots in every slice. This is because of some rule-breaking in * RemapAllWrappersForObject; see comment there. */ MarkValueUnbarriered(trc, &static_cast<AutoWrapperRooter *>(this)->value.get(), "JS::AutoWrapperRooter.value"); return; } case WRAPVECTOR: { AutoWrapperVector::VectorImpl &vector = static_cast<AutoWrapperVector *>(this)->vector; /* * We need to use MarkValueUnbarriered here because we mark wrapper * roots in every slice. This is because of some rule-breaking in * RemapAllWrappersForObject; see comment there. */ for (WrapperValue *p = vector.begin(); p < vector.end(); p++) MarkValueUnbarriered(trc, &p->get(), "js::AutoWrapperVector.vector"); return; } case JSONPARSER: static_cast<js::JSONParserBase *>(this)->trace(trc); return; case CUSTOM: static_cast<JS::CustomAutoRooter *>(this)->trace(trc); return; } MOZ_ASSERT(tag_ >= 0); if (Value *vp = static_cast<AutoArrayRooter *>(this)->array) MarkValueRootRange(trc, tag_, vp, "JS::AutoArrayRooter.array"); }