Bug 1867190 - Add prefs for PHC probablities r=glandium
[gecko.git] / xpcom / base / RLBoxSandboxPool.cpp
blobc3b86f1698713b5eaa80726aeff5545f8d88b876
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 "nsThreadUtils.h"
8 #include "mozilla/ClearOnShutdown.h"
9 #include "mozilla/DebugOnly.h"
10 #include "mozilla/RLBoxSandboxPool.h"
11 #ifdef MOZ_USING_WASM_SANDBOXING
12 # include "wasm2c_rt_mem.h"
13 #endif
15 using namespace mozilla;
17 NS_IMPL_ISUPPORTS(RLBoxSandboxPool, nsITimerCallback, nsINamed)
19 void RLBoxSandboxPool::StartTimer() {
20 mMutex.AssertCurrentThreadOwns();
21 MOZ_ASSERT(!mTimer, "timer already initialized");
22 if (NS_IsMainThread() &&
23 PastShutdownPhase(ShutdownPhase::AppShutdownConfirmed)) {
24 // If we're shutting down, setting the time might fail, and we don't need it
25 // (since all the memory will be cleaned up soon anyway). Note that
26 // PastShutdownPhase() can only be called on the main thread, but that's
27 // fine, because other threads will have joined already by the point timers
28 // start failing to register.
29 mPool.Clear();
30 return;
32 DebugOnly<nsresult> rv = NS_NewTimerWithCallback(
33 getter_AddRefs(mTimer), this, mDelaySeconds * 1000,
34 nsITimer::TYPE_ONE_SHOT, GetMainThreadSerialEventTarget());
35 MOZ_ASSERT(NS_SUCCEEDED(rv), "failed to create timer");
38 void RLBoxSandboxPool::CancelTimer() {
39 mMutex.AssertCurrentThreadOwns();
40 if (mTimer) {
41 mTimer->Cancel();
42 mTimer = nullptr;
46 NS_IMETHODIMP RLBoxSandboxPool::Notify(nsITimer* aTimer) {
47 MutexAutoLock lock(mMutex);
49 mPool.Clear();
50 mTimer = nullptr;
52 return NS_OK;
55 NS_IMETHODIMP RLBoxSandboxPool::GetName(nsACString& aName) {
56 aName.AssignLiteral("RLBoxSandboxPool");
57 return NS_OK;
60 void RLBoxSandboxPool::Push(UniquePtr<RLBoxSandboxDataBase> sbxData) {
61 MutexAutoLock lock(mMutex);
63 mPool.AppendElement(std::move(sbxData));
64 if (!mTimer) {
65 StartTimer();
69 UniquePtr<RLBoxSandboxPoolData> RLBoxSandboxPool::PopOrCreate(
70 uint64_t aMinSize) {
71 MutexAutoLock lock(mMutex);
73 UniquePtr<RLBoxSandboxDataBase> sbxData;
75 if (!mPool.IsEmpty()) {
76 const int64_t lastIndex = ReleaseAssertedCast<int64_t>(mPool.Length()) - 1;
77 for (int64_t i = lastIndex; i >= 0; i--) {
78 if (mPool[i]->mSize >= aMinSize) {
79 sbxData = std::move(mPool[i]);
80 mPool.RemoveElementAt(i);
82 // If we reuse a sandbox from the pool, reset the timer to clear the
83 // pool
84 CancelTimer();
85 if (!mPool.IsEmpty()) {
86 StartTimer();
88 break;
93 if (!sbxData) {
94 #ifdef MOZ_USING_WASM_SANDBOXING
95 // RLBox's wasm sandboxes have a limited platform dependent capacity. We
96 // track this capacity in this pool.
97 const w2c_mem_capacity w2c_capacity = get_valid_wasm2c_memory_capacity(
98 aMinSize, true /* 32-bit wasm memory*/);
99 const uint64_t chosenCapacity = w2c_capacity.max_size;
100 #else
101 // Note the noop sandboxes have no capacity limit. In this case we simply
102 // specify a value of 4gb. This is not actually enforced by the noop
103 // sandbox.
104 const uint64_t chosenCapacity = static_cast<uint64_t>(1) << 32;
105 #endif
106 sbxData = CreateSandboxData(chosenCapacity);
107 NS_ENSURE_TRUE(sbxData, nullptr);
110 return MakeUnique<RLBoxSandboxPoolData>(std::move(sbxData), this);