Loading...
--- libmalloc/libmalloc-657.60.21/tests/nano_tests.c
+++ libmalloc/libmalloc-317.40.8/tests/nano_tests.c
@@ -85,44 +85,28 @@
static void *allocations[ALLOCATION_COUNT];
-T_GLOBAL_META(T_META_RUN_CONCURRENTLY(true), T_META_TAG_VM_NOT_PREFERRED);
+T_GLOBAL_META(T_META_RUN_CONCURRENTLY(true));
T_DECL(nano_active_test, "Test that Nano is activated",
- T_META_ENVVAR("MallocNanoZone=1"), T_META_ENVVAR("MallocProbGuard=0"),
- T_META_TAG_XZONE, T_META_TAG_NANO_ON_XZONE)
-{
-#if CONFIG_NANOZONE
- bool nano_on_xzone = getenv("MallocNanoOnXzone");
- if (nano_on_xzone) {
- T_ASSERT_NE(malloc_engaged_secure_allocator(), 0,
- "Secure allocator engaged");
- }
-
- T_ASSERT_NE(malloc_engaged_nano(), 0, "Nano mode engaged");
-
- if (nano_on_xzone || !malloc_engaged_secure_allocator()) {
- void *ptr = malloc(16);
- T_LOG("Nano ptr is %p\n", ptr);
- T_ASSERT_EQ(NANOZONE_SIGNATURE, (uint64_t)((uintptr_t)ptr) >> SHIFT_NANO_SIGNATURE,
- "Nanozone is active");
- free(ptr);
- }
+ T_META_ENVVAR("MallocNanoZone=1"))
+{
+#if CONFIG_NANOZONE
+ void *ptr = malloc(16);
+ T_LOG("Nano ptr is %p\n", ptr);
+ T_ASSERT_EQ(NANOZONE_SIGNATURE, (uint64_t)((uintptr_t)ptr) >> SHIFT_NANO_SIGNATURE,
+ "Nanozone is active");
+ T_ASSERT_NE(malloc_engaged_nano(), 0, "Nanozone engaged");
+ free(ptr);
#else // CONFIG_NANOZONE
T_SKIP("Nano allocator not configured");
#endif // CONFIG_NANOZONE
}
T_DECL(nano_enumerator_test, "Test the Nanov2 enumerator",
- T_META_ENVVAR("MallocNanoZone=V2"), T_META_ENVVAR("MallocProbGuard=0"),
- T_META_TAG_XZONE)
-{
-#if CONFIG_NANOZONE
- if (malloc_engaged_secure_allocator()) {
- T_ASSERT_NE(malloc_engaged_nano(), 0,
- "Secure allocator nano mode engaged");
- } else {
- T_ASSERT_EQ(malloc_engaged_nano(), 2, "Nanozone V2 engaged");
- }
+ T_META_ENVVAR("MallocNanoZone=V2"))
+{
+#if CONFIG_NANOZONE
+ T_ASSERT_EQ(malloc_engaged_nano(), 2, "Nanozone V2 engaged");
// This test is problematic because the allocator is used before the test
// starts, so we can't start everything from zero.
@@ -154,7 +138,7 @@
"Incorrect blocks_in_use");
T_ASSERT_EQ(stats.size_in_use, initial_size_in_use + total_requested_size,
"Incorrect size_in_use");
- T_ASSERT_GE(stats.size_allocated, total_requested_size,
+ T_ASSERT_TRUE(stats.size_allocated - initial_size_allocated >= total_requested_size,
"Size allocated must be >= size requested");
T_ASSERT_EQ(ptr_count, initial_ptrs + ALLOCATION_COUNT,
@@ -177,7 +161,7 @@
T_ASSERT_EQ(stats.size_in_use,
initial_size_in_use + total_requested_size - size_freed,
"Incorrect size_in_use after half free");
- T_ASSERT_GE(stats.size_allocated, initial_size_allocated,
+ T_ASSERT_TRUE(stats.size_allocated >= initial_size_allocated ,
"Size allocated must be >= size requested");
T_ASSERT_EQ(ptr_count, initial_ptrs + ALLOCATION_COUNT / 2,
@@ -199,7 +183,7 @@
"Incorrect blocks_in_use after full free");
T_ASSERT_EQ(stats.size_in_use, initial_size_in_use,
"Incorrect size_in_use after full free");
- T_ASSERT_GE(stats.size_allocated, initial_size_allocated,
+ T_ASSERT_TRUE(stats.size_allocated >= initial_size_allocated ,
"Size allocated must be >= size requested");
T_ASSERT_EQ(ptr_count, initial_ptrs, "Incorrect number of pointers after free");
@@ -263,7 +247,7 @@
}
T_DECL(realloc_nano_to_other, "realloc with allocator change (nano)",
- T_META_ENVVAR("MallocNanoZone=1"), T_META_TAG_NANO_ON_XZONE)
+ T_META_ENVVAR("MallocNanoZone=1"))
{
#if CONFIG_NANOZONE
void *ptr = malloc(32); // From Nano
@@ -326,25 +310,6 @@
#endif // CONFIG_NANOZONE
}
-T_DECL(nano_memalign_trivial, "Test that nano serves trivial memalign allocations",
- T_META_ENVVAR("MallocNanoZone=1"))
-{
-#if CONFIG_NANOZONE
- size_t size = 16;
- void *ptr8 = aligned_alloc(8, size);
- void *ptr16 = aligned_alloc(16, size);
- T_LOG("Nano ptrs are %p, %p\n", ptr8, ptr16);
- T_ASSERT_EQ(NANOZONE_SIGNATURE, (uint64_t)((uintptr_t)ptr8) >> SHIFT_NANO_SIGNATURE,
- "8-byte-aligned allocation served from nano");
- T_ASSERT_EQ(NANOZONE_SIGNATURE, (uint64_t)((uintptr_t)ptr16) >> SHIFT_NANO_SIGNATURE,
- "16-byte-aligned allocation served from nano");
- free(ptr8);
- free(ptr16);
-#else // CONFIG_NANOZONE
- T_SKIP("Nano allocator not configured");
-#endif // CONFIG_NANOZONE
-}
-
#pragma mark -
#pragma mark Nanov2 tests
@@ -394,14 +359,16 @@
#endif // CONFIG_NANOZONE
}
-#if CONFIG_NANOZONE
+#if TARGET_OS_OSX
+
// Guaranteed number of 256-byte allocations to be sure we fill a region.
#define ALLOCS_PER_REGION ((NANOV2_REGION_SIZE)/256)
-#if NANOV2_MULTIPLE_REGIONS
+// This test is required only on macOS because iOS only uses one region.
T_DECL(overspill_region, "force overspill of a region",
T_META_ENVVAR("MallocNanoZone=V2"))
{
+#if CONFIG_NANOZONE
void **ptrs = calloc(ALLOCS_PER_REGION, sizeof(void *));
T_QUIET; T_ASSERT_NOTNULL(ptrs, "Unable to allocate pointers");
int index;
@@ -429,157 +396,9 @@
free(ptrs[i]);
}
free(ptrs);
-}
-#endif // NANOV2_MULTIPLE_REGIONS
-
-extern malloc_zone_t **malloc_zones;
-
-T_DECL(overspill_nanozone, "force overspill of nano zone",
- T_META_ENVVAR("MallocNanoZone=V2"),
- T_META_ENVVAR("MallocNanoMaxRegion=1"),
- T_META_ENVVAR("MallocProbGuard=0"),
- T_META_TAG_NANO_ON_XZONE)
-{
- int index;
- bool spilled_to_tiny = false;
- void **ptrs;
- malloc_zone_t *nano_zone = malloc_zones[0];
- malloc_zone_t *helper_zone = malloc_zones[1];
-
- // Max number of 256B allocations that will fit in the nano zone (+1 to overspill)
- const unsigned int nano_max_allocations = 2 * ALLOCS_PER_REGION + 1;
-
- T_LOG("Allocating %d pointers for allocations", nano_max_allocations);
- ptrs = calloc(nano_max_allocations, sizeof(void *));
- T_QUIET; T_ASSERT_NOTNULL(ptrs, "Unable to allocate pointers");
-
- ptrs[0] = malloc(256);
- T_QUIET; T_ASSERT_NOTNULL(ptrs[0], "Failed to make initial allocation");
- T_QUIET; T_ASSERT_TRUE(malloc_zone_claimed_address(nano_zone, ptrs[0]),
- "Initial allocation did not come from nano zone");
- T_QUIET; T_ASSERT_FALSE(malloc_zone_claimed_address(helper_zone, ptrs[0]),
- "Initial allocation came from helper zone");
-
- for (index = 1; index < (nano_max_allocations); index++) {
- ptrs[index] = malloc(256);
- if (malloc_zone_claimed_address(helper_zone, ptrs[index])) {
- T_LOG("Spilled to helper zone");
- spilled_to_tiny = true;
- break;
- }
- }
- T_EXPECT_TRUE(spilled_to_tiny, "Allocation falls through to helper zone");
-
- T_LOG("Freeing %d pointers", index);
- for (int i = 0; i < MIN(index + 1, nano_max_allocations); i++) {
- free(ptrs[i]);
- }
- free(ptrs);
-}
-
-#if NANOV2_MULTIPLE_REGIONS
-void *
-punch_holes_thread(void *arg)
-{
- T_LOG("Starting holes thread");
- bool *done = arg;
-
- bool holes[1024] = { false };
- while (!os_atomic_load(done, relaxed)) {
- bool allocate = random() % 2;
- int which = random() % 1024;
- uintptr_t base = NANOZONE_BASE_REGION_ADDRESS;
- size_t len = 128ull * 1024ull * 1024ull;
- size_t stride = 512ull * 1024ull * 1024ull;
- uint64_t offset = stride * which;
- void *addr = (void *)(base + offset);
-
- if (allocate && !holes[which]) {
- void *hole = mmap(addr, len, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0);
- if (hole == addr) {
- holes[which] = true;
- T_LOG("punched hole %d (%p, %p)", which, hole, addr);
- } else if (hole != MAP_FAILED) {
- T_LOG("failed to punch hole %d (wanted %p, got %p), unmapping", which,
- addr, hole);
- munmap(hole, len);
- }
- } else if (!allocate && holes[which]) {
- munmap(addr, len);
- holes[which] = false;
- T_LOG("unmapped hole %d", which);
- }
-
- usleep(300);
- }
-
- return NULL;
-}
-
-void *
-do_allocations_thread(void *arg)
-{
- bool *done = arg;
-
- size_t n = (256ull << 20) / 128;
- void **allocations = malloc(n * sizeof(void *));
- T_ASSERT_NOTNULL(allocations, "allocations");
-
- while (!os_atomic_load(done, relaxed)) {
- for (int i = 0; i < n; i++) {
- allocations[i] = malloc(128);
- }
-
- usleep(100);
-
- for (int i = 0; i < n; i++) {
- free(allocations[i]);
- }
-
- usleep(50000 * ((random() % 8) + 1));
- }
-
- free(allocations);
-
- return NULL;
-}
-
-T_DECL(region_holes, "ensure correct handling of holes between regions",
- T_META_ENVVAR("MallocNanoZone=V2"),
- // Region reservation does not allow for holes between regions
- T_META_ENABLED(!CONFIG_NANO_RESERVE_REGIONS))
-{
- srandom(time(NULL));
-
- bool done = false;
-
- pthread_t holes_thread;
- int rc = pthread_create(&holes_thread, NULL, punch_holes_thread, &done);
- T_ASSERT_POSIX_ZERO(rc, "pthread_create");
-
- int nthreads = 4;
- pthread_t allocation_threads[nthreads];
- for (int i = 0; i < nthreads; i++) {
- rc = pthread_create(&allocation_threads[i], NULL, do_allocations_thread,
- &done);
- T_ASSERT_POSIX_ZERO(rc, "pthread_create");
- }
-
- sleep(4); // arbitrary time to try to hit the race
-
- os_atomic_store(&done, true, relaxed);
-
- rc = pthread_join(holes_thread, NULL);
- T_ASSERT_POSIX_ZERO(rc, "pthread_join");
-
- for (int i = 0; i < nthreads; i++) {
- rc = pthread_join(allocation_threads[i], NULL);
- T_ASSERT_POSIX_ZERO(rc, "pthread_join");
- }
-
- T_PASS("Didn't crash");
- T_END;
-}
-#endif // NANOV2_MULTIPLE_REGIONS
-#endif // CONFIG_NANOZONE
-
+#else // CONFIG_NANOZONE
+ T_SKIP("Nano allocator not configured");
+#endif // CONFIG_NANOZONE
+}
+#endif // TARGET_OS_OSX
+