Loading...
src/purgeable_malloc.c libmalloc-166.220.1 libmalloc-116.50.8
--- libmalloc/libmalloc-166.220.1/src/purgeable_malloc.c
+++ libmalloc/libmalloc-116.50.8/src/purgeable_malloc.c
@@ -48,10 +48,27 @@
 static void *
 purgeable_calloc(szone_t *szone, size_t num_items, size_t size)
 {
-	size_t total_bytes;
-
-	if (calloc_get_size(num_items, size, 0, &total_bytes)) {
-		return NULL;
+	size_t total_bytes = num_items * size;
+
+	// Check for overflow of integer multiplication
+	if (num_items > 1) {
+#if __LP64__ /* size_t is uint64_t */
+		if ((num_items | size) & 0xffffffff00000000ul) {
+			// num_items or size equals or exceeds sqrt(2^64) == 2^32, appeal to wider arithmetic
+			__uint128_t product = ((__uint128_t)num_items) * ((__uint128_t)size);
+			if ((uint64_t)(product >> 64)) { // compiles to test on upper register of register pair
+				return NULL;
+			}
+		}
+#else /* size_t is uint32_t */
+		if ((num_items | size) & 0xffff0000ul) {
+			// num_items or size equals or exceeds sqrt(2^32) == 2^16, appeal to wider arithmetic
+			uint64_t product = ((uint64_t)num_items) * ((uint64_t)size);
+			if ((uint32_t)(product >> 32)) { // compiles to test on upper register of register pair
+				return NULL;
+			}
+		}
+#endif
 	}
 
 	if (total_bytes <= szone->large_threshold) {
@@ -118,7 +135,7 @@
 	}
 
 	if (!old_size) {
-		malloc_zone_error(szone->debug_flags, true, "pointer %p being reallocated was not allocated\n", ptr);
+		szone_error(szone, 1, "pointer being reallocated was not allocated", ptr, NULL);
 		return NULL;
 	}
 
@@ -169,16 +186,16 @@
 		large = szone->large_entries + index;
 		if (large->address) {
 			// we deallocate_pages, including guard pages
-			mvm_deallocate_pages((void *)(large->address), large->size, szone->debug_flags);
+			deallocate_pages(szone, (void *)(large->address), large->size, szone->debug_flags);
 		}
 	}
 	large_entries_free_no_lock(szone, szone->large_entries, szone->num_large_entries, &range_to_deallocate);
 	if (range_to_deallocate.size) {
-		mvm_deallocate_pages((void *)range_to_deallocate.address, (size_t)range_to_deallocate.size, 0);
+		deallocate_pages(szone, (void *)range_to_deallocate.address, (size_t)range_to_deallocate.size, 0);
 	}
 
 	/* Now destroy the separate szone region */
-	mvm_deallocate_pages((void *)szone, SZONE_PAGED_SIZE, 0);
+	deallocate_pages(szone, (void *)szone, SZONE_PAGED_SIZE, 0);
 }
 
 static unsigned
@@ -247,8 +264,8 @@
 static void
 purgeable_print(szone_t *szone, boolean_t verbose)
 {
-	malloc_report(MALLOC_REPORT_NOLOG | MALLOC_REPORT_NOPREFIX, "Scalable zone %p: inUse=%u(%y) flags=%d\n", szone,
-				   szone->num_large_objects_in_use, (int)szone->num_bytes_in_large_objects, szone->debug_flags);
+	_malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "Scalable zone %p: inUse=%u(%y) flags=%d\n", szone,
+				   szone->num_large_objects_in_use, szone->num_bytes_in_large_objects, szone->debug_flags);
 }
 
 static void
@@ -310,13 +327,6 @@
 	(void *)purgeable_reinit_lock, // reinit_lock version 9 and foward
 }; // marked as const to spare the DATA section
 
