#include "partition_alloc/partition_alloc.h"
#include <algorithm>
#include <atomic>
#include <limits>
#include <memory>
#include <vector>
#include "base/debug/debugging_buildflags.h"
#include "base/timer/lap_timer.h"
#include "partition_alloc/build_config.h"
#include "partition_alloc/extended_api.h"
#include "partition_alloc/partition_alloc_base/logging.h"
#include "partition_alloc/partition_alloc_base/strings/stringprintf.h"
#include "partition_alloc/partition_alloc_base/threading/platform_thread_for_testing.h"
#include "partition_alloc/partition_alloc_base/time/time.h"
#include "partition_alloc/partition_alloc_check.h"
#include "partition_alloc/partition_alloc_constants.h"
#include "partition_alloc/partition_alloc_for_testing.h"
#include "partition_alloc/partition_root.h"
#include "partition_alloc/thread_cache.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/perf/perf_result_reporter.h"
#if PA_BUILDFLAG(IS_ANDROID) || PA_BUILDFLAG(PA_ARCH_CPU_32_BITS) || \
PA_BUILDFLAG(IS_FUCHSIA)
#define MEMORY_CONSTRAINED
#endif
#if BUILDFLAG(ENABLE_ALLOCATION_STACK_TRACE_RECORDER)
#include "base/allocator/dispatcher/dispatcher.h"
#include "base/debug/allocation_trace.h"
#endif
namespace partition_alloc::internal {
namespace {
constexpr ::base::TimeDelta kTimeLimit = …;
constexpr int kWarmupRuns = …;
constexpr int kTimeCheckInterval = …;
constexpr size_t kAllocSize = …;
constexpr int kMultiBucketMinimumSize = …;
constexpr int kMultiBucketIncrement = …;
constexpr int kMultiBucketRounds = …;
constexpr char kMetricPrefixMemoryAllocation[] = …;
constexpr char kMetricThroughput[] = …;
constexpr char kMetricTimePerAllocation[] = …;
perf_test::PerfResultReporter SetUpReporter(const std::string& story_name) { … }
enum class AllocatorType { … };
class Allocator { … };
class SystemAllocator : public Allocator { … };
class PartitionAllocator : public Allocator { … };
class PartitionAllocatorWithThreadCache : public Allocator { … };
#if BUILDFLAG(ENABLE_ALLOCATION_STACK_TRACE_RECORDER)
class PartitionAllocatorWithAllocationStackTraceRecorder : public Allocator {
public:
explicit PartitionAllocatorWithAllocationStackTraceRecorder(
bool register_hooks)
: register_hooks_(register_hooks) {
if (register_hooks_) {
dispatcher_.InitializeForTesting(&recorder_);
}
}
~PartitionAllocatorWithAllocationStackTraceRecorder() override {
if (register_hooks_) {
dispatcher_.ResetForTesting();
}
}
void* Alloc(size_t size) override { return alloc_.AllocInline(size); }
void Free(void* data) override {
PartitionRoot::FreeInlineInUnknownRoot<
partition_alloc::FreeFlags::kNoHooks>(data);
}
private:
bool const register_hooks_;
PartitionRoot alloc_{PartitionOptions{}};
::base::allocator::dispatcher::Dispatcher& dispatcher_ =
::base::allocator::dispatcher::Dispatcher::GetInstance();
::base::debug::tracer::AllocationTraceRecorder recorder_;
};
#endif
class TestLoopThread : public base::PlatformThreadForTesting::Delegate { … };
void DisplayResults(const std::string& story_name,
float iterations_per_second) { … }
class MemoryAllocationPerfNode { … };
#if !defined(MEMORY_CONSTRAINED)
float SingleBucket(Allocator* allocator) { … }
#endif
float SingleBucketWithFree(Allocator* allocator) { … }
#if !defined(MEMORY_CONSTRAINED)
float MultiBucket(Allocator* allocator) { … }
#endif
float MultiBucketWithFree(Allocator* allocator) { … }
float DirectMapped(Allocator* allocator) { … }
std::unique_ptr<Allocator> CreateAllocator(AllocatorType type,
bool use_alternate_bucket_dist) { … }
void LogResults(int thread_count,
AllocatorType alloc_type,
uint64_t total_laps_per_second,
uint64_t min_laps_per_second) { … }
void RunTest(int thread_count,
bool use_alternate_bucket_dist,
AllocatorType alloc_type,
float (*test_fn)(Allocator*),
float (*noisy_neighbor_fn)(Allocator*),
const char* story_base_name) { … }
class PartitionAllocMemoryAllocationPerfTest
: public testing::TestWithParam<std::tuple<int, bool, AllocatorType>> { … };
INSTANTIATE_TEST_SUITE_P(…);
#if !defined(MEMORY_CONSTRAINED)
TEST_P(PartitionAllocMemoryAllocationPerfTest, SingleBucket) { … }
#endif
TEST_P(PartitionAllocMemoryAllocationPerfTest, SingleBucketWithFree) { … }
#if !defined(MEMORY_CONSTRAINED)
TEST_P(PartitionAllocMemoryAllocationPerfTest, MultiBucket) { … }
#endif
TEST_P(PartitionAllocMemoryAllocationPerfTest, MultiBucketWithFree) { … }
TEST_P(PartitionAllocMemoryAllocationPerfTest, DirectMapped) { … }
#if !defined(MEMORY_CONSTRAINED)
TEST_P(PartitionAllocMemoryAllocationPerfTest,
DISABLED_MultiBucketWithNoisyNeighbor) { … }
#endif
}
}