Commit 1010504c authored by bcwhite's avatar bcwhite Committed by Commit bot

Add support for turning pointers back to references.

This will be used by a CL for the "breadcrumbs" project that needs
to convert from a raw-memory pointer used by a class that knows
nothing about persistent memory, back to a reference.

BUG=620813

Review-Url: https://codereview.chromium.org/2534643002
Cr-Commit-Position: refs/heads/master@{#434788}
parent 5bb7732e
...@@ -453,6 +453,24 @@ size_t PersistentMemoryAllocator::used() const { ...@@ -453,6 +453,24 @@ size_t PersistentMemoryAllocator::used() const {
mem_size_); mem_size_);
} }
PersistentMemoryAllocator::Reference PersistentMemoryAllocator::GetAsReference(
const void* memory,
uint32_t type_id) const {
uintptr_t address = reinterpret_cast<uintptr_t>(memory);
if (address < reinterpret_cast<uintptr_t>(mem_base_))
return kReferenceNull;
uintptr_t offset = address - reinterpret_cast<uintptr_t>(mem_base_);
if (offset >= mem_size_ || offset < sizeof(BlockHeader))
return kReferenceNull;
Reference ref = static_cast<Reference>(offset) - sizeof(BlockHeader);
if (!GetBlockData(ref, type_id, kSizeAny))
return kReferenceNull;
return ref;
}
size_t PersistentMemoryAllocator::GetAllocSize(Reference ref) const { size_t PersistentMemoryAllocator::GetAllocSize(Reference ref) const {
const volatile BlockHeader* const block = GetBlock(ref, 0, 0, false, false); const volatile BlockHeader* const block = GetBlock(ref, 0, 0, false, false);
if (!block) if (!block)
......
...@@ -316,6 +316,11 @@ class BASE_EXPORT PersistentMemoryAllocator { ...@@ -316,6 +316,11 @@ class BASE_EXPORT PersistentMemoryAllocator {
GetBlockData(ref, type_id, count * sizeof(T)))); GetBlockData(ref, type_id, count * sizeof(T))));
} }
// Get the corresponding reference for an object held in persistent memory.
// If the |memory| is not valid or the type does not match, a kReferenceNull
// result will be returned.
Reference GetAsReference(const void* memory, uint32_t type_id) const;
// Get the number of bytes allocated to a block. This is useful when storing // Get the number of bytes allocated to a block. This is useful when storing
// arrays in order to validate the ending boundary. The returned value will // arrays in order to validate the ending boundary. The returned value will
// include any padding added to achieve the required alignment and so could // include any padding added to achieve the required alignment and so could
......
...@@ -121,6 +121,18 @@ TEST_F(PersistentMemoryAllocatorTest, AllocateAndIterate) { ...@@ -121,6 +121,18 @@ TEST_F(PersistentMemoryAllocatorTest, AllocateAndIterate) {
EXPECT_EQ(meminfo0.total, meminfo1.total); EXPECT_EQ(meminfo0.total, meminfo1.total);
EXPECT_GT(meminfo0.free, meminfo1.free); EXPECT_GT(meminfo0.free, meminfo1.free);
// Verify that pointers can be turned back into references and that invalid
// addresses return null.
char* memory1 = allocator_->GetAsArray<char>(block1, 1, 1);
ASSERT_TRUE(memory1);
EXPECT_EQ(block1, allocator_->GetAsReference(memory1, 0));
EXPECT_EQ(block1, allocator_->GetAsReference(memory1, 1));
EXPECT_EQ(0U, allocator_->GetAsReference(memory1, 2));
EXPECT_EQ(0U, allocator_->GetAsReference(memory1 + 1, 0));
EXPECT_EQ(0U, allocator_->GetAsReference(memory1 + 16, 0));
EXPECT_EQ(0U, allocator_->GetAsReference(nullptr, 0));
EXPECT_EQ(0U, allocator_->GetAsReference(&base_name, 0));
// Ensure that the test-object can be made iterable. // Ensure that the test-object can be made iterable.
PersistentMemoryAllocator::Iterator iter1a(allocator_.get()); PersistentMemoryAllocator::Iterator iter1a(allocator_.get());
EXPECT_EQ(0U, iter1a.GetLast()); EXPECT_EQ(0U, iter1a.GetLast());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment