Bug 1861467 - [wpt-sync] Update web-platform-tests to eedf737ce39c512d0ca3471f988972e...
[gecko.git] / dom / ipc / SharedStringMap.cpp
blob8d50de686339d1880c8cf096dc6c622a55d6d762
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/. */
7 #include "SharedStringMap.h"
9 #include "MemMapSnapshot.h"
10 #include "ScriptPreloader-inl.h"
12 #include "mozilla/BinarySearch.h"
13 #include "mozilla/Try.h"
14 #include "mozilla/ipc/FileDescriptor.h"
16 using namespace mozilla::loader;
18 namespace mozilla {
20 using namespace ipc;
22 namespace dom::ipc {
24 static constexpr uint32_t kSharedStringMapMagic = 0x9e3779b9;
26 static inline size_t GetAlignmentOffset(size_t aOffset, size_t aAlign) {
27 auto mod = aOffset % aAlign;
28 return mod ? aAlign - mod : 0;
31 SharedStringMap::SharedStringMap(const FileDescriptor& aMapFile,
32 size_t aMapSize) {
33 auto result = mMap.initWithHandle(aMapFile, aMapSize);
34 MOZ_RELEASE_ASSERT(result.isOk());
35 MOZ_RELEASE_ASSERT(GetHeader().mMagic == kSharedStringMapMagic);
36 // We return literal nsStrings and nsCStrings pointing to the mapped data,
37 // which means that we may still have references to the mapped data even
38 // after this instance is destroyed. That means that we need to keep the
39 // mapping alive until process shutdown, in order to be safe.
40 mMap.setPersistent();
43 SharedStringMap::SharedStringMap(SharedStringMapBuilder&& aBuilder) {
44 auto result = aBuilder.Finalize(mMap);
45 MOZ_RELEASE_ASSERT(result.isOk());
46 MOZ_RELEASE_ASSERT(GetHeader().mMagic == kSharedStringMapMagic);
47 mMap.setPersistent();
50 mozilla::ipc::FileDescriptor SharedStringMap::CloneFileDescriptor() const {
51 return mMap.cloneHandle();
54 bool SharedStringMap::Has(const nsCString& aKey) {
55 size_t index;
56 return Find(aKey, &index);
59 bool SharedStringMap::Get(const nsCString& aKey, nsAString& aValue) {
60 const auto& entries = Entries();
62 size_t index;
63 if (!Find(aKey, &index)) {
64 return false;
67 aValue.Assign(ValueTable().Get(entries[index].mValue));
68 return true;
71 bool SharedStringMap::Find(const nsCString& aKey, size_t* aIndex) {
72 const auto& keys = KeyTable();
74 return BinarySearchIf(
75 Entries(), 0, EntryCount(),
76 [&](const Entry& aEntry) { return Compare(aKey, keys.Get(aEntry.mKey)); },
77 aIndex);
80 void SharedStringMapBuilder::Add(const nsCString& aKey,
81 const nsString& aValue) {
82 mEntries.InsertOrUpdate(aKey,
83 Entry{mKeyTable.Add(aKey), mValueTable.Add(aValue)});
86 Result<Ok, nsresult> SharedStringMapBuilder::Finalize(
87 loader::AutoMemMap& aMap) {
88 using Header = SharedStringMap::Header;
90 MOZ_ASSERT(mEntries.Count() == mKeyTable.Count());
92 auto keys = ToTArray<nsTArray<nsCString>>(mEntries.Keys());
93 keys.Sort();
95 Header header = {kSharedStringMapMagic, uint32_t(keys.Length())};
97 size_t offset = sizeof(header);
98 offset += GetAlignmentOffset(offset, alignof(Header));
100 offset += keys.Length() * sizeof(SharedStringMap::Entry);
102 header.mKeyStringsOffset = offset;
103 header.mKeyStringsSize = mKeyTable.Size();
105 offset += header.mKeyStringsSize;
106 offset +=
107 GetAlignmentOffset(offset, alignof(decltype(mValueTable)::ElemType));
109 header.mValueStringsOffset = offset;
110 header.mValueStringsSize = mValueTable.Size();
112 offset += header.mValueStringsSize;
114 MemMapSnapshot mem;
115 MOZ_TRY(mem.Init(offset));
117 auto headerPtr = mem.Get<Header>();
118 headerPtr[0] = header;
120 auto* entry = reinterpret_cast<Entry*>(&headerPtr[1]);
121 for (auto& key : keys) {
122 *entry++ = mEntries.Get(key);
125 auto ptr = mem.Get<uint8_t>();
127 mKeyTable.Write({&ptr[header.mKeyStringsOffset], header.mKeyStringsSize});
129 mValueTable.Write(
130 {&ptr[header.mValueStringsOffset], header.mValueStringsSize});
132 mKeyTable.Clear();
133 mValueTable.Clear();
134 mEntries.Clear();
136 return mem.Finalize(aMap);
139 } // namespace dom::ipc
140 } // namespace mozilla