blob: 6363bb09aa343562e3944c69f27e8864de471951 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "tools/memory/simulator/contiguous_memory_holder.h"
#include <cstdint>
#include "base/check_op.h"
#include "base/debug/alias.h"
#include "base/memory/page_size.h"
#include "partition_alloc/page_allocator.h"
namespace memory_simulator {
ContiguousMemoryHolder::ContiguousMemoryHolder(size_t max_pages)
: memory_length_(max_pages * base::GetPageSize()),
memory_(partition_alloc::AllocPages(
memory_length_,
base::GetPageSize(),
::partition_alloc::PageAccessibilityConfiguration(
partition_alloc::PageAccessibilityConfiguration::kReadWrite),
partition_alloc::PageTag::kSimulation)),
alloc_position_(reinterpret_cast<uint64_t*>(memory_)),
read_position_(reinterpret_cast<uint64_t*>(memory_)),
write_position_(reinterpret_cast<uint64_t*>(memory_)) {
CHECK_NE(0u, memory_);
}
ContiguousMemoryHolder::~ContiguousMemoryHolder() {
partition_alloc::FreePages(memory_, memory_length_);
}
void ContiguousMemoryHolder::Allocate() {
DCHECK_EQ((reinterpret_cast<uintptr_t>(alloc_position_) - memory_) %
base::GetPageSize(),
0u);
DCHECK_LT(reinterpret_cast<uintptr_t>(alloc_position_),
memory_ + memory_length_);
// Writing zeros to the memory page forces it to be added to this process'
// private footprint.
for (size_t i = 0; i < base::GetPageSize() / sizeof(uint64_t); ++i) {
*alloc_position_ = 0;
++alloc_position_;
}
}
void ContiguousMemoryHolder::Read() {
if (read_position_ >= alloc_position_) {
read_position_ = reinterpret_cast<uint64_t*>(memory_);
if (read_position_ >= alloc_position_) {
// No-op if the initial allocation didn't happen.
return;
}
}
DCHECK_LT(reinterpret_cast<uintptr_t>(read_position_),
memory_ + memory_length_);
DCHECK_EQ((reinterpret_cast<uintptr_t>(read_position_) - memory_) %
base::GetPageSize(),
0u);
uint64_t sum = 0;
for (size_t i = 0; i < base::GetPageSize() / sizeof(uint64_t); ++i) {
sum += *read_position_;
++read_position_;
}
base::debug::Alias(&sum);
}
void ContiguousMemoryHolder::Write() {
if (write_position_ >= alloc_position_) {
write_position_ = reinterpret_cast<uint64_t*>(memory_);
if (write_position_ >= alloc_position_) {
// No-op if the initial allocation didn't happen.
return;
}
}
DCHECK_LT(reinterpret_cast<uintptr_t>(write_position_),
memory_ + memory_length_);
DCHECK_EQ((reinterpret_cast<uintptr_t>(write_position_) - memory_) %
base::GetPageSize(),
0u);
for (size_t i = 0; i < base::GetPageSize() / sizeof(uint64_t); ++i) {
*write_position_ = Rand();
++write_position_;
}
}
} // namespace memory_simulator