void JSCompartment::markTypes(JSTracer *trc) { /* * Mark all scripts, type objects and singleton JS objects in the * compartment. These can be referred to directly by type sets, which we * cannot modify while code which depends on these type sets is active. */ JS_ASSERT(activeAnalysis); for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) { JSScript *script = i.get<JSScript>(); MarkScriptRoot(trc, &script, "mark_types_script"); JS_ASSERT(script == i.get<JSScript>()); } for (size_t thingKind = FINALIZE_OBJECT0; thingKind < FINALIZE_OBJECT_LIMIT; thingKind++) { for (CellIterUnderGC i(this, AllocKind(thingKind)); !i.done(); i.next()) { JSObject *object = i.get<JSObject>(); if (object->hasSingletonType()) { MarkObjectRoot(trc, &object, "mark_types_singleton"); JS_ASSERT(object == i.get<JSObject>()); } } } for (CellIterUnderGC i(this, FINALIZE_TYPE_OBJECT); !i.done(); i.next()) { types::TypeObject *type = i.get<types::TypeObject>(); MarkTypeObjectRoot(trc, &type, "mark_types_scan"); JS_ASSERT(type == i.get<types::TypeObject>()); } }
void GCMarker::processMarkStackOther(SliceBudget &budget, uintptr_t tag, uintptr_t addr) { if (tag == TypeTag) { ScanTypeObject(this, reinterpret_cast<types::TypeObject *>(addr)); } else if (tag == SavedValueArrayTag) { JS_ASSERT(!(addr & Cell::CellMask)); JSObject *obj = reinterpret_cast<JSObject *>(addr); HeapValue *vp, *end; if (restoreValueArray(obj, (void **)&vp, (void **)&end)) pushValueArray(obj, vp, end); else pushObject(obj); } else if (tag == IonCodeTag) { MarkChildren(this, reinterpret_cast<ion::IonCode *>(addr)); } else if (tag == ArenaTag) { ArenaHeader *aheader = reinterpret_cast<ArenaHeader *>(addr); AllocKind thingKind = aheader->getAllocKind(); size_t thingSize = Arena::thingSize(thingKind); for ( ; aheader; aheader = aheader->next) { Arena *arena = aheader->getArena(); FreeSpan firstSpan(aheader->getFirstFreeSpan()); const FreeSpan *span = &firstSpan; for (uintptr_t thing = arena->thingsStart(thingKind); ; thing += thingSize) { JS_ASSERT(thing <= arena->thingsEnd()); if (thing == span->first) { if (!span->hasNext()) break; thing = span->last; span = span->nextSpan(); } else { JSObject *object = reinterpret_cast<JSObject *>(thing); if (object->hasSingletonType() && object->markIfUnmarked(getMarkColor())) pushObject(object); budget.step(); } } if (budget.isOverBudget()) { pushArenaList(aheader); return; } } } #if JS_HAS_XML_SUPPORT else { JS_ASSERT(tag == XmlTag); MarkChildren(this, reinterpret_cast<JSXML *>(addr)); } #endif }