Loading...
--- libmalloc/libmalloc-283/src/nanov2_zone.h
+++ libmalloc/libmalloc-792.41.1/src/nanov2_zone.h
@@ -29,21 +29,22 @@
 #pragma mark -
 #pragma mark Address Structure
 
-#if TARGET_OS_OSX || TARGET_OS_SIMULATOR || TARGET_OS_DRIVERKIT
+#if TARGET_OS_OSX || TARGET_OS_SIMULATOR || MALLOC_TARGET_DK_OSX
 
 #define NANOV2_REGION_BITS		15
 #define NANOV2_ARENA_BITS		3
 #define NANOV2_BLOCK_BITS		12
 #define NANOV2_OFFSET_BITS		14
 
-#else // TARGET_OS_OSX || TARGET_OS_SIMULATOR || TARGET_OS_DRIVERKIT
+#else // TARGET_OS_OSX || TARGET_OS_SIMULATOR || MALLOC_TARGET_DK_OSX
 
 #define NANOV2_REGION_BITS		0
 #define NANOV2_ARENA_BITS		3
 #define NANOV2_BLOCK_BITS		12
 #define NANOV2_OFFSET_BITS		14
 
-#endif // TARGET_OS_OSX || TARGET_OS_SIMULATOR || TARGET_OS_DRIVERKIT
+#endif // TARGET_OS_OSX || TARGET_OS_SIMULATOR || MALLOC_TARGET_DK_OSX
+
 
 #if NANOV2_REGION_BITS > 0
 #define NANOV2_MULTIPLE_REGIONS	1
@@ -69,7 +70,7 @@
 // Maximum number of slots per block
 #define NANOV2_MAX_SLOTS_PER_BLOCK	(NANOV2_BLOCK_SIZE/NANO_REGIME_QUANTA_SIZE)
 
-// Highest region number.
+// Highest region number supported by this signature
 #if NANOV2_MULTIPLE_REGIONS
 #define NANOV2_MAX_REGION_NUMBER	((1 << NANOV2_REGION_BITS) - 1)
 #else 	// NANOV2_MULTIPLE_REGIONS
@@ -155,6 +156,7 @@
 
 // Distinguished values of next_slot
 #define SLOT_NULL			0		// Slot has never been used.
+#define SLOT_GUARD			0x7fa	// Marks a guard block.
 #define SLOT_BUMP 			0x7fb	// Marks the end of the free list
 #define SLOT_FULL			0x7fc	// Slot is full (no free slots)
 #define SLOT_CAN_MADVISE 	0x7fd	// Block can be madvised (and in_use == 0)
@@ -180,8 +182,10 @@
 // Structure overlaid on slots that are on the block freelist.
 typedef struct {
     uint64_t double_free_guard;
-    uint16_t next_slot;
+    uint64_t next_slot; // Legal values are <= NEXT_SLOT_VALID_MASK
 } nanov2_free_slot_t;
+
+#define NEXT_SLOT_VALID_MASK 0x7ff
 
 MALLOC_STATIC_ASSERT(
 		sizeof(nanov2_free_slot_t) <= NANO_REGIME_QUANTA_SIZE,
@@ -203,8 +207,10 @@
 
 // Linkage between regions. Overlays the nanov2_block_meta_t that corresponds
 // to the arena metadata block, so must be the same size as nanov2_block_meta_t.
-typedef struct {
-    uint16_t next_region_offset;	// Offset to next region in 512MB blocks
+// Accessed atomically when walking the regions.
+typedef struct {
+	// Offset to next region in 512MB blocks
+	os_atomic(uint16_t) next_region_offset;
 	uint16_t unused;
 } nanov2_region_linkage_t;
 
@@ -256,9 +262,6 @@
 	// Locks for the current allocation blocks.
 	_malloc_lock_s		current_block_lock[NANO_SIZE_CLASSES][MAX_CURRENT_BLOCKS];
 
-	// Lock for delegate_allocations.
-	_malloc_lock_s		delegate_allocations_lock;
-
 	// Mask of size classes for which allocation should be delegated when a new
 	// block is needed and the class has become full.
 	uint16_t			delegate_allocations;
@@ -280,23 +283,22 @@
 	// Lock used to serialize access to current_block.
 	_malloc_lock_s		blocks_lock;
 
-	// Lock used to protect current_region_base, current_region_next_arena and
-	// current_region_limit.
+	// Lock used to protect modification of current_region_next_arena.
 	_malloc_lock_s		regions_lock;
 	
 	// Base address of the first region. Fixed once set.
 	nanov2_region_t 	*first_region_base;
 	
-	// Base address of the current region. Always the most recently allocated
-	// region and therefore the one with the highest base address.
-	nanov2_region_t 	*current_region_base;
-	
-	// Address to use for the next arena. Always between current_region_base
-	// and current_region_limit.
-	nanov2_arena_t		*current_region_next_arena;
-	
- 	// Limit address of the current region (first byte after the region).
- 	void				*current_region_limit;
+	// Address to use for the next arena, or the limit arena of the current
+	// region (i.e. the first byte after the end of the current region) if the
+	// current region is full. This is always the upper bound on addresses that
+	// can possibly be allocated from nano. When a new region is allocated, this
+	// is set directly to the _second_ arena of the new region, so a value on a
+	// region boundary is always a limit arena rather than a first arena.
+	//
+	// Modified under the protection of the regions_lock but atomically loaded
+	// outside of it from fast-path contexts; access with care.
+	os_atomic(nanov2_arena_t *) current_region_next_arena;
 	
 	// Lock used when madvising.
 	_malloc_lock_s		madvise_lock;