tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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