tor-browser

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

Tenuring.h (5565B)


      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_Tenuring_h
      8 #define gc_Tenuring_h
      9 
     10 #include "mozilla/HashTable.h"
     11 #include "mozilla/Maybe.h"
     12 
     13 #include "gc/AllocKind.h"
     14 #include "js/GCAPI.h"
     15 #include "js/TracingAPI.h"
     16 #include "js/UniquePtr.h"
     17 #include "util/Text.h"
     18 
     19 namespace js {
     20 
     21 class NativeObject;
     22 class Nursery;
     23 class PlainObject;
     24 
     25 namespace wasm {
     26 class AnyRef;
     27 }  // namespace wasm
     28 
     29 namespace gc {
     30 
     31 class AllocSite;
     32 class ArenaCellSet;
     33 class RelocationOverlay;
     34 class StringRelocationOverlay;
     35 #ifdef JS_GC_ZEAL
     36 class PromotionStats;
     37 #endif
     38 
     39 template <typename Key>
     40 struct DeduplicationStringHasher {
     41  using Lookup = Key;
     42  static inline HashNumber hash(const Lookup& lookup);
     43  static MOZ_ALWAYS_INLINE bool match(const Key& key, const Lookup& lookup);
     44 };
     45 
     46 class TenuringTracer final : public JSTracer {
     47  Nursery& nursery_;
     48 
     49  // Size of data promoted during collection.
     50  size_t promotedSize = 0;
     51  // Number of cells promoted during collection.
     52  size_t promotedCells = 0;
     53 
     54  // These lists are threaded through the Nursery using the space from
     55  // already moved things. The lists are used to fix up the moved things and
     56  // to find things held live by intra-Nursery pointers.
     57  gc::RelocationOverlay* objHead = nullptr;
     58  gc::StringRelocationOverlay* stringHead = nullptr;
     59 
     60  using StringDeDupSet =
     61      HashSet<JSString*, DeduplicationStringHasher<JSString*>,
     62              SystemAllocPolicy>;
     63 
     64  // deDupSet is emplaced at the beginning of the nursery collection and reset
     65  // at the end of the nursery collection. It can also be reset during nursery
     66  // collection when out of memory to insert new entries.
     67  mozilla::Maybe<StringDeDupSet> stringDeDupSet;
     68 
     69  bool tenureEverything;
     70 
     71  // A flag set when a GC thing is promoted to the next nursery generation (as
     72  // opposed to the tenured heap). This is used to check when we need to add an
     73  // edge to the remembered set during nursery collection.
     74  bool promotedToNursery = false;
     75 
     76 #ifdef JS_GC_ZEAL
     77  UniquePtr<PromotionStats> promotionStats;
     78 #endif
     79 
     80 public:
     81  TenuringTracer(JSRuntime* rt, Nursery* nursery, bool tenureEverything);
     82  ~TenuringTracer();
     83 
     84  Nursery& nursery() { return nursery_; }
     85 
     86 #ifdef JS_GC_ZEAL
     87  void initPromotionReport();
     88  void printPromotionReport(JSContext* cx, JS::GCReason reason,
     89                            const JS::AutoRequireNoGC& nogc) const;
     90 #endif
     91 
     92  // Promote all live objects and everything they can reach. Called after all
     93  // roots have been traced.
     94  void collectToObjectFixedPoint();
     95 
     96  // Promote all live strings and all strings they can reach, and additionally
     97  // do any fixups for when strings are pointing into memory that was
     98  // deduplicated. Called after collectToObjectFixedPoint().
     99  void collectToStringFixedPoint();
    100 
    101  size_t getPromotedSize() const;
    102  size_t getPromotedCells() const;
    103 
    104  void traverse(JS::Value* thingp);
    105  void traverse(wasm::AnyRef* thingp);
    106 
    107  // The store buffers need to be able to call these directly.
    108  void traceObject(JSObject* obj);
    109  void traceObjectSlots(NativeObject* nobj, uint32_t start, uint32_t end);
    110  void traceObjectElements(JS::Value* vp, uint32_t count);
    111  void traceString(JSString* str);
    112 
    113  // Methods to promote a live cell or get the pointer to its new location if
    114  // that has already happened. The store buffers call these.
    115  JSObject* promoteOrForward(JSObject* obj);
    116  JSString* promoteOrForward(JSString* str);
    117  JS::BigInt* promoteOrForward(JS::BigInt* bip);
    118  GetterSetter* promoteOrForward(GetterSetter* gs);
    119 
    120  // Returns whether any cells in the arena require sweeping.
    121  template <typename T>
    122  bool traceBufferedCells(Arena* arena, ArenaCellSet* cells);
    123 
    124  class AutoPromotedAnyToNursery;
    125 
    126 private:
    127 #define DEFINE_ON_EDGE_METHOD(name, type, _1, _2) \
    128  void on##name##Edge(type** thingp, const char* name) override;
    129  JS_FOR_EACH_TRACEKIND(DEFINE_ON_EDGE_METHOD)
    130 #undef DEFINE_ON_EDGE_METHOD
    131 
    132  inline void insertIntoObjectFixupList(gc::RelocationOverlay* entry);
    133  inline void insertIntoStringFixupList(gc::StringRelocationOverlay* entry);
    134 
    135  template <typename T>
    136  T* alloc(JS::Zone* zone, gc::AllocKind kind, gc::Cell* src);
    137  template <JS::TraceKind traceKind>
    138  void* allocCell(JS::Zone* zone, gc::AllocKind allocKind, gc::AllocSite* site,
    139                  gc::Cell* src);
    140  JSString* allocString(JSString* src, JS::Zone* zone, gc::AllocKind dstKind);
    141 
    142  bool shouldTenure(Zone* zone, JS::TraceKind traceKind, Cell* cell);
    143 
    144  MOZ_ALWAYS_INLINE JSObject* promoteObject(JSObject* obj);
    145  inline JSObject* promotePlainObject(PlainObject* src);
    146  JSObject* promoteObjectSlow(JSObject* src);
    147  JSString* promoteString(JSString* src);
    148  JS::BigInt* promoteBigInt(JS::BigInt* src);
    149  GetterSetter* promoteGetterSetter(GetterSetter* src);
    150 
    151  size_t moveElements(NativeObject* dst, NativeObject* src,
    152                      gc::AllocKind dstKind);
    153  size_t moveSlots(NativeObject* dst, NativeObject* src);
    154  size_t moveString(JSString* dst, JSString* src, gc::AllocKind dstKind);
    155  size_t moveBigInt(JS::BigInt* dst, JS::BigInt* src, gc::AllocKind dstKind);
    156  size_t moveGetterSetter(GetterSetter* dst, GetterSetter* src,
    157                          gc::AllocKind dstKind);
    158 
    159  void traceSlots(JS::Value* vp, JS::Value* end);
    160 };
    161 
    162 }  // namespace gc
    163 }  // namespace js
    164 
    165 #endif  // gc_Tenuring_h