Skip to content

Commit 7021c1e

Browse files
structclaude
andcommitted
condense leak detector and zone verify loops with optional NEON quick-reject
Both bitmap scans now share a single per-qword body using popcount/ctz on USED_BIT_VECTOR (and its complement for canary-bearing slots). The USE_NEON path is reduced to a 2-qword load + zero/canary quick-reject that lets us skip 64 chunk slots at a time when the bitmap range is empty of relevant bits, matching the structure used in iso_scan_zone_free_slot_slow. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent f23083b commit 7021c1e

2 files changed

Lines changed: 31 additions & 145 deletions

File tree

src/iso_alloc_profiler.c

Lines changed: 15 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -125,71 +125,30 @@ INTERNAL_HIDDEN uint64_t _iso_alloc_zone_leak_detector(iso_alloc_zone_t *zone, b
125125
uint32_t was_used = 0;
126126
int64_t bms = zone->bitmap_size / sizeof(bitmap_index_t);
127127

128+
for(int64_t i = 0; i < bms;) {
128129
#if USE_NEON
129-
/* Process the bitmap two qwords at a time. The common case is that a
130-
* qword is entirely zero (every chunk in those 32 slots is free and
131-
* never used) — vectorising the zero-check lets us skip both qwords at
132-
* once. For each non-zero qword we popcount the was_used pattern in
133-
* O(1) and walk only the chunks whose low bit is set with ctz, instead
134-
* of scanning all 32 pairs. */
135-
int64_t i = 0;
136-
const int64_t bms_pair = bms & ~(int64_t) 1;
137-
138-
for(; i < bms_pair; i += 2) {
139-
int64x2_t v = vld1q_s64((const int64_t *) &bm[i]);
140-
const uint64_t lane0 = (uint64_t) vgetq_lane_s64(v, 0);
141-
const uint64_t lane1 = (uint64_t) vgetq_lane_s64(v, 1);
142-
143-
if((lane0 | lane1) == 0) {
144-
continue;
145-
}
146-
147-
const uint64_t lanes[2] = {lane0, lane1};
148-
for(int k = 0; k < 2; k++) {
149-
uint64_t bts = lanes[k];
150-
if(bts == 0) {
130+
/* Two-qword quick-reject: load 16 bytes of bitmap and skip both
131+
* qwords when every chunk in those 64 slots is free and never used. */
132+
if(i + 1 < bms) {
133+
int64x2_t v = vld1q_s64((const int64_t *) &bm[i]);
134+
if((vgetq_lane_s64(v, 0) | vgetq_lane_s64(v, 1)) == 0) {
135+
i += 2;
151136
continue;
152137
}
153-
154-
/* was_used: chunks encoded 01 (low=0, high=1). The mask of
155-
* odd-bit positions whose paired even bit is clear is
156-
* (~bts) & (bts >> 1) & USED_BIT_VECTOR. */
157-
uint64_t was_used_mask = (~bts) & (bts >> 1) & USED_BIT_VECTOR;
158-
was_used += __builtin_popcountll(was_used_mask);
159-
160-
/* Chunks with low bit set are either in-use (10) or canary
161-
* (11). Walk just those positions to verify canaries. */
162-
uint64_t in_use_low = bts & USED_BIT_VECTOR;
163-
while(in_use_low) {
164-
int j = __builtin_ctzll(in_use_low);
165-
in_use_low &= in_use_low - 1;
166-
167-
int64_t bit_two = GET_BIT(bts, (j + 1));
168-
bit_slot_t bit_slot = (((bitmap_index_t) (i + k)) * BITS_PER_QWORD) + j;
169-
const void *leak = (zone->user_pages_start + ((bit_slot >> 1) * zone->chunk_size));
170-
171-
if(bit_two == 1 && (check_canary_no_abort(zone, leak) != ERR)) {
172-
continue;
173-
} else {
174-
in_use++;
175-
176-
if(profile == false) {
177-
LOG("Leaked chunk (%d) in zone[%d] of %d bytes detected at 0x%p (bit position = %d)", in_use, zone->index, zone->chunk_size, leak, bit_slot);
178-
}
179-
}
180-
}
181138
}
182-
}
183-
184-
for(; i < bms; i++) {
139+
#endif
185140
uint64_t bts = (uint64_t) bm[i];
186141
if(bts == 0) {
142+
i++;
187143
continue;
188144
}
189145

190-
uint64_t was_used_mask = (~bts) & (bts >> 1) & USED_BIT_VECTOR;
191-
was_used += __builtin_popcountll(was_used_mask);
146+
/* was_used (encoding 01: low=0, high=1) — popcount the odd-bit
147+
* positions whose paired even bit is clear. */
148+
was_used += __builtin_popcountll((~bts) & (bts >> 1) & USED_BIT_VECTOR);
192149

150+
/* Chunks with low bit set are either in-use (10) or canary (11).
151+
* Walk just those positions with ctz instead of testing all 32. */
193152
uint64_t in_use_low = bts & USED_BIT_VECTOR;
194153
while(in_use_low) {
195154
int j = __builtin_ctzll(in_use_low);
@@ -209,45 +168,8 @@ INTERNAL_HIDDEN uint64_t _iso_alloc_zone_leak_detector(iso_alloc_zone_t *zone, b
209168
}
210169
}
211170
}
171+
i++;
212172
}
213-
#else
214-
for(bitmap_index_t i = 0; i < bms; i++) {
215-
for(int j = 0; j < BITS_PER_QWORD; j += BITS_PER_CHUNK) {
216-
217-
if(bm[i] == 0) {
218-
continue;
219-
}
220-
221-
int64_t bit = GET_BIT(bm[i], j);
222-
int64_t bit_two = GET_BIT(bm[i], (j + 1));
223-
224-
/* Chunk was used but is now free */
225-
if(bit == 0 && bit_two == 1) {
226-
was_used++;
227-
}
228-
229-
if(bit == 1) {
230-
/* Theres no difference between a leaked and previously
231-
* used chunk (11) and a canary chunk (11). So in order
232-
* to accurately report on leaks we need to verify the
233-
* canary value. If it doesn't validate then we assume
234-
* its a true leak and increment the in_use counter */
235-
bit_slot_t bit_slot = (i * BITS_PER_QWORD) + j;
236-
const void *leak = (zone->user_pages_start + ((bit_slot >> 1) * zone->chunk_size));
237-
238-
if(bit_two == 1 && (check_canary_no_abort(zone, leak) != ERR)) {
239-
continue;
240-
} else {
241-
in_use++;
242-
243-
if(profile == false) {
244-
LOG("Leaked chunk (%d) in zone[%d] of %d bytes detected at 0x%p (bit position = %d)", in_use, zone->index, zone->chunk_size, leak, bit_slot);
245-
}
246-
}
247-
}
248-
}
249-
}
250-
#endif
251173

252174
if(profile == false) {
253175
LOG("Zone[%d] Total number of %d byte chunks(%d) used and free'd (%d) (%d percent), in use = %d", zone->index, zone->chunk_size, zone->chunk_count,

src/iso_alloc_sanity.c

Lines changed: 16 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -103,47 +103,25 @@ INTERNAL_HIDDEN void _verify_zone(iso_alloc_zone_t *zone) {
103103
}
104104
}
105105

106+
/* A chunk needs canary verification when the high bit of its 2-bit
107+
* slot is set (was-used-now-free=01 or canary=11) — the odd-bit mask. */
108+
const uint64_t CANARY_BIT_VECTOR = ~(uint64_t) USED_BIT_VECTOR;
106109
const bitmap_index_t max = zone->max_bitmap_idx;
107110

111+
for(bitmap_index_t i = 0; i < max;) {
108112
#if USE_NEON
109-
/* A chunk needs its canary verified when the high bit of its 2-bit
110-
* slot is set (was-used-now-free=01 or canary=11). The mask of all
111-
* odd bit positions is ~USED_BIT_VECTOR. We process two qwords at a
112-
* time and quick-reject any pair that has no odd bits set, then walk
113-
* just the set odd-bit positions with ctz instead of checking all 32. */
114-
const uint64_t CANARY_BIT_VECTOR = ~(uint64_t) USED_BIT_VECTOR;
115-
bitmap_index_t i = 0;
116-
const bitmap_index_t max_pair = max & ~(bitmap_index_t) 1;
117-
118-
for(; i < max_pair; i += 2) {
119-
int64x2_t v = vld1q_s64((const int64_t *) &bm[i]);
120-
const uint64_t lo = (uint64_t) vgetq_lane_s64(v, 0);
121-
const uint64_t hi = (uint64_t) vgetq_lane_s64(v, 1);
122-
123-
if(((lo | hi) & CANARY_BIT_VECTOR) == 0) {
124-
continue;
125-
}
126-
127-
uint64_t mask0 = lo & CANARY_BIT_VECTOR;
128-
while(mask0) {
129-
int j = __builtin_ctzll(mask0);
130-
mask0 &= mask0 - 1;
131-
bit_slot = ((bit_slot_t) i << BITS_PER_QWORD_SHIFT) + j;
132-
const void *p = POINTER_FROM_BITSLOT(zone, bit_slot);
133-
check_canary(zone, p);
134-
}
135-
136-
uint64_t mask1 = hi & CANARY_BIT_VECTOR;
137-
while(mask1) {
138-
int j = __builtin_ctzll(mask1);
139-
mask1 &= mask1 - 1;
140-
bit_slot = ((bit_slot_t) (i + 1) << BITS_PER_QWORD_SHIFT) + j;
141-
const void *p = POINTER_FROM_BITSLOT(zone, bit_slot);
142-
check_canary(zone, p);
113+
/* Two-qword quick-reject: skip 64 chunk slots when none of them
114+
* have the high bit set (no canaries to verify in this range). */
115+
if(i + 1 < max) {
116+
int64x2_t v = vld1q_s64((const int64_t *) &bm[i]);
117+
uint64_t lo = (uint64_t) vgetq_lane_s64(v, 0);
118+
uint64_t hi = (uint64_t) vgetq_lane_s64(v, 1);
119+
if(((lo | hi) & CANARY_BIT_VECTOR) == 0) {
120+
i += 2;
121+
continue;
122+
}
143123
}
144-
}
145-
146-
for(; i < max; i++) {
124+
#endif
147125
uint64_t mask = (uint64_t) bm[i] & CANARY_BIT_VECTOR;
148126
while(mask) {
149127
int j = __builtin_ctzll(mask);
@@ -152,22 +130,8 @@ INTERNAL_HIDDEN void _verify_zone(iso_alloc_zone_t *zone) {
152130
const void *p = POINTER_FROM_BITSLOT(zone, bit_slot);
153131
check_canary(zone, p);
154132
}
133+
i++;
155134
}
156-
#else
157-
for(bitmap_index_t i = 0; i < max; i++) {
158-
bit_slot_t bsl = bm[i];
159-
for(int64_t j = 1; j < BITS_PER_QWORD; j += BITS_PER_CHUNK) {
160-
/* If this bit is set it is either a free chunk or
161-
* a canary chunk. Either way it should have a set
162-
* of canaries we can verify */
163-
if((GET_BIT(bsl, j)) == 1) {
164-
bit_slot = (i << BITS_PER_QWORD_SHIFT) + j;
165-
const void *p = POINTER_FROM_BITSLOT(zone, bit_slot);
166-
check_canary(zone, p);
167-
}
168-
}
169-
}
170-
#endif
171135

172136
MASK_ZONE_PTRS(zone);
173137
}

0 commit comments

Comments
 (0)