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