Skip to content

Commit 53acbba

Browse files
ddegazioMark Lam
authored andcommitted
Allow custom profiling of JS and non-JS allocation counts
https://bugs.webkit.org/show_bug.cgi?id=262827 rdar://114841891 Reviewed by Mark Lam. Adds macros to FastMalloc, IsoHeap, and Gigacage malloc functions to allow for custom profiling code around different kinds of mallocs. Profiling for different categories of mallocs can be provided by defining certain macros (see AllocationCounts.h for more information). * Source/WTF/wtf/Gigacage.cpp: (Gigacage::tryAlignedMalloc): (Gigacage::tryMalloc): (Gigacage::tryZeroedMalloc): (Gigacage::tryRealloc): * Source/bmalloc/CMakeLists.txt: * Source/bmalloc/bmalloc.xcodeproj/project.pbxproj: * Source/bmalloc/bmalloc/AllocationCounts.cpp: Added. * Source/bmalloc/bmalloc/AllocationCounts.h: Added. * Source/bmalloc/bmalloc/BCompiler.h: * Source/bmalloc/bmalloc/IsoHeap.cpp: (bmalloc::api::isoAllocate): (bmalloc::api::isoTryAllocate): * Source/bmalloc/bmalloc/bmalloc.h: Canonical link: https://commits.webkit.org/269033@main
1 parent 3febba3 commit 53acbba

File tree

8 files changed

+161
-10
lines changed

8 files changed

+161
-10
lines changed

Source/WTF/wtf/FastMalloc.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,7 @@ void* fastMalloc(size_t size)
535535
if (!AvoidRecordingScope::avoidRecordingCount())
536536
MallocCallTracker::singleton().recordMalloc(result, size);
537537
#endif
538+
BPROFILE_ALLOCATION(NON_JS_CELL, result, size);
538539
return result;
539540
}
540541

@@ -547,14 +548,17 @@ void* fastZeroedMalloc(size_t size)
547548
if (!AvoidRecordingScope::avoidRecordingCount())
548549
MallocCallTracker::singleton().recordMalloc(result, size);
549550
#endif
551+
BPROFILE_ALLOCATION(NON_JS_CELL, result, size);
550552
return result;
551553
}
552554

553555
TryMallocReturnValue tryFastZeroedMalloc(size_t size)
554556
{
555557
FAIL_IF_EXCEEDS_LIMIT(size);
556558
ASSERT(!forbidMallocUseScopeCount || disableMallocRestrictionScopeCount);
557-
return bmalloc::api::tryZeroedMalloc(size);
559+
void* result = bmalloc::api::tryZeroedMalloc(size);
560+
BPROFILE_TRY_ALLOCATION(NON_JS_CELL, result, size);
561+
return result;
558562
}
559563

560564
void* fastCalloc(size_t numElements, size_t elementSize)
@@ -565,6 +569,7 @@ void* fastCalloc(size_t numElements, size_t elementSize)
565569
void* result = fastZeroedMalloc(checkedSize);
566570
if (!result)
567571
CRASH();
572+
BPROFILE_ALLOCATION(NON_JS_CELL, result, size);
568573
return result;
569574
}
570575

@@ -577,6 +582,7 @@ void* fastRealloc(void* object, size_t size)
577582
if (!AvoidRecordingScope::avoidRecordingCount())
578583
MallocCallTracker::singleton().recordRealloc(object, result, size);
579584
#endif
585+
BPROFILE_ALLOCATION(NON_JS_CELL, result, size);
580586
return result;
581587
}
582588

@@ -620,6 +626,7 @@ void* fastAlignedMalloc(size_t alignment, size_t size)
620626
if (!AvoidRecordingScope::avoidRecordingCount())
621627
MallocCallTracker::singleton().recordMalloc(result, size);
622628
#endif
629+
BPROFILE_ALLOCATION(NON_JS_CELL, result, size);
623630
return result;
624631
}
625632

@@ -632,6 +639,7 @@ void* tryFastAlignedMalloc(size_t alignment, size_t size)
632639
if (!AvoidRecordingScope::avoidRecordingCount())
633640
MallocCallTracker::singleton().recordMalloc(result, size);
634641
#endif
642+
BPROFILE_TRY_ALLOCATION(NON_JS_CELL, result, size);
635643
return result;
636644
}
637645

