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 
11 namespace js {
12 
SharedImmutableString(SharedImmutableStringsCache::StringBox * box)13 SharedImmutableString::SharedImmutableString(
14     SharedImmutableStringsCache::StringBox* box)
15     : box_(box) {
16   MOZ_ASSERT(box);
17   box->refcount++;
18 }
19 
SharedImmutableString(SharedImmutableString && rhs)20 SharedImmutableString::SharedImmutableString(SharedImmutableString&& rhs)
21     : box_(rhs.box_) {
22   MOZ_ASSERT(this != &rhs, "self move not allowed");
23 
24   MOZ_ASSERT_IF(rhs.box_, rhs.box_->refcount > 0);
25 
26   rhs.box_ = nullptr;
27 }
28 
operator =(SharedImmutableString && rhs)29 SharedImmutableString& SharedImmutableString::operator=(
30     SharedImmutableString&& rhs) {
31   this->~SharedImmutableString();
32   new (this) SharedImmutableString(std::move(rhs));
33   return *this;
34 }
35 
SharedImmutableTwoByteString(SharedImmutableString && string)36 SharedImmutableTwoByteString::SharedImmutableTwoByteString(
37     SharedImmutableString&& string)
38     : string_(std::move(string)) {}
39 
SharedImmutableTwoByteString(SharedImmutableStringsCache::StringBox * box)40 SharedImmutableTwoByteString::SharedImmutableTwoByteString(
41     SharedImmutableStringsCache::StringBox* box)
42     : string_(box) {
43   MOZ_ASSERT(box->length() % sizeof(char16_t) == 0);
44 }
45 
SharedImmutableTwoByteString(SharedImmutableTwoByteString && rhs)46 SharedImmutableTwoByteString::SharedImmutableTwoByteString(
47     SharedImmutableTwoByteString&& rhs)
48     : string_(std::move(rhs.string_)) {
49   MOZ_ASSERT(this != &rhs, "self move not allowed");
50 }
51 
operator =(SharedImmutableTwoByteString && rhs)52 SharedImmutableTwoByteString& SharedImmutableTwoByteString::operator=(
53     SharedImmutableTwoByteString&& rhs) {
54   this->~SharedImmutableTwoByteString();
55   new (this) SharedImmutableTwoByteString(std::move(rhs));
56   return *this;
57 }
58 
~SharedImmutableString()59 SharedImmutableString::~SharedImmutableString() {
60   if (!box_) {
61     return;
62   }
63 
64   auto locked = box_->cache_->lock();
65 
66   MOZ_ASSERT(box_->refcount > 0);
67 
68   box_->refcount--;
69   if (box_->refcount == 0) {
70     box_->chars_.reset(nullptr);
71   }
72 }
73 
clone() const74 SharedImmutableString SharedImmutableString::clone() const {
75   auto locked = box_->cache_->lock();
76   MOZ_ASSERT(box_);
77   MOZ_ASSERT(box_->refcount > 0);
78   return SharedImmutableString(box_);
79 }
80 
clone() const81 SharedImmutableTwoByteString SharedImmutableTwoByteString::clone() const {
82   return SharedImmutableTwoByteString(string_.clone());
83 }
84 
getOrCreate(OwnedChars && chars,size_t length)85 [[nodiscard]] SharedImmutableString SharedImmutableStringsCache::getOrCreate(
86     OwnedChars&& chars, size_t length) {
87   OwnedChars owned(std::move(chars));
88   MOZ_ASSERT(owned);
89   return getOrCreate(owned.get(), length, [&]() { return std::move(owned); });
90 }
91 
getOrCreate(const char * chars,size_t length)92 [[nodiscard]] SharedImmutableString SharedImmutableStringsCache::getOrCreate(
93     const char* chars, size_t length) {
94   return getOrCreate(chars, length,
95                      [&]() { return DuplicateString(chars, length); });
96 }
97 
98 [[nodiscard]] SharedImmutableTwoByteString
getOrCreate(OwnedTwoByteChars && chars,size_t length)99 SharedImmutableStringsCache::getOrCreate(OwnedTwoByteChars&& chars,
100                                          size_t length) {
101   OwnedTwoByteChars owned(std::move(chars));
102   MOZ_ASSERT(owned);
103   return getOrCreate(owned.get(), length, [&]() { return std::move(owned); });
104 }
105 
106 [[nodiscard]] SharedImmutableTwoByteString
getOrCreate(const char16_t * chars,size_t length)107 SharedImmutableStringsCache::getOrCreate(const char16_t* chars, size_t length) {
108   return getOrCreate(chars, length,
109                      [&]() { return DuplicateString(chars, length); });
110 }
111 
112 }  // namespace js
113