tor-browser

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

AtomMarking.h (5178B)


      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 #ifndef gc_AtomMarking_h
      8 #define gc_AtomMarking_h
      9 
     10 #include "mozilla/Atomics.h"
     11 
     12 #include "NamespaceImports.h"
     13 #include "gc/Cell.h"
     14 #include "js/Vector.h"
     15 #include "threading/ProtectedData.h"
     16 
     17 namespace js {
     18 
     19 class AutoLockGC;
     20 class DenseBitmap;
     21 
     22 namespace gc {
     23 
     24 class Arena;
     25 class GCRuntime;
     26 
     27 // This class manages state used for marking atoms during GCs.
     28 // See AtomMarking.cpp for details.
     29 class AtomMarkingRuntime {
     30  // Unused arena atom bitmap indexes.
     31  js::MainThreadData<Vector<size_t, 0, SystemAllocPolicy>> freeArenaIndexes;
     32 
     33  // Background sweep state for |freeArenaIndexes|.
     34  js::GCLockData<Vector<size_t, 0, SystemAllocPolicy>> pendingFreeArenaIndexes;
     35  mozilla::Atomic<bool, mozilla::Relaxed> hasPendingFreeArenaIndexes;
     36 
     37  inline void markChildren(Zone* zone, JSAtom*);
     38  inline void markChildren(Zone* zone, JS::Symbol* symbol);
     39 
     40 public:
     41  // The extent of all allocated and free words in atom mark bitmaps.
     42  // This monotonically increases and may be read from without locking.
     43  mozilla::Atomic<size_t, mozilla::SequentiallyConsistent> allocatedWords;
     44 
     45  AtomMarkingRuntime() : allocatedWords(0) {}
     46 
     47  // Allocate an index in the atom marking bitmap for a new arena.
     48  size_t allocateIndex(GCRuntime* gc);
     49 
     50  // Free an index in the atom marking bitmap.
     51  void freeIndex(size_t index, const AutoLockGC& lock);
     52 
     53  void mergePendingFreeArenaIndexes(GCRuntime* gc);
     54 
     55  // Update the atom marking bitmaps in all collected zones according to the
     56  // atoms zone mark bits.
     57  void refineZoneBitmapsForCollectedZones(GCRuntime* gc);
     58 
     59  // Get a bitmap of all atoms marked in zones that are not being collected by
     60  // the current GC. On failure, mark the atoms instead.
     61  UniquePtr<DenseBitmap> getOrMarkAtomsUsedByUncollectedZones(GCRuntime* gc);
     62 
     63  // Set any bits in the chunk mark bitmaps for atoms which are marked in
     64  // uncollected zones, using the bitmap returned from the previous method.
     65  void markAtomsUsedByUncollectedZones(GCRuntime* gc,
     66                                       UniquePtr<DenseBitmap> markedUnion);
     67 
     68  // If gray unmarking fails or GC marking is aborted then the gray bits may end
     69  // up in an invalid state. This updates references to all things that could be
     70  // gray in the atom marking bitmaps, marking them as black if they were
     71  // previously (and perhaps incorrectly) considered gray. This is always safe
     72  // but loses information.
     73  void unmarkAllGrayReferences(GCRuntime* gc);
     74 
     75  // Get the index into the atom marking bitmaps for the first bit associated
     76  // with an atom.
     77  // This is public for testing access.
     78  static size_t getAtomBit(TenuredCell* thing);
     79 
     80 private:
     81  // Fill |bitmap| with an atom marking bitmap based on the things that are
     82  // currently marked in the chunks used by atoms zone arenas. This returns
     83  // false on an allocation failure (but does not report an exception).
     84  bool computeBitmapFromChunkMarkBits(GCRuntime* gc, DenseBitmap& bitmap);
     85 
     86  // Update the overapproximation of the reachable atoms in |zone| in one go
     87  // according to the marking state after GC.
     88  void refineZoneBitmapForCollectedZone(Zone* zone, const DenseBitmap& bitmap);
     89 
     90  // As above but called per-arena and using the mark bits directly.
     91  void refineZoneBitmapForCollectedZone(Zone* zone, Arena* arena);
     92 
     93 public:
     94  // Mark an atom or id as being newly reachable by the context's zone.
     95  template <typename T>
     96  void markAtom(JSContext* cx, T* thing);
     97 
     98  // Version of markAtom that's always inlined, for performance-sensitive
     99  // callers.
    100  template <typename T, bool Fallible>
    101  MOZ_ALWAYS_INLINE bool inlinedMarkAtomInternal(Zone* zone, T* thing);
    102  template <typename T>
    103  MOZ_ALWAYS_INLINE void inlinedMarkAtom(Zone* zone, T* thing);
    104  template <typename T>
    105  [[nodiscard]] MOZ_ALWAYS_INLINE bool inlinedMarkAtomFallible(Zone* zone,
    106                                                               T* thing);
    107 
    108  void markId(JSContext* cx, jsid id);
    109  void markAtomValue(JSContext* cx, const Value& value);
    110 
    111  // Get the mark color of |thing| in the atom marking bitmap for |zone|.
    112  template <typename T>
    113  CellColor getAtomMarkColor(Zone* zone, T* thing);
    114 
    115  // Return whether |thing/id| is in the atom marking bitmap for |zone|.
    116  template <typename T>
    117  bool atomIsMarked(Zone* zone, T* thing) {
    118    return getAtomMarkColor(zone, thing) != CellColor::White;
    119  }
    120 
    121  // For testing purposes, get the mark color associated with |bitIndex| in the
    122  // atom marking bitmap for |zone|.
    123  CellColor getAtomMarkColorForIndex(Zone* zone, size_t bitIndex);
    124 
    125  // Called during (possibly parallel) marking to unmark possibly-gray symbols.
    126  void maybeUnmarkGrayAtomically(Zone* zone, JS::Symbol* symbol);
    127 
    128 #ifdef DEBUG
    129  bool idIsMarked(Zone* zone, jsid id);
    130  bool valueIsMarked(Zone* zone, const Value& value);
    131 #endif
    132 };
    133 
    134 }  // namespace gc
    135 }  // namespace js
    136 
    137 #endif  // gc_AtomMarking_h