Loading...
--- libmalloc/libmalloc-317.140.5/src/magazine_small.c
+++ libmalloc/libmalloc-317.40.8/src/magazine_small.c
@@ -72,13 +72,13 @@
 {
 #if CONFIG_SMALL_USES_HYPER_SHIFT
 	if (os_likely(_os_cpu_number_override == -1)) {
-		return _malloc_cpu_number() >> hyper_shift;
+		return _os_cpu_number() >> hyper_shift;
 	} else {
 		return _os_cpu_number_override >> hyper_shift;
 	}
 #else // CONFIG_SMALL_USES_HYPER_SHIFT
 	if (os_likely(_os_cpu_number_override == -1)) {
-		return _malloc_cpu_number();
+		return _os_cpu_number();
 	} else {
 		return _os_cpu_number_override;
 	}
@@ -994,30 +994,18 @@
 	for (mag_index = 0; mag_index < rack->num_magazines; mag_index++) {
 		size_t index;
 		for (index = 0; index < rack->region_generation->num_regions_allocated; ++index) {
-			rack_region_lock(rack);
+			SZONE_LOCK(SMALL_SZONE_FROM_RACK(rack));
 
 			region_t small = rack->region_generation->hashed_regions[index];
 			if (!small || small == HASHRING_REGION_DEALLOCATED) {
-				rack_region_unlock(rack);
+				SZONE_UNLOCK(SMALL_SZONE_FROM_RACK(rack));
 				continue;
 			}
 
-			region_trailer_t *trailer = REGION_TRAILER_FOR_SMALL_REGION(small);
-			// Make sure that the owning magazine doesn't try and take this out
-			// from under our feet.
-			trailer->dispose_flags |= RACK_DISPOSE_DELAY;
-			rack_region_unlock(rack);
-
 			magazine_t *mag_ptr = mag_lock_zine_for_region_trailer(rack->magazines,
-					trailer, MAGAZINE_INDEX_FOR_SMALL_REGION(small));
-
-			// If acquiring the region lock was enough to prevent the owning
-			// magazine from deallocating the region, free it now so we don't
-			// do wasted work.
-			if (rack_region_maybe_dispose(rack, small, SMALL_REGION_SIZE, trailer)) {
-				SZONE_MAGAZINE_PTR_UNLOCK(mag_ptr);
-				continue;
-			}
+					REGION_TRAILER_FOR_SMALL_REGION(small),
+					MAGAZINE_INDEX_FOR_SMALL_REGION(small));
+			SZONE_UNLOCK(SMALL_SZONE_FROM_RACK(rack));
 
 			/* Ordering is important here, the magazine of a region may potentially change
 			 * during mag_lock_zine_for_region_trailer, so src_mag_index must be taken
@@ -1155,18 +1143,31 @@
 	int objects_in_use = small_free_detach_region(rack, depot_ptr, sparse_region);
 
 	if (0 == objects_in_use) {
-		if (!rack_region_remove(rack, sparse_region, node)) {
+		// Invalidate the hash table entry for this region with HASHRING_REGION_DEALLOCATED.
+		// Using HASHRING_REGION_DEALLOCATED preserves the collision chain, using HASHRING_OPEN_ENTRY (0) would not.
+		rgnhdl_t pSlot = hash_lookup_region_no_lock(rack->region_generation->hashed_regions,
+													rack->region_generation->num_regions_allocated,
+													rack->region_generation->num_regions_allocated_shift,
+													sparse_region);
+		if (NULL == pSlot) {
+			malloc_zone_error(rack->debug_flags, true, "small_free_try_depot_unmap_no_lock hash lookup failed: %p\n", sparse_region);
 			return NULL;
 		}
+		*pSlot = HASHRING_REGION_DEALLOCATED;
 		depot_ptr->num_bytes_in_magazine -= SMALL_HEAP_SIZE;
+		// Atomically increment num_regions_dealloc
+#ifdef __LP64___
+		OSAtomicIncrement64(&rack->num_regions_dealloc);
+#else
+		OSAtomicIncrement32((int32_t *)&rack->num_regions_dealloc);
+#endif
 
 		// Caller will transfer ownership of the region back to the OS with no locks held
 		MAGMALLOC_DEALLOCREGION(SMALL_SZONE_FROM_RACK(rack), (void *)sparse_region, (int)SMALL_REGION_SIZE); // DTrace USDT Probe
 		return sparse_region;
 
 	} else {
-		malloc_zone_error(rack->debug_flags, true,
-				"small_free_try_depot_unmap_no_lock objects_in_use not zero: %d\n", objects_in_use);
+		malloc_zone_error(rack->debug_flags, true, "small_free_try_depot_unmap_no_lock objects_in_use not zero: %d\n", objects_in_use);
 		return NULL;
 	}
 }