Commit 94004694 authored by Benoît Lizé's avatar Benoît Lizé Committed by Commit Bot

base/allocator: Add tags and names for Blink GC and PartitionAlloc ranges.

Anonymous memory can be tagged (on OS X) or named (on Android). Add tags and
names for BlinkGC and PartitionAlloc, to ease memory investigations and
debugging.

Example output on Android, by looking at /proc/[PID]/smaps:
34c02000-34c04000 ---p 00000000 00:00 0                                  [anon:partition_alloc]
Name:           [anon:partition_alloc]
Size:                  8 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Rss:                   0 kB
Pss:                   0 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         0 kB
Referenced:            0 kB
Anonymous:             0 kB
AnonHugePages:         0 kB
Swap:                  0 kB
SwapPss:               0 kB
Locked:                0 kB
VmFlags: mr mw me ac
34c04000-34dfc000 rw-p 00000000 00:00 0                                  [anon:partition_alloc]
Name:           [anon:partition_alloc]
Size:               2016 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Rss:                 984 kB
Pss:                 984 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:       984 kB
Referenced:          980 kB
Anonymous:           984 kB
AnonHugePages:         0 kB
Swap:                  0 kB
SwapPss:               0 kB
Locked:                0 kB
VmFlags: rd wr mr mw me ac