@@ -644,7 +652,9 @@ TryMallocReturnValue tryFastMalloc(size_t size)
644652
{
645653
FAIL_IF_EXCEEDS_LIMIT(size);
646654
ASSERT(!forbidMallocUseScopeCount || disableMallocRestrictionScopeCount);
647-
return bmalloc::api::tryMalloc(size);
655+
void* result = bmalloc::api::tryMalloc(size);
656+
BPROFILE_TRY_ALLOCATION(NON_JS_CELL, result, size);
657+
return result;
648658
}
649659

650660
TryMallocReturnValue tryFastCalloc(size_t numElements, size_t elementSize)
@@ -661,7 +671,9 @@ TryMallocReturnValue tryFastRealloc(void* object, size_t newSize)
661671
{
662672
FAIL_IF_EXCEEDS_LIMIT(newSize);
663673
ASSERT(!forbidMallocUseScopeCount || disableMallocRestrictionScopeCount);
664-
return bmalloc::api::tryRealloc(object, newSize);
674+
void* result = bmalloc::api::tryRealloc(object, newSize);
675+
BPROFILE_TRY_ALLOCATION(NON_JS_CELL, result, size);
676+
return result;
665677
}
666678

667679
void releaseFastMallocFreeMemoryForThisThread()

Source/WTF/wtf/Gigacage.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ namespace Gigacage {
8181
void* tryAlignedMalloc(Kind kind, size_t alignment, size_t size)
8282
{
8383
void* result = bmalloc::api::tryMemalign(alignment, size, bmalloc::heapKind(kind));
84+
BPROFILE_TRY_ALLOCATION(GIGACAGE, kind, result, size);
8485
WTF::compilerFence();
8586
return result;
8687
}
@@ -97,20 +98,23 @@ void alignedFree(Kind kind, void* p)
9798
void* tryMalloc(Kind kind, size_t size)
9899
{
99100
void* result = bmalloc::api::tryMalloc(size, bmalloc::heapKind(kind));
101+
BPROFILE_TRY_ALLOCATION(GIGACAGE, kind, result, size);
100102
WTF::compilerFence();
101103
return result;
102104
}
103105

104106
void* tryZeroedMalloc(Kind kind, size_t size)
105107
{
106108
void* result = bmalloc::api::tryZeroedMalloc(size, bmalloc::heapKind(kind));
109+
BPROFILE_TRY_ALLOCATION(GIGACAGE, kind, result, size);
107110
WTF::compilerFence();
108111
return result;
109112
}
110113

111114
void* tryRealloc(Kind kind, void* pointer, size_t size)
112115
{
113116
void* result = bmalloc::api::tryRealloc(pointer, size, bmalloc::heapKind(kind));
117+
BPROFILE_TRY_ALLOCATION(GIGACAGE, kind, result, size);
114118
WTF::compilerFence();
115119
return result;
116120
}
@@ -127,6 +131,7 @@ void free(Kind kind, void* p)
127131
void* tryAllocateZeroedVirtualPages(Kind kind, size_t size)
128132
{
129133
void* result = bmalloc::api::tryLargeZeroedMemalignVirtual(WTF::pageSize(), size, bmalloc::heapKind(kind));
134+
BPROFILE_TRY_ALLOCATION(GIGACAGE, kind, result, size);
130135
WTF::compilerFence();
131136
return result;
132137
}

Source/bmalloc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ set(bmalloc_PUBLIC_HEADERS
192192
bmalloc/Algorithm.h
193193
bmalloc/AllIsoHeaps.h
194194
bmalloc/AllIsoHeapsInlines.h
195+
bmalloc/AllocationCounts.h
195196
bmalloc/Allocator.h
196197
bmalloc/AvailableMemory.h
197198
bmalloc/BAssert.h

Source/bmalloc/bmalloc.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@
131131
2B6EB7A029EE102E00F10400 /* pas_report_crash_pgm_report.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B6EB79F29EE102E00F10400 /* pas_report_crash_pgm_report.h */; settings = {ATTRIBUTES = (Private, ); }; };
132132
2BDF4F4C29E8B8BA0056BF50 /* pas_report_crash.c in Sources */ = {isa = PBXBuildFile; fileRef = 2BDF4F4A29E8B8BA0056BF50 /* pas_report_crash.c */; };
133133
2BDF4F4D29E8B8BA0056BF50 /* pas_report_crash.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BDF4F4B29E8B8BA0056BF50 /* pas_report_crash.h */; settings = {ATTRIBUTES = (Private, ); }; };
134+
306D490A2ACCA05900CCFEE5 /* AllocationCounts.h in Headers */ = {isa = PBXBuildFile; fileRef = 306D49052ACCA01400CCFEE5 /* AllocationCounts.h */; settings = {ATTRIBUTES = (Private, ); }; };
135+
306D490B2ACCA05A00CCFEE5 /* AllocationCounts.h in Headers */ = {isa = PBXBuildFile; fileRef = 306D49052ACCA01400CCFEE5 /* AllocationCounts.h */; settings = {ATTRIBUTES = (Private, ); }; };
134136
4426E2801C838EE0008EB042 /* Logging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4426E27E1C838EE0008EB042 /* Logging.cpp */; };
135137
4426E2811C838EE0008EB042 /* Logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 4426E27F1C838EE0008EB042 /* Logging.h */; settings = {ATTRIBUTES = (Private, ); }; };
136138
52F47249210BA30200B730BB /* MemoryStatusSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 52F47248210BA2F500B730BB /* MemoryStatusSPI.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -1329,6 +1331,7 @@
13291331
2CE2AE512769928200D02BBC /* pas_compact_tagged_void_ptr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pas_compact_tagged_void_ptr.h; path = libpas/src/libpas/pas_compact_tagged_void_ptr.h; sourceTree = "<group>"; };
13301332
2CE2AE572769928300D02BBC /* pas_probabilistic_guard_malloc_allocator.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pas_probabilistic_guard_malloc_allocator.c; path = libpas/src/libpas/pas_probabilistic_guard_malloc_allocator.c; sourceTree = "<group>"; };
13311333
2CE2AE582769928300D02BBC /* pas_probabilistic_guard_malloc_allocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pas_probabilistic_guard_malloc_allocator.h; path = libpas/src/libpas/pas_probabilistic_guard_malloc_allocator.h; sourceTree = "<group>"; };
1334+
306D49052ACCA01400CCFEE5 /* AllocationCounts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AllocationCounts.h; path = bmalloc/AllocationCounts.h; sourceTree = "<group>"; };
13321335
4426E27E1C838EE0008EB042 /* Logging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Logging.cpp; path = bmalloc/Logging.cpp; sourceTree = "<group>"; };
13331336
4426E27F1C838EE0008EB042 /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = bmalloc/Logging.h; sourceTree = "<group>"; };
13341337
52F47248210BA2F500B730BB /* MemoryStatusSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MemoryStatusSPI.h; path = bmalloc/darwin/MemoryStatusSPI.h; sourceTree = "<group>"; };
@@ -2071,6 +2074,7 @@
20712074
14D9DB4E17F2866E00EAAB79 /* heap */ = {
20722075
isa = PBXGroup;
20732076
children = (
2077+
306D49052ACCA01400CCFEE5 /* AllocationCounts.h */,
20742078
7939885A2076EEB50074A2E7 /* BulkDecommit.h */,
20752079
140FA00219CE429C00FFD3C8 /* BumpRange.h */,
20762080
147DC6E21CA5B70B00724E8D /* Chunk.h */,
@@ -2163,6 +2167,7 @@
21632167
isa = PBXHeadersBuildPhase;
21642168
buildActionMask = 2147483647;
21652169
files = (
2170+
306D490A2ACCA05900CCFEE5 /* AllocationCounts.h in Headers */,
21662171
);
21672172
runOnlyForDeploymentPostprocessing = 0;
21682173
};
@@ -2174,6 +2179,7 @@
21742179
14DD78C518F48D7500950702 /* Algorithm.h in Headers */,
21752180
0F7EB8341F9541B000F1ABCB /* AllIsoHeaps.h in Headers */,
21762181
0F7EB84F1F954D4E00F1ABCB /* AllIsoHeapsInlines.h in Headers */,
2182+
306D490B2ACCA05A00CCFEE5 /* AllocationCounts.h in Headers */,
21772183
14DD789818F48D4A00950702 /* Allocator.h in Headers */,
21782184
6599C5CD1EC3F15900A2F7BB /* AvailableMemory.h in Headers */,
21792185
14DD78C718F48D7500950702 /* BAssert.h in Headers */,
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright (C) 2023 Apple Inc. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* 2. Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
*
13+
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21+
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+
*/
25+
26+
#pragma once
27+
28+
#include "BExport.h"
29+
#include <atomic>
30+
31+
#define BFOR_EACH_ALLOCATION_KIND(macro) \
32+
macro(JS_CELL) /* Allocation of any JSCell */ \
33+
macro(NON_JS_CELL) /* Allocation of any non-JSCell */ \
34+
macro(GIGACAGE) /* Allocation within a gigacage, takes heap kind as first parameter */
35+
36+
#define BPROFILE_ALLOCATION(kind, ...) \
37+
BPROFILE_ALLOCATION_ ## kind(__VA_ARGS__)
38+
39+
#define BPROFILE_TRY_ALLOCATION(kind, ...) \
40+
BPROFILE_TRY_ALLOCATION_ ## kind(__VA_ARGS__)
41+
42+
// Definitions of specializations of the above macro (i.e. BPROFILE_ALLOCATION_JS_CELL(ptr, size))
43+
// may be provided in an AllocationCountsAdditions.h header to add custom profiling code
44+
// at an allocation site, taking both the pointer variable (which may be modified) and the
45+
// size of the allocation in bytes.
46+
47+
#if __has_include(<WebKitAdditions/AllocationCountsAdditions.h>)
48+
#include <WebKitAdditions/AllocationCountsAdditions.h>
49+
#elif __has_include(<AllocationCountsAdditions.h>)
50+
#include <AllocationCountsAdditions.h>
51+
#endif
52+
53+
// If allocation profiling macros weren't defined above, we define them below as no-ops.
54+
// Additionally, BENABLE(PROFILE_<type>_ALLOCATION) can be queried to see if we are profiling
55+
// allocations of a specific kind.
56+
57+
#ifdef BPROFILE_ALLOCATION_JS_CELL
58+
#define BENABLE_PROFILE_JS_CELL_ALLOCATION 1
59+
#else
60+
#define BENABLE_PROFILE_JS_CELL_ALLOCATION 0
61+
#define BPROFILE_ALLOCATION_JS_CELL(ptr, size) do { } while (false)
62+
#endif
63+
64+
#ifdef BPROFILE_ALLOCATION_NON_JS_CELL
65+
#define BENABLE_PROFILE_NON_JS_CELL_ALLOCATION 1
66+
#else
67+
#define BENABLE_PROFILE_NON_JS_CELL_ALLOCATION 0
68+
#define BPROFILE_ALLOCATION_NON_JS_CELL(ptr, size) do { } while (false)
69+
#endif
70+
71+
#ifdef BPROFILE_ALLOCATION_GIGACAGE
72+
#define BENABLE_PROFILE_GIGACAGE_ALLOCATION 1
73+
#else
74+
#define BENABLE_PROFILE_GIGACAGE_ALLOCATION 0
75+
#define BPROFILE_ALLOCATION_GIGACAGE(kind, ptr, size) do { } while (false)
76+
#endif
77+
78+
#ifdef BPROFILE_TRY_ALLOCATION_JS_CELL
79+
#define BENABLE_PROFILE_JS_CELL_TRY_ALLOCATION 1
80+
#else
81+
#define BENABLE_PROFILE_JS_CELL_TRY_ALLOCATION 0
82+
#define BPROFILE_TRY_ALLOCATION_JS_CELL(ptr, size) do { } while (false)
83+
#endif
84+
85+
#ifdef BPROFILE_TRY_ALLOCATION_NON_JS_CELL
86+
#define BENABLE_PROFILE_NON_JS_CELL_TRY_ALLOCATION 1
87+
#else
88+
#define BENABLE_PROFILE_NON_JS_CELL_TRY_ALLOCATION 0
89+
#define BPROFILE_TRY_ALLOCATION_NON_JS_CELL(ptr, size) do { } while (false)
90+
#endif
91+
92+
#ifdef BPROFILE_TRY_ALLOCATION_GIGACAGE
93+
#define BENABLE_PROFILE_GIGACAGE_TRY_ALLOCATION 1
94+
#else
95+
#define BENABLE_PROFILE_GIGACAGE_TRY_ALLOCATION 0
96+
#define BPROFILE_TRY_ALLOCATION_GIGACAGE(kind, ptr, size) do { } while (false)
97+
#endif

Source/bmalloc/bmalloc/BCompiler.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,26 @@
9393
#define BFALLTHROUGH
9494
#endif
9595

96+
/* BLIKELY */
97+
98+
#if !defined(BLIKELY) && BCOMPILER(GCC_COMPATIBLE)
99+
#define BLIKELY(x) __builtin_expect(!!(x), 1)
100+
#endif
101+
102+
#if !defined(BLIKELY)
103+
#define BLIKELY(x) (x)
104+
#endif
105+
106+
/* BUNLIKELY */
107+
108+
#if !defined(BUNLIKELY) && BCOMPILER(GCC_COMPATIBLE)
109+
#define BUNLIKELY(x) __builtin_expect(!!(x), 0)
110+
#endif
111+
112+
#if !defined(BUNLIKELY)
113+
#define BUNLIKELY(x) (x)
114+
#endif
115+
96116
/* BUNUSED_TYPE_ALIAS */
97117

98118
#if !defined(BUNUSED_TYPE_ALIAS) && BCOMPILER(GCC_COMPATIBLE)

Source/bmalloc/bmalloc/IsoHeap.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626
#include "IsoHeap.h"
2727

28+
#include "AllocationCounts.h"
29+
2830
#if BUSE(LIBPAS)
2931

3032
#include "bmalloc_heap_inlines.h"
@@ -38,28 +40,35 @@ void* isoAllocate(pas_heap_ref& heapRef)
3840
// FIXME: libpas should know how to do the fallback thing.
3941
// https://bugs.webkit.org/show_bug.cgi?id=227177
4042

43+
auto typeSize = pas_simple_type_size(reinterpret_cast<pas_simple_type>(heapRef.type));
4144
if (IsoMallocFallback::shouldTryToFallBack()) {
42-
IsoMallocFallback::MallocResult result = IsoMallocFallback::tryMalloc(
43-
pas_simple_type_size(reinterpret_cast<pas_simple_type>(heapRef.type)));
45+
IsoMallocFallback::MallocResult result = IsoMallocFallback::tryMalloc(typeSize);
4446
if (result.didFallBack) {
4547
RELEASE_BASSERT(result.ptr);
48+
BPROFILE_ALLOCATION_NON_JS_CELL(result.ptr, typeSize);
4649
return result.ptr;
4750
}
4851
}
4952

50-
return bmalloc_iso_allocate_inline(&heapRef);
53+
void* result = bmalloc_iso_allocate_inline(&heapRef);
54+
BPROFILE_ALLOCATION_NON_JS_CELL(result, typeSize);
55+
return result;
5156
}
5257

