XPCSelfHostedShmem.cpp (3220B)
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 "XPCSelfHostedShmem.h" 8 #include "xpcprivate.h" 9 10 // static 11 bool xpc::SelfHostedShmem::sSelfHostedUseSharedMemory = false; 12 mozilla::StaticRefPtr<xpc::SelfHostedShmem> 13 xpc::SelfHostedShmem::sSelfHostedXdr; 14 15 NS_IMPL_ISUPPORTS(xpc::SelfHostedShmem, nsIMemoryReporter) 16 17 // static 18 xpc::SelfHostedShmem& xpc::SelfHostedShmem::GetSingleton() { 19 MOZ_ASSERT_IF(!sSelfHostedXdr, NS_IsMainThread()); 20 21 if (!sSelfHostedXdr) { 22 sSelfHostedXdr = new SelfHostedShmem; 23 } 24 25 return *sSelfHostedXdr; 26 } 27 28 void xpc::SelfHostedShmem::InitMemoryReporter() { 29 mozilla::RegisterWeakMemoryReporter(this); 30 } 31 32 // static 33 void xpc::SelfHostedShmem::Shutdown() { 34 MOZ_ASSERT(NS_IsMainThread()); 35 // NOTE: We cannot call UnregisterWeakMemoryReporter(sSelfHostedXdr) as the 36 // service is shutdown at the time this call is made. In any cases, this would 37 // already be done when the memory reporter got destroyed. 38 sSelfHostedXdr = nullptr; 39 } 40 41 void xpc::SelfHostedShmem::InitFromParent(ContentType aXdr) { 42 MOZ_ASSERT(XRE_IsParentProcess()); 43 MOZ_ASSERT(NS_IsMainThread()); 44 MOZ_ASSERT(!mHandle && !mMem, "Shouldn't call this more than once"); 45 46 size_t len = aXdr.Length(); 47 auto handle = mozilla::ipc::shared_memory::CreateFreezable(len); 48 if (NS_WARN_IF(!handle)) { 49 return; 50 } 51 52 auto mapping = std::move(handle).Map(); 53 if (NS_WARN_IF(!mapping)) { 54 return; 55 } 56 57 void* address = mapping.Address(); 58 memcpy(address, aXdr.Elements(), aXdr.LengthBytes()); 59 60 mHandle = std::move(mapping).Freeze(); 61 mMem = mHandle.Map(); 62 } 63 64 bool xpc::SelfHostedShmem::InitFromChild( 65 mozilla::ipc::ReadOnlySharedMemoryHandle aHandle) { 66 MOZ_ASSERT(!XRE_IsParentProcess()); 67 MOZ_ASSERT(NS_IsMainThread()); 68 MOZ_ASSERT(!mMem, "Shouldn't call this more than once"); 69 70 mMem = aHandle.Map(); 71 return mMem.IsValid(); 72 } 73 74 xpc::SelfHostedShmem::ContentType xpc::SelfHostedShmem::Content() const { 75 if (!mMem) { 76 return ContentType(); 77 } 78 return mMem.DataAsSpan<uint8_t>(); 79 } 80 81 const mozilla::ipc::ReadOnlySharedMemoryHandle& xpc::SelfHostedShmem::Handle() 82 const { 83 return mHandle; 84 } 85 86 NS_IMETHODIMP 87 xpc::SelfHostedShmem::CollectReports(nsIHandleReportCallback* aHandleReport, 88 nsISupports* aData, bool aAnonymize) { 89 // If this is the parent process, then we have a handle and this instance owns 90 // the data and shares it with other processes, otherwise this is shared data. 91 if (XRE_IsParentProcess()) { 92 // This does not exactly report the amount of data mapped by the system, 93 // but the space requested when creating the handle. 94 MOZ_COLLECT_REPORT("explicit/js-non-window/shared-memory/self-hosted-xdr", 95 KIND_NONHEAP, UNITS_BYTES, mMem.Size(), 96 "Memory used to initialize the JS engine with the " 97 "self-hosted code encoded by the parent process."); 98 } 99 return NS_OK; 100 }