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; 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 FUNVECTOR: { AutoFunctionVector::VectorImpl& vector = static_cast<AutoFunctionVector*>(this)->vector; TraceRootRange(trc, vector.length(), vector.begin(), "js::AutoFunctionVector.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 OBJOBJHASHMAP: { AutoObjectObjectHashMap::HashMapImpl& map = static_cast<AutoObjectObjectHashMap*>(this)->map; for (AutoObjectObjectHashMap::Enum e(map); !e.empty(); e.popFront()) { TraceRoot(trc, &e.front().value(), "AutoObjectObjectHashMap value"); trc->setTracingLocation((void*)&e.front().key()); JSObject* key = e.front().key(); TraceRoot(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(); TraceRoot(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(); TraceRoot(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 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"); }