void js::IterateZonesCompartmentsArenasCells(JSRuntime *rt, void *data, IterateZoneCallback zoneCallback, JSIterateCompartmentCallback compartmentCallback, IterateArenaCallback arenaCallback, IterateCellCallback cellCallback) { AutoPrepareForTracing prop(rt); for (ZonesIter zone(rt); !zone.done(); zone.next()) { (*zoneCallback)(rt, data, zone); for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next()) (*compartmentCallback)(rt, data, comp); for (size_t thingKind = 0; thingKind != FINALIZE_LIMIT; thingKind++) { JSGCTraceKind traceKind = MapAllocToTraceKind(AllocKind(thingKind)); size_t thingSize = Arena::thingSize(AllocKind(thingKind)); for (ArenaIter aiter(zone, AllocKind(thingKind)); !aiter.done(); aiter.next()) { ArenaHeader *aheader = aiter.get(); (*arenaCallback)(rt, data, aheader->getArena(), traceKind, thingSize); for (CellIterUnderGC iter(aheader); !iter.done(); iter.next()) (*cellCallback)(rt, data, iter.getCell(), traceKind, thingSize); } } } }
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 }