Loading...
--- libmalloc/libmalloc-657.80.3/src/nanov2_malloc.c
+++ libmalloc/libmalloc-409.40.6/src/nanov2_malloc.c
@@ -60,7 +60,7 @@
 		nanov2_block_meta_t **block_metapp, size_t rounded_size,
 		nanov2_size_class_t size_class, int allocation_index,
 		nanov2_block_meta_t *madvise_block_metap, void *corrupt_slot,
-		bool clear, bool typed, malloc_type_id_t type_id);
+		bool clear);
 
 MALLOC_ALWAYS_INLINE MALLOC_INLINE nanov2_block_meta_t *
 nanov2_free_to_block_inline(nanozonev2_t *nanozone, void *ptr,
@@ -1067,43 +1067,32 @@
 	return size ? size : nanozone->helper_zone->size(nanozone->helper_zone, ptr);
 }
 
-MALLOC_ALWAYS_INLINE MALLOC_INLINE
-void
-nanov2_bzero(void *ptr, size_t size)
-{
-	// TODO: inline bzero from libplatform
-	bzero(ptr, size);
-}
-
-MALLOC_ALWAYS_INLINE MALLOC_INLINE
-static void *
-_nanov2_allocate(nanozonev2_t *nanozone, size_t rounded_size, bool clear,
-		bool typed, malloc_type_id_t type_id)
-{
-	nanov2_block_meta_t *madvise_block_metap = NULL;
-	nanov2_size_class_t size_class = nanov2_size_class_from_size(rounded_size);
-
-	// Get the index of the pointer to the block from which we are should be
-	// allocating. This currently depends on the physical CPU number.
-	int allocation_index = nanov2_get_allocation_block_index();
-
-	// Get the current allocation block meta data pointer. If this is NULL, we
-	// need to find a new allocation block.
-	nanov2_block_meta_t **block_metapp =
-			&nanozone->current_block[size_class][allocation_index];
-	nanov2_block_meta_t *block_metap = os_atomic_load(block_metapp, relaxed);
-	bool corruption = false;
-	void *ptr = NULL;
-	if (block_metap) {
-		// Fast path: we have a block -- try to allocate from it.
-		ptr = nanov2_allocate_from_block_inline(nanozone, block_metap,
-				size_class, &madvise_block_metap, &corruption);
-		if (ptr && !corruption) {
-			if (clear && malloc_zero_policy != MALLOC_ZERO_ON_FREE) {
-				nanov2_bzero(ptr, rounded_size);
-			} else {
-				// Always clear the double-free guard so that we can recognize that
-				// this block is not on the free list.
+MALLOC_NOEXPORT void *
+nanov2_malloc(nanozonev2_t *nanozone, size_t size)
+{
+	size_t rounded_size = _nano_common_good_size(size);
+	if (rounded_size <= NANO_MAX_SIZE) {
+		nanov2_block_meta_t *madvise_block_metap = NULL;
+		nanov2_size_class_t size_class = nanov2_size_class_from_size(rounded_size);
+
+		// Get the index of the pointer to the block from which we are should be
+		// allocating. This currently depends on the physical CPU number.
+		int allocation_index = nanov2_get_allocation_block_index();
+
+		// Get the current allocation block meta data pointer. If this is NULL,
+		// we need to find a new allocation block.
+		nanov2_block_meta_t **block_metapp =
+				&nanozone->current_block[size_class][allocation_index];
+		nanov2_block_meta_t *block_metap = os_atomic_load(block_metapp, relaxed);
+		bool corruption = false;
+		void *ptr = NULL;
+		if (block_metap) {
+			// Fast path: we have a block -- try to allocate from it.
+			ptr = nanov2_allocate_from_block_inline(nanozone, block_metap,
+					size_class, &madvise_block_metap, &corruption);
+			if (ptr && !corruption) {
+				// Always clear the double-free guard so that we can recognize
+				// that this block is not on the free list.
 				nanov2_free_slot_t *slotp = (nanov2_free_slot_t *)ptr;
 				os_atomic_store(&slotp->double_free_guard, 0, relaxed);
 
@@ -1112,41 +1101,24 @@
 				// all cases, even if a cleared allocation is not requested, to
 				// prevent any leakage through the next_slot bits.
 				os_atomic_store(&slotp->next_slot, 0, relaxed);
+				return ptr;
 			}
-			return ptr;
-		}
-	}
-
-	return nanov2_allocate_outlined(nanozone, block_metapp, rounded_size,
-			size_class, allocation_index, madvise_block_metap, ptr, clear,
-			typed, type_id);
-}
-
-MALLOC_NOEXPORT void *
-nanov2_malloc(nanozonev2_t *nanozone, size_t size)
-{
-	size_t rounded_size = _nano_common_good_size(size);
-	if (rounded_size <= NANO_MAX_SIZE) {
-		return _nanov2_allocate(nanozone, rounded_size, false, false,
-				MALLOC_TYPE_ID_NONE);
+		}
+
+		return nanov2_allocate_outlined(nanozone, block_metapp, rounded_size,
+				size_class, allocation_index, madvise_block_metap, ptr, false);
 	}
 
 	// Too big for nano, so delegate to the helper zone.
 	return nanozone->helper_zone->malloc(nanozone->helper_zone, size);
 }
 
-MALLOC_NOEXPORT void *
-nanov2_malloc_type(nanozonev2_t *nanozone, size_t size,
-		malloc_type_id_t type_id)
-{
-	size_t rounded_size = _nano_common_good_size(size);
-	if (rounded_size <= NANO_MAX_SIZE) {
-		return _nanov2_allocate(nanozone, rounded_size, false, true, type_id);
-	}
-
-	// Too big for nano, so delegate to the helper zone.
-	malloc_zone_t *helper_zone = nanozone->helper_zone;
-	return helper_zone->malloc_type_malloc(helper_zone, size, type_id);
+MALLOC_ALWAYS_INLINE MALLOC_INLINE
+void
+nanov2_bzero(void *ptr, size_t size)
+{
+	// TODO: inline bzero from libplatform
+	bzero(ptr, size);
 }
 
 MALLOC_NOEXPORT void
@@ -1155,7 +1127,7 @@
 	if (ptr && nanov2_has_valid_signature(ptr)) {
 		nanov2_size_class_t size_class = nanov2_size_class_from_size(size);
 
-		if (malloc_zero_policy == MALLOC_ZERO_ON_FREE) {
+		if (malloc_zero_on_free) {
 			if (size_class != 0) {
 				nanov2_bzero((char *)ptr + sizeof(nanov2_free_slot_t),
 						size - sizeof(nanov2_free_slot_t));
@@ -1185,7 +1157,7 @@
 		size_t size = nanov2_pointer_size_inline(nanozone, ptr, FALSE,
 				&size_class, &block_metap);
 		if (size) {
-			if (malloc_zero_policy == MALLOC_ZERO_ON_FREE) {
+			if (malloc_zero_on_free) {
 				if (size > sizeof(nanov2_free_slot_t)) {
 					nanov2_bzero((char *)ptr + sizeof(nanov2_free_slot_t),
 							size - sizeof(nanov2_free_slot_t));
@@ -1226,58 +1198,49 @@
 	}
 	size_t rounded_size = _nano_common_good_size(total_bytes);
 	if (total_bytes <= NANO_MAX_SIZE) {
-		return _nanov2_allocate(nanozone, rounded_size, true, false,
-				MALLOC_TYPE_ID_NONE);
+		nanov2_block_meta_t *madvise_block_metap = NULL;
+		nanov2_size_class_t size_class = nanov2_size_class_from_size(rounded_size);
+
+		// Get the index of the pointer to the block from which we are should be
+		// allocating. This currently depends on the physical CPU number.
+		int allocation_index = nanov2_get_allocation_block_index();
+
+		// Get the current allocation block meta data pointer. If this is NULL,
+		// we need to find a new allocation block.
+		nanov2_block_meta_t **block_metapp =
+				&nanozone->current_block[size_class][allocation_index];
+		nanov2_block_meta_t *block_metap = os_atomic_load(block_metapp, relaxed);
+		bool corruption = false;
+		void *ptr = NULL;
+		if (block_metap) {
+			// Fast path: we have a block -- try to allocate from it.
+			ptr = nanov2_allocate_from_block_inline(nanozone, block_metap,
+					size_class, &madvise_block_metap, &corruption);
+			if (ptr && !corruption) {
+				if (malloc_zero_on_free) {
+					// Always clear the double-free guard so that we can recognize that
+					// this block is not on the free list.
+					nanov2_free_slot_t *slotp = (nanov2_free_slot_t *)ptr;
+					os_atomic_store(&slotp->double_free_guard, 0, relaxed);
+
+					// We know the body of the allocation is already clear, so we just
+					// need to clean up the next_slot word to get to all-zero.  Do so in
+					// all cases, even if a cleared allocation is not requested, to
+					// prevent any leakage through the next_slot bits.
+					os_atomic_store(&slotp->next_slot, 0, relaxed);
+				} else {
+					nanov2_bzero(ptr, rounded_size);
+				}
+				return ptr;
+			}
+		}
+
+		return nanov2_allocate_outlined(nanozone, block_metapp, rounded_size,
+				size_class, allocation_index, madvise_block_metap, ptr, true);
 	}
 
 	// Too big for nano, so delegate to the helper zone.
 	return nanozone->helper_zone->calloc(nanozone->helper_zone, 1, total_bytes);
-}
-
-MALLOC_NOEXPORT void *
-nanov2_calloc_type(nanozonev2_t *nanozone, size_t num_items, size_t size,
-		malloc_type_id_t type_id)
-{
-	size_t total_bytes;
-	if (calloc_get_size(num_items, size, 0, &total_bytes)) {
-		return NULL;
-	}
-	size_t rounded_size = _nano_common_good_size(total_bytes);
-	if (total_bytes <= NANO_MAX_SIZE) {
-		return _nanov2_allocate(nanozone, rounded_size, true, true, type_id);
-	}
-
-	// Too big for nano, so delegate to the helper zone.
-	malloc_zone_t *helper_zone = nanozone->helper_zone;
-	return helper_zone->malloc_type_calloc(helper_zone, 1, total_bytes,
-			type_id);
-}
-
-MALLOC_NOEXPORT void *
-nanov2_malloc_zero_on_alloc(nanozonev2_t *nanozone, size_t size)
-{
-	size_t rounded_size = _nano_common_good_size(size);
-	if (rounded_size <= NANO_MAX_SIZE) {
-		return _nanov2_allocate(nanozone, rounded_size, true, false,
-				MALLOC_TYPE_ID_NONE);
-	}
-
-	// Too big for nano, so delegate to the helper zone.
-	return nanozone->helper_zone->malloc(nanozone->helper_zone, size);
-}
-
-MALLOC_NOEXPORT void *
-nanov2_malloc_type_zero_on_alloc(nanozonev2_t *nanozone, size_t size,
-		malloc_type_id_t type_id)
-{
-	size_t rounded_size = _nano_common_good_size(size);
-	if (rounded_size <= NANO_MAX_SIZE) {
-		return _nanov2_allocate(nanozone, rounded_size, true, true, type_id);
-	}
-
-	// Too big for nano, so delegate to the helper zone.
-	malloc_zone_t *helper_zone = nanozone->helper_zone;
-	return helper_zone->malloc_type_malloc(helper_zone, size, type_id);
 }
 #endif // OS_VARIANT_RESOLVED
 
@@ -1291,44 +1254,25 @@
 #endif // OS_VARIANT_NOTRESOLVED
 
 #if OS_VARIANT_RESOLVED
-MALLOC_ALWAYS_INLINE MALLOC_INLINE
-static void *
-_nanov2_realloc(nanozonev2_t *nanozone, void *ptr, size_t new_size, bool typed,
-		malloc_type_id_t type_id)
+MALLOC_NOEXPORT void *
+nanov2_realloc(nanozonev2_t *nanozone, void *ptr, size_t new_size)
 {
 	// If we are given a NULL pointer, just allocate memory of the requested
 	// size.
 	if (ptr == NULL) {
-		if (typed) {
-			return nanov2_malloc_type(nanozone, new_size, type_id);
-		} else {
-			return nanov2_malloc(nanozone, new_size);
-		}
-	}
-
-	malloc_zone_t *helper_zone = nanozone->helper_zone;
+		return nanov2_malloc(nanozone, new_size);
+	}
 
 	size_t old_size = nanov2_pointer_size(nanozone, ptr, FALSE);
 	if (!old_size) {
 		// Not a Nano pointer - let the helper deal with it
-		if (typed) {
-			return helper_zone->malloc_type_realloc(helper_zone, ptr, new_size,
-					type_id);
-		} else {
-			return helper_zone->realloc(helper_zone, ptr, new_size);
-		}
+		return nanozone->helper_zone->realloc(nanozone->helper_zone, ptr, new_size);
 	}
 
 	void *new_ptr;
 	if (new_size > NANO_MAX_SIZE) {
 		// Too large for Nano. Try to allocate from the helper zone.
-		if (typed) {
-			new_ptr = helper_zone->malloc_type_malloc(helper_zone, new_size,
-					type_id);
-		} else {
-			new_ptr = helper_zone->malloc(helper_zone, new_size);
-		}
-
+		new_ptr = nanozone->helper_zone->malloc(nanozone->helper_zone, new_size);
 		if (!new_ptr) {
 			// Failed to allocate - leave the existing allocation alone.
 			return NULL;
@@ -1340,15 +1284,10 @@
 		return nanov2_malloc(nanozone, 0);
 	} else {
 		size_t new_good_size = _nano_common_good_size(new_size);
-		if (new_good_size > old_size || new_good_size <= old_size / 2) {
+		if (new_good_size > old_size || new_good_size <= old_size/2) {
 			// Growing or shrinking to less than half size - we need to
 			// reallocate.
-			if (typed) {
-				new_ptr = nanov2_malloc_type(nanozone, new_good_size, type_id);
-			} else {
-				new_ptr = nanov2_malloc(nanozone, new_good_size);
-			}
-
+			new_ptr = nanov2_malloc(nanozone, new_good_size);
 			if (!new_ptr) {
 				// Failed to allocate - leave the existing allocation alone.
 				return NULL;
@@ -1376,19 +1315,6 @@
 
 	return new_ptr;
 }
-
-MALLOC_NOEXPORT void *
-nanov2_realloc(nanozonev2_t *nanozone, void *ptr, size_t new_size)
-{
-	return _nanov2_realloc(nanozone, ptr, new_size, false, MALLOC_TYPE_ID_NONE);
-}
-
-MALLOC_NOEXPORT void *
-nanov2_realloc_type(nanozonev2_t *nanozone, void *ptr, size_t new_size,
-		malloc_type_id_t type_id)
-{
-	return _nanov2_realloc(nanozone, ptr, new_size, true, type_id);
-}
 #endif // OS_VARIANT_RESOLVED
 
 #if OS_VARIANT_NOTRESOLVED
@@ -1462,22 +1388,6 @@
 	// Otherwise delegate to the helper zone
 	return nanozone->helper_zone->memalign(nanozone->helper_zone, alignment,
 			size);
-}
-
-MALLOC_NOEXPORT void *
-nanov2_memalign_type(nanozonev2_t *nanozone, size_t alignment, size_t size,
-		malloc_type_id_t type_id)
-{
-	// Serve directly if the requested alignment is trivially satisfied by our
-	// baseline alignment (16 bytes)
-	if (alignment <= NANO_REGIME_QUANTA_SIZE) {
-		return nanov2_malloc_type(nanozone, size, type_id);
-	}
-
-	// Otherwise delegate to the helper zone
-	malloc_zone_t *helper_zone = nanozone->helper_zone;
-	return helper_zone->malloc_type_memalign(helper_zone, alignment, size,
-			type_id);
 }
 
 size_t
@@ -1588,7 +1498,9 @@
 	kern_return_t kr;
 	bitarray_t slots;
 
-	reader = reader_or_in_memory_fallback(reader, task);
+	if (!reader) {
+		reader = nano_common_default_reader;
+	}
 
 	kr = reader(task, zone_address, sizeof(nanozonev2_t), (void **)&nanozone);
 	if (kr) {
@@ -1693,7 +1605,7 @@
 							bitarray_zap(slots, log_size, next_slot);
 							void *ptr = nanov2_slot_in_block_ptr(blockp, size_class, next_slot);
 							nanov2_free_slot_t *slotp = NANOV2_ZONE_PTR_TO_MAPPED_PTR(nanov2_free_slot_t *, ptr, ptr_offset);
-							next_slot = (uint16_t)slotp->next_slot;
+							next_slot = slotp->next_slot;
 							free_list_count++;
 						}
 						// Add a range for each slot that is not on the freelist,
@@ -1712,7 +1624,7 @@
 							ranges[range_count].size = slot_size;
 							range_count++;
 						}
-						_free(slots);
+						free(slots);
 					}
 					if (range_count) {
 						// Notify the in-use pointers that we found.
@@ -2029,7 +1941,7 @@
 		malloc_statistics_t *stats)
 {
 	printer = printer ? printer : nanov2_null_printer;
-	reader = reader_or_in_memory_fallback(reader, task);
+	reader = !reader && task == mach_task_self() ? _malloc_default_reader : reader;
 
 	kern_return_t err;
 
@@ -2361,49 +2273,26 @@
 
 #if OS_VARIANT_NOTRESOLVED
 
-#if CONFIG_NANO_RESERVE_REGIONS
-// Update protection for region to DEFAULT
-static bool
-nanov2_unprotect_region(nanov2_region_t *region)
-{
-	MALLOC_TRACE(TRACE_nanov2_region_protection | DBG_FUNC_START,
-			(uint64_t)region, 0, 0, 0);
-	bool result = nano_common_unprotect_vm_space((mach_vm_address_t)region,
-			NANOV2_REGION_SIZE);
-	MALLOC_TRACE(TRACE_nanov2_region_protection | DBG_FUNC_END,
-			(uint64_t)region, result, 0, 0);
-	return result;
-}
-
-// Reserve VA at [base, base+num_regions*REGION_SIZE].
-// Note: permissions must still be granted on reserved region with `nanov2_unprotect_region`
-static bool
-nanov2_reserve_regions(nanov2_region_t *base, unsigned int num_regions)
-{
-	MALLOC_TRACE(TRACE_nanov2_region_reservation | DBG_FUNC_START,
-			(uint64_t)base, num_regions, 0, 0);
-	bool result = nano_common_reserve_vm_space((mach_vm_address_t)base,
-			(NANOV2_REGION_SIZE * (mach_vm_size_t)num_regions));
-	MALLOC_TRACE(TRACE_nanov2_region_reservation | DBG_FUNC_END,
-			(uint64_t)base, num_regions, result, 0);
-
-	return result;
-}
-#else
+#if NANOV2_MULTIPLE_REGIONS
+static nanov2_addr_t nanov2_max_region_base = {
+	.fields.nano_signature = NANOZONE_SIGNATURE,
+	.fields.nano_region = NANOV2_MAX_REGION_NUMBER
+};
+#endif // NANOV2_MULTIPLE_REGIONS
+
 // Attempts to allocate VM space for a region at a given address and returns
 // whether the allocation succeeded.
-static bool
+static boolean_t
 nanov2_allocate_region(nanov2_region_t *region)
 {
 	MALLOC_TRACE(TRACE_nanov2_region_allocation | DBG_FUNC_START,
 			(uint64_t)region, 0, 0, 0);
-	bool result = nano_common_allocate_vm_space((mach_vm_address_t)region,
+	boolean_t result = nano_common_allocate_vm_space((mach_vm_address_t)region,
 			NANOV2_REGION_SIZE);
 	MALLOC_TRACE(TRACE_nanov2_region_allocation | DBG_FUNC_END,
 			(uint64_t)region, result, 0, 0);
 	return result;
 }
-#endif // CONFIG_NANO_RESERVE_REGIONS
 
 // Allocates a new region adjacent to the current one. If the allocation fails,
 // keep sliding up by the size of a region until we either succeed or run out of
@@ -2415,26 +2304,11 @@
 #if NANOV2_MULTIPLE_REGIONS
 	bool allocated = false;
 
-	nanov2_addr_t nanov2_max_region_base = {
-		.fields.nano_signature = NANOZONE_SIGNATURE,
-		.fields.nano_region = nano_max_region,
-	};
-
 	_malloc_lock_assert_owner(&nanozone->regions_lock);
 	nanov2_region_t *current_region = nanov2_current_region_base(
 			os_atomic_load(&nanozone->current_region_next_arena, relaxed));
 	nanov2_region_t *next_region = current_region + 1;
-
 	while ((void *)next_region <= nanov2_max_region_base.addr) {
-#if CONFIG_NANO_RESERVE_REGIONS
-		if (!nanov2_unprotect_region(next_region)) {
-			MALLOC_REPORT_FATAL_ERROR(next_region,
-					"Nano: Unable to raise protection on pre-allocated region");
-		}
-		nanozone->statistics.allocated_regions++;
-		allocated = true;
-		break;
-#else // CONFIG_NANO_RESERVE_REGIONS
 		if (nanov2_allocate_region(next_region)) {
 			nanozone->statistics.allocated_regions++;
 			allocated = true;
@@ -2447,7 +2321,6 @@
 		// atomically here. Published by the store-release of
 		// current_region_next_arena.
 		os_atomic_inc(&nanozone->statistics.region_address_clashes, relaxed);
-#endif // CONFIG_NANO_RESERVE_REGIONS
 	}
 
 	if (!allocated) {
@@ -2495,8 +2368,7 @@
 	uint64_t guard = *(uint64_t *)corrupt_slot;
 	malloc_zone_error(MALLOC_ABORT_ON_CORRUPTION, true,
 			"Heap corruption detected, free list is damaged at %p\n"
-			"*** Incorrect guard value: %llu\n", corrupt_slot,
-			(unsigned long long)guard);
+			"*** Incorrect guard value: %lu\n", corrupt_slot, guard);
 	__builtin_unreachable();
 }
 
@@ -2561,7 +2433,7 @@
 		slot = old_meta_view.meta.next_slot - 1; // meta.next_slot is 1-based.
 		ptr = nanov2_slot_in_block_ptr(blockp, size_class, slot);
 		nanov2_free_slot_t *slotp = (nanov2_free_slot_t *)ptr;
-		new_meta.next_slot = slot_full ? SLOT_FULL : (uint16_t)slotp->next_slot;
+		new_meta.next_slot = slot_full ? SLOT_FULL : slotp->next_slot;
 	}
 
 	// Write the updated meta data; try again if we raced with another thread.
@@ -2981,7 +2853,7 @@
 nanov2_allocate_outlined(nanozonev2_t *nanozone, nanov2_block_meta_t **block_metapp,
 		size_t rounded_size, nanov2_size_class_t size_class,
 		int allocation_index, nanov2_block_meta_t *madvise_block_metap,
-		void *corrupt_slot, bool clear, bool typed, malloc_type_id_t type_id)
+		void *corrupt_slot, bool clear)
 {
 	void *ptr = NULL;
 
@@ -3000,13 +2872,7 @@
 	// get a new block. Before doing so, delegate to the helper allocator if
 	// the size class was full and has not released enough memory yet.
 	if (nanozone->delegate_allocations & (1 << size_class)) {
-		malloc_zone_t *helper_zone = nanozone->helper_zone;
-		if (typed) {
-			ptr = helper_zone->malloc_type_malloc(helper_zone, rounded_size,
-					type_id);
-		} else {
-			ptr = helper_zone->malloc(helper_zone, rounded_size);
-		}
+		ptr = nanozone->helper_zone->malloc(nanozone->helper_zone, rounded_size);
 		goto done;
 	}
 
@@ -3041,19 +2907,12 @@
 		os_atomic_or(&nanozone->delegate_allocations,
 				(uint16_t)(1 << size_class), relaxed);
 
-		malloc_zone_t *helper_zone = nanozone->helper_zone;
-		if (typed) {
-			ptr = helper_zone->malloc_type_malloc(helper_zone, rounded_size,
-					type_id);
-		} else {
-			ptr = helper_zone->malloc(helper_zone, rounded_size);
-		}
+		ptr = nanozone->helper_zone->malloc(nanozone->helper_zone, rounded_size);
 	}
 
 done:
 	if (os_likely(ptr)) {
-		switch (malloc_zero_policy) {
-		case MALLOC_ZERO_ON_FREE: {
+		if (malloc_zero_on_free) {
 			// Always clear the double-free guard so that we can recognize that
 			// this block is not on the free list.
 			nanov2_free_slot_t *slotp = (nanov2_free_slot_t *)ptr;
@@ -3064,20 +2923,15 @@
 			// all cases, even if a cleared allocation is not requested, to
 			// prevent any leakage through the next_slot bits.
 			os_atomic_store(&slotp->next_slot, 0, relaxed);
-			break;
-		}
-		case MALLOC_ZERO_NONE:
-			if (!clear) {
+		} else {
+			if (clear) {
+				memset(ptr, '\0', rounded_size);
+			} else {
 				// Always clear the double-free guard so that we can recognize that
 				// this block is not on the free list.
 				nanov2_free_slot_t *slotp = (nanov2_free_slot_t *)ptr;
 				os_atomic_store(&slotp->double_free_guard, 0, relaxed);
-				break;
 			}
-			MALLOC_FALLTHROUGH;
-		case MALLOC_ZERO_ON_ALLOC:
-			memset(ptr, '\0', rounded_size);
-			break;
 		}
 	} else {
 		malloc_set_errno_fast(MZ_POSIX, ENOMEM);
@@ -3180,9 +3034,11 @@
 malloc_zone_t *
 nanov2_create_zone(malloc_zone_t *helper_zone, unsigned debug_flags)
 {
-	// Note: It is not necessary that nanov2_create_zone resets _malloc_engaged_nano
-	// if it is unable to enable the nanozone - functions that need to determine
-	// whether the nanozone is preset should test initial_nano_zone.
+	// Note: It is important that nanov2_create_zone resets _malloc_engaged_nano
+	// if it is unable to enable the nanozone (and chooses not to abort). As
+	// several functions rely on _malloc_engaged_nano to determine if they
+	// should manipulate the nanozone, and these should not run if we failed
+	// to create the zone.
 	MALLOC_ASSERT(_malloc_engaged_nano == NANO_V2);
 
 	// Get memory for the zone and disable Nano if we fail.
@@ -3194,18 +3050,9 @@
 	}
 
 	// Set up the basic_zone portion of the nanozonev2 structure
-	nanozone->basic_zone.version = 16;
+	nanozone->basic_zone.version = 13;
 	nanozone->basic_zone.size = OS_RESOLVED_VARIANT_ADDR(nanov2_size);
-	if (malloc_zero_policy == MALLOC_ZERO_ON_ALLOC) {
-		nanozone->basic_zone.malloc =
-				OS_RESOLVED_VARIANT_ADDR(nanov2_malloc_zero_on_alloc);
-		nanozone->basic_zone.malloc_type_malloc =
-				OS_RESOLVED_VARIANT_ADDR(nanov2_malloc_type_zero_on_alloc);
-	} else {
-		nanozone->basic_zone.malloc = OS_RESOLVED_VARIANT_ADDR(nanov2_malloc);
-		nanozone->basic_zone.malloc_type_malloc =
-				OS_RESOLVED_VARIANT_ADDR(nanov2_malloc_type);
-	}
+	nanozone->basic_zone.malloc = OS_RESOLVED_VARIANT_ADDR(nanov2_malloc);
 	nanozone->basic_zone.calloc = OS_RESOLVED_VARIANT_ADDR(nanov2_calloc);
 	nanozone->basic_zone.valloc = (void *)nanov2_valloc;
 	nanozone->basic_zone.free = OS_RESOLVED_VARIANT_ADDR(nanov2_free);
@@ -3221,13 +3068,6 @@
 	nanozone->basic_zone.claimed_address = OS_RESOLVED_VARIANT_ADDR(nanov2_claimed_address);
 	nanozone->basic_zone.try_free_default = OS_RESOLVED_VARIANT_ADDR(nanov2_try_free_default);
 
-	// zone_type == MALLOC_ZONE_TYPE_UNKNOWN
-	// No malloc_with_options
-
-	nanozone->basic_zone.malloc_type_calloc = OS_RESOLVED_VARIANT_ADDR(nanov2_calloc_type);
-	nanozone->basic_zone.malloc_type_realloc = OS_RESOLVED_VARIANT_ADDR(nanov2_realloc_type);
-	nanozone->basic_zone.malloc_type_memalign = OS_RESOLVED_VARIANT_ADDR(nanov2_memalign_type);
-
 	// Set these both to zero as required by CFAllocator.
 	nanozone->basic_zone.reserved1 = 0;
 	nanozone->basic_zone.reserved2 = 0;
@@ -3265,30 +3105,14 @@
 	_malloc_lock_init(&nanozone->madvise_lock);
 
 	// Allocate the initial region. If this does not succeed, we disable Nano.
-	nanov2_region_t *region = (nanov2_region_t *)NANOZONE_BASE_REGION_ADDRESS;
-
-	bool result;
-#if CONFIG_NANO_RESERVE_REGIONS
-	unsigned int num_regions = (nano_max_region + 1);
-	result = nanov2_reserve_regions(region, num_regions);
-	if (result) {
-		result = nanov2_unprotect_region(region);
-		if (!result) {
-			malloc_report(ASL_LEVEL_ERR,
-					"unable to protect initial region\n");
-			nano_common_deallocate_pages((void *)region,
-					num_regions * (size_t)NANOV2_REGION_SIZE, 0);
-		}
-	}
-#else // CONFIG_NANO_RESERVE_REGIONS
-	result = nanov2_allocate_region(region);
-#endif // CONFIG_NANO_RESERVE_REGIONS
+	nanov2_addr_t p = {.fields.nano_signature = NANOZONE_SIGNATURE};
+	nanov2_region_t *region = (nanov2_region_t *)p.addr;
+	boolean_t result = nanov2_allocate_region(region);
 	if (!result) {
-		nano_common_deallocate_pages((void *)nanozone,
-				NANOZONEV2_ZONE_PAGED_SIZE, 0);
+		nano_common_deallocate_pages(nanozone, NANOZONEV2_ZONE_PAGED_SIZE, 0);
 		_malloc_engaged_nano = NANO_NONE;
 		malloc_report(ASL_LEVEL_NOTICE, "nano zone abandoned due to inability "
-				"to reserve vm space.\n");
+				"to preallocate reserved vm space.\n");
 		return NULL;
 	}
 	nanov2_region_linkage_t *region_linkage =
@@ -3300,6 +3124,7 @@
 	os_atomic_store(&nanozone->current_region_next_arena,
 			((nanov2_arena_t *)region) + 1, release);
 	nanozone->statistics.allocated_regions = 1;
+
 	// Set up the guard blocks for the initial arena, if requested
 	nanov2_init_guard_blocks(nanozone, (nanov2_arena_t *)region);
 
@@ -3324,15 +3149,6 @@
 	// Just hand to the helper zone.
 	return nanozone->helper_zone->malloc(nanozone->helper_zone, size);
 }
-
-MALLOC_NOEXPORT void *
-nanov2_forked_malloc_type(nanozonev2_t *nanozone, size_t size,
-		malloc_type_id_t type_id)
-{
-	// Just hand to the helper zone.
-	malloc_zone_t *helper_zone = nanozone->helper_zone;
-	return helper_zone->malloc_type_malloc(helper_zone, size, type_id);
-}
 #endif // OS_VARIANT_RESOLVED
 
 #if OS_VARIANT_NOTRESOLVED
@@ -3346,30 +3162,11 @@
 }
 
 static void *
-nanov2_forked_calloc_type(nanozonev2_t *nanozone, size_t num_items, size_t size,
-		malloc_type_id_t type_id)
-{
-	// Just hand to the helper zone.
-	malloc_zone_t *helper_zone = nanozone->helper_zone;
-	return helper_zone->malloc_type_calloc(helper_zone, num_items, size, type_id);
-}
-
-static void *
 nanov2_forked_memalign(nanozonev2_t *nanozone, size_t alignment, size_t size)
 {
 	// Just hand to the helper zone.
 	return nanozone->helper_zone->memalign(nanozone->helper_zone, alignment,
 			size);
-}
-
-static void *
-nanov2_forked_memalign_type(nanozonev2_t *nanozone, size_t alignment,
-		size_t size, malloc_type_id_t type_id)
-{
-	// Just hand to the helper zone.
-	malloc_zone_t *helper_zone = nanozone->helper_zone;
-	return helper_zone->malloc_type_memalign(helper_zone, alignment, size,
-			type_id);
 }
 
 #endif // OS_VARIANT_NOTRESOLVED
@@ -3404,31 +3201,21 @@
 	nanov2_forked_free(nanozone, ptr);
 }
 
-MALLOC_ALWAYS_INLINE MALLOC_INLINE
-static void *
-_nanov2_forked_realloc(nanozonev2_t *nanozone, void *ptr, size_t new_size,
-		bool typed, malloc_type_id_t type_id)
+MALLOC_NOEXPORT void *
+nanov2_forked_realloc(nanozonev2_t *nanozone, void *ptr, size_t new_size)
 {
 	// could occur through malloc_zone_realloc() path
 	if (!ptr) {
 		// If ptr is a null pointer, realloc() shall be equivalent to malloc()
 		// for the specified size.
-		if (typed) {
-			return nanov2_forked_malloc_type(nanozone, new_size, type_id);
-		} else {
-			return nanov2_forked_malloc(nanozone, new_size);
-		}
+		return nanov2_forked_malloc(nanozone, new_size);
 	}
 
 	size_t old_size = nanov2_pointer_size(nanozone, ptr, FALSE);
 	if (!old_size) {
 		// not-nano pointer, hand down to helper zone
 		malloc_zone_t *zone = (malloc_zone_t *)(nanozone->helper_zone);
-		if (typed) {
-			return zone->malloc_type_realloc(zone, ptr, new_size, type_id);
-		} else {
-			return zone->realloc(zone, ptr, new_size);
-		}
+		return zone->realloc(zone, ptr, new_size);
 	} else {
 		if (!new_size) {
 			// If size is 0 and ptr is not a null pointer, the object pointed to
@@ -3440,15 +3227,8 @@
 			return nanov2_forked_malloc(nanozone, 1);
 		}
 
-		void *new_ptr;
-		if (typed) {
-			malloc_zone_t *helper_zone = nanozone->helper_zone;
-			new_ptr = helper_zone->malloc_type_malloc(helper_zone, new_size,
-					type_id);
-		} else {
-			new_ptr = nanozone->helper_zone->malloc(nanozone->helper_zone,
+		void *new_ptr = nanozone->helper_zone->malloc(nanozone->helper_zone,
 				new_size);
-		}
 		if (new_ptr) {
 			size_t valid_size = MIN(old_size, new_size);
 			memcpy(new_ptr, ptr, valid_size);
@@ -3462,20 +3242,6 @@
 		/* NOTREACHED */
 	}
 	/* NOTREACHED */
-}
-
-MALLOC_NOEXPORT void *
-nanov2_forked_realloc(nanozonev2_t *nanozone, void *ptr, size_t new_size)
-{
-	return _nanov2_forked_realloc(nanozone, ptr, new_size, false,
-			MALLOC_TYPE_ID_NONE);
-}
-
-MALLOC_NOEXPORT void *
-nanov2_forked_realloc_type(nanozonev2_t *nanozone, void *ptr, size_t new_size,
-		malloc_type_id_t type_id)
-{
-	return _nanov2_forked_realloc(nanozone, ptr, new_size, true, type_id);
 }
 #endif // OS_VARIANT_RESOLVED
 
@@ -3546,13 +3312,6 @@
 			OS_RESOLVED_VARIANT_ADDR(nanov2_forked_free_definite_size);
 	nanozone->basic_zone.claimed_address = nanov2_forked_claimed_address;
 	nanozone->basic_zone.try_free_default = NULL; // Fall back to old protocol
-	nanozone->basic_zone.malloc_type_malloc =
-			OS_RESOLVED_VARIANT_ADDR(nanov2_forked_malloc_type);
-	nanozone->basic_zone.malloc_type_calloc = (void *)nanov2_forked_calloc_type;
-	nanozone->basic_zone.malloc_type_realloc =
-			OS_RESOLVED_VARIANT_ADDR(nanov2_forked_realloc_type);
-	nanozone->basic_zone.malloc_type_memalign =
-			(void *)nanov2_forked_memalign_type;
 	mprotect(nanozone, sizeof(nanozone->basic_zone), PROT_READ);
 }