OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "services/blamer/shared_memory_heap_registry.h" |
| 6 |
| 7 #include <map> |
| 8 |
| 9 #include "base/process/process_handle.h" |
| 10 #include "base/lazy_instance.h" |
| 11 #include "base/metrics/persistent_memory_allocator.h" |
| 12 #include "services/blamer/public/interfaces/service_constants.mojom.h" |
| 13 #include "services/service_manager/public/cpp/connection.h" |
| 14 |
| 15 namespace blamer { |
| 16 |
| 17 namespace { |
| 18 |
| 19 // The identity of a heap slab, from the point of view of the blamer service. |
| 20 // This is the tuple of (process_id, slab_id). |
| 21 using HeapSlabId = std::pair<base::ProcessId, uint32_t>; |
| 22 |
| 23 // A heap slab. This holds the mojom shared memory handle, a mapping to the |
| 24 // underlying data, and a PersistentMemoryAllocator on top of that for safe |
| 25 // iteration of the underlying data. |
| 26 class HeapSlab { |
| 27 public: |
| 28 HeapSlab(mojom::SharedMemoryHeapSlabPtr slab) |
| 29 : buffer_(std::move(slab->buffer)), |
| 30 mapping_(buffer_->Map(slab->size)), |
| 31 size_(slab->size), |
| 32 allocator_(new base::PersistentMemoryAllocator( |
| 33 mapping_.get(), size_, mojom::kPageSize, slab->id, nullptr, true)) { |
| 34 } |
| 35 |
| 36 ~HeapSlab() {} |
| 37 |
| 38 private: |
| 39 // A handle to the shared memory buffer. This is owned by the remote |
| 40 // process. |
| 41 mojo::ScopedSharedBufferHandle buffer_; |
| 42 |
| 43 // A handle to the shared buffer mapping. This is permanently mapped. |
| 44 // TODO(chrisha): Revisit this! They could be mapped in on demand! |
| 45 mojo::ScopedSharedBufferMapping mapping_; |
| 46 |
| 47 // The size of the slab. |
| 48 uint32_t size_; |
| 49 |
| 50 // A persistent memory allocator over this slab, allowing iteration and |
| 51 // inspection. |
| 52 std::unique_ptr<base::PersistentMemoryAllocator> allocator_; |
| 53 }; |
| 54 |
| 55 // A map of heap slabs across all processes, indexed by their unique IDs. |
| 56 using HeapSlabMap = std::map<HeapSlabId, std::unique_ptr<HeapSlab>>; |
| 57 |
| 58 base::LazyInstance<HeapSlabMap>::Leaky g_heap_slab_map_ = |
| 59 LAZY_INSTANCE_INITIALIZER; |
| 60 |
| 61 } // namespace |
| 62 |
| 63 SharedMemoryHeapRegistry::SharedMemoryHeapRegistry( |
| 64 service_manager::ServiceContextRefFactory* service_ref_factory) |
| 65 : service_ref_factory_(service_ref_factory) { |
| 66 service_ref_ = service_ref_factory_->CreateRef(); |
| 67 } |
| 68 |
| 69 SharedMemoryHeapRegistry::~SharedMemoryHeapRegistry() = default; |
| 70 |
| 71 // static |
| 72 void SharedMemoryHeapRegistry::Create( |
| 73 service_manager::ServiceContextRefFactory* service_ref_factory, |
| 74 blamer::mojom::SharedMemoryHeapRegistryRequest request) { |
| 75 mojo::MakeStrongBinding( |
| 76 base::MakeUnique<SharedMemoryHeapRegistry>(service_ref_factory), |
| 77 std::move(request)); |
| 78 } |
| 79 |
| 80 void SharedMemoryHeapRegistry::RegisterSlab( |
| 81 mojom::SharedMemoryHeapSlabPtr slab) { |
| 82 // TODO(chrisha): Get the remote process ID from the channel? |
| 83 base::ProcessId process_id = 0; |
| 84 |
| 85 // Add the slab to the map. |
| 86 // TODO(chrisha): A way to remove mappings for processes that die! |
| 87 g_heap_slab_map_.Get().insert(std::make_pair( |
| 88 HeapSlabId(process_id, slab->id), |
| 89 base::MakeUnique<HeapSlab>(std::move(slab)))); |
| 90 } |
| 91 |
| 92 } // namespace blamer |
| 93 |
OLD | NEW |