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