5358
void* isoTryAllocate(pas_heap_ref& heapRef)
5459
{
60+
auto typeSize = pas_simple_type_size(reinterpret_cast<pas_simple_type>(heapRef.type));
5561
if (IsoMallocFallback::shouldTryToFallBack()) {
56-
IsoMallocFallback::MallocResult result = IsoMallocFallback::tryMalloc(
57-
pas_simple_type_size(reinterpret_cast<pas_simple_type>(heapRef.type)));
58-
if (result.didFallBack)
62+
IsoMallocFallback::MallocResult result = IsoMallocFallback::tryMalloc(typeSize);
63+
if (result.didFallBack) {
64+
BPROFILE_TRY_ALLOCATION(NON_JS_CELL, result.ptr, typeSize);
5965
return result.ptr;
66+
}
6067
}
6168

62-
return bmalloc_try_iso_allocate_inline(&heapRef);
69+
void* result = bmalloc_try_iso_allocate_inline(&heapRef);
70+
BPROFILE_TRY_ALLOCATION(NON_JS_CELL, result, typeSize);
71+
return result;
6372
}
6473

6574
void isoDeallocate(void* ptr)

Source/bmalloc/bmalloc/bmalloc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#pragma once
2727

28+
#include "AllocationCounts.h"
2829
#include "AvailableMemory.h"
2930
#include "Cache.h"
3031
#include "DebugHeap.h"

0 commit comments

Comments
 (0)