tor-browser

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

WasmShareable.h (3897B)


      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 *
      4 * Copyright 2021 Mozilla Foundation
      5 *
      6 * Licensed under the Apache License, Version 2.0 (the "License");
      7 * you may not use this file except in compliance with the License.
      8 * You may obtain a copy of the License at
      9 *
     10 *     http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing, software
     13 * distributed under the License is distributed on an "AS IS" BASIS,
     14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15 * See the License for the specific language governing permissions and
     16 * limitations under the License.
     17 */
     18 
     19 #ifndef wasm_shareable_h
     20 #define wasm_shareable_h
     21 
     22 #include "mozilla/RefPtr.h"
     23 #include "js/RefCounted.h"
     24 #include "wasm/WasmTypeDecls.h"
     25 
     26 namespace js {
     27 namespace wasm {
     28 
     29 // This reusable base class factors out the logic for a resource that is shared
     30 // by multiple instances/modules but should only be counted once when computing
     31 // about:memory stats.
     32 
     33 template <class T>
     34 using SeenSet = HashSet<const T*, DefaultHasher<const T*>, SystemAllocPolicy>;
     35 
     36 template <class T>
     37 struct ShareableBase : AtomicRefCounted<T> {
     38  using SeenSet = wasm::SeenSet<T>;
     39 
     40  size_t sizeOfIncludingThisIfNotSeen(mozilla::MallocSizeOf mallocSizeOf,
     41                                      SeenSet* seen) const {
     42    const T* self = static_cast<const T*>(this);
     43    typename SeenSet::AddPtr p = seen->lookupForAdd(self);
     44    if (p) {
     45      return 0;
     46    }
     47    bool ok = seen->add(p, self);
     48    (void)ok;  // oh well
     49    return mallocSizeOf(self) + self->sizeOfExcludingThis(mallocSizeOf);
     50  }
     51 };
     52 
     53 // ShareableBytes is a reference-counted Vector of bytes.
     54 
     55 // Vector is 'final' and cannot be inherited to combine with ShareableBase, so
     56 // we need to define a wrapper class with boilerplate methods.
     57 template <typename T, size_t MinInlineCapacity, class AllocPolicy>
     58 struct ShareableVector
     59    : public ShareableBase<ShareableVector<T, MinInlineCapacity, AllocPolicy>> {
     60  using VecT = mozilla::Vector<T, MinInlineCapacity, AllocPolicy>;
     61 
     62  VecT vector;
     63 
     64  size_t length() const { return vector.length(); }
     65  bool empty() const { return vector.empty(); }
     66  T* begin() { return vector.begin(); }
     67  T* end() { return vector.end(); }
     68  const T* begin() const { return vector.begin(); }
     69  const T* end() const { return vector.end(); }
     70  mozilla::Span<const T> span() const {
     71    return mozilla::Span<const T>(begin(), end());
     72  }
     73  size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
     74    return vector.sizeOfExcludingThis(mallocSizeOf);
     75  }
     76  bool append(const T* start, size_t len) { return vector.append(start, len); }
     77  bool appendAll(const VecT& other) { return vector.appendAll(other); }
     78  void shrinkTo(size_t len) { return vector.shrinkTo(len); }
     79 
     80  ShareableVector() = default;
     81  explicit ShareableVector(VecT&& vector) : vector(std::move(vector)) {}
     82 
     83  static const ShareableVector* fromSpan(mozilla::Span<const T> span) {
     84    ShareableVector* vector = js_new<ShareableVector>();
     85    if (!vector) {
     86      return nullptr;
     87    }
     88 
     89    // If we succeed in allocating the vector but fail to append something to
     90    // it, we need to delete this vector before returning.
     91    if (!vector->append(span.data(), span.size())) {
     92      js_free(vector);
     93      return nullptr;
     94    }
     95 
     96    return vector;
     97  }
     98 };
     99 
    100 using ShareableBytes = ShareableVector<uint8_t, 0, SystemAllocPolicy>;
    101 using MutableBytes = RefPtr<ShareableBytes>;
    102 using SharedBytes = RefPtr<const ShareableBytes>;
    103 
    104 struct ShareableChars : public ShareableBase<ShareableChars> {
    105  UniqueChars chars;
    106 
    107  ShareableChars() = default;
    108  explicit ShareableChars(UniqueChars&& chars) : chars(std::move(chars)) {}
    109 };
    110 
    111 using SharedChars = RefPtr<const ShareableChars>;
    112 
    113 }  // namespace wasm
    114 }  // namespace js
    115 
    116 #endif  // wasm_shareable_h