authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-25 19:48:39-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-25 19:48:39-07:00
log973e6c978cedacc9aab86999ab67e5066fc1db1d
tree9b3e1226a99387083229c449457a4fc3216a3e4c
parent6fb105fdd7798dc988de09a7b6709c5168355dfa

std: clean up GeneralPurposeAllocator memset code

The freeSlot function was only called once so I inlined the logic and utilized some of the other locals that were in scope.

1 files changed, 23 insertions(+), 36 deletions(-)

lib/std/heap/general_purpose_allocator.zig+23-36
......@@ -402,41 +402,6 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
402402 }
403403 }
404404
405 fn freeSlot(
406 self: *Self,
407 bucket: *BucketHeader,
408 bucket_index: usize,
409 size_class: usize,
410 slot_index: SlotIndex,
411 used_byte: *u8,
412 used_bit_index: u3,
413 trace_addr: usize,
414 ) void {
415 // Capture stack trace to be the "first free", in case a double free happens.
416 bucket.captureStackTrace(trace_addr, size_class, slot_index, .free);
417
418 used_byte.* &= ~(@as(u8, 1) << used_bit_index);
419 bucket.used_count -= 1;
420 if (bucket.used_count == 0) {
421 if (bucket.next == bucket) {
422 // it's the only bucket and therefore the current one
423 self.buckets[bucket_index] = null;
424 } else {
425 bucket.next.prev = bucket.prev;
426 bucket.prev.next = bucket.next;
427 self.buckets[bucket_index] = bucket.prev;
428 }
429 if (!config.never_unmap) {
430 self.backing_allocator.free(bucket.page[0..page_size]);
431 }
432 const bucket_size = bucketSize(size_class);
433 const bucket_slice = @ptrCast([*]align(@alignOf(BucketHeader)) u8, bucket)[0..bucket_size];
434 self.backing_allocator.free(bucket_slice);
435 } else {
436 @memset(bucket.page + slot_index * size_class, undefined, size_class);
437 }
438 }
439
440405 /// This function assumes the object is in the large object storage regardless
441406 /// of the parameters.
442407 fn resizeLarge(
......@@ -560,7 +525,29 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
560525 }
561526 }
562527 if (new_size == 0) {
563 self.freeSlot(bucket, bucket_index, size_class, slot_index, used_byte, used_bit_index, ret_addr);
528 // Capture stack trace to be the "first free", in case a double free happens.
529 bucket.captureStackTrace(ret_addr, size_class, slot_index, .free);
530
531 used_byte.* &= ~(@as(u8, 1) << used_bit_index);
532 bucket.used_count -= 1;
533 if (bucket.used_count == 0) {
534 if (bucket.next == bucket) {
535 // it's the only bucket and therefore the current one
536 self.buckets[bucket_index] = null;
537 } else {
538 bucket.next.prev = bucket.prev;
539 bucket.prev.next = bucket.next;
540 self.buckets[bucket_index] = bucket.prev;
541 }
542 if (!config.never_unmap) {
543 self.backing_allocator.free(bucket.page[0..page_size]);
544 }
545 const bucket_size = bucketSize(size_class);
546 const bucket_slice = @ptrCast([*]align(@alignOf(BucketHeader)) u8, bucket)[0..bucket_size];
547 self.backing_allocator.free(bucket_slice);
548 } else {
549 @memset(old_mem.ptr, undefined, old_mem.len);
550 }
564551 return @as(usize, 0);
565552 }
566553 const new_aligned_size = math.max(new_size, old_align);