-
-static boolean_t
-purgeable_claimed_address(szone_t *szone, void *ptr)
-{
-	return szone_claimed_address(szone->helper_zone, ptr);
-}
-
 malloc_zone_t *
 create_purgeable_zone(size_t initial_size, malloc_zone_t *malloc_default_zone, unsigned debug_flags)
 {
@@ -324,7 +334,7 @@
 	uint64_t hw_memsize = 0;
 
 	/* get memory for the zone. */
-	szone = mvm_allocate_pages(SZONE_PAGED_SIZE, 0, 0, VM_MEMORY_MALLOC);
+	szone = allocate_pages(NULL, SZONE_PAGED_SIZE, 0, 0, VM_MEMORY_MALLOC);
 	if (!szone) {
 		return NULL;
 	}
@@ -343,8 +353,21 @@
 	sysctlbyname("hw.memsize", &hw_memsize, &uint64_t_size, 0, 0);
 #endif
 
-	rack_init(&szone->tiny_rack, RACK_TYPE_TINY, 0, debug_flags | MALLOC_PURGEABLE);
-	rack_init(&szone->small_rack, RACK_TYPE_SMALL, 0, debug_flags | MALLOC_PURGEABLE);
+	szone->trg[0].nextgen = &(szone->trg[1]);
+	szone->trg[1].nextgen = &(szone->trg[0]);
+	szone->tiny_region_generation = &(szone->trg[0]);
+
+	szone->tiny_region_generation->hashed_regions = szone->initial_tiny_regions;
+	szone->tiny_region_generation->num_regions_allocated = INITIAL_NUM_REGIONS;
+	szone->tiny_region_generation->num_regions_allocated_shift = INITIAL_NUM_REGIONS_SHIFT;
+
+	szone->srg[0].nextgen = &(szone->srg[1]);
+	szone->srg[1].nextgen = &(szone->srg[0]);
+	szone->small_region_generation = &(szone->srg[0]);
+
+	szone->small_region_generation->hashed_regions = szone->initial_small_regions;
+	szone->small_region_generation->num_regions_allocated = INITIAL_NUM_REGIONS;
+	szone->small_region_generation->num_regions_allocated_shift = INITIAL_NUM_REGIONS_SHIFT;
 
 	/* Purgeable zone does not participate in the adaptive "largemem" sizing. */
 	szone->is_largemem = 0;
@@ -352,8 +375,8 @@
 	szone->vm_copy_threshold = VM_COPY_THRESHOLD;
 
 #if CONFIG_LARGE_CACHE
-	// madvise(..., MADV_REUSABLE) death-row arrivals above this threshold [~0.1%]
-	szone->large_entry_cache_reserve_limit = (size_t)(hw_memsize >> 10);
+	szone->large_entry_cache_reserve_limit =
+	hw_memsize >> 10; // madvise(..., MADV_REUSABLE) death-row arrivals above this threshold [~0.1%]
 
 	/* <rdar://problem/6610904> Reset protection when returning a previous large allocation? */
 	int32_t libSystemVersion = NSVersionOfLinkTimeLibrary("System");
@@ -364,7 +387,7 @@
 	}
 #endif
 
-	szone->basic_zone.version = 10;
+	szone->basic_zone.version = 9;
 	szone->basic_zone.size = (void *)purgeable_size;
 	szone->basic_zone.malloc = (void *)purgeable_malloc;
 	szone->basic_zone.calloc = (void *)purgeable_calloc;
@@ -378,7 +401,6 @@
 	szone->basic_zone.memalign = (void *)purgeable_memalign;
 	szone->basic_zone.free_definite_size = (void *)purgeable_free_definite_size;
 	szone->basic_zone.pressure_relief = (void *)purgeable_pressure_relief;
-	szone->basic_zone.claimed_address = (void *)purgeable_claimed_address;
 
 	szone->basic_zone.reserved1 = 0;					   /* Set to zero once and for all as required by CFAllocator. */
 	szone->basic_zone.reserved2 = 0;					   /* Set to zero once and for all as required by CFAllocator. */
@@ -388,7 +410,7 @@
 
 	/* Purgeable zone does not support MALLOC_ADD_GUARD_PAGES. */
 	if (szone->debug_flags & MALLOC_ADD_GUARD_PAGES) {
-		malloc_report(ASL_LEVEL_INFO, "purgeable zone does not support guard pages\n");
+		_malloc_printf(ASL_LEVEL_INFO, "purgeable zone does not support guard pages\n");
 		szone->debug_flags &= ~MALLOC_ADD_GUARD_PAGES;
 	}