tor-browser

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

SharedImmutableStringsCache.cpp (4119B)


      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 #include "vm/SharedImmutableStringsCache-inl.h"
      8 
      9 #include "util/Text.h"
     10 #include "vm/MutexIDs.h"  // js::mutexid
     11 #include "vm/Runtime.h"   // JSRuntime
     12 
     13 namespace js {
     14 
     15 /* static */
     16 SharedImmutableStringsCache SharedImmutableStringsCache::singleton_;
     17 
     18 SharedImmutableString::SharedImmutableString(
     19    SharedImmutableStringsCache::StringBox* box)
     20    : box_(box) {
     21  MOZ_ASSERT(box);
     22  box->refcount++;
     23 }
     24 
     25 SharedImmutableString::SharedImmutableString(SharedImmutableString&& rhs)
     26    : box_(rhs.box_) {
     27  MOZ_ASSERT(this != &rhs, "self move not allowed");
     28 
     29  MOZ_ASSERT_IF(rhs.box_, rhs.box_->refcount > 0);
     30 
     31  rhs.box_ = nullptr;
     32 }
     33 
     34 SharedImmutableString& SharedImmutableString::operator=(
     35    SharedImmutableString&& rhs) {
     36  this->~SharedImmutableString();
     37  new (this) SharedImmutableString(std::move(rhs));
     38  return *this;
     39 }
     40 
     41 SharedImmutableTwoByteString::SharedImmutableTwoByteString(
     42    SharedImmutableString&& string)
     43    : string_(std::move(string)) {}
     44 
     45 SharedImmutableTwoByteString::SharedImmutableTwoByteString(
     46    SharedImmutableStringsCache::StringBox* box)
     47    : string_(box) {
     48  MOZ_ASSERT(box->length() % sizeof(char16_t) == 0);
     49 }
     50 
     51 SharedImmutableTwoByteString::SharedImmutableTwoByteString(
     52    SharedImmutableTwoByteString&& rhs)
     53    : string_(std::move(rhs.string_)) {
     54  MOZ_ASSERT(this != &rhs, "self move not allowed");
     55 }
     56 
     57 SharedImmutableTwoByteString& SharedImmutableTwoByteString::operator=(
     58    SharedImmutableTwoByteString&& rhs) {
     59  this->~SharedImmutableTwoByteString();
     60  new (this) SharedImmutableTwoByteString(std::move(rhs));
     61  return *this;
     62 }
     63 
     64 SharedImmutableString::~SharedImmutableString() {
     65  if (!box_) {
     66    return;
     67  }
     68 
     69  auto locked = box_->cache_->lock();
     70 
     71  MOZ_ASSERT(box_->refcount > 0);
     72 
     73  box_->refcount--;
     74  if (box_->refcount == 0) {
     75    box_->chars_.reset(nullptr);
     76  }
     77 }
     78 
     79 SharedImmutableString SharedImmutableString::clone() const {
     80  auto locked = box_->cache_->lock();
     81  MOZ_ASSERT(box_);
     82  MOZ_ASSERT(box_->refcount > 0);
     83  return SharedImmutableString(box_);
     84 }
     85 
     86 SharedImmutableTwoByteString SharedImmutableTwoByteString::clone() const {
     87  return SharedImmutableTwoByteString(string_.clone());
     88 }
     89 
     90 [[nodiscard]] SharedImmutableString SharedImmutableStringsCache::getOrCreate(
     91    OwnedChars&& chars, size_t length) {
     92  OwnedChars owned(std::move(chars));
     93  MOZ_ASSERT(owned);
     94  return getOrCreate(owned.get(), length, [&]() { return std::move(owned); });
     95 }
     96 
     97 [[nodiscard]] SharedImmutableString SharedImmutableStringsCache::getOrCreate(
     98    const char* chars, size_t length) {
     99  return getOrCreate(chars, length,
    100                     [&]() { return DuplicateString(chars, length); });
    101 }
    102 
    103 bool SharedImmutableStringsCache::init() {
    104  MOZ_ASSERT(!inner_);
    105 
    106  auto* inner =
    107      js_new<ExclusiveData<Inner>>(mutexid::SharedImmutableStringsCache);
    108  if (!inner) {
    109    return false;
    110  }
    111 
    112  auto locked = inner->lock();
    113  inner_ = locked.parent();
    114 
    115  return true;
    116 }
    117 
    118 void SharedImmutableStringsCache::free() {
    119  if (inner_) {
    120    js_delete(inner_);
    121    inner_ = nullptr;
    122  }
    123 }
    124 
    125 bool SharedImmutableStringsCache::initSingleton() { return singleton_.init(); }
    126 
    127 void SharedImmutableStringsCache::freeSingleton() {
    128  if (!JSRuntime::hasLiveRuntimes()) {
    129    singleton_.free();
    130  }
    131 }
    132 
    133 [[nodiscard]] SharedImmutableTwoByteString
    134 SharedImmutableStringsCache::getOrCreate(OwnedTwoByteChars&& chars,
    135                                         size_t length) {
    136  OwnedTwoByteChars owned(std::move(chars));
    137  MOZ_ASSERT(owned);
    138  return getOrCreate(owned.get(), length, [&]() { return std::move(owned); });
    139 }
    140 
    141 [[nodiscard]] SharedImmutableTwoByteString
    142 SharedImmutableStringsCache::getOrCreate(const char16_t* chars, size_t length) {
    143  return getOrCreate(chars, length,
    144                     [&]() { return DuplicateString(chars, length); });
    145 }
    146 
    147 }  // namespace js