tor-browser

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

SweepingAPI.h (3806B)


      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 js_SweepingAPI_h
      8 #define js_SweepingAPI_h
      9 
     10 #include "mozilla/LinkedList.h"
     11 #include "mozilla/Maybe.h"
     12 
     13 #include "jstypes.h"
     14 
     15 #include "js/GCAnnotations.h"
     16 #include "js/GCPolicyAPI.h"
     17 #include "js/RootingAPI.h"
     18 
     19 namespace js {
     20 namespace gc {
     21 
     22 JS_PUBLIC_API void LockStoreBuffer(JSRuntime* runtime);
     23 JS_PUBLIC_API void UnlockStoreBuffer(JSRuntime* runtim);
     24 
     25 class AutoLockStoreBuffer {
     26  JSRuntime* runtime;
     27 
     28 public:
     29  explicit AutoLockStoreBuffer(JSRuntime* runtime) : runtime(runtime) {
     30    LockStoreBuffer(runtime);
     31  }
     32  ~AutoLockStoreBuffer() { UnlockStoreBuffer(runtime); }
     33 };
     34 
     35 }  // namespace gc
     36 }  // namespace js
     37 
     38 namespace JS {
     39 namespace detail {
     40 class WeakCacheBase;
     41 }  // namespace detail
     42 
     43 namespace shadow {
     44 JS_PUBLIC_API void RegisterWeakCache(JS::Zone* zone,
     45                                     JS::detail::WeakCacheBase* cachep);
     46 JS_PUBLIC_API void RegisterWeakCache(JSRuntime* rt,
     47                                     JS::detail::WeakCacheBase* cachep);
     48 }  // namespace shadow
     49 
     50 namespace detail {
     51 
     52 class WeakCacheBase : public mozilla::LinkedListElement<WeakCacheBase> {
     53  WeakCacheBase() = delete;
     54  explicit WeakCacheBase(const WeakCacheBase&) = delete;
     55 
     56 public:
     57  enum NeedsLock : bool { LockStoreBuffer = true, DontLockStoreBuffer = false };
     58 
     59  explicit WeakCacheBase(JS::Zone* zone) {
     60    shadow::RegisterWeakCache(zone, this);
     61  }
     62  explicit WeakCacheBase(JSRuntime* rt) { shadow::RegisterWeakCache(rt, this); }
     63  WeakCacheBase(WeakCacheBase&& other) = default;
     64  virtual ~WeakCacheBase() = default;
     65 
     66  virtual size_t traceWeak(JSTracer* trc, NeedsLock needLock) = 0;
     67 
     68  // Sweeping will be skipped if the cache is empty already.
     69  virtual bool empty() = 0;
     70 
     71  // Enable/disable read barrier during incremental sweeping and set the tracer
     72  // to use.
     73  virtual bool setIncrementalBarrierTracer(JSTracer* trc) {
     74    // Derived classes do not support incremental barriers by default.
     75    return false;
     76  }
     77  virtual bool needsIncrementalBarrier() const {
     78    // Derived classes do not support incremental barriers by default.
     79    return false;
     80  }
     81 };
     82 
     83 }  // namespace detail
     84 
     85 // A WeakCache stores the given Sweepable container and links itself into a
     86 // list of such caches that are swept during each GC. A WeakCache can be
     87 // specific to a zone, or across a whole runtime, depending on which
     88 // constructor is used.
     89 template <typename T>
     90 class WeakCache : protected detail::WeakCacheBase,
     91                  public js::MutableWrappedPtrOperations<T, WeakCache<T>> {
     92  T cache;
     93 
     94 public:
     95  using Type = T;
     96 
     97  template <typename... Args>
     98  explicit WeakCache(Zone* zone, Args&&... args)
     99      : WeakCacheBase(zone), cache(std::forward<Args>(args)...) {}
    100  template <typename... Args>
    101  explicit WeakCache(JSRuntime* rt, Args&&... args)
    102      : WeakCacheBase(rt), cache(std::forward<Args>(args)...) {}
    103 
    104  const T& get() const { return cache; }
    105  T& get() { return cache; }
    106 
    107  size_t traceWeak(JSTracer* trc, NeedsLock needsLock) override {
    108    // Take the store buffer lock in case sweeping triggers any generational
    109    // post barriers. This is not always required and WeakCache specializations
    110    // may delay or skip taking the lock as appropriate.
    111    mozilla::Maybe<js::gc::AutoLockStoreBuffer> lock;
    112    if (needsLock) {
    113      lock.emplace(trc->runtime());
    114    }
    115 
    116    GCPolicy<T>::traceWeak(trc, &cache);
    117    return 0;
    118  }
    119 
    120  bool empty() override { return cache.empty(); }
    121 } JS_HAZ_NON_GC_POINTER;
    122 
    123 }  // namespace JS
    124 
    125 #endif  // js_SweepingAPI_h