Loading...
--- libmalloc/libmalloc-317.140.5/src/nanov2_malloc.c
+++ libmalloc/libmalloc-374.60.3/src/nanov2_malloc.c
@@ -1334,7 +1334,7 @@
 	if (kr) {
 		return kr;
 	}
-	boolean_t self_zone = (task == mach_task_self() && (nanozonev2_t *)zone_address == nanozone);
+	boolean_t self_zone = mach_task_is_self(task) && (nanozonev2_t *)zone_address == nanozone;
 	memcpy(&zone_copy, nanozone, sizeof(zone_copy));
 	nanozone = &zone_copy;
 	nanov2_meta_index_t metablock_meta_index = nanov2_metablock_meta_index(nanozone);
@@ -1486,7 +1486,7 @@
 static boolean_t
 nanov2_check(nanozonev2_t *nanozone)
 {
-	// Does nothing, just like Nano V1.
+	// Does nothing
 	return 1;
 }
 
@@ -1722,7 +1722,7 @@
 static void
 nanov2_log(malloc_zone_t *zone, void *log_address)
 {
-	// Does nothing, just like Nano V1.
+	// Does nothing
 }
 
 static void
@@ -2512,14 +2512,22 @@
 	}
 
 	// Allocate a new arena and maybe a new region. To do either of those
-	// things, we need to take the regions_lock. After doing so, check that
-	// the state is unchanged. If it has, just assume that we might have some
-	// new space to allocate into and try again.
+	// things, we need to take the regions_lock. After doing so, check that the
+	// state is unchanged. If it has _and_ the initial next arena is safe, just
+	// assume that we might have some new space to allocate into and try again.
 	boolean_t failed = FALSE;
 	arena = initial_region_next_arena;
+
+	// The initial next arena may actually be the limit arena of its region, in
+	// which case it's not safe to attempt to allocate from.
+	bool initial_region_next_arena_is_limit =
+			(arena == (nanov2_arena_t *)nanov2_region_address_for_ptr(arena));
+
 	_malloc_lock_lock(&nanozone->regions_lock);
-	if (nanozone->current_region_next_arena == arena) {
-		if ((void *)arena >= nanozone->current_region_limit) {
+	if (nanozone->current_region_next_arena == arena ||
+			initial_region_next_arena_is_limit) {
+		if ((void *)nanozone->current_region_next_arena >=
+				nanozone->current_region_limit) {
 			// Reached the end of the region. Allocate a new one, if we can.
 			if (nanov2_allocate_new_region(nanozone)) {
 				arena = nanozone->current_region_next_arena++;
@@ -2527,8 +2535,8 @@
 				failed = TRUE;
 			}
 		} else {
-			// Assign the new arena, in the same region.
-			nanozone->current_region_next_arena = arena + 1;
+			// Assign the new arena, in the current region.
+			arena = nanozone->current_region_next_arena++;
 		}
 
 		// Set up the guard blocks for the new arena, if requested