Remove most of base/memory
Change-Id: I877807f4d8bfe8b162baa71f159f74340f562c23
Reviewed-on: https://gn-review.googlesource.com/1480
Commit-Queue: Scott Graham <scottmg@chromium.org>
Reviewed-by: Brett Wilson <brettw@chromium.org>
diff --git a/base/memory/OWNERS b/base/memory/OWNERS
deleted file mode 100644
index 9b7cbb1..0000000
--- a/base/memory/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-per-file *chromeos*=skuhne@chromium.org
-per-file *chromeos*=oshima@chromium.org
-per-file *shared_memory*=set noparent
-per-file *shared_memory*=file://ipc/SECURITY_OWNERS
diff --git a/base/memory/aligned_memory.cc b/base/memory/aligned_memory.cc
deleted file mode 100644
index 861ea50..0000000
--- a/base/memory/aligned_memory.cc
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "base/memory/aligned_memory.h"
-
-#include "base/logging.h"
-#include "build_config.h"
-
-#if defined(OS_ANDROID)
-#include <malloc.h>
-#endif
-
-namespace base {
-
-void* AlignedAlloc(size_t size, size_t alignment) {
- DCHECK_GT(size, 0U);
- DCHECK_EQ(alignment & (alignment - 1), 0U);
- DCHECK_EQ(alignment % sizeof(void*), 0U);
- void* ptr = nullptr;
-#if defined(COMPILER_MSVC)
- ptr = _aligned_malloc(size, alignment);
-// Android technically supports posix_memalign(), but does not expose it in
-// the current version of the library headers used by Chrome. Luckily,
-// memalign() on Android returns pointers which can safely be used with
-// free(), so we can use it instead. Issue filed to document this:
-// http://code.google.com/p/android/issues/detail?id=35391
-#elif defined(OS_ANDROID)
- ptr = memalign(alignment, size);
-#else
- if (posix_memalign(&ptr, alignment, size))
- ptr = nullptr;
-#endif
- // Since aligned allocations may fail for non-memory related reasons, force a
- // crash if we encounter a failed allocation; maintaining consistent behavior
- // with a normal allocation failure in Chrome.
- if (!ptr) {
- DLOG(ERROR) << "If you crashed here, your aligned allocation is incorrect: "
- << "size=" << size << ", alignment=" << alignment;
- CHECK(false);
- }
- // Sanity check alignment just to be safe.
- DCHECK_EQ(reinterpret_cast<uintptr_t>(ptr) & (alignment - 1), 0U);
- return ptr;
-}
-
-} // namespace base
diff --git a/base/memory/aligned_memory.h b/base/memory/aligned_memory.h
deleted file mode 100644
index e0dd7f5..0000000
--- a/base/memory/aligned_memory.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2012 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 BASE_MEMORY_ALIGNED_MEMORY_H_
-#define BASE_MEMORY_ALIGNED_MEMORY_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <type_traits>
-
-#include "base/base_export.h"
-#include "base/compiler_specific.h"
-#include "build_config.h"
-
-#if defined(COMPILER_MSVC)
-#include <malloc.h>
-#else
-#include <stdlib.h>
-#endif
-
-// A runtime sized aligned allocation can be created:
-//
-// float* my_array = static_cast<float*>(AlignedAlloc(size, alignment));
-//
-// // ... later, to release the memory:
-// AlignedFree(my_array);
-//
-// Or using unique_ptr:
-//
-// std::unique_ptr<float, AlignedFreeDeleter> my_array(
-// static_cast<float*>(AlignedAlloc(size, alignment)));
-
-namespace base {
-
-// This can be replaced with std::aligned_malloc when we have C++17.
-BASE_EXPORT void* AlignedAlloc(size_t size, size_t alignment);
-
-inline void AlignedFree(void* ptr) {
-#if defined(COMPILER_MSVC)
- _aligned_free(ptr);
-#else
- free(ptr);
-#endif
-}
-
-// Deleter for use with unique_ptr. E.g., use as
-// std::unique_ptr<Foo, base::AlignedFreeDeleter> foo;
-struct AlignedFreeDeleter {
- inline void operator()(void* ptr) const {
- AlignedFree(ptr);
- }
-};
-
-} // namespace base
-
-#endif // BASE_MEMORY_ALIGNED_MEMORY_H_
diff --git a/base/memory/discardable_memory.cc b/base/memory/discardable_memory.cc
deleted file mode 100644
index f0730aa..0000000
--- a/base/memory/discardable_memory.cc
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2014 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.
-
-#include "base/memory/discardable_memory.h"
-
-namespace base {
-
-DiscardableMemory::DiscardableMemory() = default;
-
-DiscardableMemory::~DiscardableMemory() = default;
-
-} // namespace base
diff --git a/base/memory/discardable_memory.h b/base/memory/discardable_memory.h
deleted file mode 100644
index 5c632d1..0000000
--- a/base/memory/discardable_memory.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 2013 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 BASE_MEMORY_DISCARDABLE_MEMORY_H_
-#define BASE_MEMORY_DISCARDABLE_MEMORY_H_
-
-#include "base/base_export.h"
-#include "base/compiler_specific.h"
-
-namespace base {
-
-namespace trace_event {
-class MemoryAllocatorDump;
-class ProcessMemoryDump;
-}
-
-// Discardable memory is used to cache large objects without worrying about
-// blowing out memory, both on mobile devices where there is no swap, and
-// desktop devices where unused free memory should be used to help the user
-// experience. This is preferable to releasing memory in response to an OOM
-// signal because it is simpler and provides system-wide management of
-// purgable memory, though it has less flexibility as to which objects get
-// discarded.
-//
-// Discardable memory has two states: locked and unlocked. While the memory is
-// locked, it will not be discarded. Unlocking the memory allows the
-// discardable memory system and the OS to reclaim it if needed. Locks do not
-// nest.
-//
-// Notes:
-// - The paging behavior of memory while it is locked is not specified. While
-// mobile platforms will not swap it out, it may qualify for swapping
-// on desktop platforms. It is not expected that this will matter, as the
-// preferred pattern of usage for DiscardableMemory is to lock down the
-// memory, use it as quickly as possible, and then unlock it.
-// - Because of memory alignment, the amount of memory allocated can be
-// larger than the requested memory size. It is not very efficient for
-// small allocations.
-// - A discardable memory instance is not thread safe. It is the
-// responsibility of users of discardable memory to ensure there are no
-// races.
-//
-class BASE_EXPORT DiscardableMemory {
- public:
- DiscardableMemory();
- virtual ~DiscardableMemory();
-
- // Locks the memory so that it will not be purged by the system. Returns
- // true on success. If the return value is false then this object should be
- // discarded and a new one should be created.
- virtual bool Lock() WARN_UNUSED_RESULT = 0;
-
- // Unlocks the memory so that it can be purged by the system. Must be called
- // after every successful lock call.
- virtual void Unlock() = 0;
-
- // Returns the memory address held by this object. The object must be locked
- // before calling this.
- virtual void* data() const = 0;
-
- // Handy method to simplify calling data() with a reinterpret_cast.
- template<typename T> T* data_as() const {
- return reinterpret_cast<T*>(data());
- }
-
- // Used for dumping the statistics of discardable memory allocated in tracing.
- // Returns a new MemoryAllocatorDump in the |pmd| with the size of the
- // discardable memory. The MemoryAllocatorDump created is owned by |pmd|. See
- // ProcessMemoryDump::CreateAllocatorDump.
- virtual trace_event::MemoryAllocatorDump* CreateMemoryAllocatorDump(
- const char* name,
- trace_event::ProcessMemoryDump* pmd) const = 0;
-};
-
-} // namespace base
-
-#endif // BASE_MEMORY_DISCARDABLE_MEMORY_H_
diff --git a/base/memory/discardable_memory_allocator.cc b/base/memory/discardable_memory_allocator.cc
deleted file mode 100644
index 3dbb276..0000000
--- a/base/memory/discardable_memory_allocator.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2015 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.
-
-#include "base/memory/discardable_memory_allocator.h"
-
-#include "base/logging.h"
-
-namespace base {
-namespace {
-
-DiscardableMemoryAllocator* g_discardable_allocator = nullptr;
-
-} // namespace
-
-// static
-void DiscardableMemoryAllocator::SetInstance(
- DiscardableMemoryAllocator* allocator) {
- DCHECK(!allocator || !g_discardable_allocator);
- g_discardable_allocator = allocator;
-}
-
-// static
-DiscardableMemoryAllocator* DiscardableMemoryAllocator::GetInstance() {
- DCHECK(g_discardable_allocator);
- return g_discardable_allocator;
-}
-
-} // namespace base
diff --git a/base/memory/discardable_memory_allocator.h b/base/memory/discardable_memory_allocator.h
deleted file mode 100644
index 8d74b16..0000000
--- a/base/memory/discardable_memory_allocator.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2015 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 BASE_MEMORY_DISCARDABLE_MEMORY_ALLOCATOR_H_
-#define BASE_MEMORY_DISCARDABLE_MEMORY_ALLOCATOR_H_
-
-#include <stddef.h>
-
-#include <memory>
-
-#include "base/base_export.h"
-
-namespace base {
-class DiscardableMemory;
-
-class BASE_EXPORT DiscardableMemoryAllocator {
- public:
- // Returns the allocator instance.
- static DiscardableMemoryAllocator* GetInstance();
-
- // Sets the allocator instance. Can only be called once, e.g. on startup.
- // Ownership of |instance| remains with the caller.
- static void SetInstance(DiscardableMemoryAllocator* allocator);
-
- // Giant WARNING: Discardable[Shared]Memory is only implemented on Android. On
- // non-Android platforms, it behaves exactly the same as SharedMemory.
- // See LockPages() in discardable_shared_memory.cc.
- virtual std::unique_ptr<DiscardableMemory> AllocateLockedDiscardableMemory(
- size_t size) = 0;
-
- protected:
- virtual ~DiscardableMemoryAllocator() = default;
-};
-
-} // namespace base
-
-#endif // BASE_MEMORY_DISCARDABLE_MEMORY_ALLOCATOR_H_
diff --git a/base/memory/discardable_shared_memory.cc b/base/memory/discardable_shared_memory.cc
deleted file mode 100644
index 8601e21..0000000
--- a/base/memory/discardable_shared_memory.cc
+++ /dev/null
@@ -1,514 +0,0 @@
-// Copyright 2014 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.
-
-#include "base/memory/discardable_shared_memory.h"
-
-#include <stdint.h>
-
-#include <algorithm>
-
-#include "base/atomicops.h"
-#include "base/bits.h"
-#include "base/logging.h"
-#include "base/memory/shared_memory_tracker.h"
-#include "base/numerics/safe_math.h"
-#include "base/process/process_metrics.h"
-#include "base/trace_event/memory_allocator_dump.h"
-#include "base/trace_event/process_memory_dump.h"
-#include "build_config.h"
-
-#if defined(OS_POSIX) && !defined(OS_NACL)
-// For madvise() which is available on all POSIX compatible systems.
-#include <sys/mman.h>
-#endif
-
-#if defined(OS_ANDROID)
-#include "third_party/ashmem/ashmem.h"
-#endif
-
-#if defined(OS_WIN)
-#include <windows.h>
-#include "base/win/windows_version.h"
-#endif
-
-namespace base {
-namespace {
-
-// Use a machine-sized pointer as atomic type. It will use the Atomic32 or
-// Atomic64 routines, depending on the architecture.
-typedef intptr_t AtomicType;
-typedef uintptr_t UAtomicType;
-
-// Template specialization for timestamp serialization/deserialization. This
-// is used to serialize timestamps using Unix time on systems where AtomicType
-// does not have enough precision to contain a timestamp in the standard
-// serialized format.
-template <int>
-Time TimeFromWireFormat(int64_t value);
-template <int>
-int64_t TimeToWireFormat(Time time);
-
-// Serialize to Unix time when using 4-byte wire format.
-// Note: 19 January 2038, this will cease to work.
-template <>
-Time ALLOW_UNUSED_TYPE TimeFromWireFormat<4>(int64_t value) {
- return value ? Time::UnixEpoch() + TimeDelta::FromSeconds(value) : Time();
-}
-template <>
-int64_t ALLOW_UNUSED_TYPE TimeToWireFormat<4>(Time time) {
- return time > Time::UnixEpoch() ? (time - Time::UnixEpoch()).InSeconds() : 0;
-}
-
-// Standard serialization format when using 8-byte wire format.
-template <>
-Time ALLOW_UNUSED_TYPE TimeFromWireFormat<8>(int64_t value) {
- return Time::FromInternalValue(value);
-}
-template <>
-int64_t ALLOW_UNUSED_TYPE TimeToWireFormat<8>(Time time) {
- return time.ToInternalValue();
-}
-
-struct SharedState {
- enum LockState { UNLOCKED = 0, LOCKED = 1 };
-
- explicit SharedState(AtomicType ivalue) { value.i = ivalue; }
- SharedState(LockState lock_state, Time timestamp) {
- int64_t wire_timestamp = TimeToWireFormat<sizeof(AtomicType)>(timestamp);
- DCHECK_GE(wire_timestamp, 0);
- DCHECK_EQ(lock_state & ~1, 0);
- value.u = (static_cast<UAtomicType>(wire_timestamp) << 1) | lock_state;
- }
-
- LockState GetLockState() const { return static_cast<LockState>(value.u & 1); }
-
- Time GetTimestamp() const {
- return TimeFromWireFormat<sizeof(AtomicType)>(value.u >> 1);
- }
-
- // Bit 1: Lock state. Bit is set when locked.
- // Bit 2..sizeof(AtomicType)*8: Usage timestamp. NULL time when locked or
- // purged.
- union {
- AtomicType i;
- UAtomicType u;
- } value;
-};
-
-// Shared state is stored at offset 0 in shared memory segments.
-SharedState* SharedStateFromSharedMemory(
- const WritableSharedMemoryMapping& shared_memory) {
- DCHECK(shared_memory.IsValid());
- return static_cast<SharedState*>(shared_memory.memory());
-}
-
-// Round up |size| to a multiple of page size.
-size_t AlignToPageSize(size_t size) {
- return bits::Align(size, base::GetPageSize());
-}
-
-} // namespace
-
-DiscardableSharedMemory::DiscardableSharedMemory()
- : mapped_size_(0), locked_page_count_(0) {
-}
-
-DiscardableSharedMemory::DiscardableSharedMemory(
- UnsafeSharedMemoryRegion shared_memory_region)
- : shared_memory_region_(std::move(shared_memory_region)),
- mapped_size_(0),
- locked_page_count_(0) {}
-
-DiscardableSharedMemory::~DiscardableSharedMemory() = default;
-
-bool DiscardableSharedMemory::CreateAndMap(size_t size) {
- CheckedNumeric<size_t> checked_size = size;
- checked_size += AlignToPageSize(sizeof(SharedState));
- if (!checked_size.IsValid())
- return false;
-
- shared_memory_region_ =
- UnsafeSharedMemoryRegion::Create(checked_size.ValueOrDie());
-
- if (!shared_memory_region_.IsValid())
- return false;
-
- shared_memory_mapping_ = shared_memory_region_.Map();
- if (!shared_memory_mapping_.IsValid())
- return false;
-
- mapped_size_ = shared_memory_mapping_.mapped_size() -
- AlignToPageSize(sizeof(SharedState));
-
- locked_page_count_ = AlignToPageSize(mapped_size_) / base::GetPageSize();
-#if DCHECK_IS_ON()
- for (size_t page = 0; page < locked_page_count_; ++page)
- locked_pages_.insert(page);
-#endif
-
- DCHECK(last_known_usage_.is_null());
- SharedState new_state(SharedState::LOCKED, Time());
- subtle::Release_Store(
- &SharedStateFromSharedMemory(shared_memory_mapping_)->value.i,
- new_state.value.i);
- return true;
-}
-
-bool DiscardableSharedMemory::Map(size_t size) {
- DCHECK(!shared_memory_mapping_.IsValid());
- if (shared_memory_mapping_.IsValid())
- return false;
-
- shared_memory_mapping_ = shared_memory_region_.MapAt(
- 0, AlignToPageSize(sizeof(SharedState)) + size);
- if (!shared_memory_mapping_.IsValid())
- return false;
-
- mapped_size_ = shared_memory_mapping_.mapped_size() -
- AlignToPageSize(sizeof(SharedState));
-
- locked_page_count_ = AlignToPageSize(mapped_size_) / base::GetPageSize();
-#if DCHECK_IS_ON()
- for (size_t page = 0; page < locked_page_count_; ++page)
- locked_pages_.insert(page);
-#endif
-
- return true;
-}
-
-bool DiscardableSharedMemory::Unmap() {
- if (!shared_memory_mapping_.IsValid())
- return false;
-
- shared_memory_mapping_ = WritableSharedMemoryMapping();
- locked_page_count_ = 0;
-#if DCHECK_IS_ON()
- locked_pages_.clear();
-#endif
- mapped_size_ = 0;
- return true;
-}
-
-DiscardableSharedMemory::LockResult DiscardableSharedMemory::Lock(
- size_t offset, size_t length) {
- DCHECK_EQ(AlignToPageSize(offset), offset);
- DCHECK_EQ(AlignToPageSize(length), length);
-
- // Calls to this function must be synchronized properly.
- DFAKE_SCOPED_LOCK(thread_collision_warner_);
-
- DCHECK(shared_memory_mapping_.IsValid());
-
- // We need to successfully acquire the platform independent lock before
- // individual pages can be locked.
- if (!locked_page_count_) {
- // Return false when instance has been purged or not initialized properly
- // by checking if |last_known_usage_| is NULL.
- if (last_known_usage_.is_null())
- return FAILED;
-
- SharedState old_state(SharedState::UNLOCKED, last_known_usage_);
- SharedState new_state(SharedState::LOCKED, Time());
- SharedState result(subtle::Acquire_CompareAndSwap(
- &SharedStateFromSharedMemory(shared_memory_mapping_)->value.i,
- old_state.value.i, new_state.value.i));
- if (result.value.u != old_state.value.u) {
- // Update |last_known_usage_| in case the above CAS failed because of
- // an incorrect timestamp.
- last_known_usage_ = result.GetTimestamp();
- return FAILED;
- }
- }
-
- // Zero for length means "everything onward".
- if (!length)
- length = AlignToPageSize(mapped_size_) - offset;
-
- size_t start = offset / base::GetPageSize();
- size_t end = start + length / base::GetPageSize();
- DCHECK_LE(start, end);
- DCHECK_LE(end, AlignToPageSize(mapped_size_) / base::GetPageSize());
-
- // Add pages to |locked_page_count_|.
- // Note: Locking a page that is already locked is an error.
- locked_page_count_ += end - start;
-#if DCHECK_IS_ON()
- // Detect incorrect usage by keeping track of exactly what pages are locked.
- for (auto page = start; page < end; ++page) {
- auto result = locked_pages_.insert(page);
- DCHECK(result.second);
- }
- DCHECK_EQ(locked_pages_.size(), locked_page_count_);
-#endif
-
- // Always behave as if memory was purged when trying to lock a 0 byte segment.
- if (!length)
- return PURGED;
-
-#if defined(OS_ANDROID)
- // Ensure that the platform won't discard the required pages.
- return LockPages(shared_memory_region_,
- AlignToPageSize(sizeof(SharedState)) + offset, length);
-#elif defined(OS_MACOSX)
- // On macOS, there is no mechanism to lock pages. However, we do need to call
- // madvise(MADV_FREE_REUSE) in order to correctly update accounting for memory
- // footprint via task_info().
- //
- // Note that calling madvise(MADV_FREE_REUSE) on regions that haven't had
- // madvise(MADV_FREE_REUSABLE) called on them has no effect.
- //
- // Note that the corresponding call to MADV_FREE_REUSABLE is in Purge(), since
- // that's where the memory is actually released, rather than Unlock(), which
- // is a no-op on macOS.
- //
- // For more information, see
- // https://bugs.chromium.org/p/chromium/issues/detail?id=823915.
- if (madvise(reinterpret_cast<char*>(shared_memory_mapping_.memory()) +
- AlignToPageSize(sizeof(SharedState)),
- AlignToPageSize(mapped_size_), MADV_FREE_REUSE))
- ;
- return DiscardableSharedMemory::SUCCESS;
-#else
- return DiscardableSharedMemory::SUCCESS;
-#endif
-}
-
-void DiscardableSharedMemory::Unlock(size_t offset, size_t length) {
- DCHECK_EQ(AlignToPageSize(offset), offset);
- DCHECK_EQ(AlignToPageSize(length), length);
-
- // Calls to this function must be synchronized properly.
- DFAKE_SCOPED_LOCK(thread_collision_warner_);
-
- // Passing zero for |length| means "everything onward". Note that |length| may
- // still be zero after this calculation, e.g. if |mapped_size_| is zero.
- if (!length)
- length = AlignToPageSize(mapped_size_) - offset;
-
- DCHECK(shared_memory_mapping_.IsValid());
-
- // Allow the pages to be discarded by the platform, if supported.
- UnlockPages(shared_memory_region_,
- AlignToPageSize(sizeof(SharedState)) + offset, length);
-
- size_t start = offset / base::GetPageSize();
- size_t end = start + length / base::GetPageSize();
- DCHECK_LE(start, end);
- DCHECK_LE(end, AlignToPageSize(mapped_size_) / base::GetPageSize());
-
- // Remove pages from |locked_page_count_|.
- // Note: Unlocking a page that is not locked is an error.
- DCHECK_GE(locked_page_count_, end - start);
- locked_page_count_ -= end - start;
-#if DCHECK_IS_ON()
- // Detect incorrect usage by keeping track of exactly what pages are locked.
- for (auto page = start; page < end; ++page) {
- auto erased_count = locked_pages_.erase(page);
- DCHECK_EQ(1u, erased_count);
- }
- DCHECK_EQ(locked_pages_.size(), locked_page_count_);
-#endif
-
- // Early out and avoid releasing the platform independent lock if some pages
- // are still locked.
- if (locked_page_count_)
- return;
-
- Time current_time = Now();
- DCHECK(!current_time.is_null());
-
- SharedState old_state(SharedState::LOCKED, Time());
- SharedState new_state(SharedState::UNLOCKED, current_time);
- // Note: timestamp cannot be NULL as that is a unique value used when
- // locked or purged.
- DCHECK(!new_state.GetTimestamp().is_null());
- // Timestamp precision should at least be accurate to the second.
- DCHECK_EQ((new_state.GetTimestamp() - Time::UnixEpoch()).InSeconds(),
- (current_time - Time::UnixEpoch()).InSeconds());
- SharedState result(subtle::Release_CompareAndSwap(
- &SharedStateFromSharedMemory(shared_memory_mapping_)->value.i,
- old_state.value.i, new_state.value.i));
-
- DCHECK_EQ(old_state.value.u, result.value.u);
-
- last_known_usage_ = current_time;
-}
-
-void* DiscardableSharedMemory::memory() const {
- return reinterpret_cast<uint8_t*>(shared_memory_mapping_.memory()) +
- AlignToPageSize(sizeof(SharedState));
-}
-
-bool DiscardableSharedMemory::Purge(Time current_time) {
- // Calls to this function must be synchronized properly.
- DFAKE_SCOPED_LOCK(thread_collision_warner_);
- DCHECK(shared_memory_mapping_.IsValid());
-
- SharedState old_state(SharedState::UNLOCKED, last_known_usage_);
- SharedState new_state(SharedState::UNLOCKED, Time());
- SharedState result(subtle::Acquire_CompareAndSwap(
- &SharedStateFromSharedMemory(shared_memory_mapping_)->value.i,
- old_state.value.i, new_state.value.i));
-
- // Update |last_known_usage_| to |current_time| if the memory is locked. This
- // allows the caller to determine if purging failed because last known usage
- // was incorrect or memory was locked. In the second case, the caller should
- // most likely wait for some amount of time before attempting to purge the
- // the memory again.
- if (result.value.u != old_state.value.u) {
- last_known_usage_ = result.GetLockState() == SharedState::LOCKED
- ? current_time
- : result.GetTimestamp();
- return false;
- }
-
-// The next section will release as much resource as can be done
-// from the purging process, until the client process notices the
-// purge and releases its own references.
-// Note: this memory will not be accessed again. The segment will be
-// freed asynchronously at a later time, so just do the best
-// immediately.
-#if defined(OS_POSIX) && !defined(OS_NACL)
-// Linux and Android provide MADV_REMOVE which is preferred as it has a
-// behavior that can be verified in tests. Other POSIX flavors (MacOSX, BSDs),
-// provide MADV_FREE which has the same result but memory is purged lazily.
-#if defined(OS_LINUX) || defined(OS_ANDROID)
-#define MADV_PURGE_ARGUMENT MADV_REMOVE
-#elif defined(OS_MACOSX)
-// MADV_FREE_REUSABLE is similar to MADV_FREE, but also marks the pages with the
-// reusable bit, which allows both Activity Monitor and memory-infra to
-// correctly track the pages.
-#define MADV_PURGE_ARGUMENT MADV_FREE_REUSABLE
-#else
-#define MADV_PURGE_ARGUMENT MADV_FREE
-#endif
- // Advise the kernel to remove resources associated with purged pages.
- // Subsequent accesses of memory pages will succeed, but might result in
- // zero-fill-on-demand pages.
- if (madvise(reinterpret_cast<char*>(shared_memory_mapping_.memory()) +
- AlignToPageSize(sizeof(SharedState)),
- AlignToPageSize(mapped_size_), MADV_PURGE_ARGUMENT)) {
- DPLOG(ERROR) << "madvise() failed";
- }
-#elif defined(OS_WIN)
- if (base::win::GetVersion() >= base::win::VERSION_WIN8_1) {
- // Discard the purged pages, which releases the physical storage (resident
- // memory, compressed or swapped), but leaves them reserved & committed.
- // This does not free commit for use by other applications, but allows the
- // system to avoid compressing/swapping these pages to free physical memory.
- static const auto discard_virtual_memory =
- reinterpret_cast<decltype(&::DiscardVirtualMemory)>(GetProcAddress(
- GetModuleHandle(L"kernel32.dll"), "DiscardVirtualMemory"));
- if (discard_virtual_memory) {
- DWORD discard_result = discard_virtual_memory(
- reinterpret_cast<char*>(shared_memory_mapping_.memory()) +
- AlignToPageSize(sizeof(SharedState)),
- AlignToPageSize(mapped_size_));
- if (discard_result != ERROR_SUCCESS) {
- DLOG(DCHECK) << "DiscardVirtualMemory() failed in Purge(): "
- << logging::SystemErrorCodeToString(discard_result);
- }
- }
- }
-#endif
-
- last_known_usage_ = Time();
- return true;
-}
-
-bool DiscardableSharedMemory::IsMemoryResident() const {
- DCHECK(shared_memory_mapping_.IsValid());
-
- SharedState result(subtle::NoBarrier_Load(
- &SharedStateFromSharedMemory(shared_memory_mapping_)->value.i));
-
- return result.GetLockState() == SharedState::LOCKED ||
- !result.GetTimestamp().is_null();
-}
-
-bool DiscardableSharedMemory::IsMemoryLocked() const {
- DCHECK(shared_memory_mapping_.IsValid());
-
- SharedState result(subtle::NoBarrier_Load(
- &SharedStateFromSharedMemory(shared_memory_mapping_)->value.i));
-
- return result.GetLockState() == SharedState::LOCKED;
-}
-
-void DiscardableSharedMemory::Close() {
- shared_memory_region_ = UnsafeSharedMemoryRegion();
-}
-
-void DiscardableSharedMemory::CreateSharedMemoryOwnershipEdge(
- trace_event::MemoryAllocatorDump* local_segment_dump,
- trace_event::ProcessMemoryDump* pmd,
- bool is_owned) const {
- auto* shared_memory_dump = SharedMemoryTracker::GetOrCreateSharedMemoryDump(
- shared_memory_mapping_, pmd);
- // TODO(ssid): Clean this by a new api to inherit size of parent dump once the
- // we send the full PMD and calculate sizes inside chrome, crbug.com/704203.
- size_t resident_size = shared_memory_dump->GetSizeInternal();
- local_segment_dump->AddScalar(trace_event::MemoryAllocatorDump::kNameSize,
- trace_event::MemoryAllocatorDump::kUnitsBytes,
- resident_size);
-
- // By creating an edge with a higher |importance| (w.r.t non-owned dumps)
- // the tracing UI will account the effective size of the segment to the
- // client instead of manager.
- // TODO(ssid): Define better constants in MemoryAllocatorDump for importance
- // values, crbug.com/754793.
- const int kImportance = is_owned ? 2 : 0;
- auto shared_memory_guid = shared_memory_mapping_.guid();
- local_segment_dump->AddString("id", "hash", shared_memory_guid.ToString());
-
- // Owned discardable segments which are allocated by client process, could
- // have been cleared by the discardable manager. So, the segment need not
- // exist in memory and weak dumps are created to indicate the UI that the dump
- // should exist only if the manager also created the global dump edge.
- if (is_owned) {
- pmd->CreateWeakSharedMemoryOwnershipEdge(local_segment_dump->guid(),
- shared_memory_guid, kImportance);
- } else {
- pmd->CreateSharedMemoryOwnershipEdge(local_segment_dump->guid(),
- shared_memory_guid, kImportance);
- }
-}
-
-// static
-DiscardableSharedMemory::LockResult DiscardableSharedMemory::LockPages(
- const UnsafeSharedMemoryRegion& region,
- size_t offset,
- size_t length) {
-#if defined(OS_ANDROID)
- if (region.IsValid()) {
- int pin_result =
- ashmem_pin_region(region.GetPlatformHandle(), offset, length);
- if (pin_result == ASHMEM_WAS_PURGED)
- return PURGED;
- if (pin_result < 0)
- return FAILED;
- }
-#endif
- return SUCCESS;
-}
-
-// static
-void DiscardableSharedMemory::UnlockPages(
- const UnsafeSharedMemoryRegion& region,
- size_t offset,
- size_t length) {
-#if defined(OS_ANDROID)
- if (region.IsValid()) {
- int unpin_result =
- ashmem_unpin_region(region.GetPlatformHandle(), offset, length);
- DCHECK_EQ(0, unpin_result);
- }
-#endif
-}
-
-Time DiscardableSharedMemory::Now() const {
- return Time::Now();
-}
-
-} // namespace base
diff --git a/base/memory/discardable_shared_memory.h b/base/memory/discardable_shared_memory.h
deleted file mode 100644
index 55e99d9..0000000
--- a/base/memory/discardable_shared_memory.h
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright 2014 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 BASE_MEMORY_DISCARDABLE_SHARED_MEMORY_H_
-#define BASE_MEMORY_DISCARDABLE_SHARED_MEMORY_H_
-
-#include <stddef.h>
-
-#include "base/base_export.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/shared_memory_mapping.h"
-#include "base/memory/unsafe_shared_memory_region.h"
-#include "base/threading/thread_collision_warner.h"
-#include "base/time/time.h"
-#include "build_config.h"
-
-#if DCHECK_IS_ON()
-#include <set>
-#endif
-
-// Linux (including Android) support the MADV_REMOVE argument with madvise()
-// which has the behavior of reliably causing zero-fill-on-demand pages to
-// be returned after a call. Here we define
-// DISCARDABLE_SHARED_MEMORY_ZERO_FILL_ON_DEMAND_PAGES_AFTER_PURGE on Linux
-// and Android to indicate that this type of behavior can be expected on
-// those platforms. Note that madvise() will still be used on other POSIX
-// platforms but doesn't provide the zero-fill-on-demand pages guarantee.
-#if defined(OS_LINUX) || defined(OS_ANDROID)
-#define DISCARDABLE_SHARED_MEMORY_ZERO_FILL_ON_DEMAND_PAGES_AFTER_PURGE
-#endif
-
-namespace base {
-
-namespace trace_event {
-class MemoryAllocatorDump;
-class ProcessMemoryDump;
-} // namespace trace_event
-
-// Platform abstraction for discardable shared memory.
-//
-// This class is not thread-safe. Clients are responsible for synchronizing
-// access to an instance of this class.
-class BASE_EXPORT DiscardableSharedMemory {
- public:
- enum LockResult { SUCCESS, PURGED, FAILED };
-
- DiscardableSharedMemory();
-
- // Create a new DiscardableSharedMemory object from an existing, open shared
- // memory file. Memory must be locked.
- explicit DiscardableSharedMemory(UnsafeSharedMemoryRegion region);
-
- // Closes any open files.
- virtual ~DiscardableSharedMemory();
-
- // Creates and maps a locked DiscardableSharedMemory object with |size|.
- // Returns true on success and false on failure.
- bool CreateAndMap(size_t size);
-
- // Maps the locked discardable memory into the caller's address space.
- // Returns true on success, false otherwise.
- bool Map(size_t size);
-
- // Unmaps the discardable shared memory from the caller's address space.
- // Unmapping won't unlock previously locked range.
- // Returns true if successful; returns false on error or if the memory is
- // not mapped.
- bool Unmap();
-
- // The actual size of the mapped memory (may be larger than requested).
- size_t mapped_size() const { return mapped_size_; }
-
- // Returns a duplicated shared memory region for this DiscardableSharedMemory
- // object.
- UnsafeSharedMemoryRegion DuplicateRegion() const {
- return shared_memory_region_.Duplicate();
- }
-
- // Returns an ID for the shared memory region. This is ID of the mapped region
- // consistent across all processes and is valid as long as the region is not
- // unmapped.
- const UnguessableToken& mapped_id() const {
- return shared_memory_mapping_.guid();
- }
-
- // Locks a range of memory so that it will not be purged by the system.
- // The range of memory must be unlocked. The result of trying to lock an
- // already locked range is undefined. |offset| and |length| must both be
- // a multiple of the page size as returned by GetPageSize().
- // Passing 0 for |length| means "everything onward".
- // Returns SUCCESS if range was successfully locked and the memory is still
- // resident, PURGED if range was successfully locked but has been purged
- // since last time it was locked and FAILED if range could not be locked.
- // Locking can fail for two reasons; object might have been purged, our
- // last known usage timestamp might be out of date. Last known usage time
- // is updated to the actual last usage timestamp if memory is still resident
- // or 0 if not.
- LockResult Lock(size_t offset, size_t length);
-
- // Unlock a previously successfully locked range of memory. The range of
- // memory must be locked. The result of trying to unlock a not
- // previously locked range is undefined.
- // |offset| and |length| must both be a multiple of the page size as returned
- // by GetPageSize().
- // Passing 0 for |length| means "everything onward".
- void Unlock(size_t offset, size_t length);
-
- // Gets a pointer to the opened discardable memory space. Discardable memory
- // must have been mapped via Map().
- void* memory() const;
-
- // Returns the last known usage time for DiscardableSharedMemory object. This
- // may be earlier than the "true" usage time when memory has been used by a
- // different process. Returns NULL time if purged.
- Time last_known_usage() const { return last_known_usage_; }
-
- // This returns true and sets |last_known_usage_| to 0 if
- // DiscardableSharedMemory object was successfully purged. Purging can fail
- // for two reasons; object might be locked or our last known usage timestamp
- // might be out of date. Last known usage time is updated to |current_time|
- // if locked or the actual last usage timestamp if unlocked. It is often
- // necessary to call this function twice for the object to successfully be
- // purged. First call, updates |last_known_usage_|. Second call, successfully
- // purges the object using the updated |last_known_usage_|.
- // Note: there is no guarantee that multiple calls to this function will
- // successfully purge object. DiscardableSharedMemory object might be locked
- // or another thread/process might be able to lock and unlock it in between
- // each call.
- bool Purge(Time current_time);
-
- // Returns true if memory is still resident.
- bool IsMemoryResident() const;
-
- // Returns true if memory is locked.
- bool IsMemoryLocked() const;
-
- // Closes the open discardable memory segment.
- // It is safe to call Close repeatedly.
- void Close();
-
- // For tracing: Creates ownership edge to the underlying shared memory dump
- // which is cross process in the given |pmd|. |local_segment_dump| is the dump
- // associated with the local discardable shared memory segment and |is_owned|
- // is true when the current process owns the segment and the effective memory
- // is assigned to the current process.
- void CreateSharedMemoryOwnershipEdge(
- trace_event::MemoryAllocatorDump* local_segment_dump,
- trace_event::ProcessMemoryDump* pmd,
- bool is_owned) const;
-
- private:
- // LockPages/UnlockPages are platform-native discardable page management
- // helper functions. Both expect |offset| to be specified relative to the
- // base address at which |memory| is mapped, and that |offset| and |length|
- // are page-aligned by the caller.
- // Returns SUCCESS on platforms which do not support discardable pages.
- static LockResult LockPages(const UnsafeSharedMemoryRegion& region,
- size_t offset,
- size_t length);
- // UnlockPages() is a no-op on platforms not supporting discardable pages.
- static void UnlockPages(const UnsafeSharedMemoryRegion& region,
- size_t offset,
- size_t length);
-
- // Virtual for tests.
- virtual Time Now() const;
-
- UnsafeSharedMemoryRegion shared_memory_region_;
- WritableSharedMemoryMapping shared_memory_mapping_;
- size_t mapped_size_;
- size_t locked_page_count_;
-#if DCHECK_IS_ON()
- std::set<size_t> locked_pages_;
-#endif
- // Implementation is not thread-safe but still usable if clients are
- // synchronized somehow. Use a collision warner to detect incorrect usage.
- DFAKE_MUTEX(thread_collision_warner_);
- Time last_known_usage_;
-
- DISALLOW_COPY_AND_ASSIGN(DiscardableSharedMemory);
-};
-
-} // namespace base
-
-#endif // BASE_MEMORY_DISCARDABLE_SHARED_MEMORY_H_
diff --git a/base/memory/linked_ptr.h b/base/memory/linked_ptr.h
deleted file mode 100644
index 6851286..0000000
--- a/base/memory/linked_ptr.h
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright (c) 2011 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.
-//
-// A "smart" pointer type with reference tracking. Every pointer to a
-// particular object is kept on a circular linked list. When the last pointer
-// to an object is destroyed or reassigned, the object is deleted.
-//
-// Used properly, this deletes the object when the last reference goes away.
-// There are several caveats:
-// - Like all reference counting schemes, cycles lead to leaks.
-// - Each smart pointer is actually two pointers (8 bytes instead of 4).
-// - Every time a pointer is released, the entire list of pointers to that
-// object is traversed. This class is therefore NOT SUITABLE when there
-// will often be more than two or three pointers to a particular object.
-// - References are only tracked as long as linked_ptr<> objects are copied.
-// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS
-// will happen (double deletion).
-//
-// Note: If you use an incomplete type with linked_ptr<>, the class
-// *containing* linked_ptr<> must have a constructor and destructor (even
-// if they do nothing!).
-//
-// Thread Safety:
-// A linked_ptr is NOT thread safe. Copying a linked_ptr object is
-// effectively a read-write operation.
-//
-// Alternative: to linked_ptr is shared_ptr, which
-// - is also two pointers in size (8 bytes for 32 bit addresses)
-// - is thread safe for copying and deletion
-// - supports weak_ptrs
-
-#ifndef BASE_MEMORY_LINKED_PTR_H_
-#define BASE_MEMORY_LINKED_PTR_H_
-
-#include "base/logging.h" // for CHECK macros
-
-// This is used internally by all instances of linked_ptr<>. It needs to be
-// a non-template class because different types of linked_ptr<> can refer to
-// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)).
-// So, it needs to be possible for different types of linked_ptr to participate
-// in the same circular linked list, so we need a single class type here.
-//
-// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr<T>.
-class linked_ptr_internal {
- public:
- // Create a new circle that includes only this instance.
- void join_new() {
- next_ = this;
- }
-
- // Join an existing circle.
- void join(linked_ptr_internal const* ptr) {
- next_ = ptr->next_;
- ptr->next_ = this;
- }
-
- // Leave whatever circle we're part of. Returns true iff we were the
- // last member of the circle. Once this is done, you can join() another.
- bool depart() {
- if (next_ == this) return true;
- linked_ptr_internal const* p = next_;
- while (p->next_ != this) p = p->next_;
- p->next_ = next_;
- return false;
- }
-
- private:
- mutable linked_ptr_internal const* next_;
-};
-
-// TODO(http://crbug.com/556939): DEPRECATED: Use unique_ptr instead (now that
-// we have support for moveable types inside STL containers).
-template <typename T>
-class linked_ptr {
- public:
- typedef T element_type;
-
- // Take over ownership of a raw pointer. This should happen as soon as
- // possible after the object is created.
- explicit linked_ptr(T* ptr = NULL) { capture(ptr); }
- ~linked_ptr() { depart(); }
-
- // Copy an existing linked_ptr<>, adding ourselves to the list of references.
- template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); }
-
- linked_ptr(linked_ptr const& ptr) {
- DCHECK_NE(&ptr, this);
- copy(&ptr);
- }
-
- // Assignment releases the old value and acquires the new.
- template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) {
- depart();
- copy(&ptr);
- return *this;
- }
-
- linked_ptr& operator=(linked_ptr const& ptr) {
- if (&ptr != this) {
- depart();
- copy(&ptr);
- }
- return *this;
- }
-
- // Smart pointer members.
- void reset(T* ptr = NULL) {
- depart();
- capture(ptr);
- }
- T* get() const { return value_; }
- T* operator->() const { return value_; }
- T& operator*() const { return *value_; }
- // Release ownership of the pointed object and returns it.
- // Sole ownership by this linked_ptr object is required.
- T* release() {
- bool last = link_.depart();
- CHECK(last);
- T* v = value_;
- value_ = NULL;
- return v;
- }
-
- bool operator==(const T* p) const { return value_ == p; }
- bool operator!=(const T* p) const { return value_ != p; }
- template <typename U>
- bool operator==(linked_ptr<U> const& ptr) const {
- return value_ == ptr.get();
- }
- template <typename U>
- bool operator!=(linked_ptr<U> const& ptr) const {
- return value_ != ptr.get();
- }
-
- private:
- template <typename U>
- friend class linked_ptr;
-
- T* value_;
- linked_ptr_internal link_;
-
- void depart() {
- if (link_.depart()) delete value_;
- }
-
- void capture(T* ptr) {
- value_ = ptr;
- link_.join_new();
- }
-
- template <typename U> void copy(linked_ptr<U> const* ptr) {
- value_ = ptr->get();
- if (value_)
- link_.join(&ptr->link_);
- else
- link_.join_new();
- }
-};
-
-template<typename T> inline
-bool operator==(T* ptr, const linked_ptr<T>& x) {
- return ptr == x.get();
-}
-
-template<typename T> inline
-bool operator!=(T* ptr, const linked_ptr<T>& x) {
- return ptr != x.get();
-}
-
-// A function to convert T* into linked_ptr<T>
-// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation
-// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
-template <typename T>
-linked_ptr<T> make_linked_ptr(T* ptr) {
- return linked_ptr<T>(ptr);
-}
-
-#endif // BASE_MEMORY_LINKED_PTR_H_
diff --git a/base/memory/memory_coordinator_client.cc b/base/memory/memory_coordinator_client.cc
deleted file mode 100644
index 7fa6232..0000000
--- a/base/memory/memory_coordinator_client.cc
+++ /dev/null
@@ -1,27 +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.
-
-#include "base/memory/memory_coordinator_client.h"
-
-#include "base/logging.h"
-
-namespace base {
-
-const char* MemoryStateToString(MemoryState state) {
- switch (state) {
- case MemoryState::UNKNOWN:
- return "unknown";
- case MemoryState::NORMAL:
- return "normal";
- case MemoryState::THROTTLED:
- return "throttled";
- case MemoryState::SUSPENDED:
- return "suspended";
- default:
- NOTREACHED();
- }
- return "";
-}
-
-} // namespace base
diff --git a/base/memory/memory_coordinator_client.h b/base/memory/memory_coordinator_client.h
deleted file mode 100644
index 804f0a6..0000000
--- a/base/memory/memory_coordinator_client.h
+++ /dev/null
@@ -1,79 +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 BASE_MEMORY_MEMORY_COORDINATOR_CLIENT_H_
-#define BASE_MEMORY_MEMORY_COORDINATOR_CLIENT_H_
-
-#include "base/base_export.h"
-
-namespace base {
-
-// OVERVIEW:
-//
-// MemoryCoordinatorClient is an interface which a component can implement to
-// adjust "future allocation" and "existing allocation". For "future allocation"
-// it provides a callback to observe memory state changes, and for "existing
-// allocation" it provides a callback to purge memory.
-//
-// Unlike MemoryPressureListener, memory state changes are stateful. State
-// transitions are throttled to avoid thrashing; the exact throttling period is
-// platform dependent, but will be at least 5-10 seconds. When a state change
-// notification is dispatched, clients are expected to update their allocation
-// policies (e.g. setting cache limit) that persist for the duration of the
-// memory state. Note that clients aren't expected to free up memory on memory
-// state changes. Clients should wait for a separate purge request to free up
-// memory. Purging requests will be throttled as well.
-
-// MemoryState is an indicator that processes can use to guide their memory
-// allocation policies. For example, a process that receives the throttled
-// state can use that as as signal to decrease memory cache limits.
-// NOTE: This enum is used to back an UMA histogram, and therefore should be
-// treated as append-only.
-enum class MemoryState : int {
- // The state is unknown.
- UNKNOWN = -1,
- // No memory constraints.
- NORMAL = 0,
- // Running and interactive but memory allocation should be throttled.
- // Clients should set lower budget for any memory that is used as an
- // optimization but that is not necessary for the process to run.
- // (e.g. caches)
- THROTTLED = 1,
- // Still resident in memory but core processing logic has been suspended.
- // In most cases, OnPurgeMemory() will be called before entering this state.
- SUSPENDED = 2,
-};
-
-const int kMemoryStateMax = static_cast<int>(MemoryState::SUSPENDED) + 1;
-
-// Returns a string representation of MemoryState.
-BASE_EXPORT const char* MemoryStateToString(MemoryState state);
-
-// This is an interface for components which can respond to memory status
-// changes. An initial state is NORMAL. See MemoryCoordinatorClientRegistry for
-// threading guarantees and ownership management.
-class BASE_EXPORT MemoryCoordinatorClient {
- public:
- // Called when memory state has changed. Any transition can occur except for
- // UNKNOWN. General guidelines are:
- // * NORMAL: Restore the default settings for memory allocation/usage if
- // it has changed.
- // * THROTTLED: Use smaller limits for future memory allocations. You don't
- // need to take any action on existing allocations.
- // * SUSPENDED: Use much smaller limits for future memory allocations. You
- // don't need to take any action on existing allocations.
- virtual void OnMemoryStateChange(MemoryState state) {}
-
- // Called to purge memory.
- // This callback should free up any memory that is used as an optimization, or
- // any memory whose contents can be reproduced.
- virtual void OnPurgeMemory() {}
-
- protected:
- virtual ~MemoryCoordinatorClient() = default;
-};
-
-} // namespace base
-
-#endif // BASE_MEMORY_MEMORY_COORDINATOR_CLIENT_H_
diff --git a/base/memory/memory_coordinator_client_registry.cc b/base/memory/memory_coordinator_client_registry.cc
deleted file mode 100644
index 45b4a7f..0000000
--- a/base/memory/memory_coordinator_client_registry.cc
+++ /dev/null
@@ -1,41 +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.
-
-#include "base/memory/memory_coordinator_client_registry.h"
-
-namespace base {
-
-// static
-MemoryCoordinatorClientRegistry*
-MemoryCoordinatorClientRegistry::GetInstance() {
- return Singleton<
- MemoryCoordinatorClientRegistry,
- LeakySingletonTraits<MemoryCoordinatorClientRegistry>>::get();
-}
-
-MemoryCoordinatorClientRegistry::MemoryCoordinatorClientRegistry()
- : clients_(new ClientList) {}
-
-MemoryCoordinatorClientRegistry::~MemoryCoordinatorClientRegistry() = default;
-
-void MemoryCoordinatorClientRegistry::Register(
- MemoryCoordinatorClient* client) {
- clients_->AddObserver(client);
-}
-
-void MemoryCoordinatorClientRegistry::Unregister(
- MemoryCoordinatorClient* client) {
- clients_->RemoveObserver(client);
-}
-
-void MemoryCoordinatorClientRegistry::Notify(MemoryState state) {
- clients_->Notify(FROM_HERE,
- &base::MemoryCoordinatorClient::OnMemoryStateChange, state);
-}
-
-void MemoryCoordinatorClientRegistry::PurgeMemory() {
- clients_->Notify(FROM_HERE, &base::MemoryCoordinatorClient::OnPurgeMemory);
-}
-
-} // namespace base
diff --git a/base/memory/memory_coordinator_client_registry.h b/base/memory/memory_coordinator_client_registry.h
deleted file mode 100644
index e2c81b7..0000000
--- a/base/memory/memory_coordinator_client_registry.h
+++ /dev/null
@@ -1,56 +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 BASE_MEMORY_MEMORY_CLIENT_REGISTRY_H_
-#define BASE_MEMORY_MEMORY_CLIENT_REGISTRY_H_
-
-#include "base/base_export.h"
-#include "base/memory/memory_coordinator_client.h"
-#include "base/memory/singleton.h"
-#include "base/observer_list_threadsafe.h"
-
-namespace base {
-
-// MemoryCoordinatorClientRegistry is the registry of MemoryCoordinatorClients.
-// This class manages clients and provides a way to notify memory state changes
-// to clients, but this isn't responsible to determine how/when to change
-// memory states.
-//
-// Threading guarantees:
-// This class uses ObserverListThreadsafe internally, which means that
-// * Registering/unregistering callbacks are thread-safe.
-// * Callbacks are invoked on the same thread on which they are registered.
-// See base/observer_list_threadsafe.h for reference.
-//
-// Ownership management:
-// This class doesn't take the ownership of clients. Clients must be
-// unregistered before they are destroyed.
-class BASE_EXPORT MemoryCoordinatorClientRegistry {
- public:
- static MemoryCoordinatorClientRegistry* GetInstance();
-
- ~MemoryCoordinatorClientRegistry();
-
- // Registers/unregisters a client. Does not take ownership of client.
- void Register(MemoryCoordinatorClient* client);
- void Unregister(MemoryCoordinatorClient* client);
-
- // Notify clients of a memory state change.
- void Notify(MemoryState state);
-
- // Requests purging memory.
- void PurgeMemory();
-
- private:
- friend struct DefaultSingletonTraits<MemoryCoordinatorClientRegistry>;
-
- MemoryCoordinatorClientRegistry();
-
- using ClientList = ObserverListThreadSafe<MemoryCoordinatorClient>;
- scoped_refptr<ClientList> clients_;
-};
-
-} // namespace base
-
-#endif // BASE_MEMORY_MEMORY_CLIENT_REGISTRY_H_
diff --git a/base/memory/memory_coordinator_proxy.cc b/base/memory/memory_coordinator_proxy.cc
deleted file mode 100644
index 4e22fe0..0000000
--- a/base/memory/memory_coordinator_proxy.cc
+++ /dev/null
@@ -1,37 +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.
-
-#include "base/memory/memory_coordinator_proxy.h"
-
-namespace base {
-
-namespace {
-
-MemoryCoordinator* g_memory_coordinator = nullptr;
-
-} // namespace
-
-MemoryCoordinatorProxy::MemoryCoordinatorProxy() = default;
-
-MemoryCoordinatorProxy::~MemoryCoordinatorProxy() = default;
-
-// static
-MemoryCoordinatorProxy* MemoryCoordinatorProxy::GetInstance() {
- return Singleton<base::MemoryCoordinatorProxy>::get();
-}
-
-// static
-void MemoryCoordinatorProxy::SetMemoryCoordinator(
- MemoryCoordinator* coordinator) {
- DCHECK(!g_memory_coordinator || !coordinator);
- g_memory_coordinator = coordinator;
-}
-
-MemoryState MemoryCoordinatorProxy::GetCurrentMemoryState() const {
- if (!g_memory_coordinator)
- return MemoryState::NORMAL;
- return g_memory_coordinator->GetCurrentMemoryState();
-}
-
-} // namespace base
diff --git a/base/memory/memory_coordinator_proxy.h b/base/memory/memory_coordinator_proxy.h
deleted file mode 100644
index b6e7b3f..0000000
--- a/base/memory/memory_coordinator_proxy.h
+++ /dev/null
@@ -1,49 +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 BASE_MEMORY_MEMORY_COORDINATOR_PROXY_H_
-#define BASE_MEMORY_MEMORY_COORDINATOR_PROXY_H_
-
-#include "base/base_export.h"
-#include "base/callback.h"
-#include "base/memory/memory_coordinator_client.h"
-#include "base/memory/singleton.h"
-
-namespace base {
-
-// The MemoryCoordinator interface. See comments in MemoryCoordinatorProxy for
-// method descriptions.
-class BASE_EXPORT MemoryCoordinator {
- public:
- virtual ~MemoryCoordinator() = default;
-
- virtual MemoryState GetCurrentMemoryState() const = 0;
-};
-
-// The proxy of MemoryCoordinator to be accessed from components that are not
-// in content/browser e.g. net.
-class BASE_EXPORT MemoryCoordinatorProxy {
- public:
- static MemoryCoordinatorProxy* GetInstance();
-
- // Sets an implementation of MemoryCoordinator. MemoryCoordinatorProxy doesn't
- // take the ownership of |coordinator|. It must outlive this proxy.
- // This should be called before any components starts using this proxy.
- static void SetMemoryCoordinator(MemoryCoordinator* coordinator);
-
- // Returns the current memory state.
- MemoryState GetCurrentMemoryState() const;
-
- private:
- friend struct base::DefaultSingletonTraits<MemoryCoordinatorProxy>;
-
- MemoryCoordinatorProxy();
- virtual ~MemoryCoordinatorProxy();
-
- DISALLOW_COPY_AND_ASSIGN(MemoryCoordinatorProxy);
-};
-
-} // namespace base
-
-#endif // BASE_MEMORY_MEMORY_COORDINATOR_PROXY_H_
diff --git a/base/memory/memory_pressure_listener.cc b/base/memory/memory_pressure_listener.cc
deleted file mode 100644
index 3768283..0000000
--- a/base/memory/memory_pressure_listener.cc
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2013 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.
-
-#include "base/memory/memory_pressure_listener.h"
-
-#include "base/observer_list_threadsafe.h"
-
-namespace base {
-
-namespace {
-
-// This class is thread safe and internally synchronized.
-class MemoryPressureObserver {
- public:
- // There is at most one MemoryPressureObserver and it is never deleted.
- ~MemoryPressureObserver() = delete;
-
- void AddObserver(MemoryPressureListener* listener, bool sync) {
- async_observers_->AddObserver(listener);
- if (sync) {
- AutoLock lock(sync_observers_lock_);
- sync_observers_.AddObserver(listener);
- }
- }
-
- void RemoveObserver(MemoryPressureListener* listener) {
- async_observers_->RemoveObserver(listener);
- AutoLock lock(sync_observers_lock_);
- sync_observers_.RemoveObserver(listener);
- }
-
- void Notify(
- MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
- async_observers_->Notify(FROM_HERE, &MemoryPressureListener::Notify,
- memory_pressure_level);
- AutoLock lock(sync_observers_lock_);
- for (auto& observer : sync_observers_)
- observer.SyncNotify(memory_pressure_level);
- }
-
- private:
- const scoped_refptr<ObserverListThreadSafe<MemoryPressureListener>>
- async_observers_ = base::MakeRefCounted<
- ObserverListThreadSafe<MemoryPressureListener>>();
- ObserverList<MemoryPressureListener> sync_observers_;
- Lock sync_observers_lock_;
-};
-
-// Gets the shared MemoryPressureObserver singleton instance.
-MemoryPressureObserver* GetMemoryPressureObserver() {
- static auto* const observer = new MemoryPressureObserver();
- return observer;
-}
-
-subtle::Atomic32 g_notifications_suppressed = 0;
-
-} // namespace
-
-MemoryPressureListener::MemoryPressureListener(
- const MemoryPressureListener::MemoryPressureCallback& callback)
- : callback_(callback) {
- GetMemoryPressureObserver()->AddObserver(this, false);
-}
-
-MemoryPressureListener::MemoryPressureListener(
- const MemoryPressureListener::MemoryPressureCallback& callback,
- const MemoryPressureListener::SyncMemoryPressureCallback&
- sync_memory_pressure_callback)
- : callback_(callback),
- sync_memory_pressure_callback_(sync_memory_pressure_callback) {
- GetMemoryPressureObserver()->AddObserver(this, true);
-}
-
-MemoryPressureListener::~MemoryPressureListener() {
- GetMemoryPressureObserver()->RemoveObserver(this);
-}
-
-void MemoryPressureListener::Notify(MemoryPressureLevel memory_pressure_level) {
- callback_.Run(memory_pressure_level);
-}
-
-void MemoryPressureListener::SyncNotify(
- MemoryPressureLevel memory_pressure_level) {
- if (!sync_memory_pressure_callback_.is_null()) {
- sync_memory_pressure_callback_.Run(memory_pressure_level);
- }
-}
-
-// static
-void MemoryPressureListener::NotifyMemoryPressure(
- MemoryPressureLevel memory_pressure_level) {
- DCHECK_NE(memory_pressure_level, MEMORY_PRESSURE_LEVEL_NONE);
- TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("memory-infra"),
- "MemoryPressureListener::NotifyMemoryPressure",
- TRACE_EVENT_SCOPE_THREAD, "level",
- memory_pressure_level);
- if (AreNotificationsSuppressed())
- return;
- DoNotifyMemoryPressure(memory_pressure_level);
-}
-
-// static
-bool MemoryPressureListener::AreNotificationsSuppressed() {
- return subtle::Acquire_Load(&g_notifications_suppressed) == 1;
-}
-
-// static
-void MemoryPressureListener::SetNotificationsSuppressed(bool suppress) {
- subtle::Release_Store(&g_notifications_suppressed, suppress ? 1 : 0);
-}
-
-// static
-void MemoryPressureListener::SimulatePressureNotification(
- MemoryPressureLevel memory_pressure_level) {
- // Notify all listeners even if regular pressure notifications are suppressed.
- DoNotifyMemoryPressure(memory_pressure_level);
-}
-
-// static
-void MemoryPressureListener::DoNotifyMemoryPressure(
- MemoryPressureLevel memory_pressure_level) {
- DCHECK_NE(memory_pressure_level, MEMORY_PRESSURE_LEVEL_NONE);
-
- GetMemoryPressureObserver()->Notify(memory_pressure_level);
-}
-
-} // namespace base
diff --git a/base/memory/memory_pressure_listener.h b/base/memory/memory_pressure_listener.h
deleted file mode 100644
index 7e97010..0000000
--- a/base/memory/memory_pressure_listener.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2013 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.
-
-// MemoryPressure provides static APIs for handling memory pressure on
-// platforms that have such signals, such as Android and ChromeOS.
-// The app will try to discard buffers that aren't deemed essential (individual
-// modules will implement their own policy).
-
-#ifndef BASE_MEMORY_MEMORY_PRESSURE_LISTENER_H_
-#define BASE_MEMORY_MEMORY_PRESSURE_LISTENER_H_
-
-#include "base/base_export.h"
-#include "base/callback.h"
-#include "base/macros.h"
-
-namespace base {
-
-// To start listening, create a new instance, passing a callback to a
-// function that takes a MemoryPressureLevel parameter. To stop listening,
-// simply delete the listener object. The implementation guarantees
-// that the callback will always be called on the thread that created
-// the listener.
-// Note that even on the same thread, the callback is not guaranteed to be
-// called synchronously within the system memory pressure broadcast.
-// Please see notes in MemoryPressureLevel enum below: some levels are
-// absolutely critical, and if not enough memory is returned to the system,
-// it'll potentially kill the app, and then later the app will have to be
-// cold-started.
-//
-// Example:
-//
-// void OnMemoryPressure(MemoryPressureLevel memory_pressure_level) {
-// ...
-// }
-//
-// // Start listening.
-// MemoryPressureListener* my_listener =
-// new MemoryPressureListener(base::Bind(&OnMemoryPressure));
-//
-// ...
-//
-// // Stop listening.
-// delete my_listener;
-//
-class BASE_EXPORT MemoryPressureListener {
- public:
- // A Java counterpart will be generated for this enum.
- // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.base
- enum MemoryPressureLevel {
- // No problems, there is enough memory to use. This event is not sent via
- // callback, but the enum is used in other places to find out the current
- // state of the system.
- MEMORY_PRESSURE_LEVEL_NONE,
-
- // Modules are advised to free buffers that are cheap to re-allocate and not
- // immediately needed.
- MEMORY_PRESSURE_LEVEL_MODERATE,
-
- // At this level, modules are advised to free all possible memory. The
- // alternative is to be killed by the system, which means all memory will
- // have to be re-created, plus the cost of a cold start.
- MEMORY_PRESSURE_LEVEL_CRITICAL,
- };
-
- typedef Callback<void(MemoryPressureLevel)> MemoryPressureCallback;
- typedef Callback<void(MemoryPressureLevel)> SyncMemoryPressureCallback;
-
- explicit MemoryPressureListener(
- const MemoryPressureCallback& memory_pressure_callback);
- MemoryPressureListener(
- const MemoryPressureCallback& memory_pressure_callback,
- const SyncMemoryPressureCallback& sync_memory_pressure_callback);
-
- ~MemoryPressureListener();
-
- // Intended for use by the platform specific implementation.
- static void NotifyMemoryPressure(MemoryPressureLevel memory_pressure_level);
-
- // These methods should not be used anywhere else but in memory measurement
- // code, where they are intended to maintain stable conditions across
- // measurements.
- static bool AreNotificationsSuppressed();
- static void SetNotificationsSuppressed(bool suppressed);
- static void SimulatePressureNotification(
- MemoryPressureLevel memory_pressure_level);
-
- void Notify(MemoryPressureLevel memory_pressure_level);
- void SyncNotify(MemoryPressureLevel memory_pressure_level);
-
- private:
- static void DoNotifyMemoryPressure(MemoryPressureLevel memory_pressure_level);
-
- MemoryPressureCallback callback_;
- SyncMemoryPressureCallback sync_memory_pressure_callback_;
-
- DISALLOW_COPY_AND_ASSIGN(MemoryPressureListener);
-};
-
-} // namespace base
-
-#endif // BASE_MEMORY_MEMORY_PRESSURE_LISTENER_H_
diff --git a/base/memory/memory_pressure_monitor.cc b/base/memory/memory_pressure_monitor.cc
deleted file mode 100644
index ed350b8..0000000
--- a/base/memory/memory_pressure_monitor.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2015 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.
-
-#include "base/memory/memory_pressure_monitor.h"
-
-#include "base/logging.h"
-#include "base/metrics/histogram_macros.h"
-
-namespace base {
-namespace {
-
-MemoryPressureMonitor* g_monitor = nullptr;
-
-// Enumeration of UMA memory pressure levels. This needs to be kept in sync with
-// histograms.xml and the memory pressure levels defined in
-// MemoryPressureListener.
-enum MemoryPressureLevelUMA {
- UMA_MEMORY_PRESSURE_LEVEL_NONE = 0,
- UMA_MEMORY_PRESSURE_LEVEL_MODERATE = 1,
- UMA_MEMORY_PRESSURE_LEVEL_CRITICAL = 2,
- // This must be the last value in the enum.
- UMA_MEMORY_PRESSURE_LEVEL_COUNT,
-};
-
-// Converts a memory pressure level to an UMA enumeration value.
-MemoryPressureLevelUMA MemoryPressureLevelToUmaEnumValue(
- base::MemoryPressureListener::MemoryPressureLevel level) {
- switch (level) {
- case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
- return UMA_MEMORY_PRESSURE_LEVEL_NONE;
- case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
- return UMA_MEMORY_PRESSURE_LEVEL_MODERATE;
- case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
- return UMA_MEMORY_PRESSURE_LEVEL_CRITICAL;
- }
- NOTREACHED();
- return UMA_MEMORY_PRESSURE_LEVEL_NONE;
-}
-
-} // namespace
-
-MemoryPressureMonitor::MemoryPressureMonitor() {
- DCHECK(!g_monitor);
- g_monitor = this;
-}
-
-MemoryPressureMonitor::~MemoryPressureMonitor() {
- DCHECK(g_monitor);
- g_monitor = nullptr;
-}
-
-// static
-MemoryPressureMonitor* MemoryPressureMonitor::Get() {
- return g_monitor;
-}
-void MemoryPressureMonitor::RecordMemoryPressure(
- base::MemoryPressureListener::MemoryPressureLevel level,
- int ticks) {
- // Use the more primitive STATIC_HISTOGRAM_POINTER_BLOCK macro because the
- // simple UMA_HISTOGRAM macros don't expose 'AddCount' functionality.
- STATIC_HISTOGRAM_POINTER_BLOCK(
- "Memory.PressureLevel",
- AddCount(MemoryPressureLevelToUmaEnumValue(level), ticks),
- base::LinearHistogram::FactoryGet(
- "Memory.PressureLevel", 1, UMA_MEMORY_PRESSURE_LEVEL_COUNT,
- UMA_MEMORY_PRESSURE_LEVEL_COUNT + 1,
- base::HistogramBase::kUmaTargetedHistogramFlag));
-}
-
-} // namespace base
diff --git a/base/memory/memory_pressure_monitor.h b/base/memory/memory_pressure_monitor.h
deleted file mode 100644
index e48244b..0000000
--- a/base/memory/memory_pressure_monitor.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2015 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 BASE_MEMORY_MEMORY_PRESSURE_MONITOR_H_
-#define BASE_MEMORY_MEMORY_PRESSURE_MONITOR_H_
-
-#include "base/base_export.h"
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/memory_pressure_listener.h"
-
-namespace base {
-
-// TODO(chrisha): Make this a concrete class with per-OS implementations rather
-// than an abstract base class.
-
-// Declares the interface for a MemoryPressureMonitor. There are multiple
-// OS specific implementations of this class. An instance of the memory
-// pressure observer is created at the process level, tracks memory usage, and
-// pushes memory state change notifications to the static function
-// base::MemoryPressureListener::NotifyMemoryPressure. This is turn notifies
-// all MemoryPressureListener instances via a callback.
-class BASE_EXPORT MemoryPressureMonitor {
- public:
- using MemoryPressureLevel = base::MemoryPressureListener::MemoryPressureLevel;
- using DispatchCallback = base::Callback<void(MemoryPressureLevel level)>;
-
- virtual ~MemoryPressureMonitor();
-
- // Return the singleton MemoryPressureMonitor.
- static MemoryPressureMonitor* Get();
-
- // Record memory pressure UMA statistic. A tick is 5 seconds.
- static void RecordMemoryPressure(MemoryPressureLevel level, int ticks);
-
- // Returns the currently observed memory pressure.
- virtual MemoryPressureLevel GetCurrentPressureLevel() = 0;
-
- // Sets a notification callback. The default callback invokes
- // base::MemoryPressureListener::NotifyMemoryPressure.
- virtual void SetDispatchCallback(const DispatchCallback& callback) = 0;
-
- protected:
- MemoryPressureMonitor();
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MemoryPressureMonitor);
-};
-
-} // namespace base
-
-#endif // BASE_MEMORY_MEMORY_PRESSURE_MONITOR_H_
diff --git a/base/memory/memory_pressure_monitor_chromeos.cc b/base/memory/memory_pressure_monitor_chromeos.cc
deleted file mode 100644
index b4e4b94..0000000
--- a/base/memory/memory_pressure_monitor_chromeos.cc
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright 2014 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.
-
-#include "base/memory/memory_pressure_monitor_chromeos.h"
-
-#include <fcntl.h>
-#include <sys/select.h>
-
-#include "base/metrics/histogram_macros.h"
-#include "base/posix/eintr_wrapper.h"
-#include "base/process/process_metrics.h"
-#include "base/single_thread_task_runner.h"
-#include "base/sys_info.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
-
-namespace base {
-namespace chromeos {
-
-namespace {
-
-// The time between memory pressure checks. While under critical pressure, this
-// is also the timer to repeat cleanup attempts.
-const int kMemoryPressureIntervalMs = 1000;
-
-// The time which should pass between two moderate memory pressure calls.
-const int kModerateMemoryPressureCooldownMs = 10000;
-
-// Number of event polls before the next moderate pressure event can be sent.
-const int kModerateMemoryPressureCooldown =
- kModerateMemoryPressureCooldownMs / kMemoryPressureIntervalMs;
-
-// Threshold constants to emit pressure events.
-const int kNormalMemoryPressureModerateThresholdPercent = 60;
-const int kNormalMemoryPressureCriticalThresholdPercent = 95;
-const int kAggressiveMemoryPressureModerateThresholdPercent = 35;
-const int kAggressiveMemoryPressureCriticalThresholdPercent = 70;
-
-// The possible state for memory pressure level. The values should be in line
-// with values in MemoryPressureListener::MemoryPressureLevel and should be
-// updated if more memory pressure levels are introduced.
-enum MemoryPressureLevelUMA {
- MEMORY_PRESSURE_LEVEL_NONE = 0,
- MEMORY_PRESSURE_LEVEL_MODERATE,
- MEMORY_PRESSURE_LEVEL_CRITICAL,
- NUM_MEMORY_PRESSURE_LEVELS
-};
-
-// This is the file that will exist if low memory notification is available
-// on the device. Whenever it becomes readable, it signals a low memory
-// condition.
-const char kLowMemFile[] = "/dev/chromeos-low-mem";
-
-// Converts a |MemoryPressureThreshold| value into a used memory percentage for
-// the moderate pressure event.
-int GetModerateMemoryThresholdInPercent(
- MemoryPressureMonitor::MemoryPressureThresholds thresholds) {
- return thresholds == MemoryPressureMonitor::
- THRESHOLD_AGGRESSIVE_CACHE_DISCARD ||
- thresholds == MemoryPressureMonitor::THRESHOLD_AGGRESSIVE
- ? kAggressiveMemoryPressureModerateThresholdPercent
- : kNormalMemoryPressureModerateThresholdPercent;
-}
-
-// Converts a |MemoryPressureThreshold| value into a used memory percentage for
-// the critical pressure event.
-int GetCriticalMemoryThresholdInPercent(
- MemoryPressureMonitor::MemoryPressureThresholds thresholds) {
- return thresholds == MemoryPressureMonitor::
- THRESHOLD_AGGRESSIVE_TAB_DISCARD ||
- thresholds == MemoryPressureMonitor::THRESHOLD_AGGRESSIVE
- ? kAggressiveMemoryPressureCriticalThresholdPercent
- : kNormalMemoryPressureCriticalThresholdPercent;
-}
-
-// Converts free percent of memory into a memory pressure value.
-MemoryPressureListener::MemoryPressureLevel GetMemoryPressureLevelFromFillLevel(
- int actual_fill_level,
- int moderate_threshold,
- int critical_threshold) {
- if (actual_fill_level < moderate_threshold)
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
- return actual_fill_level < critical_threshold
- ? MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE
- : MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
-}
-
-// This function will be called less than once a second. It will check if
-// the kernel has detected a low memory situation.
-bool IsLowMemoryCondition(int file_descriptor) {
- fd_set fds;
- struct timeval tv;
-
- FD_ZERO(&fds);
- FD_SET(file_descriptor, &fds);
-
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-
- return HANDLE_EINTR(select(file_descriptor + 1, &fds, NULL, NULL, &tv)) > 0;
-}
-
-} // namespace
-
-MemoryPressureMonitor::MemoryPressureMonitor(
- MemoryPressureThresholds thresholds)
- : current_memory_pressure_level_(
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE),
- moderate_pressure_repeat_count_(0),
- seconds_since_reporting_(0),
- moderate_pressure_threshold_percent_(
- GetModerateMemoryThresholdInPercent(thresholds)),
- critical_pressure_threshold_percent_(
- GetCriticalMemoryThresholdInPercent(thresholds)),
- low_mem_file_(HANDLE_EINTR(::open(kLowMemFile, O_RDONLY))),
- dispatch_callback_(
- base::Bind(&MemoryPressureListener::NotifyMemoryPressure)),
- weak_ptr_factory_(this) {
- StartObserving();
- LOG_IF(ERROR,
- base::SysInfo::IsRunningOnChromeOS() && !low_mem_file_.is_valid())
- << "Cannot open kernel listener";
-}
-
-MemoryPressureMonitor::~MemoryPressureMonitor() {
- StopObserving();
-}
-
-void MemoryPressureMonitor::ScheduleEarlyCheck() {
- ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, BindOnce(&MemoryPressureMonitor::CheckMemoryPressure,
- weak_ptr_factory_.GetWeakPtr()));
-}
-
-MemoryPressureListener::MemoryPressureLevel
-MemoryPressureMonitor::GetCurrentPressureLevel() {
- return current_memory_pressure_level_;
-}
-
-// static
-MemoryPressureMonitor* MemoryPressureMonitor::Get() {
- return static_cast<MemoryPressureMonitor*>(
- base::MemoryPressureMonitor::Get());
-}
-
-void MemoryPressureMonitor::StartObserving() {
- timer_.Start(FROM_HERE,
- TimeDelta::FromMilliseconds(kMemoryPressureIntervalMs),
- Bind(&MemoryPressureMonitor::
- CheckMemoryPressureAndRecordStatistics,
- weak_ptr_factory_.GetWeakPtr()));
-}
-
-void MemoryPressureMonitor::StopObserving() {
- // If StartObserving failed, StopObserving will still get called.
- timer_.Stop();
-}
-
-void MemoryPressureMonitor::CheckMemoryPressureAndRecordStatistics() {
- CheckMemoryPressure();
- if (seconds_since_reporting_++ == 5) {
- seconds_since_reporting_ = 0;
- RecordMemoryPressure(current_memory_pressure_level_, 1);
- }
- // Record UMA histogram statistics for the current memory pressure level.
- // TODO(lgrey): Remove this once there's a usable history for the
- // "Memory.PressureLevel" statistic
- MemoryPressureLevelUMA memory_pressure_level_uma(MEMORY_PRESSURE_LEVEL_NONE);
- switch (current_memory_pressure_level_) {
- case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
- memory_pressure_level_uma = MEMORY_PRESSURE_LEVEL_NONE;
- break;
- case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
- memory_pressure_level_uma = MEMORY_PRESSURE_LEVEL_MODERATE;
- break;
- case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
- memory_pressure_level_uma = MEMORY_PRESSURE_LEVEL_CRITICAL;
- break;
- }
-
- UMA_HISTOGRAM_ENUMERATION("ChromeOS.MemoryPressureLevel",
- memory_pressure_level_uma,
- NUM_MEMORY_PRESSURE_LEVELS);
-}
-
-void MemoryPressureMonitor::CheckMemoryPressure() {
- MemoryPressureListener::MemoryPressureLevel old_pressure =
- current_memory_pressure_level_;
-
- // If we have the kernel low memory observer, we use it's flag instead of our
- // own computation (for now). Note that in "simulation mode" it can be null.
- // TODO(skuhne): We need to add code which makes sure that the kernel and this
- // computation come to similar results and then remove this override again.
- // TODO(skuhne): Add some testing framework here to see how close the kernel
- // and the internal functions are.
- if (low_mem_file_.is_valid() && IsLowMemoryCondition(low_mem_file_.get())) {
- current_memory_pressure_level_ =
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
- } else {
- current_memory_pressure_level_ = GetMemoryPressureLevelFromFillLevel(
- GetUsedMemoryInPercent(),
- moderate_pressure_threshold_percent_,
- critical_pressure_threshold_percent_);
-
- // When listening to the kernel, we ignore the reported memory pressure
- // level from our own computation and reduce critical to moderate.
- if (low_mem_file_.is_valid() &&
- current_memory_pressure_level_ ==
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) {
- current_memory_pressure_level_ =
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
- }
- }
-
- // In case there is no memory pressure we do not notify.
- if (current_memory_pressure_level_ ==
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) {
- return;
- }
- if (old_pressure == current_memory_pressure_level_) {
- // If the memory pressure is still at the same level, we notify again for a
- // critical level. In case of a moderate level repeat however, we only send
- // a notification after a certain time has passed.
- if (current_memory_pressure_level_ ==
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE &&
- ++moderate_pressure_repeat_count_ <
- kModerateMemoryPressureCooldown) {
- return;
- }
- } else if (current_memory_pressure_level_ ==
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE &&
- old_pressure ==
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) {
- // When we reducing the pressure level from critical to moderate, we
- // restart the timeout and do not send another notification.
- moderate_pressure_repeat_count_ = 0;
- return;
- }
- moderate_pressure_repeat_count_ = 0;
- dispatch_callback_.Run(current_memory_pressure_level_);
-}
-
-// Gets the used ChromeOS memory in percent.
-int MemoryPressureMonitor::GetUsedMemoryInPercent() {
- base::SystemMemoryInfoKB info;
- if (!base::GetSystemMemoryInfo(&info)) {
- VLOG(1) << "Cannot determine the free memory of the system.";
- return 0;
- }
- // TODO(skuhne): Instead of adding the kernel memory pressure calculation
- // logic here, we should have a kernel mechanism similar to the low memory
- // notifier in ChromeOS which offers multiple pressure states.
- // To track this, we have crbug.com/381196.
-
- // The available memory consists of "real" and virtual (z)ram memory.
- // Since swappable memory uses a non pre-deterministic compression and
- // the compression creates its own "dynamic" in the system, it gets
- // de-emphasized by the |kSwapWeight| factor.
- const int kSwapWeight = 4;
-
- // The total memory we have is the "real memory" plus the virtual (z)ram.
- int total_memory = info.total + info.swap_total / kSwapWeight;
-
- // The kernel internally uses 50MB.
- const int kMinFileMemory = 50 * 1024;
-
- // Most file memory can be easily reclaimed.
- int file_memory = info.active_file + info.inactive_file;
- // unless it is dirty or it's a minimal portion which is required.
- file_memory -= info.dirty + kMinFileMemory;
-
- // Available memory is the sum of free, swap and easy reclaimable memory.
- int available_memory =
- info.free + info.swap_free / kSwapWeight + file_memory;
-
- DCHECK(available_memory < total_memory);
- int percentage = ((total_memory - available_memory) * 100) / total_memory;
- return percentage;
-}
-
-void MemoryPressureMonitor::SetDispatchCallback(
- const DispatchCallback& callback) {
- dispatch_callback_ = callback;
-}
-
-} // namespace chromeos
-} // namespace base
diff --git a/base/memory/memory_pressure_monitor_chromeos.h b/base/memory/memory_pressure_monitor_chromeos.h
deleted file mode 100644
index 563ba85..0000000
--- a/base/memory/memory_pressure_monitor_chromeos.h
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2014 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 BASE_MEMORY_MEMORY_PRESSURE_MONITOR_CHROMEOS_H_
-#define BASE_MEMORY_MEMORY_PRESSURE_MONITOR_CHROMEOS_H_
-
-#include "base/base_export.h"
-#include "base/files/scoped_file.h"
-#include "base/macros.h"
-#include "base/memory/memory_pressure_listener.h"
-#include "base/memory/memory_pressure_monitor.h"
-#include "base/memory/weak_ptr.h"
-#include "base/timer/timer.h"
-
-namespace base {
-namespace chromeos {
-
-class TestMemoryPressureMonitor;
-
-////////////////////////////////////////////////////////////////////////////////
-// MemoryPressureMonitor
-//
-// A class to handle the observation of our free memory. It notifies the
-// MemoryPressureListener of memory fill level changes, so that it can take
-// action to reduce memory resources accordingly.
-//
-class BASE_EXPORT MemoryPressureMonitor : public base::MemoryPressureMonitor {
- public:
- using GetUsedMemoryInPercentCallback = int (*)();
-
- // There are two memory pressure events:
- // MODERATE - which will mainly release caches.
- // CRITICAL - which will discard tabs.
- // The |MemoryPressureThresholds| enum selects the strategy of firing these
- // events: A conservative strategy will keep as much content in memory as
- // possible (causing the system to swap to zram) and an aggressive strategy
- // will release memory earlier to avoid swapping.
- enum MemoryPressureThresholds {
- // Use the system default.
- THRESHOLD_DEFAULT = 0,
- // Try to keep as much content in memory as possible.
- THRESHOLD_CONSERVATIVE = 1,
- // Discard caches earlier, allowing to keep more tabs in memory.
- THRESHOLD_AGGRESSIVE_CACHE_DISCARD = 2,
- // Discard tabs earlier, allowing the system to get faster.
- THRESHOLD_AGGRESSIVE_TAB_DISCARD = 3,
- // Discard caches and tabs earlier to allow the system to be faster.
- THRESHOLD_AGGRESSIVE = 4
- };
-
- explicit MemoryPressureMonitor(MemoryPressureThresholds thresholds);
- ~MemoryPressureMonitor() override;
-
- // Redo the memory pressure calculation soon and call again if a critical
- // memory pressure prevails. Note that this call will trigger an asynchronous
- // action which gives the system time to release memory back into the pool.
- void ScheduleEarlyCheck();
-
- // Get the current memory pressure level.
- MemoryPressureListener::MemoryPressureLevel GetCurrentPressureLevel()
- override;
- void SetDispatchCallback(const DispatchCallback& callback) override;
-
- // Returns a type-casted version of the current memory pressure monitor. A
- // simple wrapper to base::MemoryPressureMonitor::Get.
- static MemoryPressureMonitor* Get();
-
- private:
- friend TestMemoryPressureMonitor;
- // Starts observing the memory fill level.
- // Calls to StartObserving should always be matched with calls to
- // StopObserving.
- void StartObserving();
-
- // Stop observing the memory fill level.
- // May be safely called if StartObserving has not been called.
- void StopObserving();
-
- // The function which gets periodically called to check any changes in the
- // memory pressure. It will report pressure changes as well as continuous
- // critical pressure levels.
- void CheckMemoryPressure();
-
- // The function periodically checks the memory pressure changes and records
- // the UMA histogram statistics for the current memory pressure level.
- void CheckMemoryPressureAndRecordStatistics();
-
- // Get the memory pressure in percent (virtual for testing).
- virtual int GetUsedMemoryInPercent();
-
- // The current memory pressure.
- base::MemoryPressureListener::MemoryPressureLevel
- current_memory_pressure_level_;
-
- // A periodic timer to check for resource pressure changes. This will get
- // replaced by a kernel triggered event system (see crbug.com/381196).
- base::RepeatingTimer timer_;
-
- // To slow down the amount of moderate pressure event calls, this counter
- // gets used to count the number of events since the last event occured.
- int moderate_pressure_repeat_count_;
-
- // The "Memory.PressureLevel" statistic is recorded every
- // 5 seconds, but the timer to report "ChromeOS.MemoryPressureLevel"
- // fires every second. This counter is used to allow reporting
- // "Memory.PressureLevel" correctly without adding another
- // timer.
- int seconds_since_reporting_;
-
- // The thresholds for moderate and critical pressure.
- const int moderate_pressure_threshold_percent_;
- const int critical_pressure_threshold_percent_;
-
- // File descriptor used to detect low memory condition.
- ScopedFD low_mem_file_;
-
- DispatchCallback dispatch_callback_;
-
- base::WeakPtrFactory<MemoryPressureMonitor> weak_ptr_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(MemoryPressureMonitor);
-};
-
-} // namespace chromeos
-} // namespace base
-
-#endif // BASE_MEMORY_MEMORY_PRESSURE_MONITOR_CHROMEOS_H_
diff --git a/base/memory/memory_pressure_monitor_mac.cc b/base/memory/memory_pressure_monitor_mac.cc
deleted file mode 100644
index 678c276..0000000
--- a/base/memory/memory_pressure_monitor_mac.cc
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright 2015 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.
-
-#include "base/memory/memory_pressure_monitor_mac.h"
-
-#include <CoreFoundation/CoreFoundation.h>
-
-#include <dlfcn.h>
-#include <stddef.h>
-#include <sys/sysctl.h>
-
-#include <cmath>
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/mac/mac_util.h"
-
-// Redeclare for partial 10.9 availability.
-DISPATCH_EXPORT const struct dispatch_source_type_s
- _dispatch_source_type_memorypressure;
-
-namespace {
-static const int kUMATickSize = 5;
-} // namespace
-
-namespace base {
-namespace mac {
-
-MemoryPressureListener::MemoryPressureLevel
-MemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressureLevel(
- int mac_memory_pressure_level) {
- switch (mac_memory_pressure_level) {
- case DISPATCH_MEMORYPRESSURE_NORMAL:
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
- case DISPATCH_MEMORYPRESSURE_WARN:
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
- case DISPATCH_MEMORYPRESSURE_CRITICAL:
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
- }
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
-}
-
-void MemoryPressureMonitor::OnRunLoopExit(CFRunLoopObserverRef observer,
- CFRunLoopActivity activity,
- void* info) {
- MemoryPressureMonitor* self = static_cast<MemoryPressureMonitor*>(info);
- self->UpdatePressureLevelOnRunLoopExit();
-}
-
-MemoryPressureMonitor::MemoryPressureMonitor()
- : memory_level_event_source_(dispatch_source_create(
- DISPATCH_SOURCE_TYPE_MEMORYPRESSURE,
- 0,
- DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL |
- DISPATCH_MEMORYPRESSURE_NORMAL,
- dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))),
- dispatch_callback_(
- base::Bind(&MemoryPressureListener::NotifyMemoryPressure)),
- last_statistic_report_time_(CFAbsoluteTimeGetCurrent()),
- last_pressure_level_(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE),
- subtick_seconds_(0) {
- // Attach an event handler to the memory pressure event source.
- if (memory_level_event_source_.get()) {
- dispatch_source_set_event_handler(memory_level_event_source_, ^{
- OnMemoryPressureChanged(memory_level_event_source_.get(),
- dispatch_callback_);
- });
-
- // Start monitoring the event source.
- dispatch_resume(memory_level_event_source_);
- }
-
- // Create a CFRunLoopObserver to check the memory pressure at the end of
- // every pass through the event loop (modulo kUMATickSize).
- CFRunLoopObserverContext observer_context = {0, this, NULL, NULL, NULL};
-
- exit_observer_.reset(
- CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopExit, true, 0,
- OnRunLoopExit, &observer_context));
-
- CFRunLoopRef run_loop = CFRunLoopGetCurrent();
- CFRunLoopAddObserver(run_loop, exit_observer_, kCFRunLoopCommonModes);
- CFRunLoopAddObserver(run_loop, exit_observer_,
- kMessageLoopExclusiveRunLoopMode);
-}
-
-MemoryPressureMonitor::~MemoryPressureMonitor() {
- // Detach from the run loop.
- CFRunLoopRef run_loop = CFRunLoopGetCurrent();
- CFRunLoopRemoveObserver(run_loop, exit_observer_, kCFRunLoopCommonModes);
- CFRunLoopRemoveObserver(run_loop, exit_observer_,
- kMessageLoopExclusiveRunLoopMode);
-
- // Remove the memory pressure event source.
- if (memory_level_event_source_.get()) {
- dispatch_source_cancel(memory_level_event_source_);
- }
-}
-
-int MemoryPressureMonitor::GetMacMemoryPressureLevel() {
- // Get the raw memory pressure level from macOS.
- int mac_memory_pressure_level;
- size_t length = sizeof(int);
- sysctlbyname("kern.memorystatus_vm_pressure_level",
- &mac_memory_pressure_level, &length, nullptr, 0);
-
- return mac_memory_pressure_level;
-}
-
-void MemoryPressureMonitor::UpdatePressureLevel() {
- // Get the current macOS pressure level and convert to the corresponding
- // Chrome pressure level.
- int mac_memory_pressure_level = GetMacMemoryPressureLevel();
- MemoryPressureListener::MemoryPressureLevel new_pressure_level =
- MemoryPressureLevelForMacMemoryPressureLevel(mac_memory_pressure_level);
-
- // Compute the number of "ticks" spent at |last_pressure_level_| (since the
- // last report sent to UMA).
- CFTimeInterval now = CFAbsoluteTimeGetCurrent();
- CFTimeInterval time_since_last_report = now - last_statistic_report_time_;
- last_statistic_report_time_ = now;
-
- double accumulated_time = time_since_last_report + subtick_seconds_;
- int ticks_to_report = static_cast<int>(accumulated_time / kUMATickSize);
- // Save for later the seconds that didn't make it into a full tick.
- subtick_seconds_ = std::fmod(accumulated_time, kUMATickSize);
-
- // Round the tick count up on a pressure level change to ensure we capture it.
- bool pressure_level_changed = (new_pressure_level != last_pressure_level_);
- if (pressure_level_changed && ticks_to_report < 1) {
- ticks_to_report = 1;
- subtick_seconds_ = 0;
- }
-
- // Send elapsed ticks to UMA.
- if (ticks_to_report >= 1) {
- RecordMemoryPressure(last_pressure_level_, ticks_to_report);
- }
-
- // Save the now-current memory pressure level.
- last_pressure_level_ = new_pressure_level;
-}
-
-void MemoryPressureMonitor::UpdatePressureLevelOnRunLoopExit() {
- // Wait until it's time to check the pressure level.
- CFTimeInterval now = CFAbsoluteTimeGetCurrent();
- if (now >= next_run_loop_update_time_) {
- UpdatePressureLevel();
-
- // Update again in kUMATickSize seconds. We can update at any frequency,
- // but because we're only checking memory pressure levels for UMA there's
- // no need to update more frequently than we're keeping statistics on.
- next_run_loop_update_time_ = now + kUMATickSize - subtick_seconds_;
- }
-}
-
-// Static.
-int MemoryPressureMonitor::GetSecondsPerUMATick() {
- return kUMATickSize;
-}
-
-MemoryPressureListener::MemoryPressureLevel
-MemoryPressureMonitor::GetCurrentPressureLevel() {
- return last_pressure_level_;
-}
-
-void MemoryPressureMonitor::OnMemoryPressureChanged(
- dispatch_source_s* event_source,
- const MemoryPressureMonitor::DispatchCallback& dispatch_callback) {
- // The OS has sent a notification that the memory pressure level has changed.
- // Go through the normal memory pressure level checking mechanism so that
- // last_pressure_level_ and UMA get updated to the current value.
- UpdatePressureLevel();
-
- // Run the callback that's waiting on memory pressure change notifications.
- // The convention is to not send notifiations on memory pressure returning to
- // normal.
- if (last_pressure_level_ !=
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE)
- dispatch_callback.Run(last_pressure_level_);
-}
-
-void MemoryPressureMonitor::SetDispatchCallback(
- const DispatchCallback& callback) {
- dispatch_callback_ = callback;
-}
-
-} // namespace mac
-} // namespace base
diff --git a/base/memory/memory_pressure_monitor_mac.h b/base/memory/memory_pressure_monitor_mac.h
deleted file mode 100644
index b85b6c9..0000000
--- a/base/memory/memory_pressure_monitor_mac.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2015 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 BASE_MEMORY_MEMORY_PRESSURE_MONITOR_MAC_H_
-#define BASE_MEMORY_MEMORY_PRESSURE_MONITOR_MAC_H_
-
-#include <CoreFoundation/CFDate.h>
-#include <dispatch/dispatch.h>
-
-#include "base/base_export.h"
-#include "base/mac/scoped_cftyperef.h"
-#include "base/mac/scoped_dispatch_object.h"
-#include "base/macros.h"
-#include "base/memory/memory_pressure_listener.h"
-#include "base/memory/memory_pressure_monitor.h"
-#include "base/message_loop/message_pump_mac.h"
-
-namespace base {
-namespace mac {
-
-class TestMemoryPressureMonitor;
-
-// Declares the interface for the Mac MemoryPressureMonitor, which reports
-// memory pressure events and status.
-class BASE_EXPORT MemoryPressureMonitor : public base::MemoryPressureMonitor {
- public:
- MemoryPressureMonitor();
- ~MemoryPressureMonitor() override;
-
- // Returns the currently-observed memory pressure.
- MemoryPressureLevel GetCurrentPressureLevel() override;
-
- void SetDispatchCallback(const DispatchCallback& callback) override;
-
- private:
- friend TestMemoryPressureMonitor;
-
- static MemoryPressureLevel MemoryPressureLevelForMacMemoryPressureLevel(
- int mac_memory_pressure_level);
- static void OnRunLoopExit(CFRunLoopObserverRef observer,
- CFRunLoopActivity activity,
- void* info);
- // Returns the raw memory pressure level from the macOS. Exposed for
- // unit testing.
- virtual int GetMacMemoryPressureLevel();
-
- // Updates |last_pressure_level_| with the current memory pressure level.
- void UpdatePressureLevel();
-
- // Updates |last_pressure_level_| at the end of every run loop pass (modulo
- // some number of seconds).
- void UpdatePressureLevelOnRunLoopExit();
-
- // Run |dispatch_callback| on memory pressure notifications from the OS.
- void OnMemoryPressureChanged(dispatch_source_s* event_source,
- const DispatchCallback& dispatch_callback);
-
- // Returns the number of seconds per UMA tick (for statistics recording).
- // Exposed for testing.
- static int GetSecondsPerUMATick();
-
- // The dispatch source that generates memory pressure change notifications.
- ScopedDispatchObject<dispatch_source_t> memory_level_event_source_;
-
- // The callback to call upon receiving a memory pressure change notification.
- DispatchCallback dispatch_callback_;
-
- // Last UMA report time.
- CFTimeInterval last_statistic_report_time_;
-
- // Most-recent memory pressure level.
- MemoryPressureLevel last_pressure_level_;
-
- // Observer that tracks exits from the main run loop.
- ScopedCFTypeRef<CFRunLoopObserverRef> exit_observer_;
-
- // Next time to update the memory pressure level when exiting the run loop.
- CFTimeInterval next_run_loop_update_time_;
-
- // Seconds left over from the last UMA tick calculation (to be added to the
- // next calculation).
- CFTimeInterval subtick_seconds_;
-
- DISALLOW_COPY_AND_ASSIGN(MemoryPressureMonitor);
-};
-
-} // namespace mac
-} // namespace base
-
-#endif // BASE_MEMORY_MEMORY_PRESSURE_MONITOR_MAC_H_
diff --git a/base/memory/memory_pressure_monitor_win.cc b/base/memory/memory_pressure_monitor_win.cc
deleted file mode 100644
index 3effe2c..0000000
--- a/base/memory/memory_pressure_monitor_win.cc
+++ /dev/null
@@ -1,233 +0,0 @@
-// Copyright 2015 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.
-
-#include "base/memory/memory_pressure_monitor_win.h"
-
-#include <windows.h>
-
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
-
-namespace base {
-namespace win {
-
-namespace {
-
-static const DWORDLONG kMBBytes = 1024 * 1024;
-
-} // namespace
-
-// The following constants have been lifted from similar values in the ChromeOS
-// memory pressure monitor. The values were determined experimentally to ensure
-// sufficient responsiveness of the memory pressure subsystem, and minimal
-// overhead.
-const int MemoryPressureMonitor::kPollingIntervalMs = 5000;
-const int MemoryPressureMonitor::kModeratePressureCooldownMs = 10000;
-const int MemoryPressureMonitor::kModeratePressureCooldownCycles =
- kModeratePressureCooldownMs / kPollingIntervalMs;
-
-// TODO(chrisha): Explore the following constants further with an experiment.
-
-// A system is considered 'high memory' if it has more than 1.5GB of system
-// memory available for use by the memory manager (not reserved for hardware
-// and drivers). This is a fuzzy version of the ~2GB discussed below.
-const int MemoryPressureMonitor::kLargeMemoryThresholdMb = 1536;
-
-// These are the default thresholds used for systems with < ~2GB of physical
-// memory. Such systems have been observed to always maintain ~100MB of
-// available memory, paging until that is the case. To try to avoid paging a
-// threshold slightly above this is chosen. The moderate threshold is slightly
-// less grounded in reality and chosen as 2.5x critical.
-const int MemoryPressureMonitor::kSmallMemoryDefaultModerateThresholdMb = 500;
-const int MemoryPressureMonitor::kSmallMemoryDefaultCriticalThresholdMb = 200;
-
-// These are the default thresholds used for systems with >= ~2GB of physical
-// memory. Such systems have been observed to always maintain ~300MB of
-// available memory, paging until that is the case.
-const int MemoryPressureMonitor::kLargeMemoryDefaultModerateThresholdMb = 1000;
-const int MemoryPressureMonitor::kLargeMemoryDefaultCriticalThresholdMb = 400;
-
-MemoryPressureMonitor::MemoryPressureMonitor()
- : moderate_threshold_mb_(0),
- critical_threshold_mb_(0),
- current_memory_pressure_level_(
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE),
- moderate_pressure_repeat_count_(0),
- dispatch_callback_(
- base::Bind(&MemoryPressureListener::NotifyMemoryPressure)),
- weak_ptr_factory_(this) {
- InferThresholds();
- StartObserving();
-}
-
-MemoryPressureMonitor::MemoryPressureMonitor(int moderate_threshold_mb,
- int critical_threshold_mb)
- : moderate_threshold_mb_(moderate_threshold_mb),
- critical_threshold_mb_(critical_threshold_mb),
- current_memory_pressure_level_(
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE),
- moderate_pressure_repeat_count_(0),
- dispatch_callback_(
- base::Bind(&MemoryPressureListener::NotifyMemoryPressure)),
- weak_ptr_factory_(this) {
- DCHECK_GE(moderate_threshold_mb_, critical_threshold_mb_);
- DCHECK_LE(0, critical_threshold_mb_);
- StartObserving();
-}
-
-MemoryPressureMonitor::~MemoryPressureMonitor() {
- StopObserving();
-}
-
-void MemoryPressureMonitor::CheckMemoryPressureSoon() {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, Bind(&MemoryPressureMonitor::CheckMemoryPressure,
- weak_ptr_factory_.GetWeakPtr()));
-}
-
-MemoryPressureListener::MemoryPressureLevel
-MemoryPressureMonitor::GetCurrentPressureLevel() {
- return current_memory_pressure_level_;
-}
-
-void MemoryPressureMonitor::InferThresholds() {
- // Default to a 'high' memory situation, which uses more conservative
- // thresholds.
- bool high_memory = true;
- MEMORYSTATUSEX mem_status = {};
- if (GetSystemMemoryStatus(&mem_status)) {
- static const DWORDLONG kLargeMemoryThresholdBytes =
- static_cast<DWORDLONG>(kLargeMemoryThresholdMb) * kMBBytes;
- high_memory = mem_status.ullTotalPhys >= kLargeMemoryThresholdBytes;
- }
-
- if (high_memory) {
- moderate_threshold_mb_ = kLargeMemoryDefaultModerateThresholdMb;
- critical_threshold_mb_ = kLargeMemoryDefaultCriticalThresholdMb;
- } else {
- moderate_threshold_mb_ = kSmallMemoryDefaultModerateThresholdMb;
- critical_threshold_mb_ = kSmallMemoryDefaultCriticalThresholdMb;
- }
-}
-
-void MemoryPressureMonitor::StartObserving() {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- timer_.Start(FROM_HERE,
- TimeDelta::FromMilliseconds(kPollingIntervalMs),
- Bind(&MemoryPressureMonitor::
- CheckMemoryPressureAndRecordStatistics,
- weak_ptr_factory_.GetWeakPtr()));
-}
-
-void MemoryPressureMonitor::StopObserving() {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- // If StartObserving failed, StopObserving will still get called.
- timer_.Stop();
- weak_ptr_factory_.InvalidateWeakPtrs();
-}
-
-void MemoryPressureMonitor::CheckMemoryPressure() {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- // Get the previous pressure level and update the current one.
- MemoryPressureLevel old_pressure = current_memory_pressure_level_;
- current_memory_pressure_level_ = CalculateCurrentPressureLevel();
-
- // |notify| will be set to true if MemoryPressureListeners need to be
- // notified of a memory pressure level state change.
- bool notify = false;
- switch (current_memory_pressure_level_) {
- case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
- break;
-
- case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
- if (old_pressure != current_memory_pressure_level_) {
- // This is a new transition to moderate pressure so notify.
- moderate_pressure_repeat_count_ = 0;
- notify = true;
- } else {
- // Already in moderate pressure, only notify if sustained over the
- // cooldown period.
- if (++moderate_pressure_repeat_count_ ==
- kModeratePressureCooldownCycles) {
- moderate_pressure_repeat_count_ = 0;
- notify = true;
- }
- }
- break;
-
- case MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
- // Always notify of critical pressure levels.
- notify = true;
- break;
- }
-
- if (!notify)
- return;
-
- // Emit a notification of the current memory pressure level. This can only
- // happen for moderate and critical pressure levels.
- DCHECK_NE(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
- current_memory_pressure_level_);
- dispatch_callback_.Run(current_memory_pressure_level_);
-}
-
-void MemoryPressureMonitor::CheckMemoryPressureAndRecordStatistics() {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- CheckMemoryPressure();
-
- RecordMemoryPressure(current_memory_pressure_level_, 1);
-}
-
-MemoryPressureListener::MemoryPressureLevel
-MemoryPressureMonitor::CalculateCurrentPressureLevel() {
- MEMORYSTATUSEX mem_status = {};
- if (!GetSystemMemoryStatus(&mem_status))
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
-
- // How much system memory is actively available for use right now, in MBs.
- int phys_free = static_cast<int>(mem_status.ullAvailPhys / kMBBytes);
-
- // TODO(chrisha): This should eventually care about address space pressure,
- // but the browser process (where this is running) effectively never runs out
- // of address space. Renderers occasionally do, but it does them no good to
- // have the browser process monitor address space pressure. Long term,
- // renderers should run their own address space pressure monitors and act
- // accordingly, with the browser making cross-process decisions based on
- // system memory pressure.
-
- // Determine if the physical memory is under critical memory pressure.
- if (phys_free <= critical_threshold_mb_)
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
-
- // Determine if the physical memory is under moderate memory pressure.
- if (phys_free <= moderate_threshold_mb_)
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
-
- // No memory pressure was detected.
- return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
-}
-
-bool MemoryPressureMonitor::GetSystemMemoryStatus(
- MEMORYSTATUSEX* mem_status) {
- DCHECK(mem_status != nullptr);
- mem_status->dwLength = sizeof(*mem_status);
- if (!::GlobalMemoryStatusEx(mem_status))
- return false;
- return true;
-}
-
-void MemoryPressureMonitor::SetDispatchCallback(
- const DispatchCallback& callback) {
- dispatch_callback_ = callback;
-}
-
-} // namespace win
-} // namespace base
diff --git a/base/memory/memory_pressure_monitor_win.h b/base/memory/memory_pressure_monitor_win.h
deleted file mode 100644
index a65c191..0000000
--- a/base/memory/memory_pressure_monitor_win.h
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2015 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 BASE_MEMORY_MEMORY_PRESSURE_MONITOR_WIN_H_
-#define BASE_MEMORY_MEMORY_PRESSURE_MONITOR_WIN_H_
-
-#include "base/base_export.h"
-#include "base/macros.h"
-#include "base/memory/memory_pressure_listener.h"
-#include "base/memory/memory_pressure_monitor.h"
-#include "base/memory/weak_ptr.h"
-#include "base/threading/thread_checker.h"
-#include "base/timer/timer.h"
-
-// To not pull in windows.h.
-typedef struct _MEMORYSTATUSEX MEMORYSTATUSEX;
-
-namespace base {
-namespace win {
-
-// Windows memory pressure monitor. Because there is no OS provided signal this
-// polls at a low frequency (once per second), and applies internal hysteresis.
-class BASE_EXPORT MemoryPressureMonitor : public base::MemoryPressureMonitor {
- public:
- // Constants governing the polling and hysteresis behaviour of the observer.
-
- // The polling interval, in milliseconds. While under critical pressure, this
- // is also the timer to repeat cleanup attempts.
- static const int kPollingIntervalMs;
- // The time which should pass between 2 successive moderate memory pressure
- // signals, in milliseconds.
- static const int kModeratePressureCooldownMs;
- // The number of cycles that should pass between 2 successive moderate memory
- // pressure signals.
- static const int kModeratePressureCooldownCycles;
-
- // Constants governing the memory pressure level detection.
-
- // The amount of total system memory beyond which a system is considered to be
- // a large-memory system.
- static const int kLargeMemoryThresholdMb;
- // Default minimum free memory thresholds for small-memory systems, in MB.
- static const int kSmallMemoryDefaultModerateThresholdMb;
- static const int kSmallMemoryDefaultCriticalThresholdMb;
- // Default minimum free memory thresholds for large-memory systems, in MB.
- static const int kLargeMemoryDefaultModerateThresholdMb;
- static const int kLargeMemoryDefaultCriticalThresholdMb;
-
- // Default constructor. Will choose thresholds automatically basd on the
- // actual amount of system memory.
- MemoryPressureMonitor();
-
- // Constructor with explicit memory thresholds. These represent the amount of
- // free memory below which the applicable memory pressure state engages.
- MemoryPressureMonitor(int moderate_threshold_mb, int critical_threshold_mb);
-
- ~MemoryPressureMonitor() override;
-
- // Schedules a memory pressure check to run soon. This must be called on the
- // same thread where the monitor was instantiated.
- void CheckMemoryPressureSoon();
-
- // Get the current memory pressure level. This can be called from any thread.
- MemoryPressureLevel GetCurrentPressureLevel() override;
- void SetDispatchCallback(const DispatchCallback& callback) override;
-
- // Returns the moderate pressure level free memory threshold, in MB.
- int moderate_threshold_mb() const { return moderate_threshold_mb_; }
-
- // Returns the critical pressure level free memory threshold, in MB.
- int critical_threshold_mb() const { return critical_threshold_mb_; }
-
- protected:
- // Internals are exposed for unittests.
-
- // Automatically infers threshold values based on system memory. This invokes
- // GetMemoryStatus so it can be mocked in unittests.
- void InferThresholds();
-
- // Starts observing the memory fill level. Calls to StartObserving should
- // always be matched with calls to StopObserving.
- void StartObserving();
-
- // Stop observing the memory fill level. May be safely called if
- // StartObserving has not been called. Must be called from the same thread on
- // which the monitor was instantiated.
- void StopObserving();
-
- // Checks memory pressure, storing the current level, applying any hysteresis
- // and emitting memory pressure level change signals as necessary. This
- // function is called periodically while the monitor is observing memory
- // pressure. This is split out from CheckMemoryPressureAndRecordStatistics so
- // that it may be called by CheckMemoryPressureSoon and not invoke UMA
- // logging. Must be called from the same thread on which the monitor was
- // instantiated.
- void CheckMemoryPressure();
-
- // Wrapper to CheckMemoryPressure that also records the observed memory
- // pressure level via an UMA enumeration. This is the function that is called
- // periodically by the timer. Must be called from the same thread on which the
- // monitor was instantiated.
- void CheckMemoryPressureAndRecordStatistics();
-
- // Calculates the current instantaneous memory pressure level. This does not
- // use any hysteresis and simply returns the result at the current moment. Can
- // be called on any thread.
- MemoryPressureLevel CalculateCurrentPressureLevel();
-
- // Gets system memory status. This is virtual as a unittesting hook. Returns
- // true if the system call succeeds, false otherwise. Can be called on any
- // thread.
- virtual bool GetSystemMemoryStatus(MEMORYSTATUSEX* mem_status);
-
- private:
- // Threshold amounts of available memory that trigger pressure levels. See
- // memory_pressure_monitor.cc for a discussion of reasonable values for these.
- int moderate_threshold_mb_;
- int critical_threshold_mb_;
-
- // A periodic timer to check for memory pressure changes.
- base::RepeatingTimer timer_;
-
- // The current memory pressure.
- MemoryPressureLevel current_memory_pressure_level_;
-
- // To slow down the amount of moderate pressure event calls, this gets used to
- // count the number of events since the last event occured. This is used by
- // |CheckMemoryPressure| to apply hysteresis on the raw results of
- // |CalculateCurrentPressureLevel|.
- int moderate_pressure_repeat_count_;
-
- // Ensures that this object is used from a single thread.
- base::ThreadChecker thread_checker_;
-
- DispatchCallback dispatch_callback_;
-
- // Weak pointer factory to ourself used for scheduling calls to
- // CheckMemoryPressure/CheckMemoryPressureAndRecordStatistics via |timer_|.
- base::WeakPtrFactory<MemoryPressureMonitor> weak_ptr_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(MemoryPressureMonitor);
-};
-
-} // namespace win
-} // namespace base
-
-#endif // BASE_MEMORY_MEMORY_PRESSURE_MONITOR_WIN_H_
diff --git a/base/memory/platform_shared_memory_region.cc b/base/memory/platform_shared_memory_region.cc
deleted file mode 100644
index c145336..0000000
--- a/base/memory/platform_shared_memory_region.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2018 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.
-
-#include "base/memory/platform_shared_memory_region.h"
-
-#include "base/memory/shared_memory_mapping.h"
-
-namespace base {
-namespace subtle {
-
-// static
-PlatformSharedMemoryRegion PlatformSharedMemoryRegion::CreateWritable(
- size_t size) {
- return Create(Mode::kWritable, size);
-}
-
-// static
-PlatformSharedMemoryRegion PlatformSharedMemoryRegion::CreateUnsafe(
- size_t size) {
- return Create(Mode::kUnsafe, size);
-}
-
-PlatformSharedMemoryRegion::PlatformSharedMemoryRegion() = default;
-PlatformSharedMemoryRegion::PlatformSharedMemoryRegion(
- PlatformSharedMemoryRegion&& other) = default;
-PlatformSharedMemoryRegion& PlatformSharedMemoryRegion::operator=(
- PlatformSharedMemoryRegion&& other) = default;
-PlatformSharedMemoryRegion::~PlatformSharedMemoryRegion() = default;
-
-PlatformSharedMemoryRegion::ScopedPlatformHandle
-PlatformSharedMemoryRegion::PassPlatformHandle() {
- return std::move(handle_);
-}
-
-} // namespace subtle
-} // namespace base
diff --git a/base/memory/platform_shared_memory_region.h b/base/memory/platform_shared_memory_region.h
deleted file mode 100644
index df4cc4d..0000000
--- a/base/memory/platform_shared_memory_region.h
+++ /dev/null
@@ -1,223 +0,0 @@
-// Copyright 2018 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 BASE_MEMORY_PLATFORM_SHARED_MEMORY_REGION_H_
-#define BASE_MEMORY_PLATFORM_SHARED_MEMORY_REGION_H_
-
-#include <utility>
-
-#include "base/compiler_specific.h"
-#include "base/gtest_prod_util.h"
-#include "base/macros.h"
-#include "base/unguessable_token.h"
-#include "build_config.h"
-
-#if defined(OS_MACOSX) && !defined(OS_IOS)
-#include <mach/mach.h>
-#include "base/mac/scoped_mach_port.h"
-#elif defined(OS_FUCHSIA)
-#include "base/fuchsia/scoped_zx_handle.h"
-#elif defined(OS_WIN)
-#include "base/win/scoped_handle.h"
-#include "base/win/windows_types.h"
-#elif defined(OS_POSIX)
-#include <sys/types.h>
-#include "base/file_descriptor_posix.h"
-#include "base/files/scoped_file.h"
-#endif
-
-namespace base {
-namespace subtle {
-
-#if defined(OS_POSIX) && (!defined(OS_MACOSX) || defined(OS_IOS)) && \
- !defined(OS_FUCHSIA) && !defined(OS_ANDROID)
-// Helper structs to keep two descriptors on POSIX. It's needed to support
-// ConvertToReadOnly().
-struct BASE_EXPORT FDPair {
- int fd;
- int readonly_fd;
-};
-
-struct BASE_EXPORT ScopedFDPair {
- ScopedFDPair();
- ScopedFDPair(ScopedFD in_fd, ScopedFD in_readonly_fd);
- ScopedFDPair(ScopedFDPair&&);
- ScopedFDPair& operator=(ScopedFDPair&&);
- ~ScopedFDPair();
-
- FDPair get() const;
-
- ScopedFD fd;
- ScopedFD readonly_fd;
-};
-#endif
-
-// Implementation class for shared memory regions.
-//
-// This class does the following:
-//
-// - Wraps and owns a shared memory region platform handle.
-// - Provides a way to allocate a new region of platform shared memory of given
-// size.
-// - Provides a way to create mapping of the region in the current process'
-// address space, under special access-control constraints (see Mode).
-// - Provides methods to help transferring the handle across process boundaries.
-// - Holds a 128-bit unique identifier used to uniquely identify the same
-// kernel region resource across processes (used for memory tracking).
-// - Has a method to retrieve the region's size in bytes.
-//
-// IMPORTANT NOTE: Users should never use this directly, but
-// ReadOnlySharedMemoryRegion, WritableSharedMemoryRegion or
-// UnsafeSharedMemoryRegion since this is an implementation class.
-class BASE_EXPORT PlatformSharedMemoryRegion {
- public:
- // Permission mode of the platform handle. Each mode corresponds to one of the
- // typed shared memory classes:
- //
- // * ReadOnlySharedMemoryRegion: A region that can only create read-only
- // mappings.
- //
- // * WritableSharedMemoryRegion: A region that can only create writable
- // mappings. The region can be demoted to ReadOnlySharedMemoryRegion without
- // the possibility of promoting back to writable.
- //
- // * UnsafeSharedMemoryRegion: A region that can only create writable
- // mappings. The region cannot be demoted to ReadOnlySharedMemoryRegion.
- enum class Mode {
- kReadOnly, // ReadOnlySharedMemoryRegion
- kWritable, // WritableSharedMemoryRegion
- kUnsafe, // UnsafeSharedMemoryRegion
- kMaxValue = kUnsafe
- };
-
-// Platform-specific shared memory type used by this class.
-#if defined(OS_MACOSX) && !defined(OS_IOS)
- using PlatformHandle = mach_port_t;
- using ScopedPlatformHandle = mac::ScopedMachSendRight;
-#elif defined(OS_FUCHSIA)
- using PlatformHandle = zx_handle_t;
- using ScopedPlatformHandle = ScopedZxHandle;
-#elif defined(OS_WIN)
- using PlatformHandle = HANDLE;
- using ScopedPlatformHandle = win::ScopedHandle;
-#elif defined(OS_ANDROID)
- using PlatformHandle = int;
- using ScopedPlatformHandle = ScopedFD;
-#else
- using PlatformHandle = FDPair;
- using ScopedPlatformHandle = ScopedFDPair;
-#endif
-
- // The minimum alignment in bytes that any mapped address produced by Map()
- // and MapAt() is guaranteed to have.
- enum { kMapMinimumAlignment = 32 };
-
- // Creates a new PlatformSharedMemoryRegion with corresponding mode and size.
- // Creating in kReadOnly mode isn't supported because then there will be no
- // way to modify memory content.
- static PlatformSharedMemoryRegion CreateWritable(size_t size);
- static PlatformSharedMemoryRegion CreateUnsafe(size_t size);
-
- // Returns a new PlatformSharedMemoryRegion that takes ownership of the
- // |handle|. All parameters must be taken from another valid
- // PlatformSharedMemoryRegion instance, e.g. |size| must be equal to the
- // actual region size as allocated by the kernel.
- // Closes the |handle| and returns an invalid instance if passed parameters
- // are invalid.
- static PlatformSharedMemoryRegion Take(ScopedPlatformHandle handle,
- Mode mode,
- size_t size,
- const UnguessableToken& guid);
-
- // Default constructor initializes an invalid instance, i.e. an instance that
- // doesn't wrap any valid platform handle.
- PlatformSharedMemoryRegion();
-
- // Move operations are allowed.
- PlatformSharedMemoryRegion(PlatformSharedMemoryRegion&&);
- PlatformSharedMemoryRegion& operator=(PlatformSharedMemoryRegion&&);
-
- // Destructor closes the platform handle. Does nothing if the handle is
- // invalid.
- ~PlatformSharedMemoryRegion();
-
- // Passes ownership of the platform handle to the caller. The current instance
- // becomes invalid. It's the responsibility of the caller to close the handle.
- ScopedPlatformHandle PassPlatformHandle() WARN_UNUSED_RESULT;
-
- // Returns the platform handle. The current instance keeps ownership of this
- // handle.
- PlatformHandle GetPlatformHandle() const;
-
- // Whether the platform handle is valid.
- bool IsValid() const;
-
- // Duplicates the platform handle and creates a new PlatformSharedMemoryRegion
- // with the same |mode_|, |size_| and |guid_| that owns this handle. Returns
- // invalid region on failure, the current instance remains valid.
- // Can be called only in kReadOnly and kUnsafe modes, CHECK-fails if is
- // called in kWritable mode.
- PlatformSharedMemoryRegion Duplicate() const;
-
- // Converts the region to read-only. Returns whether the operation succeeded.
- // Makes the current instance invalid on failure. Can be called only in
- // kWritable mode, all other modes will CHECK-fail. The object will have
- // kReadOnly mode after this call on success.
- bool ConvertToReadOnly();
-#if defined(OS_MACOSX) && !defined(OS_IOS)
- // Same as above, but |mapped_addr| is used as a hint to avoid additional
- // mapping of the memory object.
- // |mapped_addr| must be mapped location of |memory_object_|. If the location
- // is unknown, |mapped_addr| should be |nullptr|.
- bool ConvertToReadOnly(void* mapped_addr);
-#endif // defined(OS_MACOSX) && !defined(OS_IOS)
-
- // Maps |size| bytes of the shared memory region starting with the given
- // |offset| into the caller's address space. |offset| must be aligned to value
- // of |SysInfo::VMAllocationGranularity()|. Fails if requested bytes are out
- // of the region limits.
- // Returns true and sets |memory| and |mapped_size| on success, returns false
- // and leaves output parameters in unspecified state otherwise. The mapped
- // address is guaranteed to have an alignment of at least
- // |kMapMinimumAlignment|.
- bool MapAt(off_t offset,
- size_t size,
- void** memory,
- size_t* mapped_size) const;
-
- const UnguessableToken& GetGUID() const { return guid_; }
-
- size_t GetSize() const { return size_; }
-
- Mode GetMode() const { return mode_; }
-
- private:
- FRIEND_TEST_ALL_PREFIXES(PlatformSharedMemoryRegionTest,
- CreateReadOnlyRegionDeathTest);
- FRIEND_TEST_ALL_PREFIXES(PlatformSharedMemoryRegionTest,
- CheckPlatformHandlePermissionsCorrespondToMode);
- static PlatformSharedMemoryRegion Create(Mode mode, size_t size);
-
- static bool CheckPlatformHandlePermissionsCorrespondToMode(
- PlatformHandle handle,
- Mode mode,
- size_t size);
-
- PlatformSharedMemoryRegion(ScopedPlatformHandle handle,
- Mode mode,
- size_t size,
- const UnguessableToken& guid);
-
- ScopedPlatformHandle handle_;
- Mode mode_ = Mode::kReadOnly;
- size_t size_ = 0;
- UnguessableToken guid_;
-
- DISALLOW_COPY_AND_ASSIGN(PlatformSharedMemoryRegion);
-};
-
-} // namespace subtle
-} // namespace base
-
-#endif // BASE_MEMORY_PLATFORM_SHARED_MEMORY_REGION_H_
diff --git a/base/memory/platform_shared_memory_region_fuchsia.cc b/base/memory/platform_shared_memory_region_fuchsia.cc
deleted file mode 100644
index 5a75845..0000000
--- a/base/memory/platform_shared_memory_region_fuchsia.cc
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright 2018 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.
-
-#include "base/memory/platform_shared_memory_region.h"
-
-#include <zircon/process.h>
-#include <zircon/rights.h>
-#include <zircon/syscalls.h>
-
-#include "base/bits.h"
-#include "base/fuchsia/fuchsia_logging.h"
-#include "base/numerics/checked_math.h"
-#include "base/process/process_metrics.h"
-
-namespace base {
-namespace subtle {
-
-static constexpr int kNoWriteOrExec =
- ZX_DEFAULT_VMO_RIGHTS &
- ~(ZX_RIGHT_WRITE | ZX_RIGHT_EXECUTE | ZX_RIGHT_SET_PROPERTY);
-
-// static
-PlatformSharedMemoryRegion PlatformSharedMemoryRegion::Take(
- ScopedZxHandle handle,
- Mode mode,
- size_t size,
- const UnguessableToken& guid) {
- if (!handle.is_valid())
- return {};
-
- if (size == 0)
- return {};
-
- if (size > static_cast<size_t>(std::numeric_limits<int>::max()))
- return {};
-
- CHECK(
- CheckPlatformHandlePermissionsCorrespondToMode(handle.get(), mode, size));
-
- return PlatformSharedMemoryRegion(std::move(handle), mode, size, guid);
-}
-
-zx_handle_t PlatformSharedMemoryRegion::GetPlatformHandle() const {
- return handle_.get();
-}
-
-bool PlatformSharedMemoryRegion::IsValid() const {
- return handle_.is_valid();
-}
-
-PlatformSharedMemoryRegion PlatformSharedMemoryRegion::Duplicate() const {
- if (!IsValid())
- return {};
-
- CHECK_NE(mode_, Mode::kWritable)
- << "Duplicating a writable shared memory region is prohibited";
-
- ScopedZxHandle duped_handle;
- zx_status_t status = zx_handle_duplicate(handle_.get(), ZX_RIGHT_SAME_RIGHTS,
- duped_handle.receive());
- if (status != ZX_OK) {
- ZX_DLOG(ERROR, status) << "zx_handle_duplicate";
- return {};
- }
-
- return PlatformSharedMemoryRegion(std::move(duped_handle), mode_, size_,
- guid_);
-}
-
-bool PlatformSharedMemoryRegion::ConvertToReadOnly() {
- if (!IsValid())
- return false;
-
- CHECK_EQ(mode_, Mode::kWritable)
- << "Only writable shared memory region can be converted to read-only";
-
- ScopedZxHandle old_handle(handle_.release());
- ScopedZxHandle new_handle;
- zx_status_t status =
- zx_handle_replace(old_handle.get(), kNoWriteOrExec, new_handle.receive());
- if (status != ZX_OK) {
- ZX_DLOG(ERROR, status) << "zx_handle_replace";
- return false;
- }
- ignore_result(old_handle.release());
-
- handle_ = std::move(new_handle);
- mode_ = Mode::kReadOnly;
- return true;
-}
-
-bool PlatformSharedMemoryRegion::MapAt(off_t offset,
- size_t size,
- void** memory,
- size_t* mapped_size) const {
- if (!IsValid())
- return false;
-
- size_t end_byte;
- if (!CheckAdd(offset, size).AssignIfValid(&end_byte) || end_byte > size_) {
- return false;
- }
-
- bool write_allowed = mode_ != Mode::kReadOnly;
- uintptr_t addr;
- zx_status_t status = zx_vmar_map(
- zx_vmar_root_self(), 0, handle_.get(), offset, size,
- ZX_VM_FLAG_PERM_READ | (write_allowed ? ZX_VM_FLAG_PERM_WRITE : 0),
- &addr);
- if (status != ZX_OK) {
- ZX_DLOG(ERROR, status) << "zx_vmar_map";
- return false;
- }
-
- *memory = reinterpret_cast<void*>(addr);
- *mapped_size = size;
- DCHECK_EQ(0U,
- reinterpret_cast<uintptr_t>(*memory) & (kMapMinimumAlignment - 1));
- return true;
-}
-
-// static
-PlatformSharedMemoryRegion PlatformSharedMemoryRegion::Create(Mode mode,
- size_t size) {
- if (size == 0)
- return {};
-
- size_t rounded_size = bits::Align(size, GetPageSize());
- if (rounded_size > static_cast<size_t>(std::numeric_limits<int>::max()))
- return {};
-
- CHECK_NE(mode, Mode::kReadOnly) << "Creating a region in read-only mode will "
- "lead to this region being non-modifiable";
-
- ScopedZxHandle vmo;
- zx_status_t status = zx_vmo_create(rounded_size, 0, vmo.receive());
- if (status != ZX_OK) {
- ZX_DLOG(ERROR, status) << "zx_vmo_create";
- return {};
- }
-
- const int kNoExecFlags = ZX_DEFAULT_VMO_RIGHTS & ~ZX_RIGHT_EXECUTE;
- ScopedZxHandle old_vmo(std::move(vmo));
- status = zx_handle_replace(old_vmo.get(), kNoExecFlags, vmo.receive());
- if (status != ZX_OK) {
- ZX_DLOG(ERROR, status) << "zx_handle_replace";
- return {};
- }
- ignore_result(old_vmo.release());
-
- return PlatformSharedMemoryRegion(std::move(vmo), mode, size,
- UnguessableToken::Create());
-}
-
-// static
-bool PlatformSharedMemoryRegion::CheckPlatformHandlePermissionsCorrespondToMode(
- PlatformHandle handle,
- Mode mode,
- size_t size) {
- zx_info_handle_basic_t basic = {};
- zx_status_t status = zx_object_get_info(handle, ZX_INFO_HANDLE_BASIC, &basic,
- sizeof(basic), nullptr, nullptr);
- if (status != ZX_OK) {
- ZX_DLOG(ERROR, status) << "zx_object_get_info";
- return false;
- }
-
- bool is_read_only = (basic.rights & kNoWriteOrExec) == basic.rights;
- bool expected_read_only = mode == Mode::kReadOnly;
-
- if (is_read_only != expected_read_only) {
- DLOG(ERROR) << "VMO object has wrong access rights: it is"
- << (is_read_only ? " " : " not ") << "read-only but it should"
- << (expected_read_only ? " " : " not ") << "be";
- return false;
- }
-
- return true;
-}
-
-PlatformSharedMemoryRegion::PlatformSharedMemoryRegion(
- ScopedZxHandle handle,
- Mode mode,
- size_t size,
- const UnguessableToken& guid)
- : handle_(std::move(handle)), mode_(mode), size_(size), guid_(guid) {}
-
-} // namespace subtle
-} // namespace base
diff --git a/base/memory/platform_shared_memory_region_mac.cc b/base/memory/platform_shared_memory_region_mac.cc
deleted file mode 100644
index 9cbe92e..0000000
--- a/base/memory/platform_shared_memory_region_mac.cc
+++ /dev/null
@@ -1,222 +0,0 @@
-// Copyright 2018 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.
-
-#include "base/memory/platform_shared_memory_region.h"
-
-#include <mach/mach_vm.h>
-
-#include "base/mac/mach_logging.h"
-#include "base/mac/scoped_mach_vm.h"
-#include "base/numerics/checked_math.h"
-#include "build_config.h"
-
-#if defined(OS_IOS)
-#error "MacOS only - iOS uses platform_shared_memory_region_posix.cc"
-#endif
-
-namespace base {
-namespace subtle {
-
-// static
-PlatformSharedMemoryRegion PlatformSharedMemoryRegion::Take(
- mac::ScopedMachSendRight handle,
- Mode mode,
- size_t size,
- const UnguessableToken& guid) {
- if (!handle.is_valid())
- return {};
-
- if (size == 0)
- return {};
-
- if (size > static_cast<size_t>(std::numeric_limits<int>::max()))
- return {};
-
- CHECK(
- CheckPlatformHandlePermissionsCorrespondToMode(handle.get(), mode, size));
-
- return PlatformSharedMemoryRegion(std::move(handle), mode, size, guid);
-}
-
-mach_port_t PlatformSharedMemoryRegion::GetPlatformHandle() const {
- return handle_.get();
-}
-
-bool PlatformSharedMemoryRegion::IsValid() const {
- return handle_.is_valid();
-}
-
-PlatformSharedMemoryRegion PlatformSharedMemoryRegion::Duplicate() const {
- if (!IsValid())
- return {};
-
- CHECK_NE(mode_, Mode::kWritable)
- << "Duplicating a writable shared memory region is prohibited";
-
- // Increment the ref count.
- kern_return_t kr = mach_port_mod_refs(mach_task_self(), handle_.get(),
- MACH_PORT_RIGHT_SEND, 1);
- if (kr != KERN_SUCCESS) {
- MACH_DLOG(ERROR, kr) << "mach_port_mod_refs";
- return {};
- }
-
- return PlatformSharedMemoryRegion(mac::ScopedMachSendRight(handle_.get()),
- mode_, size_, guid_);
-}
-
-bool PlatformSharedMemoryRegion::ConvertToReadOnly() {
- return ConvertToReadOnly(nullptr);
-}
-
-bool PlatformSharedMemoryRegion::ConvertToReadOnly(void* mapped_addr) {
- if (!IsValid())
- return false;
-
- CHECK_EQ(mode_, Mode::kWritable)
- << "Only writable shared memory region can be converted to read-only";
-
- mac::ScopedMachSendRight handle_copy(handle_.release());
-
- void* temp_addr = mapped_addr;
- mac::ScopedMachVM scoped_memory;
- if (!temp_addr) {
- // Intentionally lower current prot and max prot to |VM_PROT_READ|.
- kern_return_t kr = mach_vm_map(
- mach_task_self(), reinterpret_cast<mach_vm_address_t*>(&temp_addr),
- size_, 0, VM_FLAGS_ANYWHERE, handle_copy.get(), 0, FALSE, VM_PROT_READ,
- VM_PROT_READ, VM_INHERIT_NONE);
- if (kr != KERN_SUCCESS) {
- MACH_DLOG(ERROR, kr) << "mach_vm_map";
- return false;
- }
- scoped_memory.reset(reinterpret_cast<vm_address_t>(temp_addr),
- mach_vm_round_page(size_));
- }
-
- // Make new memory object.
- memory_object_size_t allocation_size = size_;
- mac::ScopedMachSendRight named_right;
- kern_return_t kr = mach_make_memory_entry_64(
- mach_task_self(), &allocation_size,
- reinterpret_cast<memory_object_offset_t>(temp_addr), VM_PROT_READ,
- named_right.receive(), MACH_PORT_NULL);
- if (kr != KERN_SUCCESS) {
- MACH_DLOG(ERROR, kr) << "mach_make_memory_entry_64";
- return false;
- }
- DCHECK_GE(allocation_size, size_);
-
- handle_ = std::move(named_right);
- mode_ = Mode::kReadOnly;
- return true;
-}
-
-bool PlatformSharedMemoryRegion::MapAt(off_t offset,
- size_t size,
- void** memory,
- size_t* mapped_size) const {
- if (!IsValid())
- return false;
-
- size_t end_byte;
- if (!CheckAdd(offset, size).AssignIfValid(&end_byte) || end_byte > size_) {
- return false;
- }
-
- bool write_allowed = mode_ != Mode::kReadOnly;
- vm_prot_t vm_prot_write = write_allowed ? VM_PROT_WRITE : 0;
- kern_return_t kr = mach_vm_map(
- mach_task_self(),
- reinterpret_cast<mach_vm_address_t*>(memory), // Output parameter
- size,
- 0, // Alignment mask
- VM_FLAGS_ANYWHERE, handle_.get(), offset,
- FALSE, // Copy
- VM_PROT_READ | vm_prot_write, // Current protection
- VM_PROT_READ | vm_prot_write, // Maximum protection
- VM_INHERIT_NONE);
- if (kr != KERN_SUCCESS) {
- MACH_DLOG(ERROR, kr) << "mach_vm_map";
- return false;
- }
-
- *mapped_size = size;
- DCHECK_EQ(0U,
- reinterpret_cast<uintptr_t>(*memory) & (kMapMinimumAlignment - 1));
- return true;
-}
-
-// static
-PlatformSharedMemoryRegion PlatformSharedMemoryRegion::Create(Mode mode,
- size_t size) {
- if (size == 0)
- return {};
-
- if (size > static_cast<size_t>(std::numeric_limits<int>::max()))
- return {};
-
- CHECK_NE(mode, Mode::kReadOnly) << "Creating a region in read-only mode will "
- "lead to this region being non-modifiable";
-
- mach_vm_size_t vm_size = size;
- mac::ScopedMachSendRight named_right;
- kern_return_t kr = mach_make_memory_entry_64(
- mach_task_self(), &vm_size,
- 0, // Address.
- MAP_MEM_NAMED_CREATE | VM_PROT_READ | VM_PROT_WRITE,
- named_right.receive(),
- MACH_PORT_NULL); // Parent handle.
- if (kr != KERN_SUCCESS) {
- MACH_DLOG(ERROR, kr) << "mach_make_memory_entry_64";
- return {};
- }
- DCHECK_GE(vm_size, size);
-
- return PlatformSharedMemoryRegion(std::move(named_right), mode, size,
- UnguessableToken::Create());
-}
-
-// static
-bool PlatformSharedMemoryRegion::CheckPlatformHandlePermissionsCorrespondToMode(
- PlatformHandle handle,
- Mode mode,
- size_t size) {
- mach_vm_address_t temp_addr = 0;
- kern_return_t kr =
- mach_vm_map(mach_task_self(), &temp_addr, size, 0, VM_FLAGS_ANYWHERE,
- handle, 0, FALSE, VM_PROT_READ | VM_PROT_WRITE,
- VM_PROT_READ | VM_PROT_WRITE, VM_INHERIT_NONE);
- if (kr == KERN_SUCCESS) {
- kern_return_t kr_deallocate =
- mach_vm_deallocate(mach_task_self(), temp_addr, size);
- MACH_DLOG_IF(ERROR, kr_deallocate != KERN_SUCCESS, kr_deallocate)
- << "mach_vm_deallocate";
- } else if (kr != KERN_INVALID_RIGHT) {
- MACH_DLOG(ERROR, kr) << "mach_vm_map";
- return false;
- }
-
- bool is_read_only = kr == KERN_INVALID_RIGHT;
- bool expected_read_only = mode == Mode::kReadOnly;
-
- if (is_read_only != expected_read_only) {
- DLOG(ERROR) << "VM region has a wrong protection mask: it is"
- << (is_read_only ? " " : " not ") << "read-only but it should"
- << (expected_read_only ? " " : " not ") << "be";
- return false;
- }
-
- return true;
-}
-
-PlatformSharedMemoryRegion::PlatformSharedMemoryRegion(
- mac::ScopedMachSendRight handle,
- Mode mode,
- size_t size,
- const UnguessableToken& guid)
- : handle_(std::move(handle)), mode_(mode), size_(size), guid_(guid) {}
-
-} // namespace subtle
-} // namespace base
diff --git a/base/memory/platform_shared_memory_region_posix.cc b/base/memory/platform_shared_memory_region_posix.cc
deleted file mode 100644
index 422cec5..0000000
--- a/base/memory/platform_shared_memory_region_posix.cc
+++ /dev/null
@@ -1,291 +0,0 @@
-// Copyright 2018 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.
-
-#include "base/memory/platform_shared_memory_region.h"
-
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-
-#include "base/files/file_util.h"
-#include "base/numerics/checked_math.h"
-#include "base/threading/thread_restrictions.h"
-#include "build_config.h"
-
-namespace base {
-namespace subtle {
-
-namespace {
-
-struct ScopedPathUnlinkerTraits {
- static const FilePath* InvalidValue() { return nullptr; }
-
- static void Free(const FilePath* path) {
- if (unlink(path->value().c_str()))
- PLOG(WARNING) << "unlink";
- }
-};
-
-// Unlinks the FilePath when the object is destroyed.
-using ScopedPathUnlinker =
- ScopedGeneric<const FilePath*, ScopedPathUnlinkerTraits>;
-
-bool CheckFDAccessMode(int fd, int expected_mode) {
- int fd_status = fcntl(fd, F_GETFL);
- if (fd_status == -1) {
- DPLOG(ERROR) << "fcntl(" << fd << ", F_GETFL) failed";
- return false;
- }
-
- int mode = fd_status & O_ACCMODE;
- if (mode != expected_mode) {
- DLOG(ERROR) << "Descriptor access mode (" << mode
- << ") differs from expected (" << expected_mode << ")";
- return false;
- }
-
- return true;
-}
-
-} // namespace
-
-ScopedFDPair::ScopedFDPair() = default;
-
-ScopedFDPair::ScopedFDPair(ScopedFDPair&&) = default;
-
-ScopedFDPair& ScopedFDPair::operator=(ScopedFDPair&&) = default;
-
-ScopedFDPair::~ScopedFDPair() = default;
-
-ScopedFDPair::ScopedFDPair(ScopedFD in_fd, ScopedFD in_readonly_fd)
- : fd(std::move(in_fd)), readonly_fd(std::move(in_readonly_fd)) {}
-
-FDPair ScopedFDPair::get() const {
- return {fd.get(), readonly_fd.get()};
-}
-
-// static
-PlatformSharedMemoryRegion PlatformSharedMemoryRegion::Take(
- ScopedFDPair handle,
- Mode mode,
- size_t size,
- const UnguessableToken& guid) {
- if (!handle.fd.is_valid())
- return {};
-
- if (size == 0)
- return {};
-
- if (size > static_cast<size_t>(std::numeric_limits<int>::max()))
- return {};
-
- CHECK(
- CheckPlatformHandlePermissionsCorrespondToMode(handle.get(), mode, size));
-
- switch (mode) {
- case Mode::kReadOnly:
- case Mode::kUnsafe:
- if (handle.readonly_fd.is_valid()) {
- handle.readonly_fd.reset();
- DLOG(WARNING) << "Readonly handle shouldn't be valid for a "
- "non-writable memory region; closing";
- }
- break;
- case Mode::kWritable:
- if (!handle.readonly_fd.is_valid()) {
- DLOG(ERROR)
- << "Readonly handle must be valid for writable memory region";
- return {};
- }
- break;
- default:
- DLOG(ERROR) << "Invalid permission mode: " << static_cast<int>(mode);
- return {};
- }
-
- return PlatformSharedMemoryRegion(std::move(handle), mode, size, guid);
-}
-
-FDPair PlatformSharedMemoryRegion::GetPlatformHandle() const {
- return handle_.get();
-}
-
-bool PlatformSharedMemoryRegion::IsValid() const {
- return handle_.fd.is_valid() &&
- (mode_ == Mode::kWritable ? handle_.readonly_fd.is_valid() : true);
-}
-
-PlatformSharedMemoryRegion PlatformSharedMemoryRegion::Duplicate() const {
- if (!IsValid())
- return {};
-
- CHECK_NE(mode_, Mode::kWritable)
- << "Duplicating a writable shared memory region is prohibited";
-
- ScopedFD duped_fd(HANDLE_EINTR(dup(handle_.fd.get())));
- if (!duped_fd.is_valid()) {
- DPLOG(ERROR) << "dup(" << handle_.fd.get() << ") failed";
- return {};
- }
-
- return PlatformSharedMemoryRegion({std::move(duped_fd), ScopedFD()}, mode_,
- size_, guid_);
-}
-
-bool PlatformSharedMemoryRegion::ConvertToReadOnly() {
- if (!IsValid())
- return false;
-
- CHECK_EQ(mode_, Mode::kWritable)
- << "Only writable shared memory region can be converted to read-only";
-
- handle_.fd.reset(handle_.readonly_fd.release());
- mode_ = Mode::kReadOnly;
- return true;
-}
-
-bool PlatformSharedMemoryRegion::MapAt(off_t offset,
- size_t size,
- void** memory,
- size_t* mapped_size) const {
- if (!IsValid())
- return false;
-
- size_t end_byte;
- if (!CheckAdd(offset, size).AssignIfValid(&end_byte) || end_byte > size_) {
- return false;
- }
-
- bool write_allowed = mode_ != Mode::kReadOnly;
- *memory = mmap(nullptr, size, PROT_READ | (write_allowed ? PROT_WRITE : 0),
- MAP_SHARED, handle_.fd.get(), offset);
-
- bool mmap_succeeded = *memory && *memory != reinterpret_cast<void*>(-1);
- if (!mmap_succeeded) {
- DPLOG(ERROR) << "mmap " << handle_.fd.get() << " failed";
- return false;
- }
-
- *mapped_size = size;
- DCHECK_EQ(0U,
- reinterpret_cast<uintptr_t>(*memory) & (kMapMinimumAlignment - 1));
- return true;
-}
-
-// static
-PlatformSharedMemoryRegion PlatformSharedMemoryRegion::Create(Mode mode,
- size_t size) {
-#if defined(OS_NACL)
- // Untrusted code can't create descriptors or handles.
- return {};
-#else
- if (size == 0)
- return {};
-
- if (size > static_cast<size_t>(std::numeric_limits<int>::max()))
- return {};
-
- CHECK_NE(mode, Mode::kReadOnly) << "Creating a region in read-only mode will "
- "lead to this region being non-modifiable";
-
- // This function theoretically can block on the disk, but realistically
- // the temporary files we create will just go into the buffer cache
- // and be deleted before they ever make it out to disk.
- ThreadRestrictions::ScopedAllowIO allow_io;
-
- // We don't use shm_open() API in order to support the --disable-dev-shm-usage
- // flag.
- FilePath directory;
- if (!GetShmemTempDir(false /* executable */, &directory))
- return {};
-
- ScopedFD fd;
- FilePath path;
- fd.reset(CreateAndOpenFdForTemporaryFileInDir(directory, &path));
-
- if (!fd.is_valid()) {
- PLOG(ERROR) << "Creating shared memory in " << path.value() << " failed";
- FilePath dir = path.DirName();
- if (access(dir.value().c_str(), W_OK | X_OK) < 0) {
- PLOG(ERROR) << "Unable to access(W_OK|X_OK) " << dir.value();
- if (dir.value() == "/dev/shm") {
- LOG(FATAL) << "This is frequently caused by incorrect permissions on "
- << "/dev/shm. Try 'sudo chmod 1777 /dev/shm' to fix.";
- }
- }
- return {};
- }
-
- // Deleting the file prevents anyone else from mapping it in (making it
- // private), and prevents the need for cleanup (once the last fd is
- // closed, it is truly freed).
- ScopedPathUnlinker path_unlinker(&path);
-
- ScopedFD readonly_fd;
- if (mode == Mode::kWritable) {
- // Also open as readonly so that we can ConvertToReadOnly().
- readonly_fd.reset(HANDLE_EINTR(open(path.value().c_str(), O_RDONLY)));
- if (!readonly_fd.is_valid()) {
- DPLOG(ERROR) << "open(\"" << path.value() << "\", O_RDONLY) failed";
- return {};
- }
- }
-
- // Get current size.
- struct stat stat = {};
- if (fstat(fd.get(), &stat) != 0)
- return {};
- const size_t current_size = stat.st_size;
- if (current_size != size) {
- if (HANDLE_EINTR(ftruncate(fd.get(), size)) != 0)
- return {};
- }
-
- if (readonly_fd.is_valid()) {
- struct stat readonly_stat = {};
- if (fstat(readonly_fd.get(), &readonly_stat))
- NOTREACHED();
-
- if (stat.st_dev != readonly_stat.st_dev ||
- stat.st_ino != readonly_stat.st_ino) {
- LOG(ERROR) << "Writable and read-only inodes don't match; bailing";
- return {};
- }
- }
-
- return PlatformSharedMemoryRegion({std::move(fd), std::move(readonly_fd)},
- mode, size, UnguessableToken::Create());
-#endif // !defined(OS_NACL)
-}
-
-bool PlatformSharedMemoryRegion::CheckPlatformHandlePermissionsCorrespondToMode(
- PlatformHandle handle,
- Mode mode,
- size_t size) {
- if (!CheckFDAccessMode(handle.fd,
- mode == Mode::kReadOnly ? O_RDONLY : O_RDWR)) {
- return false;
- }
-
- if (mode == Mode::kWritable)
- return CheckFDAccessMode(handle.readonly_fd, O_RDONLY);
-
- // The second descriptor must be invalid in kReadOnly and kUnsafe modes.
- if (handle.readonly_fd != -1) {
- DLOG(ERROR) << "The second descriptor must be invalid";
- return false;
- }
-
- return true;
-}
-
-PlatformSharedMemoryRegion::PlatformSharedMemoryRegion(
- ScopedFDPair handle,
- Mode mode,
- size_t size,
- const UnguessableToken& guid)
- : handle_(std::move(handle)), mode_(mode), size_(size), guid_(guid) {}
-
-} // namespace subtle
-} // namespace base
diff --git a/base/memory/platform_shared_memory_region_win.cc b/base/memory/platform_shared_memory_region_win.cc
deleted file mode 100644
index b6608da..0000000
--- a/base/memory/platform_shared_memory_region_win.cc
+++ /dev/null
@@ -1,345 +0,0 @@
-// Copyright 2018 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.
-
-#include "base/memory/platform_shared_memory_region.h"
-
-#include <aclapi.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include "base/allocator/partition_allocator/page_allocator.h"
-#include "base/bits.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/numerics/checked_math.h"
-#include "base/process/process_handle.h"
-#include "base/rand_util.h"
-#include "base/strings/stringprintf.h"
-
-namespace base {
-namespace subtle {
-
-namespace {
-
-// Errors that can occur during Shared Memory construction.
-// These match tools/metrics/histograms/histograms.xml.
-// This enum is append-only.
-enum CreateError {
- SUCCESS = 0,
- SIZE_ZERO = 1,
- SIZE_TOO_LARGE = 2,
- INITIALIZE_ACL_FAILURE = 3,
- INITIALIZE_SECURITY_DESC_FAILURE = 4,
- SET_SECURITY_DESC_FAILURE = 5,
- CREATE_FILE_MAPPING_FAILURE = 6,
- REDUCE_PERMISSIONS_FAILURE = 7,
- ALREADY_EXISTS = 8,
- CREATE_ERROR_LAST = ALREADY_EXISTS
-};
-
-// Emits UMA metrics about encountered errors. Pass zero (0) for |winerror|
-// if there is no associated Windows error.
-void LogError(CreateError error, DWORD winerror) {
- UMA_HISTOGRAM_ENUMERATION("SharedMemory.CreateError", error,
- CREATE_ERROR_LAST + 1);
- static_assert(ERROR_SUCCESS == 0, "Windows error code changed!");
- if (winerror != ERROR_SUCCESS)
- UmaHistogramSparse("SharedMemory.CreateWinError", winerror);
-}
-
-typedef enum _SECTION_INFORMATION_CLASS {
- SectionBasicInformation,
-} SECTION_INFORMATION_CLASS;
-
-typedef struct _SECTION_BASIC_INFORMATION {
- PVOID BaseAddress;
- ULONG Attributes;
- LARGE_INTEGER Size;
-} SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION;
-
-typedef ULONG(__stdcall* NtQuerySectionType)(
- HANDLE SectionHandle,
- SECTION_INFORMATION_CLASS SectionInformationClass,
- PVOID SectionInformation,
- ULONG SectionInformationLength,
- PULONG ResultLength);
-
-// Returns the length of the memory section starting at the supplied address.
-size_t GetMemorySectionSize(void* address) {
- MEMORY_BASIC_INFORMATION memory_info;
- if (!::VirtualQuery(address, &memory_info, sizeof(memory_info)))
- return 0;
- return memory_info.RegionSize -
- (static_cast<char*>(address) -
- static_cast<char*>(memory_info.AllocationBase));
-}
-
-// Checks if the section object is safe to map. At the moment this just means
-// it's not an image section.
-bool IsSectionSafeToMap(HANDLE handle) {
- static NtQuerySectionType nt_query_section_func =
- reinterpret_cast<NtQuerySectionType>(
- ::GetProcAddress(::GetModuleHandle(L"ntdll.dll"), "NtQuerySection"));
- DCHECK(nt_query_section_func);
-
- // The handle must have SECTION_QUERY access for this to succeed.
- SECTION_BASIC_INFORMATION basic_information = {};
- ULONG status =
- nt_query_section_func(handle, SectionBasicInformation, &basic_information,
- sizeof(basic_information), nullptr);
- if (status)
- return false;
- return (basic_information.Attributes & SEC_IMAGE) != SEC_IMAGE;
-}
-
-// Returns a HANDLE on success and |nullptr| on failure.
-// This function is similar to CreateFileMapping, but removes the permissions
-// WRITE_DAC, WRITE_OWNER, READ_CONTROL, and DELETE.
-//
-// A newly created file mapping has two sets of permissions. It has access
-// control permissions (WRITE_DAC, WRITE_OWNER, READ_CONTROL, and DELETE) and
-// file permissions (FILE_MAP_READ, FILE_MAP_WRITE, etc.). The Chrome sandbox
-// prevents HANDLEs with the WRITE_DAC permission from being duplicated into
-// unprivileged processes.
-//
-// In order to remove the access control permissions, after being created the
-// handle is duplicated with only the file access permissions.
-HANDLE CreateFileMappingWithReducedPermissions(SECURITY_ATTRIBUTES* sa,
- size_t rounded_size,
- LPCWSTR name) {
- HANDLE h = CreateFileMapping(INVALID_HANDLE_VALUE, sa, PAGE_READWRITE, 0,
- static_cast<DWORD>(rounded_size), name);
- if (!h) {
- LogError(CREATE_FILE_MAPPING_FAILURE, GetLastError());
- return nullptr;
- }
-
- HANDLE h2;
- ProcessHandle process = GetCurrentProcess();
- BOOL success = ::DuplicateHandle(
- process, h, process, &h2, FILE_MAP_READ | FILE_MAP_WRITE | SECTION_QUERY,
- FALSE, 0);
- BOOL rv = ::CloseHandle(h);
- DCHECK(rv);
-
- if (!success) {
- LogError(REDUCE_PERMISSIONS_FAILURE, GetLastError());
- return nullptr;
- }
-
- return h2;
-}
-
-} // namespace
-
-// static
-PlatformSharedMemoryRegion PlatformSharedMemoryRegion::Take(
- win::ScopedHandle handle,
- Mode mode,
- size_t size,
- const UnguessableToken& guid) {
- if (!handle.IsValid())
- return {};
-
- if (size == 0)
- return {};
-
- if (size > static_cast<size_t>(std::numeric_limits<int>::max()))
- return {};
-
- if (!IsSectionSafeToMap(handle.Get()))
- return {};
-
- CHECK(
- CheckPlatformHandlePermissionsCorrespondToMode(handle.Get(), mode, size));
-
- return PlatformSharedMemoryRegion(std::move(handle), mode, size, guid);
-}
-
-HANDLE PlatformSharedMemoryRegion::GetPlatformHandle() const {
- return handle_.Get();
-}
-
-bool PlatformSharedMemoryRegion::IsValid() const {
- return handle_.IsValid();
-}
-
-PlatformSharedMemoryRegion PlatformSharedMemoryRegion::Duplicate() const {
- if (!IsValid())
- return {};
-
- CHECK_NE(mode_, Mode::kWritable)
- << "Duplicating a writable shared memory region is prohibited";
-
- HANDLE duped_handle;
- ProcessHandle process = GetCurrentProcess();
- BOOL success =
- ::DuplicateHandle(process, handle_.Get(), process, &duped_handle, 0,
- FALSE, DUPLICATE_SAME_ACCESS);
- if (!success)
- return {};
-
- return PlatformSharedMemoryRegion(win::ScopedHandle(duped_handle), mode_,
- size_, guid_);
-}
-
-bool PlatformSharedMemoryRegion::ConvertToReadOnly() {
- if (!IsValid())
- return false;
-
- CHECK_EQ(mode_, Mode::kWritable)
- << "Only writable shared memory region can be converted to read-only";
-
- win::ScopedHandle handle_copy(handle_.Take());
-
- HANDLE duped_handle;
- ProcessHandle process = GetCurrentProcess();
- BOOL success =
- ::DuplicateHandle(process, handle_copy.Get(), process, &duped_handle,
- FILE_MAP_READ | SECTION_QUERY, FALSE, 0);
- if (!success)
- return false;
-
- handle_.Set(duped_handle);
- mode_ = Mode::kReadOnly;
- return true;
-}
-
-bool PlatformSharedMemoryRegion::MapAt(off_t offset,
- size_t size,
- void** memory,
- size_t* mapped_size) const {
- if (!IsValid())
- return false;
-
- size_t end_byte;
- if (!CheckAdd(offset, size).AssignIfValid(&end_byte) || end_byte > size_) {
- return false;
- }
-
- bool write_allowed = mode_ != Mode::kReadOnly;
- // Try to map the shared memory. On the first failure, release any reserved
- // address space for a single entry.
- for (int i = 0; i < 2; ++i) {
- *memory = MapViewOfFile(
- handle_.Get(), FILE_MAP_READ | (write_allowed ? FILE_MAP_WRITE : 0),
- static_cast<uint64_t>(offset) >> 32, static_cast<DWORD>(offset), size);
- if (*memory)
- break;
- ReleaseReservation();
- }
- if (!*memory) {
- DPLOG(ERROR) << "Failed executing MapViewOfFile";
- return false;
- }
-
- *mapped_size = GetMemorySectionSize(*memory);
- DCHECK_EQ(0U,
- reinterpret_cast<uintptr_t>(*memory) & (kMapMinimumAlignment - 1));
- return true;
-}
-
-// static
-PlatformSharedMemoryRegion PlatformSharedMemoryRegion::Create(Mode mode,
- size_t size) {
- // TODO(crbug.com/210609): NaCl forces us to round up 64k here, wasting 32k
- // per mapping on average.
- static const size_t kSectionSize = 65536;
- if (size == 0) {
- LogError(SIZE_ZERO, 0);
- return {};
- }
-
- size_t rounded_size = bits::Align(size, kSectionSize);
- if (rounded_size > static_cast<size_t>(std::numeric_limits<int>::max())) {
- LogError(SIZE_TOO_LARGE, 0);
- return {};
- }
-
- CHECK_NE(mode, Mode::kReadOnly) << "Creating a region in read-only mode will "
- "lead to this region being non-modifiable";
-
- // Add an empty DACL to enforce anonymous read-only sections.
- ACL dacl;
- SECURITY_DESCRIPTOR sd;
- if (!InitializeAcl(&dacl, sizeof(dacl), ACL_REVISION)) {
- LogError(INITIALIZE_ACL_FAILURE, GetLastError());
- return {};
- }
- if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) {
- LogError(INITIALIZE_SECURITY_DESC_FAILURE, GetLastError());
- return {};
- }
- if (!SetSecurityDescriptorDacl(&sd, TRUE, &dacl, FALSE)) {
- LogError(SET_SECURITY_DESC_FAILURE, GetLastError());
- return {};
- }
-
- // Windows ignores DACLs on unnamed shared section. Generate a random name in
- // order to be able to enforce read-only.
- uint64_t rand_values[4];
- RandBytes(&rand_values, sizeof(rand_values));
- string16 name =
- StringPrintf(L"CrSharedMem_%016llx%016llx%016llx%016llx", rand_values[0],
- rand_values[1], rand_values[2], rand_values[3]);
-
- SECURITY_ATTRIBUTES sa = {sizeof(sa), &sd, FALSE};
- // Ask for the file mapping with reduced permisions to avoid passing the
- // access control permissions granted by default into unpriviledged process.
- HANDLE h =
- CreateFileMappingWithReducedPermissions(&sa, rounded_size, name.c_str());
- if (h == nullptr) {
- // The error is logged within CreateFileMappingWithReducedPermissions().
- return {};
- }
-
- win::ScopedHandle scoped_h(h);
- // Check if the shared memory pre-exists.
- if (GetLastError() == ERROR_ALREADY_EXISTS) {
- LogError(ALREADY_EXISTS, ERROR_ALREADY_EXISTS);
- return {};
- }
-
- return PlatformSharedMemoryRegion(std::move(scoped_h), mode, size,
- UnguessableToken::Create());
-}
-
-// static
-bool PlatformSharedMemoryRegion::CheckPlatformHandlePermissionsCorrespondToMode(
- PlatformHandle handle,
- Mode mode,
- size_t size) {
- // Call ::DuplicateHandle() with FILE_MAP_WRITE as a desired access to check
- // if the |handle| has a write access.
- ProcessHandle process = GetCurrentProcess();
- HANDLE duped_handle;
- BOOL success = ::DuplicateHandle(process, handle, process, &duped_handle,
- FILE_MAP_WRITE, FALSE, 0);
- if (success) {
- BOOL rv = ::CloseHandle(duped_handle);
- DCHECK(rv);
- }
-
- bool is_read_only = !success;
- bool expected_read_only = mode == Mode::kReadOnly;
-
- if (is_read_only != expected_read_only) {
- DLOG(ERROR) << "File mapping handle has wrong access rights: it is"
- << (is_read_only ? " " : " not ") << "read-only but it should"
- << (expected_read_only ? " " : " not ") << "be";
- return false;
- }
-
- return true;
-}
-
-PlatformSharedMemoryRegion::PlatformSharedMemoryRegion(
- win::ScopedHandle handle,
- Mode mode,
- size_t size,
- const UnguessableToken& guid)
- : handle_(std::move(handle)), mode_(mode), size_(size), guid_(guid) {}
-
-} // namespace subtle
-} // namespace base
diff --git a/base/memory/protected_memory.cc b/base/memory/protected_memory.cc
deleted file mode 100644
index 157a677..0000000
--- a/base/memory/protected_memory.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2017 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.
-
-#include "base/memory/protected_memory.h"
-#include "base/synchronization/lock.h"
-
-namespace base {
-
-#if !defined(COMPONENT_BUILD)
-PROTECTED_MEMORY_SECTION int AutoWritableMemory::writers = 0;
-#endif // !defined(COMPONENT_BUILD)
-
-base::LazyInstance<Lock>::Leaky AutoWritableMemory::writers_lock =
- LAZY_INSTANCE_INITIALIZER;
-
-} // namespace base
diff --git a/base/memory/protected_memory.h b/base/memory/protected_memory.h
deleted file mode 100644
index 9f372ca..0000000
--- a/base/memory/protected_memory.h
+++ /dev/null
@@ -1,261 +0,0 @@
-// Copyright 2017 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.
-
-// Protected memory is memory holding security-sensitive data intended to be
-// left read-only for the majority of its lifetime to avoid being overwritten
-// by attackers. ProtectedMemory is a simple wrapper around platform-specific
-// APIs to set memory read-write and read-only when required. Protected memory
-// should be set read-write for the minimum amount of time required.
-
-// Normally mutable variables are held in read-write memory and constant data
-// is held in read-only memory to ensure it is not accidentally overwritten.
-// In some cases we want to hold mutable variables in read-only memory, except
-// when they are being written to, to ensure that they are not tampered with.
-//
-// ProtectedMemory is a container class intended to hold a single variable in
-// read-only memory, except when explicitly set read-write. The variable can be
-// set read-write by creating a scoped AutoWritableMemory object by calling
-// AutoWritableMemory::Create(), the memory stays writable until the returned
-// object goes out of scope and is destructed. The wrapped variable can be
-// accessed using operator* and operator->.
-//
-// Instances of ProtectedMemory must be declared in the PROTECTED_MEMORY_SECTION
-// and as global variables. Because protected memory variables are globals, the
-// the same rules apply disallowing non-trivial constructors and destructors.
-// Global definitions are required to avoid the linker placing statics in
-// inlinable functions into a comdat section and setting the protected memory
-// section read-write when they are merged.
-//
-// EXAMPLE:
-//
-// struct Items { void* item1; };
-// static PROTECTED_MEMORY_SECTION base::ProtectedMemory<Items> items;
-// void InitializeItems() {
-// // Explicitly set items read-write before writing to it.
-// auto writer = base::AutoWritableMemory::Create(items);
-// items->item1 = /* ... */;
-// assert(items->item1 != nullptr);
-// // items is set back to read-only on the destruction of writer
-// }
-//
-// using FnPtr = void (*)(void);
-// PROTECTED_MEMORY_SECTION base::ProtectedMemory<FnPtr> fnPtr;
-// FnPtr ResolveFnPtr(void) {
-// // The Initializer nested class is a helper class for creating a static
-// // initializer for a ProtectedMemory variable. It implicitly sets the
-// // variable read-write during initialization.
-// static base::ProtectedMemory<FnPtr>::Initializer I(&fnPtr,
-// reinterpret_cast<FnPtr>(dlsym(/* ... */)));
-// return *fnPtr;
-// }
-
-#ifndef BASE_MEMORY_PROTECTED_MEMORY_H_
-#define BASE_MEMORY_PROTECTED_MEMORY_H_
-
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/synchronization/lock.h"
-#include "build_config.h"
-
-#define PROTECTED_MEMORY_ENABLED 1
-
-#if defined(OS_MACOSX) && !defined(OS_IOS)
-// The segment the section is in is defined read-only with a linker flag in
-// build/config/mac/BUILD.gn
-#define PROTECTED_MEMORY_SECTION \
- __attribute__((section("PROTECTED_MEMORY, protected_memory")))
-extern char __start_protected_memory __asm(
- "section$start$PROTECTED_MEMORY$protected_memory");
-extern char __stop_protected_memory __asm(
- "section$end$PROTECTED_MEMORY$protected_memory");
-
-#elif defined(OS_WIN)
-// Define a read-write prot section. The $a, $mem, and $z 'sub-sections' are
-// merged alphabetically so $a and $z are used to define the start and end of
-// the protected memory section, and $mem holds protected variables.
-// (Note: Sections in Portable Executables are equivalent to segments in other
-// executable formats, so this section is mapped into its own pages.)
-#pragma section("prot$a", read, write)
-#pragma section("prot$mem", read, write)
-#pragma section("prot$z", read, write)
-
-// We want the protected memory section to be read-only, not read-write so we
-// instruct the linker to set the section read-only at link time. We do this
-// at link time instead of compile time, because defining the prot section
-// read-only would cause mis-compiles due to optimizations assuming that the
-// section contents are constant.
-#pragma comment(linker, "/SECTION:prot,R")
-
-__declspec(allocate("prot$a")) __declspec(selectany)
-char __start_protected_memory;
-__declspec(allocate("prot$z")) __declspec(selectany)
-char __stop_protected_memory;
-
-#define PROTECTED_MEMORY_SECTION __declspec(allocate("prot$mem"))
-
-#else
-#undef PROTECTED_MEMORY_ENABLED
-#define PROTECTED_MEMORY_ENABLED 0
-#define PROTECTED_MEMORY_SECTION
-#endif
-
-namespace base {
-
-template <typename T>
-class ProtectedMemory {
- public:
- ProtectedMemory() = default;
-
- // Expose direct access to the encapsulated variable
- T& operator*() { return data; }
- const T& operator*() const { return data; }
- T* operator->() { return &data; }
- const T* operator->() const { return &data; }
-
- // Helper class for creating simple ProtectedMemory static initializers.
- class Initializer {
- public:
- // Defined out-of-line below to break circular definition dependency between
- // ProtectedMemory and AutoWritableMemory.
- Initializer(ProtectedMemory<T>* PM, const T& Init);
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(Initializer);
- };
-
- private:
- T data;
-
- DISALLOW_COPY_AND_ASSIGN(ProtectedMemory);
-};
-
-// DCHECK that the byte at |ptr| is read-only.
-BASE_EXPORT void AssertMemoryIsReadOnly(const void* ptr);
-
-// Abstract out platform-specific methods to get the beginning and end of the
-// PROTECTED_MEMORY_SECTION. ProtectedMemoryEnd returns a pointer to the byte
-// past the end of the PROTECTED_MEMORY_SECTION.
-#if PROTECTED_MEMORY_ENABLED
-constexpr void* ProtectedMemoryStart = &__start_protected_memory;
-constexpr void* ProtectedMemoryEnd = &__stop_protected_memory;
-#endif
-
-#if defined(COMPONENT_BUILD)
-namespace internal {
-
-// For component builds we want to define a separate global writers variable
-// (explained below) in every DSO that includes this header. To do that we use
-// this template to define a global without duplicate symbol errors.
-template <typename T>
-struct DsoSpecific {
- static T value;
-};
-template <typename T>
-T DsoSpecific<T>::value = 0;
-
-} // namespace internal
-#endif // defined(COMPONENT_BUILD)
-
-// A class that sets a given ProtectedMemory variable writable while the
-// AutoWritableMemory is in scope. This class implements the logic for setting
-// the protected memory region read-only/read-write in a thread-safe manner.
-class AutoWritableMemory {
- private:
- // 'writers' is a global holding the number of ProtectedMemory instances set
- // writable, used to avoid races setting protected memory readable/writable.
- // When this reaches zero the protected memory region is set read only.
- // Access is controlled by writers_lock.
-#if defined(COMPONENT_BUILD)
- // For component builds writers is a reference to an int defined separately in
- // every DSO.
- static constexpr int& writers = internal::DsoSpecific<int>::value;
-#else
- // Otherwise, we declare writers in the protected memory section to avoid the
- // scenario where an attacker could overwrite it with a large value and invoke
- // code that constructs and destructs an AutoWritableMemory. After such a call
- // protected memory would still be set writable because writers > 0.
- static int writers;
-#endif // defined(COMPONENT_BUILD)
-
- // Synchronizes access to the writers variable and the simultaneous actions
- // that need to happen alongside writers changes, e.g. setting the protected
- // memory region readable when writers is decremented to 0.
- static BASE_EXPORT base::LazyInstance<Lock>::Leaky writers_lock;
-
- // Abstract out platform-specific memory APIs. |end| points to the byte past
- // the end of the region of memory having its memory protections changed.
- BASE_EXPORT bool SetMemoryReadWrite(void* start, void* end);
- BASE_EXPORT bool SetMemoryReadOnly(void* start, void* end);
-
- // If this is the first writer (e.g. writers == 0) set the writers variable
- // read-write. Next, increment writers and set the requested memory writable.
- AutoWritableMemory(void* ptr, void* ptr_end) {
-#if PROTECTED_MEMORY_ENABLED
- DCHECK(ptr >= ProtectedMemoryStart && ptr_end <= ProtectedMemoryEnd);
-
- {
- base::AutoLock auto_lock(writers_lock.Get());
- if (writers == 0) {
- AssertMemoryIsReadOnly(ptr);
-#if !defined(COMPONENT_BUILD)
- AssertMemoryIsReadOnly(&writers);
- CHECK(SetMemoryReadWrite(&writers, &writers + 1));
-#endif // !defined(COMPONENT_BUILD)
- }
-
- writers++;
- }
-
- CHECK(SetMemoryReadWrite(ptr, ptr_end));
-#endif // PROTECTED_MEMORY_ENABLED
- }
-
- public:
- // Wrap the private constructor to create an easy-to-use interface to
- // construct AutoWritableMemory objects.
- template <typename T>
- static AutoWritableMemory Create(ProtectedMemory<T>& PM) {
- T* ptr = &*PM;
- return AutoWritableMemory(ptr, ptr + 1);
- }
-
- // Move constructor just increments writers
- AutoWritableMemory(AutoWritableMemory&& original) {
-#if PROTECTED_MEMORY_ENABLED
- base::AutoLock auto_lock(writers_lock.Get());
- CHECK_GT(writers, 0);
- writers++;
-#endif // PROTECTED_MEMORY_ENABLED
- }
-
- // On destruction decrement writers, and if no other writers exist, set the
- // entire protected memory region read-only.
- ~AutoWritableMemory() {
-#if PROTECTED_MEMORY_ENABLED
- base::AutoLock auto_lock(writers_lock.Get());
- CHECK_GT(writers, 0);
- writers--;
-
- if (writers == 0) {
- CHECK(SetMemoryReadOnly(ProtectedMemoryStart, ProtectedMemoryEnd));
-#if !defined(COMPONENT_BUILD)
- AssertMemoryIsReadOnly(&writers);
-#endif // !defined(COMPONENT_BUILD)
- }
-#endif // PROTECTED_MEMORY_ENABLED
- }
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(AutoWritableMemory);
-};
-
-template <typename T>
-ProtectedMemory<T>::Initializer::Initializer(ProtectedMemory<T>* PM,
- const T& Init) {
- AutoWritableMemory writer = AutoWritableMemory::Create(*PM);
- **PM = Init;
-}
-
-} // namespace base
-
-#endif // BASE_MEMORY_PROTECTED_MEMORY_H_
diff --git a/base/memory/protected_memory_cfi.h b/base/memory/protected_memory_cfi.h
deleted file mode 100644
index f5b0121..0000000
--- a/base/memory/protected_memory_cfi.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2017 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.
-
-// Helper routines to call function pointers stored in protected memory with
-// Control Flow Integrity indirect call checking disabled. Some indirect calls,
-// e.g. dynamically resolved symbols in another DSO, can not be accounted for by
-// CFI-icall. These routines allow those symbols to be called without CFI-icall
-// checking safely by ensuring that they are placed in protected memory.
-
-#ifndef BASE_MEMORY_PROTECTED_MEMORY_CFI_H_
-#define BASE_MEMORY_PROTECTED_MEMORY_CFI_H_
-
-#include <utility>
-
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "base/memory/protected_memory.h"
-#include "build_config.h"
-
-namespace base {
-namespace internal {
-
-// This class is used to exempt calls to function pointers stored in
-// ProtectedMemory from cfi-icall checking. It's not secure to use directly, it
-// should only be used by the UnsanitizedCfiCall() functions below. Given an
-// UnsanitizedCfiCall object, you can use operator() to call the encapsulated
-// function pointer without cfi-icall checking.
-template <typename FunctionType>
-class UnsanitizedCfiCall {
- public:
- explicit UnsanitizedCfiCall(FunctionType function) : function_(function) {}
- UnsanitizedCfiCall(UnsanitizedCfiCall&&) = default;
-
- template <typename... Args>
- NO_SANITIZE("cfi-icall")
- auto operator()(Args&&... args) {
- return function_(std::forward<Args>(args)...);
- }
-
- private:
- FunctionType function_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(UnsanitizedCfiCall);
-};
-
-} // namespace internal
-
-// These functions can be used to call function pointers in ProtectedMemory
-// without cfi-icall checking. They are intended to be used to create an
-// UnsanitizedCfiCall object and immediately call it. UnsanitizedCfiCall objects
-// should not initialized directly or stored because they hold a function
-// pointer that will be called without CFI-icall checking in mutable memory. The
-// functions can be used as shown below:
-
-// ProtectedMemory<void (*)(int)> p;
-// UnsanitizedCfiCall(p)(5); /* In place of (*p)(5); */
-
-template <typename T>
-auto UnsanitizedCfiCall(const ProtectedMemory<T>& PM) {
-#if PROTECTED_MEMORY_ENABLED
- DCHECK(&PM >= ProtectedMemoryStart && &PM < ProtectedMemoryEnd);
-#endif // PROTECTED_MEMORY_ENABLED
- return internal::UnsanitizedCfiCall<T>(*PM);
-}
-
-// struct S { void (*fp)(int); } s;
-// ProtectedMemory<S> p;
-// UnsanitizedCfiCall(p, &S::fp)(5); /* In place of p->fp(5); */
-
-template <typename T, typename Member>
-auto UnsanitizedCfiCall(const ProtectedMemory<T>& PM, Member member) {
-#if PROTECTED_MEMORY_ENABLED
- DCHECK(&PM >= ProtectedMemoryStart && &PM < ProtectedMemoryEnd);
-#endif // PROTECTED_MEMORY_ENABLED
- return internal::UnsanitizedCfiCall<decltype(*PM.*member)>(*PM.*member);
-}
-
-} // namespace base
-
-#endif // BASE_MEMORY_PROTECTED_MEMORY_CFI_H_
diff --git a/base/memory/protected_memory_posix.cc b/base/memory/protected_memory_posix.cc
deleted file mode 100644
index 1839e3e..0000000
--- a/base/memory/protected_memory_posix.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2017 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.
-
-#include "base/memory/protected_memory.h"
-
-#include <stdint.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-#if defined(OS_LINUX)
-#include <sys/resource.h>
-#endif // defined(OS_LINUX)
-
-#if defined(OS_MACOSX) && !defined(OS_IOS)
-#include <mach/mach.h>
-#include <mach/mach_vm.h>
-#endif // defined(OS_MACOSX) && !defined(OS_IOS)
-
-#include "base/posix/eintr_wrapper.h"
-#include "base/process/process_metrics.h"
-#include "base/synchronization/lock.h"
-#include "build_config.h"
-
-namespace base {
-
-namespace {
-
-bool SetMemory(void* start, void* end, int prot) {
- DCHECK(end > start);
- const uintptr_t page_mask = ~(base::GetPageSize() - 1);
- const uintptr_t page_start = reinterpret_cast<uintptr_t>(start) & page_mask;
- return mprotect(reinterpret_cast<void*>(page_start),
- reinterpret_cast<uintptr_t>(end) - page_start, prot) == 0;
-}
-
-} // namespace
-
-bool AutoWritableMemory::SetMemoryReadWrite(void* start, void* end) {
- return SetMemory(start, end, PROT_READ | PROT_WRITE);
-}
-
-bool AutoWritableMemory::SetMemoryReadOnly(void* start, void* end) {
- return SetMemory(start, end, PROT_READ);
-}
-
-#if defined(OS_LINUX)
-void AssertMemoryIsReadOnly(const void* ptr) {
-#if DCHECK_IS_ON()
- const uintptr_t page_mask = ~(base::GetPageSize() - 1);
- const uintptr_t page_start = reinterpret_cast<uintptr_t>(ptr) & page_mask;
-
- // Note: We've casted away const here, which should not be meaningful since
- // if the memory is written to we will abort immediately.
- int result =
- getrlimit(RLIMIT_NPROC, reinterpret_cast<struct rlimit*>(page_start));
- DCHECK_EQ(result, -1);
- DCHECK_EQ(errno, EFAULT);
-#endif // DCHECK_IS_ON()
-}
-#elif defined(OS_MACOSX) && !defined(OS_IOS)
-void AssertMemoryIsReadOnly(const void* ptr) {
-#if DCHECK_IS_ON()
- mach_port_t object_name;
- vm_region_basic_info_64 region_info;
- mach_vm_size_t size = 1;
- mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64;
-
- kern_return_t kr = mach_vm_region(
- mach_task_self(), reinterpret_cast<mach_vm_address_t*>(&ptr), &size,
- VM_REGION_BASIC_INFO_64, reinterpret_cast<vm_region_info_t>(®ion_info),
- &count, &object_name);
- DCHECK_EQ(kr, KERN_SUCCESS);
- DCHECK_EQ(region_info.protection, VM_PROT_READ);
-#endif // DCHECK_IS_ON()
-}
-#endif // defined(OS_LINUX) || (defined(OS_MACOSX) && !defined(OS_IOS))
-
-} // namespace base
diff --git a/base/memory/protected_memory_win.cc b/base/memory/protected_memory_win.cc
deleted file mode 100644
index 43ad8ba..0000000
--- a/base/memory/protected_memory_win.cc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2017 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.
-
-#include "base/memory/protected_memory.h"
-
-#include <windows.h>
-
-#include <stdint.h>
-
-#include "base/process/process_metrics.h"
-#include "base/synchronization/lock.h"
-#include "build_config.h"
-
-namespace base {
-
-namespace {
-
-bool SetMemory(void* start, void* end, DWORD prot) {
- DCHECK(end > start);
- const uintptr_t page_mask = ~(base::GetPageSize() - 1);
- const uintptr_t page_start = reinterpret_cast<uintptr_t>(start) & page_mask;
- DWORD old_prot;
- return VirtualProtect(reinterpret_cast<void*>(page_start),
- reinterpret_cast<uintptr_t>(end) - page_start, prot,
- &old_prot) != 0;
-}
-
-} // namespace
-
-bool AutoWritableMemory::SetMemoryReadWrite(void* start, void* end) {
- return SetMemory(start, end, PAGE_READWRITE);
-}
-
-bool AutoWritableMemory::SetMemoryReadOnly(void* start, void* end) {
- return SetMemory(start, end, PAGE_READONLY);
-}
-
-void AssertMemoryIsReadOnly(const void* ptr) {
-#if DCHECK_IS_ON()
- const uintptr_t page_mask = ~(base::GetPageSize() - 1);
- const uintptr_t page_start = reinterpret_cast<uintptr_t>(ptr) & page_mask;
-
- MEMORY_BASIC_INFORMATION info;
- SIZE_T result =
- VirtualQuery(reinterpret_cast<LPCVOID>(page_start), &info, sizeof(info));
- DCHECK_GT(result, 0U);
- DCHECK(info.Protect == PAGE_READONLY);
-#endif // DCHECK_IS_ON()
-}
-
-} // namespace base
diff --git a/base/memory/read_only_shared_memory_region.cc b/base/memory/read_only_shared_memory_region.cc
deleted file mode 100644
index 0a5f900..0000000
--- a/base/memory/read_only_shared_memory_region.cc
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2018 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.
-
-#include "base/memory/read_only_shared_memory_region.h"
-
-#include <utility>
-
-#include "base/memory/shared_memory.h"
-#include "build_config.h"
-
-namespace base {
-
-// static
-MappedReadOnlyRegion ReadOnlySharedMemoryRegion::Create(size_t size) {
- subtle::PlatformSharedMemoryRegion handle =
- subtle::PlatformSharedMemoryRegion::CreateWritable(size);
- if (!handle.IsValid())
- return {};
-
- void* memory_ptr = nullptr;
- size_t mapped_size = 0;
- if (!handle.MapAt(0, handle.GetSize(), &memory_ptr, &mapped_size))
- return {};
-
- WritableSharedMemoryMapping mapping(memory_ptr, size, mapped_size,
- handle.GetGUID());
-#if defined(OS_MACOSX) && !defined(OS_IOS)
- handle.ConvertToReadOnly(memory_ptr);
-#else
- handle.ConvertToReadOnly();
-#endif // defined(OS_MACOSX) && !defined(OS_IOS)
- ReadOnlySharedMemoryRegion region(std::move(handle));
-
- if (!region.IsValid() || !mapping.IsValid())
- return {};
-
- return {std::move(region), std::move(mapping)};
-}
-
-// static
-ReadOnlySharedMemoryRegion ReadOnlySharedMemoryRegion::Deserialize(
- subtle::PlatformSharedMemoryRegion handle) {
- return ReadOnlySharedMemoryRegion(std::move(handle));
-}
-
-// static
-subtle::PlatformSharedMemoryRegion
-ReadOnlySharedMemoryRegion::TakeHandleForSerialization(
- ReadOnlySharedMemoryRegion region) {
- return std::move(region.handle_);
-}
-
-ReadOnlySharedMemoryRegion::ReadOnlySharedMemoryRegion() = default;
-ReadOnlySharedMemoryRegion::ReadOnlySharedMemoryRegion(
- ReadOnlySharedMemoryRegion&& region) = default;
-ReadOnlySharedMemoryRegion& ReadOnlySharedMemoryRegion::operator=(
- ReadOnlySharedMemoryRegion&& region) = default;
-ReadOnlySharedMemoryRegion::~ReadOnlySharedMemoryRegion() = default;
-
-ReadOnlySharedMemoryRegion ReadOnlySharedMemoryRegion::Duplicate() const {
- return ReadOnlySharedMemoryRegion(handle_.Duplicate());
-}
-
-ReadOnlySharedMemoryMapping ReadOnlySharedMemoryRegion::Map() const {
- return MapAt(0, handle_.GetSize());
-}
-
-ReadOnlySharedMemoryMapping ReadOnlySharedMemoryRegion::MapAt(
- off_t offset,
- size_t size) const {
- if (!IsValid())
- return {};
-
- void* memory = nullptr;
- size_t mapped_size = 0;
- if (!handle_.MapAt(offset, size, &memory, &mapped_size))
- return {};
-
- return ReadOnlySharedMemoryMapping(memory, size, mapped_size,
- handle_.GetGUID());
-}
-
-bool ReadOnlySharedMemoryRegion::IsValid() const {
- return handle_.IsValid();
-}
-
-ReadOnlySharedMemoryRegion::ReadOnlySharedMemoryRegion(
- subtle::PlatformSharedMemoryRegion handle)
- : handle_(std::move(handle)) {
- if (handle_.IsValid()) {
- CHECK_EQ(handle_.GetMode(),
- subtle::PlatformSharedMemoryRegion::Mode::kReadOnly);
- }
-}
-
-} // namespace base
diff --git a/base/memory/read_only_shared_memory_region.h b/base/memory/read_only_shared_memory_region.h
deleted file mode 100644
index 54e73ed..0000000
--- a/base/memory/read_only_shared_memory_region.h
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2018 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 BASE_MEMORY_READ_ONLY_SHARED_MEMORY_REGION_H_
-#define BASE_MEMORY_READ_ONLY_SHARED_MEMORY_REGION_H_
-
-#include <utility>
-
-#include "base/macros.h"
-#include "base/memory/platform_shared_memory_region.h"
-#include "base/memory/shared_memory_mapping.h"
-
-namespace base {
-
-struct MappedReadOnlyRegion;
-
-// Scoped move-only handle to a region of platform shared memory. The instance
-// owns the platform handle it wraps. Mappings created by this region are
-// read-only. These mappings remain valid even after the region handle is moved
-// or destroyed.
-class BASE_EXPORT ReadOnlySharedMemoryRegion {
- public:
- using MappingType = ReadOnlySharedMemoryMapping;
- // Creates a new ReadOnlySharedMemoryRegion instance of a given size along
- // with the WritableSharedMemoryMapping which provides the only way to modify
- // the content of the newly created region. The returned region and mapping
- // are guaranteed to either be both valid or both invalid. Use
- // |MappedReadOnlyRegion::IsValid()| as a shortcut for checking creation
- // success.
- //
- // This means that the caller's process is the only process that can modify
- // the region content. If you need to pass write access to another process,
- // consider using WritableSharedMemoryRegion or UnsafeSharedMemoryRegion.
- static MappedReadOnlyRegion Create(size_t size);
-
- // Returns a ReadOnlySharedMemoryRegion built from a platform-specific handle
- // that was taken from another ReadOnlySharedMemoryRegion instance. Returns an
- // invalid region iff the |handle| is invalid. CHECK-fails if the |handle|
- // isn't read-only.
- // This should be used only by the code passing handles across process
- // boundaries.
- static ReadOnlySharedMemoryRegion Deserialize(
- subtle::PlatformSharedMemoryRegion handle);
-
- // Extracts a platform handle from the region. Ownership is transferred to the
- // returned region object.
- // This should be used only for sending the handle from the current process to
- // another.
- static subtle::PlatformSharedMemoryRegion TakeHandleForSerialization(
- ReadOnlySharedMemoryRegion region);
-
- // Default constructor initializes an invalid instance.
- ReadOnlySharedMemoryRegion();
-
- // Move operations are allowed.
- ReadOnlySharedMemoryRegion(ReadOnlySharedMemoryRegion&&);
- ReadOnlySharedMemoryRegion& operator=(ReadOnlySharedMemoryRegion&&);
-
- // Destructor closes shared memory region if valid.
- // All created mappings will remain valid.
- ~ReadOnlySharedMemoryRegion();
-
- // Duplicates the underlying platform handle and creates a new
- // ReadOnlySharedMemoryRegion instance that owns this handle. Returns a valid
- // ReadOnlySharedMemoryRegion on success, invalid otherwise. The current
- // region instance remains valid in any case.
- ReadOnlySharedMemoryRegion Duplicate() const;
-
- // Maps the shared memory region into the caller's address space with
- // read-only access. The mapped address is guaranteed to have an alignment of
- // at least |subtle::PlatformSharedMemoryRegion::kMapMinimumAlignment|.
- // Returns a valid ReadOnlySharedMemoryMapping instance on success, invalid
- // otherwise.
- ReadOnlySharedMemoryMapping Map() const;
-
- // Same as above, but maps only |size| bytes of the shared memory region
- // starting with the given |offset|. |offset| must be aligned to value of
- // |SysInfo::VMAllocationGranularity()|. Returns an invalid mapping if
- // requested bytes are out of the region limits.
- ReadOnlySharedMemoryMapping MapAt(off_t offset, size_t size) const;
-
- // Whether the underlying platform handle is valid.
- bool IsValid() const;
-
- // Returns the maximum mapping size that can be created from this region.
- size_t GetSize() const {
- DCHECK(IsValid());
- return handle_.GetSize();
- }
-
- private:
- explicit ReadOnlySharedMemoryRegion(
- subtle::PlatformSharedMemoryRegion handle);
-
- subtle::PlatformSharedMemoryRegion handle_;
-
- DISALLOW_COPY_AND_ASSIGN(ReadOnlySharedMemoryRegion);
-};
-
-// Helper struct for return value of ReadOnlySharedMemoryRegion::Create().
-struct MappedReadOnlyRegion {
- ReadOnlySharedMemoryRegion region;
- WritableSharedMemoryMapping mapping;
- // Helper function to check return value of
- // ReadOnlySharedMemoryRegion::Create(). |region| and |mapping| either both
- // valid or invalid.
- bool IsValid() {
- DCHECK_EQ(region.IsValid(), mapping.IsValid());
- return region.IsValid() && mapping.IsValid();
- }
-};
-
-} // namespace base
-
-#endif // BASE_MEMORY_READ_ONLY_SHARED_MEMORY_REGION_H_
diff --git a/base/memory/ref_counted_delete_on_sequence.h b/base/memory/ref_counted_delete_on_sequence.h
deleted file mode 100644
index dd30106..0000000
--- a/base/memory/ref_counted_delete_on_sequence.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2013 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 BASE_MEMORY_REF_COUNTED_DELETE_ON_SEQUENCE_H_
-#define BASE_MEMORY_REF_COUNTED_DELETE_ON_SEQUENCE_H_
-
-#include <utility>
-
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/sequenced_task_runner.h"
-
-namespace base {
-
-// RefCountedDeleteOnSequence is similar to RefCountedThreadSafe, and ensures
-// that the object will be deleted on a specified sequence.
-//
-// Sample usage:
-// class Foo : public RefCountedDeleteOnSequence<Foo> {
-//
-// Foo(scoped_refptr<SequencedTaskRunner> task_runner)
-// : RefCountedDeleteOnSequence<Foo>(std::move(task_runner)) {}
-// ...
-// private:
-// friend class RefCountedDeleteOnSequence<Foo>;
-// friend class DeleteHelper<Foo>;
-//
-// ~Foo();
-// };
-template <class T>
-class RefCountedDeleteOnSequence : public subtle::RefCountedThreadSafeBase {
- public:
- static constexpr subtle::StartRefCountFromZeroTag kRefCountPreference =
- subtle::kStartRefCountFromZeroTag;
-
- // A SequencedTaskRunner for the current sequence can be acquired by calling
- // SequencedTaskRunnerHandle::Get().
- RefCountedDeleteOnSequence(
- scoped_refptr<SequencedTaskRunner> owning_task_runner)
- : subtle::RefCountedThreadSafeBase(T::kRefCountPreference),
- owning_task_runner_(std::move(owning_task_runner)) {
- DCHECK(owning_task_runner_);
- }
-
- void AddRef() const { subtle::RefCountedThreadSafeBase::AddRef(); }
-
- void Release() const {
- if (subtle::RefCountedThreadSafeBase::Release())
- DestructOnSequence();
- }
-
- protected:
- friend class DeleteHelper<RefCountedDeleteOnSequence>;
- ~RefCountedDeleteOnSequence() = default;
-
- SequencedTaskRunner* owning_task_runner() {
- return owning_task_runner_.get();
- }
- const SequencedTaskRunner* owning_task_runner() const {
- return owning_task_runner_.get();
- }
-
- private:
- void DestructOnSequence() const {
- const T* t = static_cast<const T*>(this);
- if (owning_task_runner_->RunsTasksInCurrentSequence())
- delete t;
- else
- owning_task_runner_->DeleteSoon(FROM_HERE, t);
- }
-
- const scoped_refptr<SequencedTaskRunner> owning_task_runner_;
-
- DISALLOW_COPY_AND_ASSIGN(RefCountedDeleteOnSequence);
-};
-
-} // namespace base
-
-#endif // BASE_MEMORY_REF_COUNTED_DELETE_ON_SEQUENCE_H_
diff --git a/base/memory/ref_counted_memory.cc b/base/memory/ref_counted_memory.cc
deleted file mode 100644
index 23a5ffc..0000000
--- a/base/memory/ref_counted_memory.cc
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "base/memory/ref_counted_memory.h"
-
-#include <utility>
-
-#include "base/logging.h"
-#include "base/memory/read_only_shared_memory_region.h"
-
-namespace base {
-
-bool RefCountedMemory::Equals(
- const scoped_refptr<RefCountedMemory>& other) const {
- return other.get() &&
- size() == other->size() &&
- (memcmp(front(), other->front(), size()) == 0);
-}
-
-RefCountedMemory::RefCountedMemory() = default;
-
-RefCountedMemory::~RefCountedMemory() = default;
-
-const unsigned char* RefCountedStaticMemory::front() const {
- return data_;
-}
-
-size_t RefCountedStaticMemory::size() const {
- return length_;
-}
-
-RefCountedStaticMemory::~RefCountedStaticMemory() = default;
-
-RefCountedBytes::RefCountedBytes() = default;
-
-RefCountedBytes::RefCountedBytes(const std::vector<unsigned char>& initializer)
- : data_(initializer) {
-}
-
-RefCountedBytes::RefCountedBytes(const unsigned char* p, size_t size)
- : data_(p, p + size) {}
-
-RefCountedBytes::RefCountedBytes(size_t size) : data_(size, 0) {}
-
-scoped_refptr<RefCountedBytes> RefCountedBytes::TakeVector(
- std::vector<unsigned char>* to_destroy) {
- auto bytes = MakeRefCounted<RefCountedBytes>();
- bytes->data_.swap(*to_destroy);
- return bytes;
-}
-
-const unsigned char* RefCountedBytes::front() const {
- // STL will assert if we do front() on an empty vector, but calling code
- // expects a NULL.
- return size() ? &data_.front() : nullptr;
-}
-
-size_t RefCountedBytes::size() const {
- return data_.size();
-}
-
-RefCountedBytes::~RefCountedBytes() = default;
-
-RefCountedString::RefCountedString() = default;
-
-RefCountedString::~RefCountedString() = default;
-
-// static
-scoped_refptr<RefCountedString> RefCountedString::TakeString(
- std::string* to_destroy) {
- auto self = MakeRefCounted<RefCountedString>();
- to_destroy->swap(self->data_);
- return self;
-}
-
-const unsigned char* RefCountedString::front() const {
- return data_.empty() ? nullptr
- : reinterpret_cast<const unsigned char*>(data_.data());
-}
-
-size_t RefCountedString::size() const {
- return data_.size();
-}
-
-RefCountedSharedMemory::RefCountedSharedMemory(
- std::unique_ptr<SharedMemory> shm,
- size_t size)
- : shm_(std::move(shm)), size_(size) {
- DCHECK(shm_);
- DCHECK(shm_->memory());
- DCHECK_GT(size_, 0U);
- DCHECK_LE(size_, shm_->mapped_size());
-}
-
-RefCountedSharedMemory::~RefCountedSharedMemory() = default;
-
-const unsigned char* RefCountedSharedMemory::front() const {
- return static_cast<const unsigned char*>(shm_->memory());
-}
-
-size_t RefCountedSharedMemory::size() const {
- return size_;
-}
-
-RefCountedSharedMemoryMapping::RefCountedSharedMemoryMapping(
- ReadOnlySharedMemoryMapping mapping)
- : mapping_(std::move(mapping)), size_(mapping_.size()) {
- DCHECK_GT(size_, 0U);
-}
-
-RefCountedSharedMemoryMapping::~RefCountedSharedMemoryMapping() = default;
-
-const unsigned char* RefCountedSharedMemoryMapping::front() const {
- return static_cast<const unsigned char*>(mapping_.memory());
-}
-
-size_t RefCountedSharedMemoryMapping::size() const {
- return size_;
-}
-
-// static
-scoped_refptr<RefCountedSharedMemoryMapping>
-RefCountedSharedMemoryMapping::CreateFromWholeRegion(
- const ReadOnlySharedMemoryRegion& region) {
- ReadOnlySharedMemoryMapping mapping = region.Map();
- if (!mapping.IsValid())
- return nullptr;
- return MakeRefCounted<RefCountedSharedMemoryMapping>(std::move(mapping));
-}
-
-} // namespace base
diff --git a/base/memory/ref_counted_memory.h b/base/memory/ref_counted_memory.h
deleted file mode 100644
index 92a7d7b..0000000
--- a/base/memory/ref_counted_memory.h
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright (c) 2012 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 BASE_MEMORY_REF_COUNTED_MEMORY_H_
-#define BASE_MEMORY_REF_COUNTED_MEMORY_H_
-
-#include <stddef.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/base_export.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/shared_memory.h"
-#include "base/memory/shared_memory_mapping.h"
-
-namespace base {
-
-class ReadOnlySharedMemoryRegion;
-
-// A generic interface to memory. This object is reference counted because most
-// of its subclasses own the data they carry, and this interface needs to
-// support heterogeneous containers of these different types of memory.
-class BASE_EXPORT RefCountedMemory
- : public RefCountedThreadSafe<RefCountedMemory> {
- public:
- // Retrieves a pointer to the beginning of the data we point to. If the data
- // is empty, this will return NULL.
- virtual const unsigned char* front() const = 0;
-
- // Size of the memory pointed to.
- virtual size_t size() const = 0;
-
- // Returns true if |other| is byte for byte equal.
- bool Equals(const scoped_refptr<RefCountedMemory>& other) const;
-
- // Handy method to simplify calling front() with a reinterpret_cast.
- template<typename T> const T* front_as() const {
- return reinterpret_cast<const T*>(front());
- }
-
- protected:
- friend class RefCountedThreadSafe<RefCountedMemory>;
- RefCountedMemory();
- virtual ~RefCountedMemory();
-};
-
-// An implementation of RefCountedMemory, where the ref counting does not
-// matter.
-class BASE_EXPORT RefCountedStaticMemory : public RefCountedMemory {
- public:
- RefCountedStaticMemory() : data_(nullptr), length_(0) {}
- RefCountedStaticMemory(const void* data, size_t length)
- : data_(static_cast<const unsigned char*>(length ? data : nullptr)),
- length_(length) {}
-
- // RefCountedMemory:
- const unsigned char* front() const override;
- size_t size() const override;
-
- private:
- ~RefCountedStaticMemory() override;
-
- const unsigned char* data_;
- size_t length_;
-
- DISALLOW_COPY_AND_ASSIGN(RefCountedStaticMemory);
-};
-
-// An implementation of RefCountedMemory, where the data is stored in a STL
-// vector.
-class BASE_EXPORT RefCountedBytes : public RefCountedMemory {
- public:
- RefCountedBytes();
-
- // Constructs a RefCountedBytes object by copying from |initializer|.
- explicit RefCountedBytes(const std::vector<unsigned char>& initializer);
-
- // Constructs a RefCountedBytes object by copying |size| bytes from |p|.
- RefCountedBytes(const unsigned char* p, size_t size);
-
- // Constructs a RefCountedBytes object by zero-initializing a new vector of
- // |size| bytes.
- explicit RefCountedBytes(size_t size);
-
- // Constructs a RefCountedBytes object by performing a swap. (To non
- // destructively build a RefCountedBytes, use the constructor that takes a
- // vector.)
- static scoped_refptr<RefCountedBytes> TakeVector(
- std::vector<unsigned char>* to_destroy);
-
- // RefCountedMemory:
- const unsigned char* front() const override;
- size_t size() const override;
-
- const std::vector<unsigned char>& data() const { return data_; }
- std::vector<unsigned char>& data() { return data_; }
-
- // Non-const versions of front() and front_as() that are simply shorthand for
- // data().data().
- unsigned char* front() { return data_.data(); }
- template <typename T>
- T* front_as() {
- return reinterpret_cast<T*>(front());
- }
-
- private:
- ~RefCountedBytes() override;
-
- std::vector<unsigned char> data_;
-
- DISALLOW_COPY_AND_ASSIGN(RefCountedBytes);
-};
-
-// An implementation of RefCountedMemory, where the bytes are stored in a STL
-// string. Use this if your data naturally arrives in that format.
-class BASE_EXPORT RefCountedString : public RefCountedMemory {
- public:
- RefCountedString();
-
- // Constructs a RefCountedString object by performing a swap. (To non
- // destructively build a RefCountedString, use the default constructor and
- // copy into object->data()).
- static scoped_refptr<RefCountedString> TakeString(std::string* to_destroy);
-
- // RefCountedMemory:
- const unsigned char* front() const override;
- size_t size() const override;
-
- const std::string& data() const { return data_; }
- std::string& data() { return data_; }
-
- private:
- ~RefCountedString() override;
-
- std::string data_;
-
- DISALLOW_COPY_AND_ASSIGN(RefCountedString);
-};
-
-// An implementation of RefCountedMemory, where the bytes are stored in
-// SharedMemory.
-class BASE_EXPORT RefCountedSharedMemory : public RefCountedMemory {
- public:
- // Constructs a RefCountedMemory object by taking ownership of an already
- // mapped SharedMemory object.
- RefCountedSharedMemory(std::unique_ptr<SharedMemory> shm, size_t size);
-
- // RefCountedMemory:
- const unsigned char* front() const override;
- size_t size() const override;
-
- private:
- ~RefCountedSharedMemory() override;
-
- const std::unique_ptr<SharedMemory> shm_;
- const size_t size_;
-
- DISALLOW_COPY_AND_ASSIGN(RefCountedSharedMemory);
-};
-
-// An implementation of RefCountedMemory, where the bytes are stored in
-// ReadOnlySharedMemoryMapping.
-class BASE_EXPORT RefCountedSharedMemoryMapping : public RefCountedMemory {
- public:
- // Constructs a RefCountedMemory object by taking ownership of an already
- // mapped ReadOnlySharedMemoryMapping object.
- explicit RefCountedSharedMemoryMapping(ReadOnlySharedMemoryMapping mapping);
-
- // Convenience method to map all of |region| and take ownership of the
- // mapping. Returns an empty scoped_refptr if the map operation fails.
- static scoped_refptr<RefCountedSharedMemoryMapping> CreateFromWholeRegion(
- const ReadOnlySharedMemoryRegion& region);
-
- // RefCountedMemory:
- const unsigned char* front() const override;
- size_t size() const override;
-
- private:
- ~RefCountedSharedMemoryMapping() override;
-
- const ReadOnlySharedMemoryMapping mapping_;
- const size_t size_;
-
- DISALLOW_COPY_AND_ASSIGN(RefCountedSharedMemoryMapping);
-};
-
-} // namespace base
-
-#endif // BASE_MEMORY_REF_COUNTED_MEMORY_H_
diff --git a/base/memory/shared_memory.h b/base/memory/shared_memory.h
deleted file mode 100644
index aa1f682..0000000
--- a/base/memory/shared_memory.h
+++ /dev/null
@@ -1,254 +0,0 @@
-// Copyright (c) 2012 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 BASE_MEMORY_SHARED_MEMORY_H_
-#define BASE_MEMORY_SHARED_MEMORY_H_
-
-#include <stddef.h>
-
-#include <string>
-
-#include "base/base_export.h"
-#include "base/hash.h"
-#include "base/macros.h"
-#include "base/memory/shared_memory_handle.h"
-#include "base/process/process_handle.h"
-#include "base/strings/string16.h"
-#include "build_config.h"
-
-#if defined(OS_POSIX) || defined(OS_FUCHSIA)
-#include <stdio.h>
-#include <sys/types.h>
-#include <semaphore.h>
-#include "base/file_descriptor_posix.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_file.h"
-#endif
-
-#if defined(OS_WIN)
-#include "base/win/scoped_handle.h"
-#endif
-
-namespace base {
-
-class FilePath;
-
-// Options for creating a shared memory object.
-struct BASE_EXPORT SharedMemoryCreateOptions {
-#if defined(OS_MACOSX) && !defined(OS_IOS)
- // The type of OS primitive that should back the SharedMemory object.
- SharedMemoryHandle::Type type = SharedMemoryHandle::MACH;
-#elif !defined(OS_FUCHSIA)
- // DEPRECATED (crbug.com/345734):
- // If NULL, the object is anonymous. This pointer is owned by the caller
- // and must live through the call to Create().
- const std::string* name_deprecated = nullptr;
-
- // DEPRECATED (crbug.com/345734):
- // If true, and the shared memory already exists, Create() will open the
- // existing shared memory and ignore the size parameter. If false,
- // shared memory must not exist. This flag is meaningless unless
- // name_deprecated is non-NULL.
- bool open_existing_deprecated = false;
-#endif // defined(OS_MACOSX) && !defined(OS_IOS)
-
- // Size of the shared memory object to be created.
- // When opening an existing object, this has no effect.
- size_t size = 0;
-
- // If true, mappings might need to be made executable later.
- bool executable = false;
-
- // If true, the file can be shared read-only to a process.
- bool share_read_only = false;
-};
-
-// Platform abstraction for shared memory.
-// SharedMemory consumes a SharedMemoryHandle [potentially one that it created]
-// to map a shared memory OS resource into the virtual address space of the
-// current process.
-class BASE_EXPORT SharedMemory {
- public:
- SharedMemory();
-
-#if defined(OS_WIN)
- // Similar to the default constructor, except that this allows for
- // calling LockDeprecated() to acquire the named mutex before either Create or
- // Open are called on Windows.
- explicit SharedMemory(const string16& name);
-#endif
-
- // Create a new SharedMemory object from an existing, open
- // shared memory file.
- //
- // WARNING: This does not reduce the OS-level permissions on the handle; it
- // only affects how the SharedMemory will be mmapped. Use
- // GetReadOnlyHandle to drop permissions. TODO(jln,jyasskin): DCHECK
- // that |read_only| matches the permissions of the handle.
- SharedMemory(const SharedMemoryHandle& handle, bool read_only);
-
- // Closes any open files.
- ~SharedMemory();
-
- // Return true iff the given handle is valid (i.e. not the distingished
- // invalid value; NULL for a HANDLE and -1 for a file descriptor)
- static bool IsHandleValid(const SharedMemoryHandle& handle);
-
- // Closes a shared memory handle.
- static void CloseHandle(const SharedMemoryHandle& handle);
-
- // Returns the maximum number of handles that can be open at once per process.
- static size_t GetHandleLimit();
-
- // Duplicates The underlying OS primitive. Returns an invalid handle on
- // failure. The caller is responsible for destroying the duplicated OS
- // primitive.
- static SharedMemoryHandle DuplicateHandle(const SharedMemoryHandle& handle);
-
-#if defined(OS_POSIX)
- // This method requires that the SharedMemoryHandle is backed by a POSIX fd.
- static int GetFdFromSharedMemoryHandle(const SharedMemoryHandle& handle);
-#endif
-
- // Creates a shared memory object as described by the options struct.
- // Returns true on success and false on failure.
- bool Create(const SharedMemoryCreateOptions& options);
-
- // Creates and maps an anonymous shared memory segment of size size.
- // Returns true on success and false on failure.
- bool CreateAndMapAnonymous(size_t size);
-
- // Creates an anonymous shared memory segment of size size.
- // Returns true on success and false on failure.
- bool CreateAnonymous(size_t size) {
- SharedMemoryCreateOptions options;
- options.size = size;
- return Create(options);
- }
-
-#if (!defined(OS_MACOSX) || defined(OS_IOS)) && !defined(OS_FUCHSIA)
- // DEPRECATED (crbug.com/345734):
- // Creates or opens a shared memory segment based on a name.
- // If open_existing is true, and the shared memory already exists,
- // opens the existing shared memory and ignores the size parameter.
- // If open_existing is false, shared memory must not exist.
- // size is the size of the block to be created.
- // Returns true on success, false on failure.
- bool CreateNamedDeprecated(
- const std::string& name, bool open_existing, size_t size) {
- SharedMemoryCreateOptions options;
- options.name_deprecated = &name;
- options.open_existing_deprecated = open_existing;
- options.size = size;
- return Create(options);
- }
-
- // Deletes resources associated with a shared memory segment based on name.
- // Not all platforms require this call.
- bool Delete(const std::string& name);
-
- // Opens a shared memory segment based on a name.
- // If read_only is true, opens for read-only access.
- // Returns true on success, false on failure.
- bool Open(const std::string& name, bool read_only);
-#endif // !defined(OS_MACOSX) || defined(OS_IOS)
-
- // Maps the shared memory into the caller's address space.
- // Returns true on success, false otherwise. The memory address
- // is accessed via the memory() accessor. The mapped address is guaranteed to
- // have an alignment of at least MAP_MINIMUM_ALIGNMENT. This method will fail
- // if this object is currently mapped.
- bool Map(size_t bytes) {
- return MapAt(0, bytes);
- }
-
- // Same as above, but with |offset| to specify from begining of the shared
- // memory block to map.
- // |offset| must be alignent to value of |SysInfo::VMAllocationGranularity()|.
- bool MapAt(off_t offset, size_t bytes);
- enum { MAP_MINIMUM_ALIGNMENT = 32 };
-
- // Unmaps the shared memory from the caller's address space.
- // Returns true if successful; returns false on error or if the
- // memory is not mapped.
- bool Unmap();
-
- // The size requested when the map is first created.
- size_t requested_size() const { return requested_size_; }
-
- // The actual size of the mapped memory (may be larger than requested).
- size_t mapped_size() const { return mapped_size_; }
-
- // Gets a pointer to the opened memory space if it has been
- // Mapped via Map(). Returns NULL if it is not mapped.
- void* memory() const { return memory_; }
-
- // Returns the underlying OS handle for this segment.
- // Use of this handle for anything other than an opaque
- // identifier is not portable.
- SharedMemoryHandle handle() const;
-
- // Returns the underlying OS handle for this segment. The caller takes
- // ownership of the handle and memory is unmapped. This is equivalent to
- // duplicating the handle and then calling Unmap() and Close() on this object,
- // without the overhead of duplicating the handle.
- SharedMemoryHandle TakeHandle();
-
- // Closes the open shared memory segment. The memory will remain mapped if
- // it was previously mapped.
- // It is safe to call Close repeatedly.
- void Close();
-
- // Returns a read-only handle to this shared memory region. The caller takes
- // ownership of the handle. For POSIX handles, CHECK-fails if the region
- // wasn't Created or Opened with share_read_only=true, which is required to
- // make the handle read-only. When the handle is passed to the IPC subsystem,
- // that takes ownership of the handle. As such, it's not valid to pass the
- // sample handle to the IPC subsystem twice. Returns an invalid handle on
- // failure.
- SharedMemoryHandle GetReadOnlyHandle() const;
-
- // Returns an ID for the mapped region. This is ID of the SharedMemoryHandle
- // that was mapped. The ID is valid even after the SharedMemoryHandle is
- // Closed, as long as the region is not unmapped.
- const UnguessableToken& mapped_id() const { return mapped_id_; }
-
- private:
-#if defined(OS_POSIX) && !defined(OS_NACL) && !defined(OS_ANDROID) && \
- (!defined(OS_MACOSX) || defined(OS_IOS))
- bool FilePathForMemoryName(const std::string& mem_name, FilePath* path);
-#endif
-
-#if defined(OS_WIN)
- // If true indicates this came from an external source so needs extra checks
- // before being mapped.
- bool external_section_ = false;
- string16 name_;
-#elif !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
- // If valid, points to the same memory region as shm_, but with readonly
- // permissions.
- SharedMemoryHandle readonly_shm_;
-#endif
-
-#if defined(OS_MACOSX) && !defined(OS_IOS)
- // The mechanism by which the memory is mapped. Only valid if |memory_| is not
- // |nullptr|.
- SharedMemoryHandle::Type mapped_memory_mechanism_ = SharedMemoryHandle::MACH;
-#endif
-
- // The OS primitive that backs the shared memory region.
- SharedMemoryHandle shm_;
-
- size_t mapped_size_ = 0;
- void* memory_ = nullptr;
- bool read_only_ = false;
- size_t requested_size_ = 0;
- base::UnguessableToken mapped_id_;
-
- DISALLOW_COPY_AND_ASSIGN(SharedMemory);
-};
-
-} // namespace base
-
-#endif // BASE_MEMORY_SHARED_MEMORY_H_
diff --git a/base/memory/shared_memory_fuchsia.cc b/base/memory/shared_memory_fuchsia.cc
deleted file mode 100644
index 4036bf6..0000000
--- a/base/memory/shared_memory_fuchsia.cc
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2017 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.
-
-#include "base/memory/shared_memory.h"
-
-#include <limits>
-
-#include <zircon/process.h>
-#include <zircon/rights.h>
-#include <zircon/syscalls.h>
-
-#include "base/bits.h"
-#include "base/fuchsia/scoped_zx_handle.h"
-#include "base/logging.h"
-#include "base/memory/shared_memory_tracker.h"
-#include "base/process/process_metrics.h"
-
-namespace base {
-
-SharedMemory::SharedMemory() {}
-
-SharedMemory::SharedMemory(const SharedMemoryHandle& handle, bool read_only)
- : shm_(handle), read_only_(read_only) {}
-
-SharedMemory::~SharedMemory() {
- Unmap();
- Close();
-}
-
-// static
-bool SharedMemory::IsHandleValid(const SharedMemoryHandle& handle) {
- return handle.IsValid();
-}
-
-// static
-void SharedMemory::CloseHandle(const SharedMemoryHandle& handle) {
- DCHECK(handle.IsValid());
- handle.Close();
-}
-
-// static
-size_t SharedMemory::GetHandleLimit() {
- // Duplicated from the internal Magenta kernel constant kMaxHandleCount
- // (kernel/lib/zircon/zircon.cpp).
- return 256 * 1024u;
-}
-
-bool SharedMemory::CreateAndMapAnonymous(size_t size) {
- return CreateAnonymous(size) && Map(size);
-}
-
-bool SharedMemory::Create(const SharedMemoryCreateOptions& options) {
- requested_size_ = options.size;
- mapped_size_ = bits::Align(requested_size_, GetPageSize());
- ScopedZxHandle vmo;
- zx_status_t status = zx_vmo_create(mapped_size_, 0, vmo.receive());
- if (status != ZX_OK) {
- DLOG(ERROR) << "zx_vmo_create failed, status=" << status;
- return false;
- }
-
- if (!options.executable) {
- // If options.executable isn't set, drop that permission by replacement.
- const int kNoExecFlags = ZX_DEFAULT_VMO_RIGHTS & ~ZX_RIGHT_EXECUTE;
- ScopedZxHandle old_vmo(std::move(vmo));
- status = zx_handle_replace(old_vmo.get(), kNoExecFlags, vmo.receive());
- if (status != ZX_OK) {
- DLOG(ERROR) << "zx_handle_replace() failed: "
- << zx_status_get_string(status);
- return false;
- }
- ignore_result(old_vmo.release());
- }
-
- shm_ = SharedMemoryHandle(vmo.release(), mapped_size_,
- UnguessableToken::Create());
- return true;
-}
-
-bool SharedMemory::MapAt(off_t offset, size_t bytes) {
- if (!shm_.IsValid())
- return false;
-
- if (bytes > static_cast<size_t>(std::numeric_limits<int>::max()))
- return false;
-
- if (memory_)
- return false;
-
- int flags = ZX_VM_FLAG_PERM_READ;
- if (!read_only_)
- flags |= ZX_VM_FLAG_PERM_WRITE;
- uintptr_t addr;
- zx_status_t status = zx_vmar_map(zx_vmar_root_self(), 0, shm_.GetHandle(),
- offset, bytes, flags, &addr);
- if (status != ZX_OK) {
- DLOG(ERROR) << "zx_vmar_map failed, status=" << status;
- return false;
- }
- memory_ = reinterpret_cast<void*>(addr);
-
- mapped_size_ = bytes;
- mapped_id_ = shm_.GetGUID();
- SharedMemoryTracker::GetInstance()->IncrementMemoryUsage(*this);
- return true;
-}
-
-bool SharedMemory::Unmap() {
- if (!memory_)
- return false;
-
- SharedMemoryTracker::GetInstance()->DecrementMemoryUsage(*this);
-
- uintptr_t addr = reinterpret_cast<uintptr_t>(memory_);
- zx_status_t status = zx_vmar_unmap(zx_vmar_root_self(), addr, mapped_size_);
- if (status != ZX_OK) {
- DLOG(ERROR) << "zx_vmar_unmap failed, status=" << status;
- return false;
- }
-
- memory_ = nullptr;
- mapped_id_ = UnguessableToken();
- return true;
-}
-
-void SharedMemory::Close() {
- if (shm_.IsValid()) {
- shm_.Close();
- shm_ = SharedMemoryHandle();
- }
-}
-
-SharedMemoryHandle SharedMemory::handle() const {
- return shm_;
-}
-
-SharedMemoryHandle SharedMemory::TakeHandle() {
- SharedMemoryHandle handle(shm_);
- handle.SetOwnershipPassesToIPC(true);
- Unmap();
- shm_ = SharedMemoryHandle();
- return handle;
-}
-
-SharedMemoryHandle SharedMemory::DuplicateHandle(
- const SharedMemoryHandle& handle) {
- return handle.Duplicate();
-}
-
-SharedMemoryHandle SharedMemory::GetReadOnlyHandle() const {
- zx_handle_t duped_handle;
- const int kNoWriteOrExec =
- ZX_DEFAULT_VMO_RIGHTS &
- ~(ZX_RIGHT_WRITE | ZX_RIGHT_EXECUTE | ZX_RIGHT_SET_PROPERTY);
- zx_status_t status =
- zx_handle_duplicate(shm_.GetHandle(), kNoWriteOrExec, &duped_handle);
- if (status != ZX_OK)
- return SharedMemoryHandle();
-
- SharedMemoryHandle handle(duped_handle, shm_.GetSize(), shm_.GetGUID());
- handle.SetOwnershipPassesToIPC(true);
- return handle;
-}
-
-} // namespace base
diff --git a/base/memory/shared_memory_handle.cc b/base/memory/shared_memory_handle.cc
deleted file mode 100644
index 085bde4..0000000
--- a/base/memory/shared_memory_handle.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017 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.
-
-#include "base/memory/shared_memory_handle.h"
-
-namespace base {
-
-SharedMemoryHandle::SharedMemoryHandle(const SharedMemoryHandle& handle) =
- default;
-
-SharedMemoryHandle& SharedMemoryHandle::operator=(
- const SharedMemoryHandle& handle) = default;
-
-base::UnguessableToken SharedMemoryHandle::GetGUID() const {
- return guid_;
-}
-
-size_t SharedMemoryHandle::GetSize() const {
- return size_;
-}
-
-} // namespace base
diff --git a/base/memory/shared_memory_handle.h b/base/memory/shared_memory_handle.h
deleted file mode 100644
index 18aa816..0000000
--- a/base/memory/shared_memory_handle.h
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright 2015 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 BASE_MEMORY_SHARED_MEMORY_HANDLE_H_
-#define BASE_MEMORY_SHARED_MEMORY_HANDLE_H_
-
-#include <stddef.h>
-
-#include "base/unguessable_token.h"
-#include "build_config.h"
-
-#if defined(OS_WIN)
-#include "base/process/process_handle.h"
-#include "base/win/windows_types.h"
-#elif defined(OS_MACOSX) && !defined(OS_IOS)
-#include <mach/mach.h>
-#include "base/base_export.h"
-#include "base/file_descriptor_posix.h"
-#include "base/macros.h"
-#include "base/process/process_handle.h"
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
-#include <sys/types.h>
-#include "base/file_descriptor_posix.h"
-#endif
-
-namespace base {
-
-// SharedMemoryHandle is the smallest possible IPC-transportable "reference" to
-// a shared memory OS resource. A "reference" can be consumed exactly once [by
-// base::SharedMemory] to map the shared memory OS resource into the virtual
-// address space of the current process.
-// TODO(erikchen): This class should have strong ownership semantics to prevent
-// leaks of the underlying OS resource. https://crbug.com/640840.
-class BASE_EXPORT SharedMemoryHandle {
- public:
- // The default constructor returns an invalid SharedMemoryHandle.
- SharedMemoryHandle();
-
- // Standard copy constructor. The new instance shares the underlying OS
- // primitives.
- SharedMemoryHandle(const SharedMemoryHandle& handle);
-
- // Standard assignment operator. The updated instance shares the underlying
- // OS primitives.
- SharedMemoryHandle& operator=(const SharedMemoryHandle& handle);
-
- // Closes the underlying OS resource.
- // The fact that this method needs to be "const" is an artifact of the
- // original interface for base::SharedMemory::CloseHandle.
- // TODO(erikchen): This doesn't clear the underlying reference, which seems
- // like a bug, but is how this class has always worked. Fix this:
- // https://crbug.com/716072.
- void Close() const;
-
- // Whether ownership of the underlying OS resource is implicitly passed to
- // the IPC subsystem during serialization.
- void SetOwnershipPassesToIPC(bool ownership_passes);
- bool OwnershipPassesToIPC() const;
-
- // Whether the underlying OS resource is valid.
- bool IsValid() const;
-
- // Duplicates the underlying OS resource. Using the return value as a
- // parameter to an IPC message will cause the IPC subsystem to consume the OS
- // resource.
- SharedMemoryHandle Duplicate() const;
-
- // Uniques identifies the shared memory region that the underlying OS resource
- // points to. Multiple SharedMemoryHandles that point to the same shared
- // memory region will have the same GUID. Preserved across IPC.
- base::UnguessableToken GetGUID() const;
-
- // Returns the size of the memory region that SharedMemoryHandle points to.
- size_t GetSize() const;
-
-#if defined(OS_WIN)
- // Takes implicit ownership of |h|.
- // |guid| uniquely identifies the shared memory region pointed to by the
- // underlying OS resource. If the HANDLE is associated with another
- // SharedMemoryHandle, the caller must pass the |guid| of that
- // SharedMemoryHandle. Otherwise, the caller should generate a new
- // UnguessableToken.
- // Passing the wrong |size| has no immediate consequence, but may cause errors
- // when trying to map the SharedMemoryHandle at a later point in time.
- SharedMemoryHandle(HANDLE h, size_t size, const base::UnguessableToken& guid);
- HANDLE GetHandle() const;
-#elif defined(OS_FUCHSIA)
- // Takes implicit ownership of |h|.
- // |guid| uniquely identifies the shared memory region pointed to by the
- // underlying OS resource. If the zx_handle_t is associated with another
- // SharedMemoryHandle, the caller must pass the |guid| of that
- // SharedMemoryHandle. Otherwise, the caller should generate a new
- // UnguessableToken.
- // Passing the wrong |size| has no immediate consequence, but may cause errors
- // when trying to map the SharedMemoryHandle at a later point in time.
- SharedMemoryHandle(zx_handle_t h,
- size_t size,
- const base::UnguessableToken& guid);
- zx_handle_t GetHandle() const;
-#elif defined(OS_MACOSX) && !defined(OS_IOS)
- enum Type {
- // The SharedMemoryHandle is backed by a POSIX fd.
- POSIX,
- // The SharedMemoryHandle is backed by the Mach primitive "memory object".
- MACH,
- };
-
- // Makes a Mach-based SharedMemoryHandle of the given size. On error,
- // subsequent calls to IsValid() return false.
- // Passing the wrong |size| has no immediate consequence, but may cause errors
- // when trying to map the SharedMemoryHandle at a later point in time.
- SharedMemoryHandle(mach_vm_size_t size, const base::UnguessableToken& guid);
-
- // Makes a Mach-based SharedMemoryHandle from |memory_object|, a named entry
- // in the current task. The memory region has size |size|.
- // Passing the wrong |size| has no immediate consequence, but may cause errors
- // when trying to map the SharedMemoryHandle at a later point in time.
- SharedMemoryHandle(mach_port_t memory_object,
- mach_vm_size_t size,
- const base::UnguessableToken& guid);
-
- // Exposed so that the SharedMemoryHandle can be transported between
- // processes.
- mach_port_t GetMemoryObject() const;
-
- // The SharedMemoryHandle must be valid.
- // Returns whether the SharedMemoryHandle was successfully mapped into memory.
- // On success, |memory| is an output variable that contains the start of the
- // mapped memory.
- bool MapAt(off_t offset, size_t bytes, void** memory, bool read_only);
-#elif defined(OS_POSIX)
- // Creates a SharedMemoryHandle from an |fd| supplied from an external
- // service.
- // Passing the wrong |size| has no immediate consequence, but may cause errors
- // when trying to map the SharedMemoryHandle at a later point in time.
- static SharedMemoryHandle ImportHandle(int fd, size_t size);
-
- // Returns the underlying OS resource.
- int GetHandle() const;
-
- // Invalidates [but doesn't close] the underlying OS resource. This will leak
- // unless the caller is careful.
- int Release();
-#endif
-
-#if defined(OS_ANDROID)
- // Marks the current file descriptor as read-only, for the purpose of
- // mapping. This is independent of the region's read-only status.
- void SetReadOnly() { read_only_ = true; }
-
- // Returns true iff the descriptor is to be used for read-only
- // mappings.
- bool IsReadOnly() const { return read_only_; }
-
- // Returns true iff the corresponding region is read-only.
- bool IsRegionReadOnly() const;
-
- // Try to set the region read-only. This will fail any future attempt
- // at read-write mapping.
- bool SetRegionReadOnly() const;
-#endif
-
-#if defined(OS_POSIX)
- // Constructs a SharedMemoryHandle backed by a FileDescriptor. The newly
- // created instance has the same ownership semantics as base::FileDescriptor.
- // This typically means that the SharedMemoryHandle takes ownership of the
- // |fd| if |auto_close| is true. Unfortunately, it's common for existing code
- // to make shallow copies of SharedMemoryHandle, and the one that is finally
- // passed into a base::SharedMemory is the one that "consumes" the fd.
- //
- // |guid| uniquely identifies the shared memory region pointed to by the
- // underlying OS resource. If |file_descriptor| is associated with another
- // SharedMemoryHandle, the caller must pass the |guid| of that
- // SharedMemoryHandle. Otherwise, the caller should generate a new
- // UnguessableToken.
- // Passing the wrong |size| has no immediate consequence, but may cause errors
- // when trying to map the SharedMemoryHandle at a later point in time.
- SharedMemoryHandle(const base::FileDescriptor& file_descriptor,
- size_t size,
- const base::UnguessableToken& guid);
-#endif
-
- private:
-#if defined(OS_WIN)
- HANDLE handle_ = nullptr;
-
- // Whether passing this object as a parameter to an IPC message passes
- // ownership of |handle_| to the IPC stack. This is meant to mimic the
- // behavior of the |auto_close| parameter of FileDescriptor. This member only
- // affects attachment-brokered SharedMemoryHandles.
- // Defaults to |false|.
- bool ownership_passes_to_ipc_ = false;
-#elif defined(OS_FUCHSIA)
- zx_handle_t handle_ = ZX_HANDLE_INVALID;
- bool ownership_passes_to_ipc_ = false;
-#elif defined(OS_MACOSX) && !defined(OS_IOS)
- friend class SharedMemory;
- friend bool CheckReadOnlySharedMemoryHandleForTesting(
- SharedMemoryHandle handle);
-
- Type type_ = MACH;
-
- // Each instance of a SharedMemoryHandle is backed either by a POSIX fd or a
- // mach port. |type_| determines the backing member.
- union {
- FileDescriptor file_descriptor_;
-
- struct {
- mach_port_t memory_object_ = MACH_PORT_NULL;
-
- // Whether passing this object as a parameter to an IPC message passes
- // ownership of |memory_object_| to the IPC stack. This is meant to mimic
- // the behavior of the |auto_close| parameter of FileDescriptor.
- // Defaults to |false|.
- bool ownership_passes_to_ipc_ = false;
- };
- };
-#elif defined(OS_ANDROID)
- friend class SharedMemory;
-
- FileDescriptor file_descriptor_;
- bool read_only_ = false;
-#elif defined(OS_POSIX)
- FileDescriptor file_descriptor_;
-#endif
-
- base::UnguessableToken guid_;
-
- // The size of the region referenced by the SharedMemoryHandle.
- size_t size_ = 0;
-};
-
-} // namespace base
-
-#endif // BASE_MEMORY_SHARED_MEMORY_HANDLE_H_
diff --git a/base/memory/shared_memory_handle_fuchsia.cc b/base/memory/shared_memory_handle_fuchsia.cc
deleted file mode 100644
index eab681f..0000000
--- a/base/memory/shared_memory_handle_fuchsia.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2017 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.
-
-#include "base/memory/shared_memory_handle.h"
-
-#include <zircon/syscalls.h>
-
-#include "base/logging.h"
-#include "base/unguessable_token.h"
-
-namespace base {
-
-SharedMemoryHandle::SharedMemoryHandle() {}
-
-SharedMemoryHandle::SharedMemoryHandle(zx_handle_t h,
- size_t size,
- const base::UnguessableToken& guid)
- : handle_(h), guid_(guid), size_(size) {}
-
-void SharedMemoryHandle::Close() const {
- DCHECK(handle_ != ZX_HANDLE_INVALID);
- zx_handle_close(handle_);
-}
-
-bool SharedMemoryHandle::IsValid() const {
- return handle_ != ZX_HANDLE_INVALID;
-}
-
-SharedMemoryHandle SharedMemoryHandle::Duplicate() const {
- zx_handle_t duped_handle;
- zx_status_t status =
- zx_handle_duplicate(handle_, ZX_RIGHT_SAME_RIGHTS, &duped_handle);
- if (status != ZX_OK)
- return SharedMemoryHandle();
-
- SharedMemoryHandle handle(duped_handle, GetSize(), GetGUID());
- handle.SetOwnershipPassesToIPC(true);
- return handle;
-}
-
-zx_handle_t SharedMemoryHandle::GetHandle() const {
- return handle_;
-}
-
-void SharedMemoryHandle::SetOwnershipPassesToIPC(bool ownership_passes) {
- ownership_passes_to_ipc_ = ownership_passes;
-}
-
-bool SharedMemoryHandle::OwnershipPassesToIPC() const {
- return ownership_passes_to_ipc_;
-}
-
-} // namespace base
diff --git a/base/memory/shared_memory_handle_mac.cc b/base/memory/shared_memory_handle_mac.cc
deleted file mode 100644
index 0e863fa..0000000
--- a/base/memory/shared_memory_handle_mac.cc
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2015 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.
-
-#include "base/memory/shared_memory_handle.h"
-
-#include <mach/mach_vm.h>
-#include <stddef.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-#include "base/mac/mac_util.h"
-#include "base/mac/mach_logging.h"
-#include "base/posix/eintr_wrapper.h"
-#include "base/unguessable_token.h"
-
-namespace base {
-
-SharedMemoryHandle::SharedMemoryHandle() {}
-
-SharedMemoryHandle::SharedMemoryHandle(
- const base::FileDescriptor& file_descriptor,
- size_t size,
- const base::UnguessableToken& guid)
- : type_(POSIX),
- file_descriptor_(file_descriptor),
- guid_(guid),
- size_(size) {}
-
-SharedMemoryHandle::SharedMemoryHandle(mach_vm_size_t size,
- const base::UnguessableToken& guid) {
- type_ = MACH;
- mach_port_t named_right;
- kern_return_t kr = mach_make_memory_entry_64(
- mach_task_self(),
- &size,
- 0, // Address.
- MAP_MEM_NAMED_CREATE | VM_PROT_READ | VM_PROT_WRITE,
- &named_right,
- MACH_PORT_NULL); // Parent handle.
- if (kr != KERN_SUCCESS) {
- memory_object_ = MACH_PORT_NULL;
- return;
- }
-
- memory_object_ = named_right;
- size_ = size;
- ownership_passes_to_ipc_ = false;
- guid_ = guid;
-}
-
-SharedMemoryHandle::SharedMemoryHandle(mach_port_t memory_object,
- mach_vm_size_t size,
- const base::UnguessableToken& guid)
- : type_(MACH),
- memory_object_(memory_object),
- ownership_passes_to_ipc_(false),
- guid_(guid),
- size_(size) {}
-
-SharedMemoryHandle SharedMemoryHandle::Duplicate() const {
- switch (type_) {
- case POSIX: {
- if (!IsValid())
- return SharedMemoryHandle();
- int duped_fd = HANDLE_EINTR(dup(file_descriptor_.fd));
- if (duped_fd < 0)
- return SharedMemoryHandle();
- return SharedMemoryHandle(FileDescriptor(duped_fd, true), size_, guid_);
- }
- case MACH: {
- if (!IsValid())
- return SharedMemoryHandle();
-
- // Increment the ref count.
- kern_return_t kr = mach_port_mod_refs(mach_task_self(), memory_object_,
- MACH_PORT_RIGHT_SEND, 1);
- DCHECK_EQ(kr, KERN_SUCCESS);
- SharedMemoryHandle handle(*this);
- handle.SetOwnershipPassesToIPC(true);
- return handle;
- }
- }
-}
-
-bool SharedMemoryHandle::IsValid() const {
- switch (type_) {
- case POSIX:
- return file_descriptor_.fd >= 0;
- case MACH:
- return memory_object_ != MACH_PORT_NULL;
- }
-}
-
-mach_port_t SharedMemoryHandle::GetMemoryObject() const {
- DCHECK_EQ(type_, MACH);
- return memory_object_;
-}
-
-bool SharedMemoryHandle::MapAt(off_t offset,
- size_t bytes,
- void** memory,
- bool read_only) {
- DCHECK(IsValid());
- switch (type_) {
- case SharedMemoryHandle::POSIX:
- *memory = mmap(nullptr, bytes, PROT_READ | (read_only ? 0 : PROT_WRITE),
- MAP_SHARED, file_descriptor_.fd, offset);
- return *memory != MAP_FAILED;
- case SharedMemoryHandle::MACH:
- kern_return_t kr = mach_vm_map(
- mach_task_self(),
- reinterpret_cast<mach_vm_address_t*>(memory), // Output parameter
- bytes,
- 0, // Alignment mask
- VM_FLAGS_ANYWHERE,
- memory_object_,
- offset,
- FALSE, // Copy
- VM_PROT_READ | (read_only ? 0 : VM_PROT_WRITE), // Current protection
- VM_PROT_WRITE | VM_PROT_READ | VM_PROT_IS_MASK, // Maximum protection
- VM_INHERIT_NONE);
- return kr == KERN_SUCCESS;
- }
-}
-
-void SharedMemoryHandle::Close() const {
- if (!IsValid())
- return;
-
- switch (type_) {
- case POSIX:
- if (IGNORE_EINTR(close(file_descriptor_.fd)) < 0)
- DPLOG(ERROR) << "Error closing fd";
- break;
- case MACH:
- kern_return_t kr = mach_port_deallocate(mach_task_self(), memory_object_);
- if (kr != KERN_SUCCESS)
- MACH_DLOG(ERROR, kr) << "Error deallocating mach port";
- break;
- }
-}
-
-void SharedMemoryHandle::SetOwnershipPassesToIPC(bool ownership_passes) {
- DCHECK_EQ(type_, MACH);
- ownership_passes_to_ipc_ = ownership_passes;
-}
-
-bool SharedMemoryHandle::OwnershipPassesToIPC() const {
- DCHECK_EQ(type_, MACH);
- return ownership_passes_to_ipc_;
-}
-
-} // namespace base
diff --git a/base/memory/shared_memory_handle_posix.cc b/base/memory/shared_memory_handle_posix.cc
deleted file mode 100644
index 09dfb9c..0000000
--- a/base/memory/shared_memory_handle_posix.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2017 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.
-
-#include "base/memory/shared_memory_handle.h"
-
-#include <unistd.h>
-
-#include "base/logging.h"
-#include "base/posix/eintr_wrapper.h"
-#include "base/unguessable_token.h"
-
-namespace base {
-
-SharedMemoryHandle::SharedMemoryHandle() = default;
-
-SharedMemoryHandle::SharedMemoryHandle(
- const base::FileDescriptor& file_descriptor,
- size_t size,
- const base::UnguessableToken& guid)
- : file_descriptor_(file_descriptor), guid_(guid), size_(size) {}
-
-// static
-SharedMemoryHandle SharedMemoryHandle::ImportHandle(int fd, size_t size) {
- SharedMemoryHandle handle;
- handle.file_descriptor_.fd = fd;
- handle.file_descriptor_.auto_close = false;
- handle.guid_ = UnguessableToken::Create();
- handle.size_ = size;
- return handle;
-}
-
-int SharedMemoryHandle::GetHandle() const {
- return file_descriptor_.fd;
-}
-
-bool SharedMemoryHandle::IsValid() const {
- return file_descriptor_.fd >= 0;
-}
-
-void SharedMemoryHandle::Close() const {
- if (IGNORE_EINTR(close(file_descriptor_.fd)) < 0)
- PLOG(ERROR) << "close";
-}
-
-int SharedMemoryHandle::Release() {
- int old_fd = file_descriptor_.fd;
- file_descriptor_.fd = -1;
- return old_fd;
-}
-
-SharedMemoryHandle SharedMemoryHandle::Duplicate() const {
- if (!IsValid())
- return SharedMemoryHandle();
-
- int duped_handle = HANDLE_EINTR(dup(file_descriptor_.fd));
- if (duped_handle < 0)
- return SharedMemoryHandle();
- return SharedMemoryHandle(FileDescriptor(duped_handle, true), GetSize(),
- GetGUID());
-}
-
-void SharedMemoryHandle::SetOwnershipPassesToIPC(bool ownership_passes) {
- file_descriptor_.auto_close = ownership_passes;
-}
-
-bool SharedMemoryHandle::OwnershipPassesToIPC() const {
- return file_descriptor_.auto_close;
-}
-
-} // namespace base
diff --git a/base/memory/shared_memory_handle_win.cc b/base/memory/shared_memory_handle_win.cc
deleted file mode 100644
index 8c11d39..0000000
--- a/base/memory/shared_memory_handle_win.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2015 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.
-
-#include "base/memory/shared_memory_handle.h"
-
-#include "base/logging.h"
-#include "base/unguessable_token.h"
-
-#include <windows.h>
-
-namespace base {
-
-SharedMemoryHandle::SharedMemoryHandle() {}
-
-SharedMemoryHandle::SharedMemoryHandle(HANDLE h,
- size_t size,
- const base::UnguessableToken& guid)
- : handle_(h), guid_(guid), size_(size) {}
-
-void SharedMemoryHandle::Close() const {
- DCHECK(handle_ != nullptr);
- ::CloseHandle(handle_);
-}
-
-bool SharedMemoryHandle::IsValid() const {
- return handle_ != nullptr;
-}
-
-SharedMemoryHandle SharedMemoryHandle::Duplicate() const {
- HANDLE duped_handle;
- ProcessHandle process = GetCurrentProcess();
- BOOL success = ::DuplicateHandle(process, handle_, process, &duped_handle, 0,
- FALSE, DUPLICATE_SAME_ACCESS);
- if (!success)
- return SharedMemoryHandle();
-
- base::SharedMemoryHandle handle(duped_handle, GetSize(), GetGUID());
- handle.SetOwnershipPassesToIPC(true);
- return handle;
-}
-
-HANDLE SharedMemoryHandle::GetHandle() const {
- return handle_;
-}
-
-void SharedMemoryHandle::SetOwnershipPassesToIPC(bool ownership_passes) {
- ownership_passes_to_ipc_ = ownership_passes;
-}
-
-bool SharedMemoryHandle::OwnershipPassesToIPC() const {
- return ownership_passes_to_ipc_;
-}
-
-} // namespace base
diff --git a/base/memory/shared_memory_helper.cc b/base/memory/shared_memory_helper.cc
deleted file mode 100644
index f98b734..0000000
--- a/base/memory/shared_memory_helper.cc
+++ /dev/null
@@ -1,157 +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.
-
-#include "base/memory/shared_memory_helper.h"
-
-#if defined(OS_CHROMEOS)
-#include <sys/resource.h>
-#include <sys/time.h>
-
-#include "base/debug/alias.h"
-#endif // defined(OS_CHROMEOS)
-
-#include "base/threading/thread_restrictions.h"
-
-namespace base {
-
-struct ScopedPathUnlinkerTraits {
- static const FilePath* InvalidValue() { return nullptr; }
-
- static void Free(const FilePath* path) {
- if (unlink(path->value().c_str()))
- PLOG(WARNING) << "unlink";
- }
-};
-
-// Unlinks the FilePath when the object is destroyed.
-using ScopedPathUnlinker =
- ScopedGeneric<const FilePath*, ScopedPathUnlinkerTraits>;
-
-#if !defined(OS_ANDROID)
-bool CreateAnonymousSharedMemory(const SharedMemoryCreateOptions& options,
- ScopedFD* fd,
- ScopedFD* readonly_fd,
- FilePath* path) {
-#if defined(OS_LINUX)
- // It doesn't make sense to have a open-existing private piece of shmem
- DCHECK(!options.open_existing_deprecated);
-#endif // defined(OS_LINUX)
- // Q: Why not use the shm_open() etc. APIs?
- // A: Because they're limited to 4mb on OS X. FFFFFFFUUUUUUUUUUU
- FilePath directory;
- ScopedPathUnlinker path_unlinker;
- if (!GetShmemTempDir(options.executable, &directory))
- return false;
-
- fd->reset(base::CreateAndOpenFdForTemporaryFileInDir(directory, path));
-
- if (!fd->is_valid())
- return false;
-
- // Deleting the file prevents anyone else from mapping it in (making it
- // private), and prevents the need for cleanup (once the last fd is
- // closed, it is truly freed).
- path_unlinker.reset(path);
-
- if (options.share_read_only) {
- // Also open as readonly so that we can GetReadOnlyHandle.
- readonly_fd->reset(HANDLE_EINTR(open(path->value().c_str(), O_RDONLY)));
- if (!readonly_fd->is_valid()) {
- DPLOG(ERROR) << "open(\"" << path->value() << "\", O_RDONLY) failed";
- fd->reset();
- return false;
- }
- }
- return true;
-}
-
-bool PrepareMapFile(ScopedFD fd,
- ScopedFD readonly_fd,
- int* mapped_file,
- int* readonly_mapped_file) {
- DCHECK_EQ(-1, *mapped_file);
- DCHECK_EQ(-1, *readonly_mapped_file);
- if (!fd.is_valid())
- return false;
-
- // This function theoretically can block on the disk, but realistically
- // the temporary files we create will just go into the buffer cache
- // and be deleted before they ever make it out to disk.
- base::ThreadRestrictions::ScopedAllowIO allow_io;
-
- if (readonly_fd.is_valid()) {
- struct stat st = {};
- if (fstat(fd.get(), &st))
- NOTREACHED();
-
- struct stat readonly_st = {};
- if (fstat(readonly_fd.get(), &readonly_st))
- NOTREACHED();
- if (st.st_dev != readonly_st.st_dev || st.st_ino != readonly_st.st_ino) {
- LOG(ERROR) << "writable and read-only inodes don't match; bailing";
- return false;
- }
- }
-
- *mapped_file = HANDLE_EINTR(dup(fd.get()));
- if (*mapped_file == -1) {
- NOTREACHED() << "Call to dup failed, errno=" << errno;
-
-#if defined(OS_CHROMEOS)
- if (errno == EMFILE) {
- // We're out of file descriptors and are probably about to crash somewhere
- // else in Chrome anyway. Let's collect what FD information we can and
- // crash.
- // Added for debugging crbug.com/733718
- int original_fd_limit = 16384;
- struct rlimit rlim;
- if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
- original_fd_limit = rlim.rlim_cur;
- if (rlim.rlim_max > rlim.rlim_cur) {
- // Increase fd limit so breakpad has a chance to write a minidump.
- rlim.rlim_cur = rlim.rlim_max;
- if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) {
- PLOG(ERROR) << "setrlimit() failed";
- }
- }
- } else {
- PLOG(ERROR) << "getrlimit() failed";
- }
-
- const char kFileDataMarker[] = "FDATA";
- char buf[PATH_MAX];
- char fd_path[PATH_MAX];
- char crash_buffer[32 * 1024] = {0};
- char* crash_ptr = crash_buffer;
- base::debug::Alias(crash_buffer);
-
- // Put a marker at the start of our data so we can confirm where it
- // begins.
- crash_ptr = strncpy(crash_ptr, kFileDataMarker, strlen(kFileDataMarker));
- for (int i = original_fd_limit; i >= 0; --i) {
- memset(buf, 0, arraysize(buf));
- memset(fd_path, 0, arraysize(fd_path));
- snprintf(fd_path, arraysize(fd_path) - 1, "/proc/self/fd/%d", i);
- ssize_t count = readlink(fd_path, buf, arraysize(buf) - 1);
- if (count < 0) {
- PLOG(ERROR) << "readlink failed for: " << fd_path;
- continue;
- }
-
- if (crash_ptr + count + 1 < crash_buffer + arraysize(crash_buffer)) {
- crash_ptr = strncpy(crash_ptr, buf, count + 1);
- }
- LOG(ERROR) << i << ": " << buf;
- }
- LOG(FATAL) << "Logged for file descriptor exhaustion, crashing now";
- }
-#endif // defined(OS_CHROMEOS)
- }
- *readonly_mapped_file = readonly_fd.release();
-
- return true;
-}
-#endif // !defined(OS_ANDROID)
-
-} // namespace base
diff --git a/base/memory/shared_memory_helper.h b/base/memory/shared_memory_helper.h
deleted file mode 100644
index 9da810e..0000000
--- a/base/memory/shared_memory_helper.h
+++ /dev/null
@@ -1,36 +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 BASE_MEMORY_SHARED_MEMORY_HELPER_H_
-#define BASE_MEMORY_SHARED_MEMORY_HELPER_H_
-
-#include "base/memory/shared_memory.h"
-#include "build_config.h"
-
-#include <fcntl.h>
-
-namespace base {
-
-#if !defined(OS_ANDROID)
-// Makes a temporary file, fdopens it, and then unlinks it. |fd| is populated
-// with the opened fd. |readonly_fd| is populated with the opened fd if
-// options.share_read_only is true. |path| is populated with the location of
-// the file before it was unlinked.
-// Returns false if there's an unhandled failure.
-bool CreateAnonymousSharedMemory(const SharedMemoryCreateOptions& options,
- ScopedFD* fd,
- ScopedFD* readonly_fd,
- FilePath* path);
-
-// Takes the outputs of CreateAnonymousSharedMemory and maps them properly to
-// |mapped_file| or |readonly_mapped_file|, depending on which one is populated.
-bool PrepareMapFile(ScopedFD fd,
- ScopedFD readonly_fd,
- int* mapped_file,
- int* readonly_mapped_file);
-#endif // !defined(OS_ANDROID)
-
-} // namespace base
-
-#endif // BASE_MEMORY_SHARED_MEMORY_HELPER_H_
diff --git a/base/memory/shared_memory_mac.cc b/base/memory/shared_memory_mac.cc
deleted file mode 100644
index 5e9e8fc..0000000
--- a/base/memory/shared_memory_mac.cc
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "base/memory/shared_memory.h"
-
-#include <errno.h>
-#include <mach/mach_vm.h>
-#include <stddef.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "base/files/file_util.h"
-#include "base/files/scoped_file.h"
-#include "base/logging.h"
-#include "base/mac/foundation_util.h"
-#include "base/mac/mac_util.h"
-#include "base/mac/scoped_mach_vm.h"
-#include "base/memory/shared_memory_helper.h"
-#include "base/memory/shared_memory_tracker.h"
-#include "base/posix/eintr_wrapper.h"
-#include "base/posix/safe_strerror.h"
-#include "base/process/process_metrics.h"
-#include "base/scoped_generic.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/threading/thread_restrictions.h"
-#include "base/unguessable_token.h"
-#include "build_config.h"
-
-#if defined(OS_IOS)
-#error "MacOS only - iOS uses shared_memory_posix.cc"
-#endif
-
-namespace base {
-
-namespace {
-
-// Returns whether the operation succeeded.
-// |new_handle| is an output variable, populated on success. The caller takes
-// ownership of the underlying memory object.
-// |handle| is the handle to copy.
-// If |handle| is already mapped, |mapped_addr| is its mapped location.
-// Otherwise, |mapped_addr| should be |nullptr|.
-bool MakeMachSharedMemoryHandleReadOnly(SharedMemoryHandle* new_handle,
- SharedMemoryHandle handle,
- void* mapped_addr) {
- if (!handle.IsValid())
- return false;
-
- size_t size = handle.GetSize();
-
- // Map if necessary.
- void* temp_addr = mapped_addr;
- base::mac::ScopedMachVM scoper;
- if (!temp_addr) {
- // Intentionally lower current prot and max prot to |VM_PROT_READ|.
- kern_return_t kr = mach_vm_map(
- mach_task_self(), reinterpret_cast<mach_vm_address_t*>(&temp_addr),
- size, 0, VM_FLAGS_ANYWHERE, handle.GetMemoryObject(), 0, FALSE,
- VM_PROT_READ, VM_PROT_READ, VM_INHERIT_NONE);
- if (kr != KERN_SUCCESS)
- return false;
- scoper.reset(reinterpret_cast<vm_address_t>(temp_addr),
- mach_vm_round_page(size));
- }
-
- // Make new memory object.
- mach_port_t named_right;
- kern_return_t kr = mach_make_memory_entry_64(
- mach_task_self(), reinterpret_cast<memory_object_size_t*>(&size),
- reinterpret_cast<memory_object_offset_t>(temp_addr), VM_PROT_READ,
- &named_right, MACH_PORT_NULL);
- if (kr != KERN_SUCCESS)
- return false;
-
- *new_handle = SharedMemoryHandle(named_right, size, handle.GetGUID());
- return true;
-}
-
-} // namespace
-
-SharedMemory::SharedMemory() {}
-
-SharedMemory::SharedMemory(const SharedMemoryHandle& handle, bool read_only)
- : mapped_memory_mechanism_(SharedMemoryHandle::POSIX),
- shm_(handle),
- read_only_(read_only) {}
-
-SharedMemory::~SharedMemory() {
- Unmap();
- Close();
-}
-
-// static
-bool SharedMemory::IsHandleValid(const SharedMemoryHandle& handle) {
- return handle.IsValid();
-}
-
-// static
-void SharedMemory::CloseHandle(const SharedMemoryHandle& handle) {
- handle.Close();
-}
-
-// static
-size_t SharedMemory::GetHandleLimit() {
- return GetMaxFds();
-}
-
-// static
-SharedMemoryHandle SharedMemory::DuplicateHandle(
- const SharedMemoryHandle& handle) {
- return handle.Duplicate();
-}
-
-// static
-int SharedMemory::GetFdFromSharedMemoryHandle(
- const SharedMemoryHandle& handle) {
- return handle.file_descriptor_.fd;
-}
-
-bool SharedMemory::CreateAndMapAnonymous(size_t size) {
- return CreateAnonymous(size) && Map(size);
-}
-
-// Chromium mostly only uses the unique/private shmem as specified by
-// "name == L"". The exception is in the StatsTable.
-bool SharedMemory::Create(const SharedMemoryCreateOptions& options) {
- DCHECK(!shm_.IsValid());
- if (options.size == 0)
- return false;
-
- if (options.size > static_cast<size_t>(std::numeric_limits<int>::max()))
- return false;
-
- if (options.type == SharedMemoryHandle::MACH) {
- shm_ = SharedMemoryHandle(options.size, UnguessableToken::Create());
- requested_size_ = options.size;
- return shm_.IsValid();
- }
-
- // This function theoretically can block on the disk. Both profiling of real
- // users and local instrumentation shows that this is a real problem.
- // https://code.google.com/p/chromium/issues/detail?id=466437
- ThreadRestrictions::ScopedAllowIO allow_io;
-
- ScopedFD fd;
- ScopedFD readonly_fd;
-
- FilePath path;
- bool result = CreateAnonymousSharedMemory(options, &fd, &readonly_fd, &path);
- if (!result)
- return false;
- // Should be guaranteed by CreateAnonymousSharedMemory().
- DCHECK(fd.is_valid());
-
- // Get current size.
- struct stat stat;
- if (fstat(fd.get(), &stat) != 0)
- return false;
- const size_t current_size = stat.st_size;
- if (current_size != options.size) {
- if (HANDLE_EINTR(ftruncate(fd.get(), options.size)) != 0)
- return false;
- }
- requested_size_ = options.size;
-
- int mapped_file = -1;
- int readonly_mapped_file = -1;
- result = PrepareMapFile(std::move(fd), std::move(readonly_fd), &mapped_file,
- &readonly_mapped_file);
- shm_ = SharedMemoryHandle(FileDescriptor(mapped_file, false), options.size,
- UnguessableToken::Create());
- readonly_shm_ =
- SharedMemoryHandle(FileDescriptor(readonly_mapped_file, false),
- options.size, shm_.GetGUID());
- return result;
-}
-
-bool SharedMemory::MapAt(off_t offset, size_t bytes) {
- if (!shm_.IsValid())
- return false;
- if (bytes > static_cast<size_t>(std::numeric_limits<int>::max()))
- return false;
- if (memory_)
- return false;
-
- bool success = shm_.MapAt(offset, bytes, &memory_, read_only_);
- if (success) {
- mapped_size_ = bytes;
- DCHECK_EQ(0U, reinterpret_cast<uintptr_t>(memory_) &
- (SharedMemory::MAP_MINIMUM_ALIGNMENT - 1));
- mapped_memory_mechanism_ = shm_.type_;
- mapped_id_ = shm_.GetGUID();
- SharedMemoryTracker::GetInstance()->IncrementMemoryUsage(*this);
- } else {
- memory_ = nullptr;
- }
-
- return success;
-}
-
-bool SharedMemory::Unmap() {
- if (!memory_)
- return false;
-
- SharedMemoryTracker::GetInstance()->DecrementMemoryUsage(*this);
- switch (mapped_memory_mechanism_) {
- case SharedMemoryHandle::POSIX:
- munmap(memory_, mapped_size_);
- break;
- case SharedMemoryHandle::MACH:
- mach_vm_deallocate(mach_task_self(),
- reinterpret_cast<mach_vm_address_t>(memory_),
- mapped_size_);
- break;
- }
- memory_ = nullptr;
- mapped_size_ = 0;
- mapped_id_ = UnguessableToken();
- return true;
-}
-
-SharedMemoryHandle SharedMemory::handle() const {
- return shm_;
-}
-
-SharedMemoryHandle SharedMemory::TakeHandle() {
- SharedMemoryHandle dup = DuplicateHandle(handle());
- Unmap();
- Close();
- return dup;
-}
-
-void SharedMemory::Close() {
- shm_.Close();
- shm_ = SharedMemoryHandle();
- if (shm_.type_ == SharedMemoryHandle::POSIX) {
- if (readonly_shm_.IsValid()) {
- readonly_shm_.Close();
- readonly_shm_ = SharedMemoryHandle();
- }
- }
-}
-
-SharedMemoryHandle SharedMemory::GetReadOnlyHandle() const {
- if (shm_.type_ == SharedMemoryHandle::POSIX) {
- // We could imagine re-opening the file from /dev/fd, but that can't make it
- // readonly on Mac: https://codereview.chromium.org/27265002/#msg10.
- CHECK(readonly_shm_.IsValid());
- return readonly_shm_.Duplicate();
- }
-
- DCHECK(shm_.IsValid());
- SharedMemoryHandle new_handle;
- bool success = MakeMachSharedMemoryHandleReadOnly(&new_handle, shm_, memory_);
- if (success)
- new_handle.SetOwnershipPassesToIPC(true);
- return new_handle;
-}
-
-} // namespace base
diff --git a/base/memory/shared_memory_mapping.cc b/base/memory/shared_memory_mapping.cc
deleted file mode 100644
index 878a012..0000000
--- a/base/memory/shared_memory_mapping.cc
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2018 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.
-
-#include "base/memory/shared_memory_mapping.h"
-
-#include <utility>
-
-#include "base/logging.h"
-#include "base/memory/shared_memory_tracker.h"
-#include "base/unguessable_token.h"
-#include "build_config.h"
-
-#if defined(OS_POSIX)
-#include <sys/mman.h>
-#endif
-
-#if defined(OS_WIN)
-#include <aclapi.h>
-#endif
-
-#if defined(OS_MACOSX) && !defined(OS_IOS)
-#include <mach/mach_vm.h>
-#include "base/mac/mach_logging.h"
-#endif
-
-#if defined(OS_FUCHSIA)
-#include <zircon/process.h>
-#include <zircon/status.h>
-#include <zircon/syscalls.h>
-#endif
-
-namespace base {
-
-SharedMemoryMapping::SharedMemoryMapping() = default;
-
-SharedMemoryMapping::SharedMemoryMapping(SharedMemoryMapping&& mapping)
- : memory_(mapping.memory_),
- size_(mapping.size_),
- mapped_size_(mapping.mapped_size_),
- guid_(mapping.guid_) {
- mapping.memory_ = nullptr;
-}
-
-SharedMemoryMapping& SharedMemoryMapping::operator=(
- SharedMemoryMapping&& mapping) {
- Unmap();
- memory_ = mapping.memory_;
- size_ = mapping.size_;
- mapped_size_ = mapping.mapped_size_;
- guid_ = mapping.guid_;
- mapping.memory_ = nullptr;
- return *this;
-}
-
-SharedMemoryMapping::~SharedMemoryMapping() {
- Unmap();
-}
-
-SharedMemoryMapping::SharedMemoryMapping(void* memory,
- size_t size,
- size_t mapped_size,
- const UnguessableToken& guid)
- : memory_(memory), size_(size), mapped_size_(mapped_size), guid_(guid) {
- SharedMemoryTracker::GetInstance()->IncrementMemoryUsage(*this);
-}
-
-void SharedMemoryMapping::Unmap() {
- if (!IsValid())
- return;
-
- SharedMemoryTracker::GetInstance()->DecrementMemoryUsage(*this);
-#if defined(OS_WIN)
- if (!UnmapViewOfFile(memory_))
- DPLOG(ERROR) << "UnmapViewOfFile";
-#elif defined(OS_FUCHSIA)
- uintptr_t addr = reinterpret_cast<uintptr_t>(memory_);
- zx_status_t status = zx_vmar_unmap(zx_vmar_root_self(), addr, size_);
- DLOG_IF(ERROR, status != ZX_OK)
- << "zx_vmar_unmap failed: " << zx_status_get_string(status);
-#elif defined(OS_MACOSX) && !defined(OS_IOS)
- kern_return_t kr = mach_vm_deallocate(
- mach_task_self(), reinterpret_cast<mach_vm_address_t>(memory_), size_);
- MACH_DLOG_IF(ERROR, kr != KERN_SUCCESS, kr) << "mach_vm_deallocate";
-#else
- if (munmap(memory_, size_) < 0)
- DPLOG(ERROR) << "munmap";
-#endif
-}
-
-ReadOnlySharedMemoryMapping::ReadOnlySharedMemoryMapping() = default;
-ReadOnlySharedMemoryMapping::ReadOnlySharedMemoryMapping(
- ReadOnlySharedMemoryMapping&&) = default;
-ReadOnlySharedMemoryMapping& ReadOnlySharedMemoryMapping::operator=(
- ReadOnlySharedMemoryMapping&&) = default;
-ReadOnlySharedMemoryMapping::ReadOnlySharedMemoryMapping(
- void* address,
- size_t size,
- size_t mapped_size,
- const UnguessableToken& guid)
- : SharedMemoryMapping(address, size, mapped_size, guid) {}
-
-WritableSharedMemoryMapping::WritableSharedMemoryMapping() = default;
-WritableSharedMemoryMapping::WritableSharedMemoryMapping(
- WritableSharedMemoryMapping&&) = default;
-WritableSharedMemoryMapping& WritableSharedMemoryMapping::operator=(
- WritableSharedMemoryMapping&&) = default;
-WritableSharedMemoryMapping::WritableSharedMemoryMapping(
- void* address,
- size_t size,
- size_t mapped_size,
- const UnguessableToken& guid)
- : SharedMemoryMapping(address, size, mapped_size, guid) {}
-
-} // namespace base
diff --git a/base/memory/shared_memory_mapping.h b/base/memory/shared_memory_mapping.h
deleted file mode 100644
index ace4c15..0000000
--- a/base/memory/shared_memory_mapping.h
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2018 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 BASE_MEMORY_SHARED_MEMORY_MAPPING_H_
-#define BASE_MEMORY_SHARED_MEMORY_MAPPING_H_
-
-#include <cstddef>
-
-#include "base/macros.h"
-#include "base/unguessable_token.h"
-
-namespace base {
-
-namespace subtle {
-class PlatformSharedMemoryRegion;
-} // namespace subtle
-
-// Base class for scoped handles to a shared memory mapping created from a
-// shared memory region. Created shared memory mappings remain valid even if the
-// creator region is transferred or destroyed.
-//
-// Each mapping has an UnguessableToken that identifies the shared memory region
-// it was created from. This is used for memory metrics, to avoid overcounting
-// shared memory.
-class BASE_EXPORT SharedMemoryMapping {
- public:
- // Default constructor initializes an invalid instance.
- SharedMemoryMapping();
-
- // Move operations are allowed.
- SharedMemoryMapping(SharedMemoryMapping&& mapping);
- SharedMemoryMapping& operator=(SharedMemoryMapping&& mapping);
-
- // Unmaps the region if the mapping is valid.
- virtual ~SharedMemoryMapping();
-
- // Returns true iff the mapping is valid. False means there is no
- // corresponding area of memory.
- bool IsValid() const { return memory_ != nullptr; }
-
- // Returns the logical size of the mapping in bytes. This is precisely the
- // size requested by whoever created the mapping, and it is always less than
- // or equal to |mapped_size()|. This is undefined for invalid instances.
- size_t size() const {
- DCHECK(IsValid());
- return size_;
- }
-
- // Returns the actual size of the mapping in bytes. This is always at least
- // as large as |size()| but may be larger due to platform mapping alignment
- // constraints. This is undefined for invalid instances.
- size_t mapped_size() const {
- DCHECK(IsValid());
- return mapped_size_;
- }
-
- // Returns 128-bit GUID of the region this mapping belongs to.
- const UnguessableToken& guid() const {
- DCHECK(IsValid());
- return guid_;
- }
-
- protected:
- SharedMemoryMapping(void* address,
- size_t size,
- size_t mapped_size,
- const UnguessableToken& guid);
- void* raw_memory_ptr() const { return memory_; }
-
- private:
- friend class SharedMemoryTracker;
-
- void Unmap();
-
- void* memory_ = nullptr;
- size_t size_ = 0;
- size_t mapped_size_ = 0;
- UnguessableToken guid_;
-
- DISALLOW_COPY_AND_ASSIGN(SharedMemoryMapping);
-};
-
-// Class modeling a read-only mapping of a shared memory region into the
-// current process' address space. This is created by ReadOnlySharedMemoryRegion
-// instances.
-class BASE_EXPORT ReadOnlySharedMemoryMapping : public SharedMemoryMapping {
- public:
- // Default constructor initializes an invalid instance.
- ReadOnlySharedMemoryMapping();
-
- // Move operations are allowed.
- ReadOnlySharedMemoryMapping(ReadOnlySharedMemoryMapping&&);
- ReadOnlySharedMemoryMapping& operator=(ReadOnlySharedMemoryMapping&&);
-
- // Returns the base address of the mapping. This is read-only memory. This is
- // page-aligned. This is nullptr for invalid instances.
- const void* memory() const { return raw_memory_ptr(); }
-
- private:
- friend class ReadOnlySharedMemoryRegion;
- ReadOnlySharedMemoryMapping(void* address,
- size_t size,
- size_t mapped_size,
- const UnguessableToken& guid);
-
- DISALLOW_COPY_AND_ASSIGN(ReadOnlySharedMemoryMapping);
-};
-
-// Class modeling a writable mapping of a shared memory region into the
-// current process' address space. This is created by *SharedMemoryRegion
-// instances.
-class BASE_EXPORT WritableSharedMemoryMapping : public SharedMemoryMapping {
- public:
- // Default constructor initializes an invalid instance.
- WritableSharedMemoryMapping();
-
- // Move operations are allowed.
- WritableSharedMemoryMapping(WritableSharedMemoryMapping&&);
- WritableSharedMemoryMapping& operator=(WritableSharedMemoryMapping&&);
-
- // Returns the base address of the mapping. This is writable memory. This is
- // page-aligned. This is nullptr for invalid instances.
- void* memory() const { return raw_memory_ptr(); }
-
- private:
- friend WritableSharedMemoryMapping MapAtForTesting(
- subtle::PlatformSharedMemoryRegion* region,
- off_t offset,
- size_t size);
- friend class ReadOnlySharedMemoryRegion;
- friend class WritableSharedMemoryRegion;
- friend class UnsafeSharedMemoryRegion;
- WritableSharedMemoryMapping(void* address,
- size_t size,
- size_t mapped_size,
- const UnguessableToken& guid);
-
- DISALLOW_COPY_AND_ASSIGN(WritableSharedMemoryMapping);
-};
-
-} // namespace base
-
-#endif // BASE_MEMORY_SHARED_MEMORY_MAPPING_H_
diff --git a/base/memory/shared_memory_nacl.cc b/base/memory/shared_memory_nacl.cc
deleted file mode 100644
index 4bcbb54..0000000
--- a/base/memory/shared_memory_nacl.cc
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "base/memory/shared_memory.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stddef.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include <limits>
-
-#include "base/logging.h"
-#include "base/memory/shared_memory_tracker.h"
-
-namespace base {
-
-SharedMemory::SharedMemory()
- : mapped_size_(0), memory_(NULL), read_only_(false), requested_size_(0) {}
-
-SharedMemory::SharedMemory(const SharedMemoryHandle& handle, bool read_only)
- : shm_(handle),
- mapped_size_(0),
- memory_(NULL),
- read_only_(read_only),
- requested_size_(0) {}
-
-SharedMemory::~SharedMemory() {
- Unmap();
- Close();
-}
-
-// static
-bool SharedMemory::IsHandleValid(const SharedMemoryHandle& handle) {
- return handle.IsValid();
-}
-
-// static
-void SharedMemory::CloseHandle(const SharedMemoryHandle& handle) {
- DCHECK(handle.IsValid());
- handle.Close();
-}
-
-// static
-SharedMemoryHandle SharedMemory::DuplicateHandle(
- const SharedMemoryHandle& handle) {
- return handle.Duplicate();
-}
-
-bool SharedMemory::CreateAndMapAnonymous(size_t size) {
- // Untrusted code can't create descriptors or handles.
- return false;
-}
-
-bool SharedMemory::Create(const SharedMemoryCreateOptions& options) {
- // Untrusted code can't create descriptors or handles.
- return false;
-}
-
-bool SharedMemory::Delete(const std::string& name) {
- return false;
-}
-
-bool SharedMemory::Open(const std::string& name, bool read_only) {
- return false;
-}
-
-bool SharedMemory::MapAt(off_t offset, size_t bytes) {
- if (!shm_.IsValid())
- return false;
-
- if (bytes > static_cast<size_t>(std::numeric_limits<int>::max()))
- return false;
-
- if (memory_)
- return false;
-
- memory_ = mmap(NULL, bytes, PROT_READ | (read_only_ ? 0 : PROT_WRITE),
- MAP_SHARED, shm_.GetHandle(), offset);
-
- bool mmap_succeeded = memory_ != MAP_FAILED && memory_ != NULL;
- if (mmap_succeeded) {
- mapped_size_ = bytes;
- DCHECK_EQ(0U, reinterpret_cast<uintptr_t>(memory_) &
- (SharedMemory::MAP_MINIMUM_ALIGNMENT - 1));
- mapped_id_ = shm_.GetGUID();
- SharedMemoryTracker::GetInstance()->IncrementMemoryUsage(*this);
- } else {
- memory_ = NULL;
- }
-
- return mmap_succeeded;
-}
-
-bool SharedMemory::Unmap() {
- if (memory_ == NULL)
- return false;
-
- SharedMemoryTracker::GetInstance()->DecrementMemoryUsage(*this);
- if (munmap(memory_, mapped_size_) < 0)
- DPLOG(ERROR) << "munmap";
- memory_ = NULL;
- mapped_size_ = 0;
- mapped_id_ = UnguessableToken();
- return true;
-}
-
-SharedMemoryHandle SharedMemory::handle() const {
- SharedMemoryHandle handle_copy = shm_;
- handle_copy.SetOwnershipPassesToIPC(false);
- return handle_copy;
-}
-
-SharedMemoryHandle SharedMemory::TakeHandle() {
- SharedMemoryHandle handle_copy = shm_;
- handle_copy.SetOwnershipPassesToIPC(true);
- Unmap();
- shm_ = SharedMemoryHandle();
- return handle_copy;
-}
-
-void SharedMemory::Close() {
- if (shm_.IsValid()) {
- shm_.Close();
- shm_ = SharedMemoryHandle();
- }
-}
-
-SharedMemoryHandle SharedMemory::GetReadOnlyHandle() const {
- // Untrusted code can't create descriptors or handles, which is needed to
- // drop permissions.
- return SharedMemoryHandle();
-}
-
-} // namespace base
diff --git a/base/memory/shared_memory_posix.cc b/base/memory/shared_memory_posix.cc
deleted file mode 100644
index f868eb2..0000000
--- a/base/memory/shared_memory_posix.cc
+++ /dev/null
@@ -1,385 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "base/memory/shared_memory.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stddef.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "base/files/file_util.h"
-#include "base/files/scoped_file.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/shared_memory_helper.h"
-#include "base/memory/shared_memory_tracker.h"
-#include "base/posix/eintr_wrapper.h"
-#include "base/posix/safe_strerror.h"
-#include "base/process/process_metrics.h"
-#include "base/scoped_generic.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/threading/thread_restrictions.h"
-#include "base/unguessable_token.h"
-#include "build_config.h"
-
-#if defined(OS_ANDROID)
-#include "base/os_compat_android.h"
-#include "third_party/ashmem/ashmem.h"
-#endif
-
-#if defined(OS_MACOSX) && !defined(OS_IOS)
-#error "MacOS uses shared_memory_mac.cc"
-#endif
-
-namespace base {
-
-SharedMemory::SharedMemory() = default;
-
-SharedMemory::SharedMemory(const SharedMemoryHandle& handle, bool read_only)
- : shm_(handle), read_only_(read_only) {}
-
-SharedMemory::~SharedMemory() {
- Unmap();
- Close();
-}
-
-// static
-bool SharedMemory::IsHandleValid(const SharedMemoryHandle& handle) {
- return handle.IsValid();
-}
-
-// static
-void SharedMemory::CloseHandle(const SharedMemoryHandle& handle) {
- DCHECK(handle.IsValid());
- handle.Close();
-}
-
-// static
-size_t SharedMemory::GetHandleLimit() {
- return GetMaxFds();
-}
-
-// static
-SharedMemoryHandle SharedMemory::DuplicateHandle(
- const SharedMemoryHandle& handle) {
- return handle.Duplicate();
-}
-
-// static
-int SharedMemory::GetFdFromSharedMemoryHandle(
- const SharedMemoryHandle& handle) {
- return handle.GetHandle();
-}
-
-bool SharedMemory::CreateAndMapAnonymous(size_t size) {
- return CreateAnonymous(size) && Map(size);
-}
-
-#if !defined(OS_ANDROID)
-
-// Chromium mostly only uses the unique/private shmem as specified by
-// "name == L"". The exception is in the StatsTable.
-// TODO(jrg): there is no way to "clean up" all unused named shmem if
-// we restart from a crash. (That isn't a new problem, but it is a problem.)
-// In case we want to delete it later, it may be useful to save the value
-// of mem_filename after FilePathForMemoryName().
-bool SharedMemory::Create(const SharedMemoryCreateOptions& options) {
- DCHECK(!shm_.IsValid());
- if (options.size == 0) return false;
-
- if (options.size > static_cast<size_t>(std::numeric_limits<int>::max()))
- return false;
-
- // This function theoretically can block on the disk, but realistically
- // the temporary files we create will just go into the buffer cache
- // and be deleted before they ever make it out to disk.
- ThreadRestrictions::ScopedAllowIO allow_io;
-
- bool fix_size = true;
- ScopedFD fd;
- ScopedFD readonly_fd;
- FilePath path;
- if (!options.name_deprecated || options.name_deprecated->empty()) {
- bool result =
- CreateAnonymousSharedMemory(options, &fd, &readonly_fd, &path);
- if (!result)
- return false;
- } else {
- if (!FilePathForMemoryName(*options.name_deprecated, &path))
- return false;
-
- // Make sure that the file is opened without any permission
- // to other users on the system.
- const mode_t kOwnerOnly = S_IRUSR | S_IWUSR;
-
- // First, try to create the file.
- fd.reset(HANDLE_EINTR(
- open(path.value().c_str(), O_RDWR | O_CREAT | O_EXCL, kOwnerOnly)));
- if (!fd.is_valid() && options.open_existing_deprecated) {
- // If this doesn't work, try and open an existing file in append mode.
- // Opening an existing file in a world writable directory has two main
- // security implications:
- // - Attackers could plant a file under their control, so ownership of
- // the file is checked below.
- // - Attackers could plant a symbolic link so that an unexpected file
- // is opened, so O_NOFOLLOW is passed to open().
-#if !defined(OS_AIX)
- fd.reset(HANDLE_EINTR(
- open(path.value().c_str(), O_RDWR | O_APPEND | O_NOFOLLOW)));
-#else
- // AIX has no 64-bit support for open flags such as -
- // O_CLOEXEC, O_NOFOLLOW and O_TTY_INIT.
- fd.reset(HANDLE_EINTR(open(path.value().c_str(), O_RDWR | O_APPEND)));
-#endif
- // Check that the current user owns the file.
- // If uid != euid, then a more complex permission model is used and this
- // API is not appropriate.
- const uid_t real_uid = getuid();
- const uid_t effective_uid = geteuid();
- struct stat sb;
- if (fd.is_valid() &&
- (fstat(fd.get(), &sb) != 0 || sb.st_uid != real_uid ||
- sb.st_uid != effective_uid)) {
- LOG(ERROR) <<
- "Invalid owner when opening existing shared memory file.";
- close(fd.get());
- return false;
- }
-
- // An existing file was opened, so its size should not be fixed.
- fix_size = false;
- }
-
- if (options.share_read_only) {
- // Also open as readonly so that we can GetReadOnlyHandle.
- readonly_fd.reset(HANDLE_EINTR(open(path.value().c_str(), O_RDONLY)));
- if (!readonly_fd.is_valid()) {
- DPLOG(ERROR) << "open(\"" << path.value() << "\", O_RDONLY) failed";
- close(fd.get());
- return false;
- }
- }
- if (fd.is_valid()) {
- // "a+" is always appropriate: if it's a new file, a+ is similar to w+.
- if (!fdopen(fd.get(), "a+")) {
- PLOG(ERROR) << "Creating file stream in " << path.value() << " failed";
- return false;
- }
- }
- }
- if (fd.is_valid() && fix_size) {
- // Get current size.
- struct stat stat;
- if (fstat(fd.get(), &stat) != 0)
- return false;
- const size_t current_size = stat.st_size;
- if (current_size != options.size) {
- if (HANDLE_EINTR(ftruncate(fd.get(), options.size)) != 0)
- return false;
- }
- requested_size_ = options.size;
- }
- if (!fd.is_valid()) {
- PLOG(ERROR) << "Creating shared memory in " << path.value() << " failed";
- FilePath dir = path.DirName();
- if (access(dir.value().c_str(), W_OK | X_OK) < 0) {
- PLOG(ERROR) << "Unable to access(W_OK|X_OK) " << dir.value();
- if (dir.value() == "/dev/shm") {
- LOG(FATAL) << "This is frequently caused by incorrect permissions on "
- << "/dev/shm. Try 'sudo chmod 1777 /dev/shm' to fix.";
- }
- }
- return false;
- }
-
- int mapped_file = -1;
- int readonly_mapped_file = -1;
-
- bool result = PrepareMapFile(std::move(fd), std::move(readonly_fd),
- &mapped_file, &readonly_mapped_file);
- shm_ = SharedMemoryHandle(FileDescriptor(mapped_file, false), options.size,
- UnguessableToken::Create());
- readonly_shm_ =
- SharedMemoryHandle(FileDescriptor(readonly_mapped_file, false),
- options.size, shm_.GetGUID());
- return result;
-}
-
-// Our current implementation of shmem is with mmap()ing of files.
-// These files need to be deleted explicitly.
-// In practice this call is only needed for unit tests.
-bool SharedMemory::Delete(const std::string& name) {
- FilePath path;
- if (!FilePathForMemoryName(name, &path))
- return false;
-
- if (PathExists(path))
- return DeleteFile(path, false);
-
- // Doesn't exist, so success.
- return true;
-}
-
-bool SharedMemory::Open(const std::string& name, bool read_only) {
- FilePath path;
- if (!FilePathForMemoryName(name, &path))
- return false;
-
- read_only_ = read_only;
-
- int mode = read_only ? O_RDONLY : O_RDWR;
- ScopedFD fd(HANDLE_EINTR(open(path.value().c_str(), mode)));
- ScopedFD readonly_fd(HANDLE_EINTR(open(path.value().c_str(), O_RDONLY)));
- if (!readonly_fd.is_valid()) {
- DPLOG(ERROR) << "open(\"" << path.value() << "\", O_RDONLY) failed";
- return false;
- }
- int mapped_file = -1;
- int readonly_mapped_file = -1;
- bool result = PrepareMapFile(std::move(fd), std::move(readonly_fd),
- &mapped_file, &readonly_mapped_file);
- // This form of sharing shared memory is deprecated. https://crbug.com/345734.
- // However, we can't get rid of it without a significant refactor because its
- // used to communicate between two versions of the same service process, very
- // early in the life cycle.
- // Technically, we should also pass the GUID from the original shared memory
- // region. We don't do that - this means that we will overcount this memory,
- // which thankfully isn't relevant since Chrome only communicates with a
- // single version of the service process.
- // We pass the size |0|, which is a dummy size and wrong, but otherwise
- // harmless.
- shm_ = SharedMemoryHandle(FileDescriptor(mapped_file, false), 0u,
- UnguessableToken::Create());
- readonly_shm_ = SharedMemoryHandle(
- FileDescriptor(readonly_mapped_file, false), 0, shm_.GetGUID());
- return result;
-}
-#endif // !defined(OS_ANDROID)
-
-bool SharedMemory::MapAt(off_t offset, size_t bytes) {
- if (!shm_.IsValid())
- return false;
-
- if (bytes > static_cast<size_t>(std::numeric_limits<int>::max()))
- return false;
-
- if (memory_)
- return false;
-
-#if defined(OS_ANDROID)
- // On Android, Map can be called with a size and offset of zero to use the
- // ashmem-determined size.
- if (bytes == 0) {
- DCHECK_EQ(0, offset);
- int ashmem_bytes = ashmem_get_size_region(shm_.GetHandle());
- if (ashmem_bytes < 0)
- return false;
- bytes = ashmem_bytes;
- }
-
- // Sanity check. This shall catch invalid uses of the SharedMemory APIs
- // but will not protect against direct mmap() attempts.
- if (shm_.IsReadOnly()) {
- // Use a DCHECK() to call writable mappings with read-only descriptors
- // in debug builds immediately. Return an error for release builds
- // or during unit-testing (assuming a ScopedLogAssertHandler was installed).
- DCHECK(read_only_)
- << "Trying to map a region writable with a read-only descriptor.";
- if (!read_only_) {
- return false;
- }
- if (!shm_.SetRegionReadOnly()) { // Ensure the region is read-only.
- return false;
- }
- }
-#endif
-
- memory_ = mmap(nullptr, bytes, PROT_READ | (read_only_ ? 0 : PROT_WRITE),
- MAP_SHARED, shm_.GetHandle(), offset);
-
- bool mmap_succeeded = memory_ && memory_ != reinterpret_cast<void*>(-1);
- if (mmap_succeeded) {
- mapped_size_ = bytes;
- mapped_id_ = shm_.GetGUID();
- DCHECK_EQ(0U,
- reinterpret_cast<uintptr_t>(memory_) &
- (SharedMemory::MAP_MINIMUM_ALIGNMENT - 1));
- SharedMemoryTracker::GetInstance()->IncrementMemoryUsage(*this);
- } else {
- memory_ = nullptr;
- }
-
- return mmap_succeeded;
-}
-
-bool SharedMemory::Unmap() {
- if (!memory_)
- return false;
-
- SharedMemoryTracker::GetInstance()->DecrementMemoryUsage(*this);
- munmap(memory_, mapped_size_);
- memory_ = nullptr;
- mapped_size_ = 0;
- mapped_id_ = UnguessableToken();
- return true;
-}
-
-SharedMemoryHandle SharedMemory::handle() const {
- return shm_;
-}
-
-SharedMemoryHandle SharedMemory::TakeHandle() {
- SharedMemoryHandle handle_copy = shm_;
- handle_copy.SetOwnershipPassesToIPC(true);
- Unmap();
- shm_ = SharedMemoryHandle();
- return handle_copy;
-}
-
-#if !defined(OS_ANDROID)
-void SharedMemory::Close() {
- if (shm_.IsValid()) {
- shm_.Close();
- shm_ = SharedMemoryHandle();
- }
- if (readonly_shm_.IsValid()) {
- readonly_shm_.Close();
- readonly_shm_ = SharedMemoryHandle();
- }
-}
-
-// For the given shmem named |mem_name|, return a filename to mmap()
-// (and possibly create). Modifies |filename|. Return false on
-// error, or true of we are happy.
-bool SharedMemory::FilePathForMemoryName(const std::string& mem_name,
- FilePath* path) {
- // mem_name will be used for a filename; make sure it doesn't
- // contain anything which will confuse us.
- DCHECK_EQ(std::string::npos, mem_name.find('/'));
- DCHECK_EQ(std::string::npos, mem_name.find('\0'));
-
- FilePath temp_dir;
- if (!GetShmemTempDir(false, &temp_dir))
- return false;
-
-#if defined(GOOGLE_CHROME_BUILD)
- static const char kShmem[] = "com.google.Chrome.shmem.";
-#else
- static const char kShmem[] = "org.chromium.Chromium.shmem.";
-#endif
- CR_DEFINE_STATIC_LOCAL(const std::string, name_base, (kShmem));
- *path = temp_dir.AppendASCII(name_base + mem_name);
- return true;
-}
-
-SharedMemoryHandle SharedMemory::GetReadOnlyHandle() const {
- CHECK(readonly_shm_.IsValid());
- return readonly_shm_.Duplicate();
-}
-#endif // !defined(OS_ANDROID)
-
-} // namespace base
diff --git a/base/memory/shared_memory_tracker.cc b/base/memory/shared_memory_tracker.cc
deleted file mode 100644
index ee2b490..0000000
--- a/base/memory/shared_memory_tracker.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2017 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.
-
-#include "base/memory/shared_memory_tracker.h"
-
-#include "base/memory/shared_memory.h"
-#include "base/strings/string_number_conversions.h"
-
-namespace base {
-
-const char SharedMemoryTracker::kDumpRootName[] = "shared_memory";
-
-// static
-SharedMemoryTracker* SharedMemoryTracker::GetInstance() {
- static SharedMemoryTracker* instance = new SharedMemoryTracker;
- return instance;
-}
-
-// static
-std::string SharedMemoryTracker::GetDumpNameForTracing(
- const UnguessableToken& id) {
- DCHECK(!id.is_empty());
- return std::string(kDumpRootName) + "/" + id.ToString();
-}
-
-void SharedMemoryTracker::IncrementMemoryUsage(
- const SharedMemory& shared_memory) {
- AutoLock hold(usages_lock_);
- DCHECK(usages_.find(shared_memory.memory()) == usages_.end());
- usages_.emplace(shared_memory.memory(), UsageInfo(shared_memory.mapped_size(),
- shared_memory.mapped_id()));
-}
-
-void SharedMemoryTracker::IncrementMemoryUsage(
- const SharedMemoryMapping& mapping) {
- AutoLock hold(usages_lock_);
- DCHECK(usages_.find(mapping.raw_memory_ptr()) == usages_.end());
- usages_.emplace(mapping.raw_memory_ptr(),
- UsageInfo(mapping.mapped_size(), mapping.guid()));
-}
-
-void SharedMemoryTracker::DecrementMemoryUsage(
- const SharedMemory& shared_memory) {
- AutoLock hold(usages_lock_);
- DCHECK(usages_.find(shared_memory.memory()) != usages_.end());
- usages_.erase(shared_memory.memory());
-}
-
-void SharedMemoryTracker::DecrementMemoryUsage(
- const SharedMemoryMapping& mapping) {
- AutoLock hold(usages_lock_);
- DCHECK(usages_.find(mapping.raw_memory_ptr()) != usages_.end());
- usages_.erase(mapping.raw_memory_ptr());
-}
-
-SharedMemoryTracker::SharedMemoryTracker() {
-}
-
-SharedMemoryTracker::~SharedMemoryTracker() = default;
-
-} // namespace
diff --git a/base/memory/shared_memory_tracker.h b/base/memory/shared_memory_tracker.h
deleted file mode 100644
index 72c7b7a..0000000
--- a/base/memory/shared_memory_tracker.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2017 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 BASE_MEMORY_SHARED_MEMORY_TRACKER_H_
-#define BASE_MEMORY_SHARED_MEMORY_TRACKER_H_
-
-#include <map>
-#include <string>
-
-#include "base/memory/shared_memory.h"
-#include "base/memory/shared_memory_mapping.h"
-#include "base/synchronization/lock.h"
-
-namespace base {
-
-// SharedMemoryTracker tracks shared memory usage.
-class BASE_EXPORT SharedMemoryTracker {
- public:
- // Returns a singleton instance.
- static SharedMemoryTracker* GetInstance();
-
- static std::string GetDumpNameForTracing(const UnguessableToken& id);
-
- // Records shared memory usage on valid mapping.
- void IncrementMemoryUsage(const SharedMemory& shared_memory);
- void IncrementMemoryUsage(const SharedMemoryMapping& mapping);
-
- // Records shared memory usage on unmapping.
- void DecrementMemoryUsage(const SharedMemory& shared_memory);
- void DecrementMemoryUsage(const SharedMemoryMapping& mapping);
-
- // Root dump name for all shared memory dumps.
- static const char kDumpRootName[];
-
- private:
- SharedMemoryTracker();
- ~SharedMemoryTracker();
-
- // Information associated with each mapped address.
- struct UsageInfo {
- UsageInfo(size_t size, const UnguessableToken& id)
- : mapped_size(size), mapped_id(id) {}
-
- size_t mapped_size;
- UnguessableToken mapped_id;
- };
-
- // Used to lock when |usages_| is modified or read.
- Lock usages_lock_;
- std::map<void*, UsageInfo> usages_;
-
- DISALLOW_COPY_AND_ASSIGN(SharedMemoryTracker);
-};
-
-} // namespace base
-
-#endif // BASE_MEMORY_SHARED_MEMORY_TRACKER_H_
diff --git a/base/memory/shared_memory_win.cc b/base/memory/shared_memory_win.cc
deleted file mode 100644
index cf06dd3..0000000
--- a/base/memory/shared_memory_win.cc
+++ /dev/null
@@ -1,381 +0,0 @@
-// Copyright (c) 2011 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.
-
-#include "base/memory/shared_memory.h"
-
-#include <aclapi.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include "base/allocator/partition_allocator/page_allocator.h"
-#include "base/logging.h"
-#include "base/memory/shared_memory_tracker.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/rand_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/unguessable_token.h"
-
-namespace base {
-namespace {
-
-// Errors that can occur during Shared Memory construction.
-// These match tools/metrics/histograms/histograms.xml.
-// This enum is append-only.
-enum CreateError {
- SUCCESS = 0,
- SIZE_ZERO = 1,
- SIZE_TOO_LARGE = 2,
- INITIALIZE_ACL_FAILURE = 3,
- INITIALIZE_SECURITY_DESC_FAILURE = 4,
- SET_SECURITY_DESC_FAILURE = 5,
- CREATE_FILE_MAPPING_FAILURE = 6,
- REDUCE_PERMISSIONS_FAILURE = 7,
- ALREADY_EXISTS = 8,
- CREATE_ERROR_LAST = ALREADY_EXISTS
-};
-
-// Emits UMA metrics about encountered errors. Pass zero (0) for |winerror|
-// if there is no associated Windows error.
-void LogError(CreateError error, DWORD winerror) {
- UMA_HISTOGRAM_ENUMERATION("SharedMemory.CreateError", error,
- CREATE_ERROR_LAST + 1);
- static_assert(ERROR_SUCCESS == 0, "Windows error code changed!");
- if (winerror != ERROR_SUCCESS)
- UmaHistogramSparse("SharedMemory.CreateWinError", winerror);
-}
-
-typedef enum _SECTION_INFORMATION_CLASS {
- SectionBasicInformation,
-} SECTION_INFORMATION_CLASS;
-
-typedef struct _SECTION_BASIC_INFORMATION {
- PVOID BaseAddress;
- ULONG Attributes;
- LARGE_INTEGER Size;
-} SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION;
-
-typedef ULONG(__stdcall* NtQuerySectionType)(
- HANDLE SectionHandle,
- SECTION_INFORMATION_CLASS SectionInformationClass,
- PVOID SectionInformation,
- ULONG SectionInformationLength,
- PULONG ResultLength);
-
-// Returns the length of the memory section starting at the supplied address.
-size_t GetMemorySectionSize(void* address) {
- MEMORY_BASIC_INFORMATION memory_info;
- if (!::VirtualQuery(address, &memory_info, sizeof(memory_info)))
- return 0;
- return memory_info.RegionSize - (static_cast<char*>(address) -
- static_cast<char*>(memory_info.AllocationBase));
-}
-
-// Checks if the section object is safe to map. At the moment this just means
-// it's not an image section.
-bool IsSectionSafeToMap(HANDLE handle) {
- static NtQuerySectionType nt_query_section_func;
- if (!nt_query_section_func) {
- nt_query_section_func = reinterpret_cast<NtQuerySectionType>(
- ::GetProcAddress(::GetModuleHandle(L"ntdll.dll"), "NtQuerySection"));
- DCHECK(nt_query_section_func);
- }
-
- // The handle must have SECTION_QUERY access for this to succeed.
- SECTION_BASIC_INFORMATION basic_information = {};
- ULONG status =
- nt_query_section_func(handle, SectionBasicInformation, &basic_information,
- sizeof(basic_information), nullptr);
- if (status)
- return false;
- return (basic_information.Attributes & SEC_IMAGE) != SEC_IMAGE;
-}
-
-// Returns a HANDLE on success and |nullptr| on failure.
-// This function is similar to CreateFileMapping, but removes the permissions
-// WRITE_DAC, WRITE_OWNER, READ_CONTROL, and DELETE.
-//
-// A newly created file mapping has two sets of permissions. It has access
-// control permissions (WRITE_DAC, WRITE_OWNER, READ_CONTROL, and DELETE) and
-// file permissions (FILE_MAP_READ, FILE_MAP_WRITE, etc.). ::DuplicateHandle()
-// with the parameter DUPLICATE_SAME_ACCESS copies both sets of permissions.
-//
-// The Chrome sandbox prevents HANDLEs with the WRITE_DAC permission from being
-// duplicated into unprivileged processes. But the only way to copy file
-// permissions is with the parameter DUPLICATE_SAME_ACCESS. This means that
-// there is no way for a privileged process to duplicate a file mapping into an
-// unprivileged process while maintaining the previous file permissions.
-//
-// By removing all access control permissions of a file mapping immediately
-// after creation, ::DuplicateHandle() effectively only copies the file
-// permissions.
-HANDLE CreateFileMappingWithReducedPermissions(SECURITY_ATTRIBUTES* sa,
- size_t rounded_size,
- LPCWSTR name) {
- HANDLE h = CreateFileMapping(INVALID_HANDLE_VALUE, sa, PAGE_READWRITE, 0,
- static_cast<DWORD>(rounded_size), name);
- if (!h) {
- LogError(CREATE_FILE_MAPPING_FAILURE, GetLastError());
- return nullptr;
- }
-
- HANDLE h2;
- BOOL success = ::DuplicateHandle(
- GetCurrentProcess(), h, GetCurrentProcess(), &h2,
- FILE_MAP_READ | FILE_MAP_WRITE | SECTION_QUERY, FALSE, 0);
- BOOL rv = ::CloseHandle(h);
- DCHECK(rv);
-
- if (!success) {
- LogError(REDUCE_PERMISSIONS_FAILURE, GetLastError());
- return nullptr;
- }
-
- return h2;
-}
-
-} // namespace.
-
-SharedMemory::SharedMemory() {}
-
-SharedMemory::SharedMemory(const string16& name) : name_(name) {}
-
-SharedMemory::SharedMemory(const SharedMemoryHandle& handle, bool read_only)
- : external_section_(true), shm_(handle), read_only_(read_only) {}
-
-SharedMemory::~SharedMemory() {
- Unmap();
- Close();
-}
-
-// static
-bool SharedMemory::IsHandleValid(const SharedMemoryHandle& handle) {
- return handle.IsValid();
-}
-
-// static
-void SharedMemory::CloseHandle(const SharedMemoryHandle& handle) {
- handle.Close();
-}
-
-// static
-size_t SharedMemory::GetHandleLimit() {
- // Rounded down from value reported here:
- // http://blogs.technet.com/b/markrussinovich/archive/2009/09/29/3283844.aspx
- return static_cast<size_t>(1 << 23);
-}
-
-// static
-SharedMemoryHandle SharedMemory::DuplicateHandle(
- const SharedMemoryHandle& handle) {
- return handle.Duplicate();
-}
-
-bool SharedMemory::CreateAndMapAnonymous(size_t size) {
- return CreateAnonymous(size) && Map(size);
-}
-
-bool SharedMemory::Create(const SharedMemoryCreateOptions& options) {
- // TODO(crbug.com/210609): NaCl forces us to round up 64k here, wasting 32k
- // per mapping on average.
- static const size_t kSectionMask = 65536 - 1;
- DCHECK(!options.executable);
- DCHECK(!shm_.IsValid());
- if (options.size == 0) {
- LogError(SIZE_ZERO, 0);
- return false;
- }
-
- // Check maximum accounting for overflow.
- if (options.size >
- static_cast<size_t>(std::numeric_limits<int>::max()) - kSectionMask) {
- LogError(SIZE_TOO_LARGE, 0);
- return false;
- }
-
- size_t rounded_size = (options.size + kSectionMask) & ~kSectionMask;
- name_ = options.name_deprecated ?
- ASCIIToUTF16(*options.name_deprecated) : L"";
- SECURITY_ATTRIBUTES sa = {sizeof(sa), nullptr, FALSE};
- SECURITY_DESCRIPTOR sd;
- ACL dacl;
-
- if (name_.empty()) {
- // Add an empty DACL to enforce anonymous read-only sections.
- sa.lpSecurityDescriptor = &sd;
- if (!InitializeAcl(&dacl, sizeof(dacl), ACL_REVISION)) {
- LogError(INITIALIZE_ACL_FAILURE, GetLastError());
- return false;
- }
- if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) {
- LogError(INITIALIZE_SECURITY_DESC_FAILURE, GetLastError());
- return false;
- }
- if (!SetSecurityDescriptorDacl(&sd, TRUE, &dacl, FALSE)) {
- LogError(SET_SECURITY_DESC_FAILURE, GetLastError());
- return false;
- }
-
- // Windows ignores DACLs on certain unnamed objects (like shared sections).
- // So, we generate a random name when we need to enforce read-only.
- uint64_t rand_values[4];
- RandBytes(&rand_values, sizeof(rand_values));
- name_ = StringPrintf(L"CrSharedMem_%016llx%016llx%016llx%016llx",
- rand_values[0], rand_values[1],
- rand_values[2], rand_values[3]);
- }
- DCHECK(!name_.empty());
- shm_ = SharedMemoryHandle(
- CreateFileMappingWithReducedPermissions(&sa, rounded_size, name_.c_str()),
- rounded_size, UnguessableToken::Create());
- if (!shm_.IsValid()) {
- // The error is logged within CreateFileMappingWithReducedPermissions().
- return false;
- }
-
- requested_size_ = options.size;
-
- // Check if the shared memory pre-exists.
- if (GetLastError() == ERROR_ALREADY_EXISTS) {
- // If the file already existed, set requested_size_ to 0 to show that
- // we don't know the size.
- requested_size_ = 0;
- external_section_ = true;
- if (!options.open_existing_deprecated) {
- Close();
- // From "if" above: GetLastError() == ERROR_ALREADY_EXISTS.
- LogError(ALREADY_EXISTS, ERROR_ALREADY_EXISTS);
- return false;
- }
- }
-
- LogError(SUCCESS, ERROR_SUCCESS);
- return true;
-}
-
-bool SharedMemory::Delete(const std::string& name) {
- // intentionally empty -- there is nothing for us to do on Windows.
- return true;
-}
-
-bool SharedMemory::Open(const std::string& name, bool read_only) {
- DCHECK(!shm_.IsValid());
- DWORD access = FILE_MAP_READ | SECTION_QUERY;
- if (!read_only)
- access |= FILE_MAP_WRITE;
- name_ = ASCIIToUTF16(name);
- read_only_ = read_only;
-
- // This form of sharing shared memory is deprecated. https://crbug.com/345734.
- // However, we can't get rid of it without a significant refactor because its
- // used to communicate between two versions of the same service process, very
- // early in the life cycle.
- // Technically, we should also pass the GUID from the original shared memory
- // region. We don't do that - this means that we will overcount this memory,
- // which thankfully isn't relevant since Chrome only communicates with a
- // single version of the service process.
- // We pass the size |0|, which is a dummy size and wrong, but otherwise
- // harmless.
- shm_ = SharedMemoryHandle(
- OpenFileMapping(access, false, name_.empty() ? nullptr : name_.c_str()),
- 0u, UnguessableToken::Create());
- if (!shm_.IsValid())
- return false;
- // If a name specified assume it's an external section.
- if (!name_.empty())
- external_section_ = true;
- // Note: size_ is not set in this case.
- return true;
-}
-
-bool SharedMemory::MapAt(off_t offset, size_t bytes) {
- if (!shm_.IsValid()) {
- DLOG(ERROR) << "Invalid SharedMemoryHandle.";
- return false;
- }
-
- if (bytes > static_cast<size_t>(std::numeric_limits<int>::max())) {
- DLOG(ERROR) << "Bytes required exceeds the 2G limitation.";
- return false;
- }
-
- if (memory_) {
- DLOG(ERROR) << "The SharedMemory has been mapped already.";
- return false;
- }
-
- if (external_section_ && !IsSectionSafeToMap(shm_.GetHandle())) {
- DLOG(ERROR) << "SharedMemoryHandle is not safe to be mapped.";
- return false;
- }
-
- // Try to map the shared memory. On the first failure, release any reserved
- // address space for a single retry.
- for (int i = 0; i < 2; ++i) {
- memory_ = MapViewOfFile(
- shm_.GetHandle(),
- read_only_ ? FILE_MAP_READ : FILE_MAP_READ | FILE_MAP_WRITE,
- static_cast<uint64_t>(offset) >> 32, static_cast<DWORD>(offset), bytes);
- if (memory_)
- break;
- ReleaseReservation();
- }
- if (!memory_) {
- DPLOG(ERROR) << "Failed executing MapViewOfFile";
- return false;
- }
-
- DCHECK_EQ(0U, reinterpret_cast<uintptr_t>(memory_) &
- (SharedMemory::MAP_MINIMUM_ALIGNMENT - 1));
- mapped_size_ = GetMemorySectionSize(memory_);
- mapped_id_ = shm_.GetGUID();
- SharedMemoryTracker::GetInstance()->IncrementMemoryUsage(*this);
- return true;
-}
-
-bool SharedMemory::Unmap() {
- if (!memory_)
- return false;
-
- SharedMemoryTracker::GetInstance()->DecrementMemoryUsage(*this);
- UnmapViewOfFile(memory_);
- memory_ = nullptr;
- mapped_id_ = UnguessableToken();
- return true;
-}
-
-SharedMemoryHandle SharedMemory::GetReadOnlyHandle() const {
- HANDLE result;
- ProcessHandle process = GetCurrentProcess();
- if (!::DuplicateHandle(process, shm_.GetHandle(), process, &result,
- FILE_MAP_READ | SECTION_QUERY, FALSE, 0)) {
- return SharedMemoryHandle();
- }
- SharedMemoryHandle handle =
- SharedMemoryHandle(result, shm_.GetSize(), shm_.GetGUID());
- handle.SetOwnershipPassesToIPC(true);
- return handle;
-}
-
-void SharedMemory::Close() {
- if (shm_.IsValid()) {
- shm_.Close();
- shm_ = SharedMemoryHandle();
- }
-}
-
-SharedMemoryHandle SharedMemory::handle() const {
- return shm_;
-}
-
-SharedMemoryHandle SharedMemory::TakeHandle() {
- SharedMemoryHandle handle(shm_);
- handle.SetOwnershipPassesToIPC(true);
- Unmap();
- shm_ = SharedMemoryHandle();
- return handle;
-}
-
-} // namespace base
diff --git a/base/memory/unsafe_shared_memory_region.cc b/base/memory/unsafe_shared_memory_region.cc
deleted file mode 100644
index 422b5a9..0000000
--- a/base/memory/unsafe_shared_memory_region.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2018 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.
-
-#include "base/memory/unsafe_shared_memory_region.h"
-
-#include <utility>
-
-#include "base/memory/shared_memory.h"
-
-namespace base {
-
-// static
-UnsafeSharedMemoryRegion UnsafeSharedMemoryRegion::Create(size_t size) {
- subtle::PlatformSharedMemoryRegion handle =
- subtle::PlatformSharedMemoryRegion::CreateUnsafe(size);
-
- return UnsafeSharedMemoryRegion(std::move(handle));
-}
-
-// static
-UnsafeSharedMemoryRegion UnsafeSharedMemoryRegion::Deserialize(
- subtle::PlatformSharedMemoryRegion handle) {
- return UnsafeSharedMemoryRegion(std::move(handle));
-}
-
-// static
-subtle::PlatformSharedMemoryRegion
-UnsafeSharedMemoryRegion::TakeHandleForSerialization(
- UnsafeSharedMemoryRegion region) {
- return std::move(region.handle_);
-}
-
-UnsafeSharedMemoryRegion::UnsafeSharedMemoryRegion() = default;
-UnsafeSharedMemoryRegion::UnsafeSharedMemoryRegion(
- UnsafeSharedMemoryRegion&& region) = default;
-UnsafeSharedMemoryRegion& UnsafeSharedMemoryRegion::operator=(
- UnsafeSharedMemoryRegion&& region) = default;
-UnsafeSharedMemoryRegion::~UnsafeSharedMemoryRegion() = default;
-
-UnsafeSharedMemoryRegion UnsafeSharedMemoryRegion::Duplicate() const {
- return UnsafeSharedMemoryRegion(handle_.Duplicate());
-}
-
-WritableSharedMemoryMapping UnsafeSharedMemoryRegion::Map() const {
- return MapAt(0, handle_.GetSize());
-}
-
-WritableSharedMemoryMapping UnsafeSharedMemoryRegion::MapAt(off_t offset,
- size_t size) const {
- if (!IsValid())
- return {};
-
- void* memory = nullptr;
- size_t mapped_size = 0;
- if (!handle_.MapAt(offset, size, &memory, &mapped_size))
- return {};
-
- return WritableSharedMemoryMapping(memory, size, mapped_size,
- handle_.GetGUID());
-}
-
-bool UnsafeSharedMemoryRegion::IsValid() const {
- return handle_.IsValid();
-}
-
-UnsafeSharedMemoryRegion::UnsafeSharedMemoryRegion(
- subtle::PlatformSharedMemoryRegion handle)
- : handle_(std::move(handle)) {
- if (handle_.IsValid()) {
- CHECK_EQ(handle_.GetMode(),
- subtle::PlatformSharedMemoryRegion::Mode::kUnsafe);
- }
-}
-
-} // namespace base
diff --git a/base/memory/unsafe_shared_memory_region.h b/base/memory/unsafe_shared_memory_region.h
deleted file mode 100644
index d77eaaa..0000000
--- a/base/memory/unsafe_shared_memory_region.h
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2018 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 BASE_MEMORY_UNSAFE_SHARED_MEMORY_REGION_H_
-#define BASE_MEMORY_UNSAFE_SHARED_MEMORY_REGION_H_
-
-#include "base/gtest_prod_util.h"
-#include "base/macros.h"
-#include "base/memory/platform_shared_memory_region.h"
-#include "base/memory/shared_memory_mapping.h"
-
-namespace base {
-
-// Scoped move-only handle to a region of platform shared memory. The instance
-// owns the platform handle it wraps. Mappings created by this region are
-// writable. These mappings remain valid even after the region handle is moved
-// or destroyed.
-//
-// NOTE: UnsafeSharedMemoryRegion cannot be converted to a read-only region. Use
-// with caution as the region will be writable to any process with a handle to
-// the region.
-//
-// Use this if and only if the following is true:
-// - You do not need to share the region as read-only, and,
-// - You need to have several instances of the region simultaneously, possibly
-// in different processes, that can produce writable mappings.
-
-class BASE_EXPORT UnsafeSharedMemoryRegion {
- public:
- using MappingType = WritableSharedMemoryMapping;
- // Creates a new UnsafeSharedMemoryRegion instance of a given size that can be
- // used for mapping writable shared memory into the virtual address space.
- static UnsafeSharedMemoryRegion Create(size_t size);
-
- // Returns an UnsafeSharedMemoryRegion built from a platform-specific handle
- // that was taken from another UnsafeSharedMemoryRegion instance. Returns an
- // invalid region iff the |handle| is invalid. CHECK-fails if the |handle|
- // isn't unsafe.
- // This should be used only by the code passing a handle across
- // process boundaries.
- static UnsafeSharedMemoryRegion Deserialize(
- subtle::PlatformSharedMemoryRegion handle);
-
- // Extracts a platform handle from the region. Ownership is transferred to the
- // returned region object.
- // This should be used only for sending the handle from the current
- // process to another.
- static subtle::PlatformSharedMemoryRegion TakeHandleForSerialization(
- UnsafeSharedMemoryRegion region);
-
- // Default constructor initializes an invalid instance.
- UnsafeSharedMemoryRegion();
-
- // Move operations are allowed.
- UnsafeSharedMemoryRegion(UnsafeSharedMemoryRegion&&);
- UnsafeSharedMemoryRegion& operator=(UnsafeSharedMemoryRegion&&);
-
- // Destructor closes shared memory region if valid.
- // All created mappings will remain valid.
- ~UnsafeSharedMemoryRegion();
-
- // Duplicates the underlying platform handle and creates a new
- // UnsafeSharedMemoryRegion instance that owns the newly created handle.
- // Returns a valid UnsafeSharedMemoryRegion on success, invalid otherwise.
- // The current region instance remains valid in any case.
- UnsafeSharedMemoryRegion Duplicate() const;
-
- // Maps the shared memory region into the caller's address space with write
- // access. The mapped address is guaranteed to have an alignment of
- // at least |subtle::PlatformSharedMemoryRegion::kMapMinimumAlignment|.
- // Returns a valid WritableSharedMemoryMapping instance on success, invalid
- // otherwise.
- WritableSharedMemoryMapping Map() const;
-
- // Same as above, but maps only |size| bytes of the shared memory region
- // starting with the given |offset|. |offset| must be aligned to value of
- // |SysInfo::VMAllocationGranularity()|. Returns an invalid mapping if
- // requested bytes are out of the region limits.
- WritableSharedMemoryMapping MapAt(off_t offset, size_t size) const;
-
- // Whether the underlying platform handle is valid.
- bool IsValid() const;
-
- // Returns the maximum mapping size that can be created from this region.
- size_t GetSize() const {
- DCHECK(IsValid());
- return handle_.GetSize();
- }
-
- private:
- FRIEND_TEST_ALL_PREFIXES(DiscardableSharedMemoryTest,
- LockShouldFailIfPlatformLockPagesFails);
- friend class DiscardableSharedMemory;
-
- explicit UnsafeSharedMemoryRegion(subtle::PlatformSharedMemoryRegion handle);
-
- // Returns a platform shared memory handle. |this| remains the owner of the
- // handle.
- subtle::PlatformSharedMemoryRegion::PlatformHandle GetPlatformHandle() const {
- DCHECK(IsValid());
- return handle_.GetPlatformHandle();
- }
-
- subtle::PlatformSharedMemoryRegion handle_;
-
- DISALLOW_COPY_AND_ASSIGN(UnsafeSharedMemoryRegion);
-};
-
-} // namespace base
-
-#endif // BASE_MEMORY_UNSAFE_SHARED_MEMORY_REGION_H_
diff --git a/base/memory/writable_shared_memory_region.cc b/base/memory/writable_shared_memory_region.cc
deleted file mode 100644
index 7a29522..0000000
--- a/base/memory/writable_shared_memory_region.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2018 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.
-
-#include "base/memory/writable_shared_memory_region.h"
-
-#include <utility>
-
-#include "base/memory/shared_memory.h"
-#include "build_config.h"
-
-namespace base {
-
-// static
-WritableSharedMemoryRegion WritableSharedMemoryRegion::Create(size_t size) {
- subtle::PlatformSharedMemoryRegion handle =
- subtle::PlatformSharedMemoryRegion::CreateWritable(size);
-
- return WritableSharedMemoryRegion(std::move(handle));
-}
-
-// static
-WritableSharedMemoryRegion WritableSharedMemoryRegion::Deserialize(
- subtle::PlatformSharedMemoryRegion handle) {
- return WritableSharedMemoryRegion(std::move(handle));
-}
-
-// static
-subtle::PlatformSharedMemoryRegion
-WritableSharedMemoryRegion::TakeHandleForSerialization(
- WritableSharedMemoryRegion region) {
- return std::move(region.handle_);
-}
-
-// static
-ReadOnlySharedMemoryRegion WritableSharedMemoryRegion::ConvertToReadOnly(
- WritableSharedMemoryRegion region) {
- subtle::PlatformSharedMemoryRegion handle = std::move(region.handle_);
- if (!handle.ConvertToReadOnly())
- return {};
-
- return ReadOnlySharedMemoryRegion::Deserialize(std::move(handle));
-}
-
-WritableSharedMemoryRegion::WritableSharedMemoryRegion() = default;
-WritableSharedMemoryRegion::WritableSharedMemoryRegion(
- WritableSharedMemoryRegion&& region) = default;
-WritableSharedMemoryRegion& WritableSharedMemoryRegion::operator=(
- WritableSharedMemoryRegion&& region) = default;
-WritableSharedMemoryRegion::~WritableSharedMemoryRegion() = default;
-
-WritableSharedMemoryMapping WritableSharedMemoryRegion::Map() const {
- return MapAt(0, handle_.GetSize());
-}
-
-WritableSharedMemoryMapping WritableSharedMemoryRegion::MapAt(
- off_t offset,
- size_t size) const {
- if (!IsValid())
- return {};
-
- void* memory = nullptr;
- size_t mapped_size = 0;
- if (!handle_.MapAt(offset, size, &memory, &mapped_size))
- return {};
-
- return WritableSharedMemoryMapping(memory, size, mapped_size,
- handle_.GetGUID());
-}
-
-bool WritableSharedMemoryRegion::IsValid() const {
- return handle_.IsValid();
-}
-
-WritableSharedMemoryRegion::WritableSharedMemoryRegion(
- subtle::PlatformSharedMemoryRegion handle)
- : handle_(std::move(handle)) {
- if (handle_.IsValid()) {
- CHECK_EQ(handle_.GetMode(),
- subtle::PlatformSharedMemoryRegion::Mode::kWritable);
- }
-}
-
-} // namespace base
diff --git a/base/memory/writable_shared_memory_region.h b/base/memory/writable_shared_memory_region.h
deleted file mode 100644
index b953a10..0000000
--- a/base/memory/writable_shared_memory_region.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2018 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 BASE_MEMORY_WRITABLE_SHARED_MEMORY_REGION_H_
-#define BASE_MEMORY_WRITABLE_SHARED_MEMORY_REGION_H_
-
-#include "base/macros.h"
-#include "base/memory/platform_shared_memory_region.h"
-#include "base/memory/read_only_shared_memory_region.h"
-#include "base/memory/shared_memory_mapping.h"
-
-namespace base {
-
-// Scoped move-only handle to a region of platform shared memory. The instance
-// owns the platform handle it wraps. Mappings created by this region are
-// writable. These mappings remain valid even after the region handle is moved
-// or destroyed.
-//
-// This region can be locked to read-only access by converting it to a
-// ReadOnlySharedMemoryRegion. However, unlike ReadOnlySharedMemoryRegion and
-// UnsafeSharedMemoryRegion, ownership of this region (while writable) is unique
-// and may only be transferred, not duplicated.
-class BASE_EXPORT WritableSharedMemoryRegion {
- public:
- using MappingType = WritableSharedMemoryMapping;
- // Creates a new WritableSharedMemoryRegion instance of a given
- // size that can be used for mapping writable shared memory into the virtual
- // address space.
- static WritableSharedMemoryRegion Create(size_t size);
-
- // Returns a WritableSharedMemoryRegion built from a platform handle that was
- // taken from another WritableSharedMemoryRegion instance. Returns an invalid
- // region iff the |handle| is invalid. CHECK-fails if the |handle| isn't
- // writable.
- // This should be used only by the code passing handles across process
- // boundaries.
- static WritableSharedMemoryRegion Deserialize(
- subtle::PlatformSharedMemoryRegion handle);
-
- // Extracts a platform handle from the region. Ownership is transferred to the
- // returned region object.
- // This should be used only for sending the handle from the current
- // process to another.
- static subtle::PlatformSharedMemoryRegion TakeHandleForSerialization(
- WritableSharedMemoryRegion region);
-
- // Makes the region read-only. No new writable mappings of the region can be
- // created after this call. Returns an invalid region on failure.
- static ReadOnlySharedMemoryRegion ConvertToReadOnly(
- WritableSharedMemoryRegion region);
-
- // Default constructor initializes an invalid instance.
- WritableSharedMemoryRegion();
-
- // Move operations are allowed.
- WritableSharedMemoryRegion(WritableSharedMemoryRegion&&);
- WritableSharedMemoryRegion& operator=(WritableSharedMemoryRegion&&);
-
- // Destructor closes shared memory region if valid.
- // All created mappings will remain valid.
- ~WritableSharedMemoryRegion();
-
- // Maps the shared memory region into the caller's address space with write
- // access. The mapped address is guaranteed to have an alignment of
- // at least |subtle::PlatformSharedMemoryRegion::kMapMinimumAlignment|.
- // Returns a valid WritableSharedMemoryMapping instance on success, invalid
- // otherwise.
- WritableSharedMemoryMapping Map() const;
-
- // Same as above, but maps only |size| bytes of the shared memory block
- // starting with the given |offset|. |offset| must be aligned to value of
- // |SysInfo::VMAllocationGranularity()|. Returns an invalid mapping if
- // requested bytes are out of the region limits.
- WritableSharedMemoryMapping MapAt(off_t offset, size_t size) const;
-
- // Whether underlying platform handles are valid.
- bool IsValid() const;
-
- // Returns the maximum mapping size that can be created from this region.
- size_t GetSize() const {
- DCHECK(IsValid());
- return handle_.GetSize();
- }
-
- private:
- explicit WritableSharedMemoryRegion(
- subtle::PlatformSharedMemoryRegion handle);
-
- subtle::PlatformSharedMemoryRegion handle_;
-
- DISALLOW_COPY_AND_ASSIGN(WritableSharedMemoryRegion);
-};
-
-} // namespace base
-
-#endif // BASE_MEMORY_WRITABLE_SHARED_MEMORY_REGION_H_
diff --git a/build/gen.py b/build/gen.py
index 5f73187..95f8fe1 100755
--- a/build/gen.py
+++ b/build/gen.py
@@ -263,13 +263,7 @@
'base/location.cc',
'base/logging.cc',
'base/md5.cc',
- 'base/memory/platform_shared_memory_region.cc',
- 'base/memory/read_only_shared_memory_region.cc',
'base/memory/ref_counted.cc',
- 'base/memory/ref_counted_memory.cc',
- 'base/memory/shared_memory_mapping.cc',
- 'base/memory/shared_memory_handle.cc',
- 'base/memory/shared_memory_tracker.cc',
'base/memory/weak_ptr.cc',
'base/message_loop/incoming_task_queue.cc',
'base/message_loop/message_loop.cc',
@@ -554,19 +548,6 @@
], 'tool': 'cxx', 'include_dirs': [], 'libs': []},
}
- if is_win:
- static_libraries['base']['sources'].extend([
- 'base/memory/platform_shared_memory_region_win.cc'
- ])
- elif is_mac:
- static_libraries['base']['sources'].extend([
- 'base/memory/platform_shared_memory_region_mac.cc'
- ])
- elif is_linux:
- static_libraries['base']['sources'].extend([
- 'base/memory/platform_shared_memory_region_posix.cc'
- ])
-
if is_posix:
static_libraries['base']['sources'].extend([
'base/base_paths_posix.cc',
@@ -577,7 +558,6 @@
'base/files/file_posix.cc',
'base/files/file_util_posix.cc',
'base/files/memory_mapped_file_posix.cc',
- 'base/memory/shared_memory_helper.cc',
'base/message_loop/message_pump_libevent.cc',
'base/posix/file_descriptor_shuffle.cc',
'base/posix/global_descriptors.cc',
@@ -626,8 +606,6 @@
'tool': 'cxx',
}
static_libraries['base']['sources'].extend([
- 'base/memory/shared_memory_handle_posix.cc',
- 'base/memory/shared_memory_posix.cc',
'base/nix/xdg_util.cc',
'base/process/internal_linux.cc',
'base/process/memory_linux.cc',
@@ -675,8 +653,6 @@
'base/mac/scoped_mach_port.cc',
'base/mac/scoped_mach_vm.cc',
'base/mac/scoped_nsautorelease_pool.mm',
- 'base/memory/shared_memory_handle_mac.cc',
- 'base/memory/shared_memory_mac.cc',
'base/message_loop/message_pump_mac.mm',
'base/process/process_handle_mac.cc',
'base/process/process_info_mac.cc',
@@ -723,9 +699,6 @@
'base/files/memory_mapped_file_win.cc',
'base/guid.cc',
'base/logging_win.cc',
- 'base/memory/memory_pressure_monitor_win.cc',
- 'base/memory/shared_memory_handle_win.cc',
- 'base/memory/shared_memory_win.cc',
'base/message_loop/message_pump_win.cc',
'base/native_library_win.cc',
'base/power_monitor/power_monitor_device_source_win.cc',