Loading...
--- libmalloc/libmalloc-166.251.2/src/purgeable_malloc.c
+++ libmalloc/libmalloc-140.40.1/src/purgeable_malloc.c
@@ -38,7 +38,7 @@
static void *
purgeable_malloc(szone_t *szone, size_t size)
{
- if (size <= LARGE_THRESHOLD(szone)) {
+ if (size <= szone->large_threshold) {
return szone_malloc(szone->helper_zone, size);
} else {
return szone_malloc(szone, size);
@@ -48,13 +48,30 @@
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;
- }
-
- if (total_bytes <= LARGE_THRESHOLD(szone)) {
+ 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) {
return szone_calloc(szone->helper_zone, 1, total_bytes);
} else {
return szone_calloc(szone, 1, total_bytes);
@@ -64,7 +81,7 @@
static void *
purgeable_valloc(szone_t *szone, size_t size)
{
- if (size <= LARGE_THRESHOLD(szone)) {
+ if (size <= szone->large_threshold) {
return szone_valloc(szone->helper_zone, size);
} else {
return szone_valloc(szone, size);
@@ -89,7 +106,7 @@
static void
purgeable_free_definite_size(szone_t *szone, void *ptr, size_t size)
{
- if (size <= LARGE_THRESHOLD(szone)) {
+ if (size <= szone->large_threshold) {
return szone_free_definite_size(szone->helper_zone, ptr, size);
} else {
return szone_free_definite_size(szone, ptr, size);
@@ -118,14 +135,14 @@
}
if (!old_size) {
- malloc_zone_error(szone->debug_flags, true, "pointer %p being reallocated was not allocated\n", ptr);
+ szone_error(szone->debug_flags, 1, "pointer being reallocated was not allocated", ptr, NULL);
return NULL;
}
// Distinguish 4 cases: {oldsize, newsize} x { <= , > large_threshold }
// and deal with the allocation crossing from the purgeable zone to the helper zone and vice versa.
- if (old_size <= LARGE_THRESHOLD(szone)) {
- if (new_size <= LARGE_THRESHOLD(szone)) {
+ if (old_size <= szone->large_threshold) {
+ if (new_size <= szone->large_threshold) {
return szone_realloc(szone->helper_zone, ptr, new_size);
} else {
// allocation crosses from helper to purgeable zone
@@ -137,7 +154,7 @@
return new_ptr; // in state VM_PURGABLE_NONVOLATILE
}
} else {
- if (new_size <= LARGE_THRESHOLD(szone)) {
+ if (new_size <= szone->large_threshold) {
// allocation crosses from purgeable to helper zone
void *new_ptr = szone_malloc(szone->helper_zone, new_size);
if (new_ptr) {
@@ -196,7 +213,7 @@
static void *
purgeable_memalign(szone_t *szone, size_t alignment, size_t size)
{
- if (size <= LARGE_THRESHOLD(szone)) {
+ if (size <= szone->large_threshold) {
return szone_memalign(szone->helper_zone, alignment, size);
} else {
return szone_memalign(szone, alignment, size);
@@ -231,7 +248,7 @@
static size_t
purgeable_good_size(szone_t *szone, size_t size)
{
- if (size <= LARGE_THRESHOLD(szone)) {
+ if (size <= szone->large_threshold) {
return szone_good_size(szone->helper_zone, size);
} else {
return szone_good_size(szone, size);
@@ -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)
{
@@ -346,6 +356,11 @@
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);
+ /* Purgeable zone does not participate in the adaptive "largemem" sizing. */
+ szone->is_largemem = 0;
+ szone->large_threshold = LARGE_THRESHOLD;
+ 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);
@@ -359,7 +374,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;
@@ -373,7 +388,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. */
@@ -383,7 +397,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;
}