tor-browser

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

GCArray.h (3284B)


      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_GCArray_h
      8 #define js_GCArray_h
      9 
     10 #include "mozilla/Assertions.h"
     11 
     12 #include "gc/Barrier.h"
     13 #include "gc/Tracer.h"
     14 #include "js/Value.h"
     15 
     16 namespace js {
     17 
     18 /*
     19 * A fixed size array of |T| for use with GC things.
     20 *
     21 * Must be allocated manually to allow space for the trailing elements
     22 * data. Call bytesRequired to get the required allocation size.
     23 *
     24 * Does not provide any barriers by default.
     25 */
     26 template <typename T>
     27 class GCArray {
     28  const uint32_t size_;
     29  T elements_[1];
     30 
     31 public:
     32  explicit GCArray(uint32_t size) : size_(size) {
     33    // The array contents following the first element are not initialized.
     34  }
     35 
     36  uint32_t size() const { return size_; }
     37 
     38  const T& operator[](uint32_t i) const {
     39    MOZ_ASSERT(i < size_);
     40    return elements_[i];
     41  }
     42  T& operator[](uint32_t i) {
     43    MOZ_ASSERT(i < size_);
     44    return elements_[i];
     45  }
     46 
     47  const T* begin() const { return elements_; }
     48  T* begin() { return elements_; }
     49  const T* end() const { return elements_ + size_; }
     50  T* end() { return elements_ + size_; }
     51 
     52  void trace(JSTracer* trc) {
     53    TraceRange(trc, size(), begin(), "array element");
     54  }
     55 
     56  static constexpr ptrdiff_t offsetOfElements() {
     57    return offsetof(GCArray, elements_);
     58  }
     59 
     60  static size_t bytesRequired(size_t size) {
     61    return offsetOfElements() + std::max(size, size_t(1)) * sizeof(T);
     62  }
     63 };
     64 
     65 /*
     66 * A fixed size array of GC things owned by a GC thing.
     67 *
     68 * Uses the appropriate barriers depending on whether the owner is in the
     69 * nursery or the tenured heap. If the owner cannot be allocated in the nursery
     70 * then this class is not required.
     71 */
     72 template <typename T>
     73 class GCOwnedArray {
     74  using StorageType = GCArray<PreAndPostBarrierWrapper<T>>;
     75  using TenuredInterface = StorageType;
     76  using NurseryInterface = GCArray<PreBarrierWrapper<T>>;
     77 
     78  StorageType array;
     79 
     80 public:
     81  explicit GCOwnedArray(uint32_t size) : array(size) {}
     82 
     83  uint32_t size() const { return array.size(); }
     84  const T& operator[](uint32_t i) const { return array[i].get(); }
     85 
     86  // Apply |f| to a view of the data with appropriate barriers given |owner|.
     87  template <typename F>
     88  void withOwner(gc::Cell* owner, F&& f) {
     89    if (gc::IsInsideNursery(owner)) {
     90      f(nurseryOwned());
     91    } else {
     92      f(tenuredOwned());
     93    }
     94  }
     95 
     96  // For convenience, special case setElement.
     97  void setElement(gc::Cell* owner, uint32_t i, const T& newValue) {
     98    withOwner(owner, [&](auto& self) { self[i] = newValue; });
     99  }
    100 
    101  void trace(JSTracer* trc) { array.trace(trc); }
    102 
    103  static constexpr ptrdiff_t offsetOfElements() {
    104    return offsetof(GCOwnedArray, array) + StorageType::offsetOfElements();
    105  }
    106 
    107  static size_t bytesRequired(size_t size) {
    108    return offsetof(GCOwnedArray, array) + StorageType::bytesRequired(size);
    109  }
    110 
    111 private:
    112  TenuredInterface& tenuredOwned() { return array; }
    113  NurseryInterface& nurseryOwned() {
    114    return reinterpret_cast<NurseryInterface&>(array);
    115  }
    116 };
    117 
    118 }  // namespace js
    119 
    120 #endif  // js_GCArray_h