summaryrefslogtreecommitdiff
path: root/chromium/components/discardable_memory
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-04-05 14:08:31 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-04-11 07:46:53 +0000
commit6a4cabb866f66d4128a97cdc6d9d08ce074f1247 (patch)
treeab00f70a5e89278d6a0d16ff0c42578dc4d84a2d /chromium/components/discardable_memory
parente733310db58160074f574c429d48f8308c0afe17 (diff)
downloadqtwebengine-chromium-6a4cabb866f66d4128a97cdc6d9d08ce074f1247.tar.gz
BASELINE: Update Chromium to 57.0.2987.144
Change-Id: I29db402ff696c71a04c4dbaec822c2e53efe0267 Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
Diffstat (limited to 'chromium/components/discardable_memory')
-rw-r--r--chromium/components/discardable_memory/DEPS3
-rw-r--r--chromium/components/discardable_memory/client/BUILD.gn1
-rw-r--r--chromium/components/discardable_memory/client/client_discardable_shared_memory_manager.cc158
-rw-r--r--chromium/components/discardable_memory/client/client_discardable_shared_memory_manager.h44
-rw-r--r--chromium/components/discardable_memory/common/BUILD.gn1
-rw-r--r--chromium/components/discardable_memory/common/discardable_shared_memory_id.h17
-rw-r--r--chromium/components/discardable_memory/public/interfaces/BUILD.gn17
-rw-r--r--chromium/components/discardable_memory/public/interfaces/OWNERS2
-rw-r--r--chromium/components/discardable_memory/public/interfaces/discardable_shared_memory_manager.mojom16
-rw-r--r--chromium/components/discardable_memory/service/BUILD.gn1
-rw-r--r--chromium/components/discardable_memory/service/discardable_shared_memory_manager.cc92
-rw-r--r--chromium/components/discardable_memory/service/discardable_shared_memory_manager.h31
-rw-r--r--chromium/components/discardable_memory/service/discardable_shared_memory_manager_unittest.cc21
13 files changed, 262 insertions, 142 deletions
diff --git a/chromium/components/discardable_memory/DEPS b/chromium/components/discardable_memory/DEPS
new file mode 100644
index 00000000000..093b1d9fde5
--- /dev/null
+++ b/chromium/components/discardable_memory/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+mojo/public/cpp",
+]
diff --git a/chromium/components/discardable_memory/client/BUILD.gn b/chromium/components/discardable_memory/client/BUILD.gn
index 583a8ee11b8..8cf73572b80 100644
--- a/chromium/components/discardable_memory/client/BUILD.gn
+++ b/chromium/components/discardable_memory/client/BUILD.gn
@@ -17,5 +17,6 @@ component("client") {
deps = [
"//base",
"//components/discardable_memory/common",
+ "//components/discardable_memory/public/interfaces",
]
}
diff --git a/chromium/components/discardable_memory/client/client_discardable_shared_memory_manager.cc b/chromium/components/discardable_memory/client/client_discardable_shared_memory_manager.cc
index 22239e13869..cd768d0f2d6 100644
--- a/chromium/components/discardable_memory/client/client_discardable_shared_memory_manager.cc
+++ b/chromium/components/discardable_memory/client/client_discardable_shared_memory_manager.cc
@@ -21,9 +21,11 @@
#include "base/process/process_metrics.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
+#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/trace_event.h"
+#include "mojo/public/cpp/system/platform_handle.h"
namespace discardable_memory {
namespace {
@@ -82,29 +84,52 @@ class DiscardableMemoryImpl : public base::DiscardableMemory {
DISALLOW_COPY_AND_ASSIGN(DiscardableMemoryImpl);
};
-void SendDeletedDiscardableSharedMemoryMessage(
- ClientDiscardableSharedMemoryManager::Delegate* delegate,
- DiscardableSharedMemoryId id) {
- delegate->DeletedDiscardableSharedMemory(id);
+void InitManagerMojoOnIO(mojom::DiscardableSharedMemoryManagerPtr* manager_mojo,
+ mojom::DiscardableSharedMemoryManagerPtrInfo info) {
+ manager_mojo->Bind(std::move(info));
+}
+
+void DeletedDiscardableSharedMemoryOnIO(
+ mojom::DiscardableSharedMemoryManagerPtr* manager_mojo,
+ int32_t id) {
+ (*manager_mojo)->DeletedDiscardableSharedMemory(id);
}
} // namespace
ClientDiscardableSharedMemoryManager::ClientDiscardableSharedMemoryManager(
- Delegate* delegate)
- : heap_(base::GetPageSize()), delegate_(delegate) {
+ mojom::DiscardableSharedMemoryManagerPtr manager,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
+ : io_task_runner_(std::move(io_task_runner)),
+ manager_mojo_(new mojom::DiscardableSharedMemoryManagerPtr),
+ heap_(new DiscardableSharedMemoryHeap(base::GetPageSize())) {
base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
this, "ClientDiscardableSharedMemoryManager",
base::ThreadTaskRunnerHandle::Get());
+ mojom::DiscardableSharedMemoryManagerPtrInfo info = manager.PassInterface();
+ io_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&InitManagerMojoOnIO, manager_mojo_.get(),
+ base::Passed(&info)));
}
ClientDiscardableSharedMemoryManager::~ClientDiscardableSharedMemoryManager() {
base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
this);
// TODO(reveman): Determine if this DCHECK can be enabled. crbug.com/430533
- // DCHECK_EQ(heap_.GetSize(), heap_.GetSizeOfFreeLists());
- if (heap_.GetSize())
+ // DCHECK_EQ(heap_->GetSize(), heap_->GetSizeOfFreeLists());
+ if (heap_->GetSize())
MemoryUsageChanged(0, 0);
+
+ // Releasing the |heap_| before posting a task for deleting |manager_mojo_|.
+ // It is because releasing |heap_| will invoke DeletedDiscardableSharedMemory
+ // which needs |manager_mojo_|.
+ heap_.reset();
+
+ // Delete the |manager_mojo_| on IO thread, so any pending tasks on IO thread
+ // will be executed before the |manager_mojo_| is deleted.
+ bool posted = io_task_runner_->DeleteSoon(FROM_HERE, manager_mojo_.release());
+ if (!posted)
+ manager_mojo_.reset();
}
std::unique_ptr<base::DiscardableMemory>
@@ -138,11 +163,11 @@ ClientDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(
if (pages < allocation_pages)
slack = allocation_pages - pages;
- size_t heap_size_prior_to_releasing_purged_memory = heap_.GetSize();
+ size_t heap_size_prior_to_releasing_purged_memory = heap_->GetSize();
for (;;) {
// Search free lists for suitable span.
std::unique_ptr<DiscardableSharedMemoryHeap::Span> free_span =
- heap_.SearchFreeLists(pages, slack);
+ heap_->SearchFreeLists(pages, slack);
if (!free_span.get())
break;
@@ -155,7 +180,7 @@ ClientDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(
base::DiscardableSharedMemory::FAILED) {
DCHECK(!free_span->shared_memory()->IsMemoryResident());
// We have to release purged memory before |free_span| can be destroyed.
- heap_.ReleasePurgedMemory();
+ heap_->ReleasePurgedMemory();
DCHECK(!free_span->shared_memory());
continue;
}
@@ -164,50 +189,53 @@ ClientDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(
// Memory usage is guaranteed to have changed after having removed
// at least one span from the free lists.
- MemoryUsageChanged(heap_.GetSize(), heap_.GetSizeOfFreeLists());
+ MemoryUsageChanged(heap_->GetSize(), heap_->GetSizeOfFreeLists());
return base::MakeUnique<DiscardableMemoryImpl>(this, std::move(free_span));
}
// Release purged memory to free up the address space before we attempt to
// allocate more memory.
- heap_.ReleasePurgedMemory();
+ heap_->ReleasePurgedMemory();
// Make sure crash keys are up to date in case allocation fails.
- if (heap_.GetSize() != heap_size_prior_to_releasing_purged_memory)
- MemoryUsageChanged(heap_.GetSize(), heap_.GetSizeOfFreeLists());
+ if (heap_->GetSize() != heap_size_prior_to_releasing_purged_memory)
+ MemoryUsageChanged(heap_->GetSize(), heap_->GetSizeOfFreeLists());
size_t pages_to_allocate =
std::max(kAllocationSize / base::GetPageSize(), pages);
size_t allocation_size_in_bytes = pages_to_allocate * base::GetPageSize();
- DiscardableSharedMemoryId new_id =
- g_next_discardable_shared_memory_id.GetNext();
+ int32_t new_id = g_next_discardable_shared_memory_id.GetNext();
// Ask parent process to allocate a new discardable shared memory segment.
- std::unique_ptr<base::DiscardableSharedMemory> shared_memory(
- AllocateLockedDiscardableSharedMemory(allocation_size_in_bytes, new_id));
+ std::unique_ptr<base::DiscardableSharedMemory> shared_memory =
+ AllocateLockedDiscardableSharedMemory(allocation_size_in_bytes, new_id);
// Create span for allocated memory.
- std::unique_ptr<DiscardableSharedMemoryHeap::Span> new_span(
- heap_.Grow(std::move(shared_memory), allocation_size_in_bytes, new_id,
- base::Bind(&SendDeletedDiscardableSharedMemoryMessage,
- delegate_, new_id)));
+ // Spans are managed by |heap_| (the member of
+ // the ClientDiscardableSharedMemoryManager), so it is safe to use
+ // base::Unretained(this) here.
+ std::unique_ptr<DiscardableSharedMemoryHeap::Span> new_span(heap_->Grow(
+ std::move(shared_memory), allocation_size_in_bytes, new_id,
+ base::Bind(
+ &ClientDiscardableSharedMemoryManager::DeletedDiscardableSharedMemory,
+ base::Unretained(this), new_id)));
new_span->set_is_locked(true);
// Unlock and insert any left over memory into free lists.
if (pages < pages_to_allocate) {
std::unique_ptr<DiscardableSharedMemoryHeap::Span> leftover =
- heap_.Split(new_span.get(), pages);
+ heap_->Split(new_span.get(), pages);
leftover->shared_memory()->Unlock(
leftover->start() * base::GetPageSize() -
reinterpret_cast<size_t>(leftover->shared_memory()->memory()),
leftover->length() * base::GetPageSize());
leftover->set_is_locked(false);
- heap_.MergeIntoFreeLists(std::move(leftover));
+ heap_->MergeIntoFreeLists(std::move(leftover));
}
- MemoryUsageChanged(heap_.GetSize(), heap_.GetSizeOfFreeLists());
+ MemoryUsageChanged(heap_->GetSize(), heap_->GetSizeOfFreeLists());
return base::MakeUnique<DiscardableMemoryImpl>(this, std::move(new_span));
}
@@ -222,8 +250,8 @@ bool ClientDiscardableSharedMemoryManager::OnMemoryDump(
pmd->CreateAllocatorDump(
base::StringPrintf("discardable/child_0x%" PRIXPTR,
reinterpret_cast<uintptr_t>(this)));
- const size_t total_size = heap_.GetSize();
- const size_t freelist_size = heap_.GetSizeOfFreeLists();
+ const size_t total_size = heap_->GetSize();
+ const size_t freelist_size = heap_->GetSizeOfFreeLists();
total_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
base::trace_event::MemoryAllocatorDump::kUnitsBytes,
total_size - freelist_size);
@@ -233,29 +261,29 @@ bool ClientDiscardableSharedMemoryManager::OnMemoryDump(
return true;
}
- return heap_.OnMemoryDump(pmd);
+ return heap_->OnMemoryDump(pmd);
}
ClientDiscardableSharedMemoryManager::Statistics
ClientDiscardableSharedMemoryManager::GetStatistics() const {
base::AutoLock lock(lock_);
Statistics stats;
- stats.total_size = heap_.GetSize();
- stats.freelist_size = heap_.GetSizeOfFreeLists();
+ stats.total_size = heap_->GetSize();
+ stats.freelist_size = heap_->GetSizeOfFreeLists();
return stats;
}
void ClientDiscardableSharedMemoryManager::ReleaseFreeMemory() {
base::AutoLock lock(lock_);
- size_t heap_size_prior_to_releasing_memory = heap_.GetSize();
+ size_t heap_size_prior_to_releasing_memory = heap_->GetSize();
// Release both purged and free memory.
- heap_.ReleasePurgedMemory();
- heap_.ReleaseFreeMemory();
+ heap_->ReleasePurgedMemory();
+ heap_->ReleaseFreeMemory();
- if (heap_.GetSize() != heap_size_prior_to_releasing_memory)
- MemoryUsageChanged(heap_.GetSize(), heap_.GetSizeOfFreeLists());
+ if (heap_->GetSize() != heap_size_prior_to_releasing_memory)
+ MemoryUsageChanged(heap_->GetSize(), heap_->GetSizeOfFreeLists());
}
bool ClientDiscardableSharedMemoryManager::LockSpan(
@@ -306,10 +334,10 @@ void ClientDiscardableSharedMemoryManager::ReleaseSpan(
if (!span->shared_memory())
return;
- heap_.MergeIntoFreeLists(std::move(span));
+ heap_->MergeIntoFreeLists(std::move(span));
// Bytes of free memory changed.
- MemoryUsageChanged(heap_.GetSize(), heap_.GetSizeOfFreeLists());
+ MemoryUsageChanged(heap_->GetSize(), heap_->GetSizeOfFreeLists());
}
base::trace_event::MemoryAllocatorDump*
@@ -318,27 +346,67 @@ ClientDiscardableSharedMemoryManager::CreateMemoryAllocatorDump(
const char* name,
base::trace_event::ProcessMemoryDump* pmd) const {
base::AutoLock lock(lock_);
- return heap_.CreateMemoryAllocatorDump(span, name, pmd);
+ return heap_->CreateMemoryAllocatorDump(span, name, pmd);
}
std::unique_ptr<base::DiscardableSharedMemory>
ClientDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory(
size_t size,
- DiscardableSharedMemoryId id) {
+ int32_t id) {
TRACE_EVENT2("renderer",
"ClientDiscardableSharedMemoryManager::"
"AllocateLockedDiscardableSharedMemory",
"size", size, "id", id);
-
- base::SharedMemoryHandle handle = base::SharedMemory::NULLHandle();
- delegate_->AllocateLockedDiscardableSharedMemory(size, id, &handle);
- std::unique_ptr<base::DiscardableSharedMemory> memory(
- new base::DiscardableSharedMemory(handle));
+ base::SharedMemoryHandle handle;
+ base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
+ base::ScopedClosureRunner event_signal_runner(
+ base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)));
+ io_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&ClientDiscardableSharedMemoryManager::AllocateOnIO,
+ base::Unretained(this), size, id, &handle,
+ base::Passed(&event_signal_runner)));
+ // Waiting until IPC has finished on the IO thread.
+ event.Wait();
+ auto memory = base::MakeUnique<base::DiscardableSharedMemory>(handle);
if (!memory->Map(size))
base::TerminateBecauseOutOfMemory(size);
return memory;
}
+void ClientDiscardableSharedMemoryManager::AllocateOnIO(
+ size_t size,
+ int32_t id,
+ base::SharedMemoryHandle* handle,
+ base::ScopedClosureRunner closure_runner) {
+ (*manager_mojo_)
+ ->AllocateLockedDiscardableSharedMemory(
+ static_cast<uint32_t>(size), id,
+ base::Bind(
+ &ClientDiscardableSharedMemoryManager::AllocateCompletedOnIO,
+ base::Unretained(this), handle, base::Passed(&closure_runner)));
+}
+
+void ClientDiscardableSharedMemoryManager::AllocateCompletedOnIO(
+ base::SharedMemoryHandle* handle,
+ base::ScopedClosureRunner closure_runner,
+ mojo::ScopedSharedBufferHandle mojo_handle) {
+ size_t memory_size = 0;
+ bool read_only = false;
+ if (!mojo_handle.is_valid())
+ return;
+ auto result = mojo::UnwrapSharedMemoryHandle(std::move(mojo_handle), handle,
+ &memory_size, &read_only);
+ DCHECK_EQ(result, MOJO_RESULT_OK);
+}
+
+void ClientDiscardableSharedMemoryManager::DeletedDiscardableSharedMemory(
+ int32_t id) {
+ io_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&DeletedDiscardableSharedMemoryOnIO, manager_mojo_.get(), id));
+}
+
void ClientDiscardableSharedMemoryManager::MemoryUsageChanged(
size_t new_bytes_total,
size_t new_bytes_free) const {
diff --git a/chromium/components/discardable_memory/client/client_discardable_shared_memory_manager.h b/chromium/components/discardable_memory/client/client_discardable_shared_memory_manager.h
index 76215bc099f..c6b375bdaa2 100644
--- a/chromium/components/discardable_memory/client/client_discardable_shared_memory_manager.h
+++ b/chromium/components/discardable_memory/client/client_discardable_shared_memory_manager.h
@@ -7,6 +7,7 @@
#include <stddef.h>
+#include "base/callback_helpers.h"
#include "base/macros.h"
#include "base/memory/discardable_memory_allocator.h"
#include "base/memory/ref_counted.h"
@@ -15,7 +16,11 @@
#include "base/trace_event/memory_dump_provider.h"
#include "components/discardable_memory/common/discardable_memory_export.h"
#include "components/discardable_memory/common/discardable_shared_memory_heap.h"
-#include "components/discardable_memory/common/discardable_shared_memory_id.h"
+#include "components/discardable_memory/public/interfaces/discardable_shared_memory_manager.mojom.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}
namespace discardable_memory {
@@ -25,20 +30,9 @@ class DISCARDABLE_MEMORY_EXPORT ClientDiscardableSharedMemoryManager
: public base::DiscardableMemoryAllocator,
public base::trace_event::MemoryDumpProvider {
public:
- class Delegate {
- public:
- virtual void AllocateLockedDiscardableSharedMemory(
- size_t size,
- DiscardableSharedMemoryId id,
- base::SharedMemoryHandle* handle) = 0;
- virtual void DeletedDiscardableSharedMemory(
- DiscardableSharedMemoryId id) = 0;
-
- protected:
- virtual ~Delegate() {}
- };
-
- explicit ClientDiscardableSharedMemoryManager(Delegate* delegate);
+ ClientDiscardableSharedMemoryManager(
+ mojom::DiscardableSharedMemoryManagerPtr manager,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
~ClientDiscardableSharedMemoryManager() override;
// Overridden from base::DiscardableMemoryAllocator:
@@ -70,14 +64,26 @@ class DISCARDABLE_MEMORY_EXPORT ClientDiscardableSharedMemoryManager
private:
std::unique_ptr<base::DiscardableSharedMemory>
- AllocateLockedDiscardableSharedMemory(size_t size,
- DiscardableSharedMemoryId id);
+ AllocateLockedDiscardableSharedMemory(size_t size, int32_t id);
+ void AllocateOnIO(size_t size,
+ int32_t id,
+ base::SharedMemoryHandle* handle,
+ base::ScopedClosureRunner closure_runner);
+ void AllocateCompletedOnIO(base::SharedMemoryHandle* handle,
+ base::ScopedClosureRunner closure_runner,
+ mojo::ScopedSharedBufferHandle mojo_handle);
+
+ void DeletedDiscardableSharedMemory(int32_t id);
void MemoryUsageChanged(size_t new_bytes_allocated,
size_t new_bytes_free) const;
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
+ // TODO(penghuang): Switch to ThreadSafeInterfacePtr when it starts supporting
+ // sync method call.
+ std::unique_ptr<mojom::DiscardableSharedMemoryManagerPtr> manager_mojo_;
+
mutable base::Lock lock_;
- DiscardableSharedMemoryHeap heap_;
- Delegate* const delegate_;
+ std::unique_ptr<DiscardableSharedMemoryHeap> heap_;
DISALLOW_COPY_AND_ASSIGN(ClientDiscardableSharedMemoryManager);
};
diff --git a/chromium/components/discardable_memory/common/BUILD.gn b/chromium/components/discardable_memory/common/BUILD.gn
index 9450c87a8c4..9d9ffae80a8 100644
--- a/chromium/components/discardable_memory/common/BUILD.gn
+++ b/chromium/components/discardable_memory/common/BUILD.gn
@@ -13,7 +13,6 @@ component("common") {
"discardable_memory_export.h",
"discardable_shared_memory_heap.cc",
"discardable_shared_memory_heap.h",
- "discardable_shared_memory_id.h",
]
deps = [
diff --git a/chromium/components/discardable_memory/common/discardable_shared_memory_id.h b/chromium/components/discardable_memory/common/discardable_shared_memory_id.h
deleted file mode 100644
index 53f98a57a34..00000000000
--- a/chromium/components/discardable_memory/common/discardable_shared_memory_id.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_DISCARDABLE_MEMORY_COMMON_DISCARDABLE_SHARED_MEMORY_ID_H_
-#define COMPONENTS_DISCARDABLE_MEMORY_COMMON_DISCARDABLE_SHARED_MEMORY_ID_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-namespace discardable_memory {
-
-typedef int32_t DiscardableSharedMemoryId;
-
-} // namespace discardable_memory
-
-#endif // COMPONENTS_DISCARDABLE_MEMORY_COMMON_DISCARDABLE_SHARED_MEMORY_ID_H_
diff --git a/chromium/components/discardable_memory/public/interfaces/BUILD.gn b/chromium/components/discardable_memory/public/interfaces/BUILD.gn
new file mode 100644
index 00000000000..0ce0a31e416
--- /dev/null
+++ b/chromium/components/discardable_memory/public/interfaces/BUILD.gn
@@ -0,0 +1,17 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//mojo/public/tools/bindings/mojom.gni")
+import("//testing/test.gni")
+
+mojom("interfaces") {
+ sources = [
+ "discardable_shared_memory_manager.mojom",
+ ]
+
+ import_dirs = [
+ get_path_info("../../../..", "abspath"),
+ "//mojo/services",
+ ]
+}
diff --git a/chromium/components/discardable_memory/public/interfaces/OWNERS b/chromium/components/discardable_memory/public/interfaces/OWNERS
new file mode 100644
index 00000000000..08850f42120
--- /dev/null
+++ b/chromium/components/discardable_memory/public/interfaces/OWNERS
@@ -0,0 +1,2 @@
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chromium/components/discardable_memory/public/interfaces/discardable_shared_memory_manager.mojom b/chromium/components/discardable_memory/public/interfaces/discardable_shared_memory_manager.mojom
new file mode 100644
index 00000000000..9d291d82d22
--- /dev/null
+++ b/chromium/components/discardable_memory/public/interfaces/discardable_shared_memory_manager.mojom
@@ -0,0 +1,16 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module discardable_memory.mojom;
+
+// This interface is used for allocating discardable shared memory from browser
+// process. For mus+ash, this service will live in mus process.
+interface DiscardableSharedMemoryManager {
+ // Allocate a locked discardable shared memory segment.
+ AllocateLockedDiscardableSharedMemory(
+ uint32 size,
+ int32 id) => (handle<shared_buffer>? memory);
+ // Notify manager that a memory segment has been deleted.
+ DeletedDiscardableSharedMemory(int32 id);
+};
diff --git a/chromium/components/discardable_memory/service/BUILD.gn b/chromium/components/discardable_memory/service/BUILD.gn
index 4061d7208df..6ac608b78df 100644
--- a/chromium/components/discardable_memory/service/BUILD.gn
+++ b/chromium/components/discardable_memory/service/BUILD.gn
@@ -17,6 +17,7 @@ component("service") {
deps = [
"//base",
"//components/discardable_memory/common",
+ "//components/discardable_memory/public/interfaces",
]
}
diff --git a/chromium/components/discardable_memory/service/discardable_shared_memory_manager.cc b/chromium/components/discardable_memory/service/discardable_shared_memory_manager.cc
index 1036dc84d69..a974b2d9e27 100644
--- a/chromium/components/discardable_memory/service/discardable_shared_memory_manager.cc
+++ b/chromium/components/discardable_memory/service/discardable_shared_memory_manager.cc
@@ -12,7 +12,6 @@
#include "base/callback.h"
#include "base/command_line.h"
#include "base/debug/crash_logging.h"
-#include "base/lazy_instance.h"
#include "base/macros.h"
#include "base/memory/discardable_memory.h"
#include "base/memory/memory_coordinator_client_registry.h"
@@ -29,6 +28,8 @@
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "components/discardable_memory/common/discardable_shared_memory_heap.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "mojo/public/cpp/system/platform_handle.h"
#if defined(OS_LINUX)
#include "base/files/file_path.h"
@@ -57,6 +58,48 @@ uint64_t ClientProcessUniqueIdToTracingProcessId(int client_id) {
1;
}
+// mojom::DiscardableSharedMemoryManager implementation. It contains the
+// |client_id_| which is not visible to client. We associate allocations with a
+// given mojo instance, so if the instance is closed, we can release the
+// allocations associated with that instance.
+class MojoDiscardableSharedMemoryManagerImpl
+ : public mojom::DiscardableSharedMemoryManager {
+ public:
+ MojoDiscardableSharedMemoryManagerImpl(
+ int32_t client_id,
+ ::discardable_memory::DiscardableSharedMemoryManager* manager)
+ : client_id_(client_id), manager_(manager) {}
+
+ ~MojoDiscardableSharedMemoryManagerImpl() override {
+ // Remove this client from the |manager_|, so all allocated discardable
+ // memory belong to this client will be released.
+ manager_->ClientRemoved(client_id_);
+ }
+
+ // mojom::DiscardableSharedMemoryManager overrides:
+ void AllocateLockedDiscardableSharedMemory(
+ uint32_t size,
+ int32_t id,
+ const AllocateLockedDiscardableSharedMemoryCallback& callback) override {
+ base::SharedMemoryHandle handle;
+ manager_->AllocateLockedDiscardableSharedMemoryForClient(client_id_, size,
+ id, &handle);
+ mojo::ScopedSharedBufferHandle memory =
+ mojo::WrapSharedMemoryHandle(handle, size, false /* read_only */);
+ return callback.Run(std::move(memory));
+ }
+
+ void DeletedDiscardableSharedMemory(int32_t id) override {
+ manager_->ClientDeletedDiscardableSharedMemory(id, client_id_);
+ }
+
+ private:
+ const int32_t client_id_;
+ ::discardable_memory::DiscardableSharedMemoryManager* const manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(MojoDiscardableSharedMemoryManagerImpl);
+};
+
class DiscardableMemoryImpl : public base::DiscardableMemory {
public:
DiscardableMemoryImpl(
@@ -163,9 +206,6 @@ int64_t GetDefaultMemoryLimit() {
base::SysInfo::AmountOfPhysicalMemory() / 4);
}
-base::LazyInstance<DiscardableSharedMemoryManager>
- g_discardable_shared_memory_manager = LAZY_INSTANCE_INITIALIZER;
-
const int kEnforceMemoryPolicyDelayMs = 1000;
// Global atomic to generate unique discardable shared memory IDs.
@@ -180,7 +220,8 @@ DiscardableSharedMemoryManager::MemorySegment::MemorySegment(
DiscardableSharedMemoryManager::MemorySegment::~MemorySegment() {}
DiscardableSharedMemoryManager::DiscardableSharedMemoryManager()
- : default_memory_limit_(GetDefaultMemoryLimit()),
+ : next_client_id_(1),
+ default_memory_limit_(GetDefaultMemoryLimit()),
memory_limit_(default_memory_limit_),
bytes_allocated_(0),
memory_pressure_listener_(new base::MemoryPressureListener(
@@ -205,23 +246,25 @@ DiscardableSharedMemoryManager::~DiscardableSharedMemoryManager() {
this);
}
-DiscardableSharedMemoryManager* DiscardableSharedMemoryManager::current() {
- return g_discardable_shared_memory_manager.Pointer();
+void DiscardableSharedMemoryManager::Bind(
+ mojom::DiscardableSharedMemoryManagerRequest request) {
+ mojo::MakeStrongBinding(
+ base::MakeUnique<MojoDiscardableSharedMemoryManagerImpl>(
+ next_client_id_++, this),
+ std::move(request));
}
std::unique_ptr<base::DiscardableMemory>
DiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(size_t size) {
DCHECK_NE(size, 0u);
- DiscardableSharedMemoryId new_id =
- g_next_discardable_shared_memory_id.GetNext();
- base::ProcessHandle current_process_handle = base::GetCurrentProcessHandle();
+ int32_t new_id = g_next_discardable_shared_memory_id.GetNext();
// Note: Use DiscardableSharedMemoryHeap for in-process allocation
// of discardable memory if the cost of each allocation is too high.
base::SharedMemoryHandle handle;
- AllocateLockedDiscardableSharedMemory(
- current_process_handle, kInvalidUniqueClientID, size, new_id, &handle);
+ AllocateLockedDiscardableSharedMemory(kInvalidUniqueClientID, size, new_id,
+ &handle);
std::unique_ptr<base::DiscardableSharedMemory> memory(
new base::DiscardableSharedMemory(handle));
if (!memory->Map(size))
@@ -308,17 +351,16 @@ bool DiscardableSharedMemoryManager::OnMemoryDump(
void DiscardableSharedMemoryManager::
AllocateLockedDiscardableSharedMemoryForClient(
- base::ProcessHandle process_handle,
int client_id,
size_t size,
- DiscardableSharedMemoryId id,
+ int32_t id,
base::SharedMemoryHandle* shared_memory_handle) {
- AllocateLockedDiscardableSharedMemory(process_handle, client_id, size, id,
+ AllocateLockedDiscardableSharedMemory(client_id, size, id,
shared_memory_handle);
}
void DiscardableSharedMemoryManager::ClientDeletedDiscardableSharedMemory(
- DiscardableSharedMemoryId id,
+ int32_t id,
int client_id) {
DeletedDiscardableSharedMemory(id, client_id);
}
@@ -380,10 +422,9 @@ void DiscardableSharedMemoryManager::OnMemoryStateChange(
}
void DiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory(
- base::ProcessHandle process_handle,
int client_id,
size_t size,
- DiscardableSharedMemoryId id,
+ int32_t id,
base::SharedMemoryHandle* shared_memory_handle) {
base::AutoLock lock(lock_);
@@ -416,15 +457,6 @@ void DiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory(
return;
}
- if (!memory->ShareToProcess(process_handle, shared_memory_handle)) {
- LOG(ERROR) << "Cannot share discardable memory segment";
- *shared_memory_handle = base::SharedMemory::NULLHandle();
- return;
- }
-
- // Close file descriptor to avoid running out.
- memory->Close();
-
base::CheckedNumeric<size_t> checked_bytes_allocated = bytes_allocated_;
checked_bytes_allocated += memory->mapped_size();
if (!checked_bytes_allocated.IsValid()) {
@@ -435,6 +467,10 @@ void DiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory(
bytes_allocated_ = checked_bytes_allocated.ValueOrDie();
BytesAllocatedChanged(bytes_allocated_);
+ *shared_memory_handle = base::SharedMemory::DuplicateHandle(memory->handle());
+ // Close file descriptor to avoid running out.
+ memory->Close();
+
scoped_refptr<MemorySegment> segment(new MemorySegment(std::move(memory)));
client_segments[id] = segment.get();
segments_.push_back(segment.get());
@@ -445,7 +481,7 @@ void DiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory(
}
void DiscardableSharedMemoryManager::DeletedDiscardableSharedMemory(
- DiscardableSharedMemoryId id,
+ int32_t id,
int client_id) {
base::AutoLock lock(lock_);
diff --git a/chromium/components/discardable_memory/service/discardable_shared_memory_manager.h b/chromium/components/discardable_memory/service/discardable_shared_memory_manager.h
index 7ccadf18a44..9491af4b663 100644
--- a/chromium/components/discardable_memory/service/discardable_shared_memory_manager.h
+++ b/chromium/components/discardable_memory/service/discardable_shared_memory_manager.h
@@ -27,7 +27,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/memory_dump_provider.h"
#include "components/discardable_memory/common/discardable_memory_export.h"
-#include "components/discardable_memory/common/discardable_shared_memory_id.h"
+#include "components/discardable_memory/public/interfaces/discardable_shared_memory_manager.mojom.h"
namespace discardable_memory {
@@ -44,8 +44,8 @@ class DISCARDABLE_MEMORY_EXPORT DiscardableSharedMemoryManager
DiscardableSharedMemoryManager();
~DiscardableSharedMemoryManager() override;
- // Returns a singleton instance.
- static DiscardableSharedMemoryManager* current();
+ // Bind the manager to a mojo interface request.
+ void Bind(mojom::DiscardableSharedMemoryManagerRequest request);
// Overridden from base::DiscardableMemoryAllocator:
std::unique_ptr<base::DiscardableMemory> AllocateLockedDiscardableMemory(
@@ -55,20 +55,17 @@ class DISCARDABLE_MEMORY_EXPORT DiscardableSharedMemoryManager
bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) override;
- // TODO(penghuang): Get ride of the |process_handle| when we switch to mojo.
// This allocates a discardable memory segment for |process_handle|.
// A valid shared memory handle is returned on success.
void AllocateLockedDiscardableSharedMemoryForClient(
- base::ProcessHandle process_handle,
int client_id,
size_t size,
- DiscardableSharedMemoryId id,
+ int32_t id,
base::SharedMemoryHandle* shared_memory_handle);
// Call this to notify the manager that client process associated with
// |client_id| has deleted discardable memory segment with |id|.
- void ClientDeletedDiscardableSharedMemory(DiscardableSharedMemoryId id,
- int client_id);
+ void ClientDeletedDiscardableSharedMemory(int32_t id, int client_id);
// Call this to notify the manager that client associated with |client_id|
// has been removed. The manager will use this to release memory segments
@@ -111,15 +108,12 @@ class DISCARDABLE_MEMORY_EXPORT DiscardableSharedMemoryManager
// base::MemoryCoordinatorClient implementation:
void OnMemoryStateChange(base::MemoryState state) override;
- // TODO(penghuang): Get ride of the |process_handle| when we switch to mojo.
void AllocateLockedDiscardableSharedMemory(
- base::ProcessHandle process_handle,
int client_id,
size_t size,
- DiscardableSharedMemoryId id,
+ int32_t id,
base::SharedMemoryHandle* shared_memory_handle);
- void DeletedDiscardableSharedMemory(DiscardableSharedMemoryId id,
- int client_id);
+ void DeletedDiscardableSharedMemory(int32_t id, int client_id);
void OnMemoryPressure(
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);
void ReduceMemoryUsageUntilWithinMemoryLimit();
@@ -131,15 +125,16 @@ class DISCARDABLE_MEMORY_EXPORT DiscardableSharedMemoryManager
virtual base::Time Now() const;
virtual void ScheduleEnforceMemoryPolicy();
+ int32_t next_client_id_;
+
base::Lock lock_;
- typedef base::hash_map<DiscardableSharedMemoryId,
- scoped_refptr<MemorySegment>>
- MemorySegmentMap;
- typedef base::hash_map<int, MemorySegmentMap> ClientMap;
+ using MemorySegmentMap =
+ base::hash_map<int32_t, scoped_refptr<MemorySegment>>;
+ using ClientMap = base::hash_map<int, MemorySegmentMap>;
ClientMap clients_;
// Note: The elements in |segments_| are arranged in such a way that they form
// a heap. The LRU memory segment always first.
- typedef std::vector<scoped_refptr<MemorySegment>> MemorySegmentVector;
+ using MemorySegmentVector = std::vector<scoped_refptr<MemorySegment>>;
MemorySegmentVector segments_;
size_t default_memory_limit_;
size_t memory_limit_;
diff --git a/chromium/components/discardable_memory/service/discardable_shared_memory_manager_unittest.cc b/chromium/components/discardable_memory/service/discardable_shared_memory_manager_unittest.cc
index f190736a28f..3c2992401a6 100644
--- a/chromium/components/discardable_memory/service/discardable_shared_memory_manager_unittest.cc
+++ b/chromium/components/discardable_memory/service/discardable_shared_memory_manager_unittest.cc
@@ -77,8 +77,7 @@ TEST_F(DiscardableSharedMemoryManagerTest, AllocateForClient) {
base::SharedMemoryHandle shared_handle;
manager_->AllocateLockedDiscardableSharedMemoryForClient(
- base::GetCurrentProcessHandle(), kInvalidUniqueID, kDataSize, 0,
- &shared_handle);
+ kInvalidUniqueID, kDataSize, 0, &shared_handle);
ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle));
TestDiscardableSharedMemory memory(shared_handle);
@@ -99,8 +98,7 @@ TEST_F(DiscardableSharedMemoryManagerTest, Purge) {
base::SharedMemoryHandle shared_handle1;
manager_->AllocateLockedDiscardableSharedMemoryForClient(
- base::GetCurrentProcessHandle(), kInvalidUniqueID, kDataSize, 1,
- &shared_handle1);
+ kInvalidUniqueID, kDataSize, 1, &shared_handle1);
ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle1));
TestDiscardableSharedMemory memory1(shared_handle1);
@@ -109,8 +107,7 @@ TEST_F(DiscardableSharedMemoryManagerTest, Purge) {
base::SharedMemoryHandle shared_handle2;
manager_->AllocateLockedDiscardableSharedMemoryForClient(
- base::GetCurrentProcessHandle(), kInvalidUniqueID, kDataSize, 2,
- &shared_handle2);
+ kInvalidUniqueID, kDataSize, 2, &shared_handle2);
ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle2));
TestDiscardableSharedMemory memory2(shared_handle2);
@@ -165,8 +162,7 @@ TEST_F(DiscardableSharedMemoryManagerTest, EnforceMemoryPolicy) {
base::SharedMemoryHandle shared_handle;
manager_->AllocateLockedDiscardableSharedMemoryForClient(
- base::GetCurrentProcessHandle(), kInvalidUniqueID, kDataSize, 0,
- &shared_handle);
+ kInvalidUniqueID, kDataSize, 0, &shared_handle);
ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle));
TestDiscardableSharedMemory memory(shared_handle);
@@ -204,8 +200,7 @@ TEST_F(DiscardableSharedMemoryManagerTest,
base::SharedMemoryHandle shared_handle1;
manager_->AllocateLockedDiscardableSharedMemoryForClient(
- base::GetCurrentProcessHandle(), kInvalidUniqueID, kDataSize, 1,
- &shared_handle1);
+ kInvalidUniqueID, kDataSize, 1, &shared_handle1);
ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle1));
TestDiscardableSharedMemory memory1(shared_handle1);
@@ -214,8 +209,7 @@ TEST_F(DiscardableSharedMemoryManagerTest,
base::SharedMemoryHandle shared_handle2;
manager_->AllocateLockedDiscardableSharedMemoryForClient(
- base::GetCurrentProcessHandle(), kInvalidUniqueID, kDataSize, 2,
- &shared_handle2);
+ kInvalidUniqueID, kDataSize, 2, &shared_handle2);
ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle2));
TestDiscardableSharedMemory memory2(shared_handle2);
@@ -269,8 +263,7 @@ TEST_F(DiscardableSharedMemoryManagerScheduleEnforceMemoryPolicyTest,
base::SharedMemoryHandle shared_handle;
manager_->AllocateLockedDiscardableSharedMemoryForClient(
- base::GetCurrentProcessHandle(), kInvalidUniqueID, kDataSize, 0,
- &shared_handle);
+ kInvalidUniqueID, kDataSize, 0, &shared_handle);
ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle));
// Set the memory limit to a value that will require EnforceMemoryPolicy()