Loading...
--- libmalloc/libmalloc-792.80.2/tests/xctests/magazine_tiny_tests.m
+++ /dev/null
@@ -1,311 +0,0 @@
-#import "internal.h"
-
-#import <XCTest/XCTest.h>
-
-#define XCTAssertNotNull(ptr) XCTAssertNotEqual(ptr, NULL)
-
-static void assert_zero(void *ptr, size_t len)
-{
- char *p = ptr;
-
- // naive zero check
- for (size_t i = 0; i < len; i++) {
- XCTAssertEqual(p[i], 0, @"at byte %zu", i);
- }
-}
-
-static void
-assert_freelist_block_zero(void *ptr, size_t len, bool cache)
-{
- size_t orig_len = len;
- char *p = ptr;
-
- if (!cache) {
- // Skip the free list pointers
- p += sizeof(tiny_free_list_t);
- len -= sizeof(tiny_free_list_t);
-
- if (orig_len > TINY_QUANTUM) {
- // Skip leading inline size
- p += sizeof(msize_t);
- len -= sizeof(msize_t);
-
- // Skip trailing inline size
- len -= sizeof(msize_t);
- }
- }
-
- assert_zero(p, len);
-}
-
-@interface magazine_tiny_tests : XCTestCase {
-@public
- struct rack_s tiny_rack;
-}
-
-- (void *)tiny_malloc:(size_t)size;
-- (void *)tiny_calloc:(size_t)size;
-- (void)tiny_free:(void *)ptr;
-
-@end
-
-@implementation magazine_tiny_tests
-
-- (void)setUp {
- malloc_zero_policy = MALLOC_ZERO_ON_FREE;
-
- memset(&tiny_rack, 'a', sizeof(tiny_rack));
- rack_init(&tiny_rack, RACK_TYPE_TINY, 1, 0);
-
- // make an arbitrary initial allocation just to make sure the region isn't
- // fully free at any point during the subsequent test
- (void)[self tiny_malloc:42];
-}
-
-- (void)tearDown {
- rack_destroy_regions(&tiny_rack, TINY_REGION_SIZE);
- rack_destroy(&tiny_rack);
-}
-
-- (void *)tiny_malloc:(size_t)size {
- return tiny_malloc_should_clear(&tiny_rack, TINY_MSIZE_FOR_BYTES(size), false);
-}
-
-- (void *)tiny_calloc:(size_t)size {
- return tiny_malloc_should_clear(&tiny_rack, TINY_MSIZE_FOR_BYTES(size), true);
-}
-
-- (void)tiny_free:(void *)ptr {
- region_t region = tiny_region_for_ptr_no_lock(&tiny_rack, ptr);
- XCTAssertNotNull(region);
- free_tiny(&tiny_rack, ptr, region, 0, false);
-}
-
-@end
-
-@interface magazine_tiny_regular_tests : magazine_tiny_tests
-@end
-
-@implementation magazine_tiny_regular_tests
-
-- (void)tearDown {
- XCTAssertNotEqual(tiny_check(&tiny_rack, 0), 0);
- [super tearDown];
-}
-
-- (void)testTinyMallocSucceeds {
- XCTAssertNotNull([self tiny_malloc:256]);
-}
-
-- (void)testTinyRegionFoundAfterMalloc {
- void *ptr = [self tiny_malloc:256];
- XCTAssertNotNull(ptr);
-
- XCTAssertNotNull(tiny_region_for_ptr_no_lock(&tiny_rack, ptr));
-}
-
-- (void)testTinySizeMatchesMalloc {
- void *ptr = [self tiny_malloc:256];
- XCTAssertNotNull(ptr);
-
- XCTAssertEqual(tiny_size(&tiny_rack, ptr), 256);
-}
-
-// A block freed to the tiny cache should be cleared
-- (void)testTinyZeroOnFreeToCache {
- const size_t size = 64;
-
- void *ptr = [self tiny_malloc:size];
- memset(ptr, 'a', size);
-
- [self tiny_free:ptr];
-
- assert_freelist_block_zero(ptr, size, true);
-}
-
-// A block coalesced with a previous block should result in a cleared coalesced
-// block
-- (void)testTinyZeroOnFreeCoalescePrevious {
- const size_t size = 272; // skip the tiny cache
-
- void *ptr1 = [self tiny_malloc:size];
- memset(ptr1, 'a', size);
-
- void *ptr2 = [self tiny_malloc:size];
- memset(ptr2, 'b', size);
-
- XCTAssertEqual((uintptr_t)ptr1 + size, (uintptr_t)ptr2);
-
- [self tiny_free:ptr1];
- // Should coalesce backward with block 1
- [self tiny_free:ptr2];
-
- assert_freelist_block_zero(ptr1, size * 2, false);
-
- // Make sure calloc clears
- void *ptr3 = [self tiny_calloc:size];
- XCTAssertEqual(ptr3, ptr1);
- assert_zero(ptr3, size);
-}
-
-// A block coalesced with a next block should result in a cleared coalesced
-// block
-- (void)testTinyZeroOnFreeCoalesceNext {
- const size_t size = 272; // skip the tiny cache
-
- void *ptr1 = [self tiny_malloc:size];
- memset(ptr1, 'a', size);
-
- void *ptr2 = [self tiny_malloc:size];
- memset(ptr2, 'b', size);
-
- XCTAssertEqual((uintptr_t)ptr1 + size, (uintptr_t)ptr2);
-
- [self tiny_free:ptr2];
- // Should coalesce forward with block 2
- [self tiny_free:ptr1];
-
- assert_freelist_block_zero(ptr1, size * 2, false);
-
- // Make sure calloc clears
- void *ptr3 = [self tiny_calloc:size];
- XCTAssertEqual(ptr3, ptr1);
- assert_zero(ptr3, size);
-}
-
-// A block coalesced with a small next block should result in a cleared
-// coalesced block
-- (void)testTinyZeroOnFreeCoalesceNextSmall {
- const size_t size = 272; // skip the cache
- const size_t small_size = 64; // go through the cache
-
- void *ptr1 = [self tiny_malloc:size];
- memset(ptr1, 'a', size);
-
- void *ptr2 = [self tiny_malloc:small_size];
- memset(ptr2, 'b', small_size);
-
- void *ptr3 = [self tiny_malloc:small_size];
- memset(ptr3, 'c', small_size);
-
- XCTAssertEqual((uintptr_t)ptr1 + size, (uintptr_t)ptr2);
- XCTAssertEqual((uintptr_t)ptr2 + small_size, (uintptr_t)ptr3);
-
- [self tiny_free:ptr2];
- // Push block 2 out of the cache
- [self tiny_free:ptr3];
- // Should coalesce forward with block 2
- [self tiny_free:ptr1];
-
- assert_freelist_block_zero(ptr1, size + small_size, false);
-}
-
-// A leftover block should be cleared correctly
-- (void)testTinyZeroOnFreeLeftover {
- const size_t size = 272; // skip the tiny cache
-
- void *ptr1 = [self tiny_malloc:size];
- memset(ptr1, 'a', size);
-
- void *ptr2 = [self tiny_malloc:size];
- memset(ptr2, 'b', size);
-
- void *ptr3 = [self tiny_malloc:size];
- memset(ptr3, 'c', size);
-
- XCTAssertEqual((uintptr_t)ptr1 + size, (uintptr_t)ptr2);
- XCTAssertEqual((uintptr_t)ptr2 + size, (uintptr_t)ptr3);
-
- // Should all coalesce together
- [self tiny_free:ptr1];
- [self tiny_free:ptr2];
- [self tiny_free:ptr3];
-
- // Now pull the first one off again
- void *ptr4 = [self tiny_malloc:size];
- XCTAssertEqual(ptr4, ptr1); // Should get ptr1 back
-
- // The leftover starting at ptr2 should be cleared correctly
- assert_freelist_block_zero(ptr2, size * 2, false);
-}
-
-// A leftover block from realloc should be cleared correctly
-- (void)testTinyZeroOnFreeReallocLeftover {
- const size_t size = 272; // skip the tiny cache
-
- void *ptr1 = [self tiny_malloc:size];
- memset(ptr1, 'a', size);
-
- void *ptr2 = [self tiny_malloc:size];
- memset(ptr2, 'b', size);
-
- void *ptr3 = [self tiny_malloc:size];
- memset(ptr3, 'c', size);
-
- void *ptr4 = [self tiny_malloc:size];
- memset(ptr4, 'd', size);
-
- XCTAssertEqual((uintptr_t)ptr1 + size, (uintptr_t)ptr2);
- XCTAssertEqual((uintptr_t)ptr2 + size, (uintptr_t)ptr3);
- XCTAssertEqual((uintptr_t)ptr3 + size, (uintptr_t)ptr4);
-
- // Should coalesce together
- [self tiny_free:ptr2];
- [self tiny_free:ptr3];
- [self tiny_free:ptr4];
-
- // Now grow the first allocation into the free block after, which should
- // consume up until ptr3
- boolean_t result = tiny_try_realloc_in_place(&tiny_rack, ptr1, size,
- size * 2);
- XCTAssertEqual(result, 1);
-
- // The leftover starting at ptr3 should be cleared correctly
- assert_freelist_block_zero(ptr3, size * 2, false);
-}
-
-@end
-
-@interface magazine_tiny_scribble_tests : magazine_tiny_tests
-@end
-
-@implementation magazine_tiny_scribble_tests
-
-- (void)setUp {
- malloc_zero_policy = MALLOC_ZERO_ON_FREE;
- aggressive_madvise_enabled = true;
-
- memset(&tiny_rack, 'a', sizeof(tiny_rack));
- rack_init(&tiny_rack, RACK_TYPE_TINY, 1, MALLOC_DO_SCRIBBLE);
-
- // make an arbitrary initial allocation just to make sure the region isn't
- // fully free at any point during the subsequent test
- (void)[self tiny_malloc:42];
-}
-
-// 128 * 256 == 32k
-#define SCRIBBLE_TEST_ALLOCATIONS 128
-
-- (void)testTinyZeroOnFreeScribbleCalloc {
- const size_t size = 256;
-
- // Allocate and free two full max-size pages, twice, to exercise madvise
- // scribbling logic
- for (int outer = 0; outer < 2; outer++) {
- void *allocations[SCRIBBLE_TEST_ALLOCATIONS];
- for (int i = 0; i < SCRIBBLE_TEST_ALLOCATIONS; i++) {
- allocations[i] = [self tiny_malloc:size];
- }
- for (int i = 0; i < SCRIBBLE_TEST_ALLOCATIONS; i++) {
- [self tiny_free:allocations[i]];
- }
- }
-
- // Now make sure we get back cleared allocations
- for (int i = 0; i < SCRIBBLE_TEST_ALLOCATIONS; i++) {
- void *allocation = [self tiny_calloc:size];
- assert_zero(allocation, size);
- }
-}
-
-@end