PrivateIterators-inl.h (4072B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /* 8 * GC-internal iterators for various data structures. 9 */ 10 11 #ifndef gc_PrivateIterators_inl_h 12 #define gc_PrivateIterators_inl_h 13 14 #include "gc/PublicIterators.h" 15 16 #include "gc/GC-inl.h" 17 18 namespace js::gc { 19 20 class ArenaCellIterUnderGC : public ArenaCellIter { 21 public: 22 explicit ArenaCellIterUnderGC(Arena* arena) : ArenaCellIter(arena) { 23 MOZ_ASSERT(CurrentThreadIsPerformingGC()); 24 } 25 }; 26 27 class ArenaCellIterUnderFinalize : public ArenaCellIter { 28 public: 29 explicit ArenaCellIterUnderFinalize(Arena* arena) : ArenaCellIter(arena) { 30 MOZ_ASSERT(CurrentThreadIsGCFinalizing()); 31 } 32 }; 33 34 class GrayObjectIter : public ZoneAllCellIter<js::gc::TenuredCell> { 35 public: 36 explicit GrayObjectIter(JS::Zone* zone, AllocKind kind) { 37 initForTenuredIteration(zone, kind); 38 } 39 40 JSObject* get() const { 41 return ZoneAllCellIter<js::gc::TenuredCell>::get<JSObject>(); 42 } 43 operator JSObject*() const { return get(); } 44 JSObject* operator->() const { return get(); } 45 }; 46 47 class GCZonesIter { 48 AllZonesIter zone; 49 50 public: 51 explicit GCZonesIter(GCRuntime* gc) : zone(gc) { 52 MOZ_ASSERT(gc->heapState() != JS::HeapState::Idle); 53 if (!done() && !zone->wasGCStarted()) { 54 next(); 55 } 56 } 57 explicit GCZonesIter(JSRuntime* rt) : GCZonesIter(&rt->gc) {} 58 59 bool done() const { return zone.done(); } 60 61 void next() { 62 MOZ_ASSERT(!done()); 63 do { 64 zone.next(); 65 } while (!zone.done() && !zone->wasGCStarted()); 66 } 67 68 JS::Zone* get() const { 69 MOZ_ASSERT(!done()); 70 return zone; 71 } 72 73 operator JS::Zone*() const { return get(); } 74 JS::Zone* operator->() const { return get(); } 75 }; 76 77 using GCCompartmentsIter = 78 CompartmentsOrRealmsIterT<GCZonesIter, CompartmentsInZoneIter>; 79 using GCRealmsIter = CompartmentsOrRealmsIterT<GCZonesIter, RealmsInZoneIter>; 80 81 /* Iterates over all zones in the current sweep group. */ 82 class SweepGroupZonesIter { 83 JS::Zone* current; 84 85 public: 86 explicit SweepGroupZonesIter(GCRuntime* gc) 87 : current(gc->getCurrentSweepGroup()) { 88 MOZ_ASSERT(CurrentThreadIsPerformingGC()); 89 } 90 explicit SweepGroupZonesIter(JSRuntime* rt) : SweepGroupZonesIter(&rt->gc) {} 91 92 bool done() const { return !current; } 93 94 void next() { 95 MOZ_ASSERT(!done()); 96 current = current->nextNodeInGroup(); 97 } 98 99 JS::Zone* get() const { 100 MOZ_ASSERT(!done()); 101 return current; 102 } 103 104 operator JS::Zone*() const { return get(); } 105 JS::Zone* operator->() const { return get(); } 106 }; 107 108 using SweepGroupCompartmentsIter = 109 CompartmentsOrRealmsIterT<SweepGroupZonesIter, CompartmentsInZoneIter>; 110 using SweepGroupRealmsIter = 111 CompartmentsOrRealmsIterT<SweepGroupZonesIter, RealmsInZoneIter>; 112 113 // Iterate the free cells in an arena. See also ArenaCellIter which iterates 114 // the allocated cells. 115 class ArenaFreeCellIter { 116 Arena* arena; 117 size_t thingSize; 118 FreeSpan span; 119 uint_fast16_t thing; 120 121 public: 122 explicit ArenaFreeCellIter(Arena* arena) 123 : arena(arena), 124 thingSize(arena->getThingSize()), 125 span(*arena->getFirstFreeSpan()), 126 thing(span.first) { 127 MOZ_ASSERT(arena); 128 MOZ_ASSERT(thing < ArenaSize); 129 } 130 131 bool done() const { 132 MOZ_ASSERT(thing < ArenaSize); 133 return !thing; 134 } 135 136 TenuredCell* get() const { 137 MOZ_ASSERT(!done()); 138 return reinterpret_cast<TenuredCell*>(uintptr_t(arena) + thing); 139 } 140 141 void next() { 142 MOZ_ASSERT(!done()); 143 MOZ_ASSERT(thing >= span.first && thing <= span.last); 144 145 if (thing == span.last) { 146 span = *span.nextSpan(arena); 147 thing = span.first; 148 } else { 149 thing += thingSize; 150 } 151 152 MOZ_ASSERT(thing < ArenaSize); 153 } 154 155 operator TenuredCell*() const { return get(); } 156 TenuredCell* operator->() const { return get(); } 157 }; 158 159 } // namespace js::gc 160 161 #endif // gc_PrivateIterators_inl_h