tor-browser

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

Zone.h (3971B)


      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 /* Shadow definition of |JS::Zone| innards.  Do not use this directly! */
      8 
      9 #ifndef js_shadow_Zone_h
     10 #define js_shadow_Zone_h
     11 
     12 #include "mozilla/Assertions.h"  // MOZ_ASSERT
     13 #include "mozilla/Atomics.h"
     14 
     15 #include <stdint.h>  // uint8_t, uint32_t
     16 
     17 #include "jspubtd.h"  // js::CurrentThreadCanAccessRuntime
     18 #include "jstypes.h"  // js::Bit
     19 
     20 struct JS_PUBLIC_API JSRuntime;
     21 class JS_PUBLIC_API JSTracer;
     22 
     23 namespace JS {
     24 
     25 namespace shadow {
     26 
     27 struct Zone {
     28  enum GCState : uint32_t {
     29    NoGC = 0,
     30    Prepare,
     31    MarkBlackOnly,
     32    MarkBlackAndGray,
     33    Sweep,
     34    Finished,
     35    Compact,
     36    VerifyPreBarriers,
     37 
     38    Limit
     39  };
     40 
     41  using BarrierState = mozilla::Atomic<uint32_t, mozilla::Relaxed>;
     42 
     43  enum Kind : uint8_t { NormalZone, AtomsZone, SystemZone };
     44 
     45 protected:
     46  JSRuntime* const runtime_;
     47  JSTracer* const barrierTracer_;  // A pointer to the JSRuntime's |gcMarker|.
     48  BarrierState needsIncrementalBarrier_;
     49  GCState gcState_ = NoGC;
     50  const Kind kind_;
     51 
     52  Zone(JSRuntime* runtime, JSTracer* barrierTracerArg, Kind kind)
     53      : runtime_(runtime), barrierTracer_(barrierTracerArg), kind_(kind) {
     54    MOZ_ASSERT(!needsIncrementalBarrier());
     55  }
     56 
     57 public:
     58  bool needsIncrementalBarrier() const { return needsIncrementalBarrier_; }
     59 
     60  JSTracer* barrierTracer() {
     61    MOZ_ASSERT(needsIncrementalBarrier_);
     62    MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(runtime_));
     63    return barrierTracer_;
     64  }
     65 
     66  JSRuntime* runtimeFromMainThread() const {
     67    MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(runtime_));
     68    return runtime_;
     69  }
     70 
     71  // Note: Unrestricted access to the zone's runtime from an arbitrary
     72  // thread can easily lead to races. Use this method very carefully.
     73  JSRuntime* runtimeFromAnyThread() const { return runtime_; }
     74 
     75  GCState gcState() const { return GCState(uint32_t(gcState_)); }
     76 
     77  static constexpr uint32_t gcStateMask(GCState state) {
     78    static_assert(uint32_t(Limit) < 32);
     79    return js::Bit(state);
     80  }
     81 
     82  bool hasAnyGCState(uint32_t stateMask) const {
     83    return js::Bit(gcState_) & stateMask;
     84  }
     85 
     86  bool wasGCStarted() const { return gcState() != NoGC; }
     87  bool isGCPreparing() const { return gcState() == Prepare; }
     88  bool isGCMarkingBlackOnly() const { return gcState() == MarkBlackOnly; }
     89  bool isGCMarkingBlackAndGray() const { return gcState() == MarkBlackAndGray; }
     90  bool isGCSweeping() const { return gcState() == Sweep; }
     91  bool isGCFinished() const { return gcState() == Finished; }
     92  bool isGCCompacting() const { return gcState() == Compact; }
     93  bool isGCMarking() const {
     94    return hasAnyGCState(gcStateMask(MarkBlackOnly) |
     95                         gcStateMask(MarkBlackAndGray));
     96  }
     97  bool isGCMarkingOrSweeping() const {
     98    return hasAnyGCState(gcStateMask(MarkBlackOnly) |
     99                         gcStateMask(MarkBlackAndGray) | gcStateMask(Sweep));
    100  }
    101  bool isGCMarkingOrVerifyingPreBarriers() const {
    102    return hasAnyGCState(gcStateMask(MarkBlackOnly) |
    103                         gcStateMask(MarkBlackAndGray) |
    104                         gcStateMask(VerifyPreBarriers));
    105  }
    106  bool isGCSweepingOrCompacting() const {
    107    return hasAnyGCState(gcStateMask(Sweep) | gcStateMask(Compact));
    108  }
    109  bool isVerifyingPreBarriers() const { return gcState() == VerifyPreBarriers; }
    110 
    111  bool isAtomsZone() const { return kind_ == AtomsZone; }
    112  bool isSystemZone() const { return kind_ == SystemZone; }
    113 
    114  static shadow::Zone* from(JS::Zone* zone) {
    115    return reinterpret_cast<shadow::Zone*>(zone);
    116  }
    117  static const shadow::Zone* from(const JS::Zone* zone) {
    118    return reinterpret_cast<const shadow::Zone*>(zone);
    119  }
    120 };
    121 
    122 }  // namespace shadow
    123 
    124 }  // namespace JS
    125 
    126 #endif  // js_shadow_Zone_h