Bug: 998048
Change-Id: I82b5ccdf5979fec920043aa62169607625aa7dbc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1774286
Commit-Queue: Benoit L <lizeb@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarChris Palmer <palmer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#692015}
parent b01eb3f0
......@@ -26,12 +26,15 @@ enum PageAccessibilityConfiguration {
PageReadWriteExecute,
};
// Mac OSX supports tagged memory regions, to help in debugging.
// macOS supports tagged memory regions, to help in debugging. On Android,
// these tags are used to name anonymous mappings.
enum class PageTag {
kFirst = 240, // Minimum tag value.
kChromium = 254, // Chromium page, including off-heap V8 ArrayBuffers.
kV8 = 255, // V8 heap pages.
kLast = kV8 // Maximum tag value.
kFirst = 240, // Minimum tag value.
kBlinkGC = 252, // Blink GC pages.
kPartitionAlloc = 253, // PartitionAlloc, no matter the partition.
kChromium = 254, // Chromium page.
kV8 = 255, // V8 heap pages.
kLast = kV8 // Maximum tag value.
};
// Allocate one or more pages.
......@@ -46,13 +49,15 @@ enum class PageTag {
// automatically.
//
// |page_accessibility| controls the permission of the allocated pages.
// |page_tag| is used on some platforms to identify the source of the
// allocation. Use PageTag::kChromium as a catch-all category.
//
// This call will return null if the allocation cannot be satisfied.
BASE_EXPORT void* AllocPages(void* address,
size_t length,
size_t align,
PageAccessibilityConfiguration page_accessibility,
PageTag tag = PageTag::kChromium,
PageTag tag,
bool commit = true);
// Free one or more pages starting at |address| and continuing for |length|
......
......@@ -36,7 +36,17 @@ namespace base {
#if defined(OS_ANDROID)
namespace {
const char* PageTagToName(PageTag tag) {
// Important: All the names should be string literals. As per prctl.h in
// //third_party/android_ndk the kernel keeps a pointer to the name instead
// of copying it.
//
// Having the name in .rodata ensures that the pointer remains valid as
// long as the mapping is alive.
switch (tag) {
case PageTag::kBlinkGC:
return "blink_gc";
case PageTag::kPartitionAlloc:
return "partition_alloc";
case PageTag::kChromium:
return "chromium";
case PageTag::kV8:
......
......@@ -1154,13 +1154,13 @@ TEST_F(PartitionAllocTest, MappingCollision) {
page_base -= kPartitionPageSize;
// Map a single system page either side of the mapping for our allocations,
// with the goal of tripping up alignment of the next mapping.
void* map1 = AllocPages(page_base - kPageAllocationGranularity,
kPageAllocationGranularity,
kPageAllocationGranularity, PageInaccessible);
void* map1 = AllocPages(
page_base - kPageAllocationGranularity, kPageAllocationGranularity,
kPageAllocationGranularity, PageInaccessible, PageTag::kPartitionAlloc);
EXPECT_TRUE(map1);
void* map2 =
AllocPages(page_base + kSuperPageSize, kPageAllocationGranularity,
kPageAllocationGranularity, PageInaccessible);
void* map2 = AllocPages(
page_base + kSuperPageSize, kPageAllocationGranularity,
kPageAllocationGranularity, PageInaccessible, PageTag::kPartitionAlloc);
EXPECT_TRUE(map2);
for (i = 0; i < num_partition_pages_needed; ++i)
......@@ -1178,10 +1178,11 @@ TEST_F(PartitionAllocTest, MappingCollision) {
// with the goal of tripping up alignment of the next mapping.
map1 = AllocPages(page_base - kPageAllocationGranularity,
kPageAllocationGranularity, kPageAllocationGranularity,
PageReadWrite);
PageReadWrite, PageTag::kPartitionAlloc);
EXPECT_TRUE(map1);
map2 = AllocPages(page_base + kSuperPageSize, kPageAllocationGranularity,
kPageAllocationGranularity, PageReadWrite);
kPageAllocationGranularity, PageReadWrite,
PageTag::kPartitionAlloc);
EXPECT_TRUE(map2);
EXPECT_TRUE(TrySetSystemPagesAccess(map1, kPageAllocationGranularity,
PageInaccessible));
......
......@@ -39,8 +39,9 @@ ALWAYS_INLINE PartitionPage* PartitionDirectMap(PartitionRootBase* root,
map_size += kPageAllocationGranularityOffsetMask;
map_size &= kPageAllocationGranularityBaseMask;
char* ptr = reinterpret_cast<char*>(
AllocPages(nullptr, map_size, kSuperPageSize, PageReadWrite));
char* ptr = reinterpret_cast<char*>(AllocPages(nullptr, map_size,
kSuperPageSize, PageReadWrite,
PageTag::kPartitionAlloc));
if (UNLIKELY(!ptr))
return nullptr;
......@@ -219,8 +220,9 @@ ALWAYS_INLINE void* PartitionBucket::AllocNewSlotSpan(
// page table bloat and not fragmenting address spaces in 32 bit
// architectures.
char* requested_address = root->next_super_page;
char* super_page = reinterpret_cast<char*>(AllocPages(
requested_address, kSuperPageSize, kSuperPageSize, PageReadWrite));
char* super_page = reinterpret_cast<char*>(
AllocPages(requested_address, kSuperPageSize, kSuperPageSize,
PageReadWrite, PageTag::kPartitionAlloc));
if (UNLIKELY(!super_page))
return nullptr;
......
......@@ -113,7 +113,7 @@ GCInfoTable::GCInfoTable() {
CHECK(!table_);
table_ = reinterpret_cast<GCInfo const**>(base::AllocPages(
nullptr, MaxTableSize(), base::kPageAllocationGranularity,
base::PageInaccessible));
base::PageInaccessible, base::PageTag::kBlinkGC));
CHECK(table_);
Resize();
}
......
......@@ -65,7 +65,8 @@ PageMemoryRegion* PageMemoryRegion::Allocate(size_t size,
// Round size up to the allocation granularity.
size = base::RoundUpToPageAllocationGranularity(size);
Address base = static_cast<Address>(
base::AllocPages(nullptr, size, kBlinkPageSize, base::PageInaccessible));
base::AllocPages(nullptr, size, kBlinkPageSize, base::PageInaccessible,
base::PageTag::kBlinkGC));
if (!base)
BlinkGCOutOfMemory();
return new PageMemoryRegion(base, size, num_pages, region_tree);
......
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