diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-04-05 14:08:31 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-04-11 07:46:53 +0000 |
commit | 6a4cabb866f66d4128a97cdc6d9d08ce074f1247 (patch) | |
tree | ab00f70a5e89278d6a0d16ff0c42578dc4d84a2d /chromium/components/discardable_memory | |
parent | e733310db58160074f574c429d48f8308c0afe17 (diff) | |
download | qtwebengine-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')
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() |