Bug 1920241 - Update Persisted Search preferences text - r=daleharvey,fluent-reviewer...
[gecko.git] / ipc / glue / SharedMemory.cpp
blob94a81aea0d38a963ba4ef28cc2cf5d240c3d19fa
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 "mozilla/ipc/SharedMemory.h"
9 #include "mozilla/Atomics.h"
10 #include "nsIMemoryReporter.h"
12 #ifdef FUZZING
13 # include "mozilla/ipc/SharedMemoryFuzzer.h"
14 #endif
16 namespace mozilla::ipc {
18 static Atomic<size_t> gShmemAllocated;
19 static Atomic<size_t> gShmemMapped;
21 class ShmemReporter final : public nsIMemoryReporter {
22 ~ShmemReporter() = default;
24 public:
25 NS_DECL_THREADSAFE_ISUPPORTS
27 NS_IMETHOD
28 CollectReports(nsIHandleReportCallback* aHandleReport, nsISupports* aData,
29 bool aAnonymize) override {
30 MOZ_COLLECT_REPORT(
31 "shmem-allocated", KIND_OTHER, UNITS_BYTES, gShmemAllocated,
32 "Memory shared with other processes that is accessible (but not "
33 "necessarily mapped).");
35 MOZ_COLLECT_REPORT(
36 "shmem-mapped", KIND_OTHER, UNITS_BYTES, gShmemMapped,
37 "Memory shared with other processes that is mapped into the address "
38 "space.");
40 return NS_OK;
44 NS_IMPL_ISUPPORTS(ShmemReporter, nsIMemoryReporter)
46 SharedMemory::SharedMemory() : mAllocSize(0), mMappedSize(0) {
47 static Atomic<bool> registered;
48 if (registered.compareExchange(false, true)) {
49 RegisterStrongMemoryReporter(new ShmemReporter());
53 SharedMemory::~SharedMemory() {
54 Unmap();
55 CloseHandle();
57 MOZ_ASSERT(gShmemAllocated >= mAllocSize,
58 "Can't destroy more than allocated");
59 gShmemAllocated -= mAllocSize;
60 mAllocSize = 0;
63 bool SharedMemory::WriteHandle(IPC::MessageWriter* aWriter) {
64 Handle handle = CloneHandle();
65 if (!handle) {
66 return false;
68 IPC::WriteParam(aWriter, std::move(handle));
69 return true;
72 bool SharedMemory::ReadHandle(IPC::MessageReader* aReader) {
73 Handle handle;
74 return IPC::ReadParam(aReader, &handle) && IsHandleValid(handle) &&
75 SetHandle(std::move(handle), RightsReadWrite);
78 void SharedMemory::Protect(char* aAddr, size_t aSize, int aRights) {
79 char* memStart = reinterpret_cast<char*>(Memory());
80 if (!memStart) MOZ_CRASH("SharedMemory region points at NULL!");
81 char* memEnd = memStart + Size();
83 char* protStart = aAddr;
84 if (!protStart) MOZ_CRASH("trying to Protect() a NULL region!");
85 char* protEnd = protStart + aSize;
87 if (!(memStart <= protStart && protEnd <= memEnd)) {
88 MOZ_CRASH("attempt to Protect() a region outside this SharedMemory");
91 // checks alignment etc.
92 SystemProtect(aAddr, aSize, aRights);
95 size_t SharedMemory::PageAlignedSize(size_t aSize) {
96 size_t pageSize = SystemPageSize();
97 size_t nPagesNeeded = size_t(ceil(double(aSize) / double(pageSize)));
98 return pageSize * nPagesNeeded;
101 bool SharedMemory::Create(size_t aNBytes) {
102 bool ok = CreateImpl(aNBytes);
103 if (ok) {
104 mAllocSize = aNBytes;
105 gShmemAllocated += mAllocSize;
107 return ok;
110 bool SharedMemory::Map(size_t aNBytes, void* fixedAddress) {
111 bool ok = MapImpl(aNBytes, fixedAddress);
112 if (ok) {
113 mMappedSize = aNBytes;
114 gShmemMapped += mMappedSize;
116 return ok;
119 void SharedMemory::Unmap() {
120 MOZ_ASSERT(gShmemMapped >= mMappedSize, "Can't unmap more than mapped");
121 UnmapImpl(mMappedSize);
122 gShmemMapped -= mMappedSize;
123 mMappedSize = 0;
126 void* SharedMemory::Memory() const {
127 #ifdef FUZZING
128 return SharedMemoryFuzzer::MutateSharedMemory(MemoryImpl(), mAllocSize);
129 #else
130 return MemoryImpl();
131 #endif
134 } // namespace mozilla::ipc