Loading...
--- libmalloc/libmalloc-317.40.8/src/magazine_zone.h
+++ libmalloc/libmalloc-792.80.2/src/magazine_zone.h
@@ -23,6 +23,9 @@
#ifndef __MAGAZINE_ZONE_H
#define __MAGAZINE_ZONE_H
+
+#include <malloc/_ptrcheck.h>
+__ptrcheck_abi_assume_single()
/********************* DEFINITIONS ************************/
@@ -42,7 +45,7 @@
// In-place free list entry. Unlike the out-of-band entry, the in-place entries
// are stored at the start of the range that has been freed.
-typedef struct _inplace_free_entry_s *inplace_free_entry_t;
+typedef struct _inplace_free_entry_s * __single inplace_free_entry_t;
typedef struct {
void *ptr;
@@ -57,7 +60,7 @@
typedef struct _inplace_free_entry_s {
inplace_union previous;
inplace_union next;
-} inplace_free_entry_s, *inplace_free_entry_t;
+} inplace_free_entry_s, * __single inplace_free_entry_t;
#ifdef __LP64__
MALLOC_STATIC_ASSERT(sizeof(inplace_free_entry_s) == 16, "inplace free list must be 16-bytes long");
@@ -90,10 +93,6 @@
typedef unsigned int grain_t; // N.B. wide enough to index all free slots
-#define CHECK_REGIONS (1 << 31)
-#define DISABLE_ASLR (1 << 30)
-#define DISABLE_LARGE_ASLR (1 << 29)
-
#define MAX_RECORDER_BUFFER 256
/********************* DEFINITIONS for tiny ************************/
@@ -132,6 +131,11 @@
* their size in the block, and store it both after the 'next' pointer, and in
* the last 2 bytes of the block.
*
+ * With zero-on-free, free blocks of two or more quanta are zeroed out after
+ * their leading inline metadata. This invariant is maintained when blocks are
+ * split and coalesced, enabling calloc(3) to return free blocks as-is after
+ * clearing the metadata.
+ *
* 1-quantum block
* Offset (32-bit mode) (64-bit mode)
* 0x0 0x0 : previous
@@ -143,6 +147,7 @@
* 0x0 0x0 : previous
* 0x4 0x08 : next
* 0x8 0x10 : size (in quantum counts)
+ * 0xa 0x12 : start of zeroed body
* end - 2 end - 2 : size (in quantum counts)
* end end
*
@@ -184,12 +189,12 @@
* Beginning and end pointers for a region's heap.
*/
#define TINY_REGION_HEAP_BASE(region) ((void *)(((tiny_region_t)region)->blocks))
-#define TINY_REGION_HEAP_END(region) ((void *)(((uintptr_t)TINY_REGION_HEAP_BASE(region)) + TINY_HEAP_SIZE))
+#define TINY_REGION_HEAP_END(region) __unsafe_forge_single(void *, ((uintptr_t)TINY_REGION_HEAP_BASE(region)) + TINY_HEAP_SIZE)
/*
* Locate the region for a pointer known to be within a tiny region.
*/
-#define TINY_REGION_FOR_PTR(ptr) ((tiny_region_t)((uintptr_t)(ptr) & ~((1 << TINY_BLOCKS_ALIGN) - 1)))
+#define TINY_REGION_FOR_PTR(ptr) __unsafe_forge_single(tiny_region_t, (uintptr_t)(ptr) & ~((1 << TINY_BLOCKS_ALIGN) - 1))
/*
* Convert between byte and msize units.
@@ -225,6 +230,11 @@
} region_free_blocks_t;
typedef uint32_t region_cookie_t;
+
+OS_ENUM(rack_dispose_flags, uint32_t,
+ RACK_DISPOSE_DELAY = 0x1,
+ RACK_DISPOSE_NEEDED = 0x2,
+);
typedef struct region_trailer {
struct region_trailer *prev;
@@ -234,6 +244,8 @@
mag_index_t mag_index;
volatile int32_t pinned_to_depot;
bool recirc_suitable;
+ // Locking: dispose_flags must be locked under the rack's region lock
+ rack_dispose_flags_t dispose_flags;
} region_trailer_t;
typedef struct tiny_region {
@@ -407,7 +419,7 @@
/*
* Locate the heap base for a pointer known to be within a small region.
*/
-#define SMALL_REGION_FOR_PTR(ptr) ((small_region_t)((uintptr_t)(ptr) & ~((1 << SMALL_BLOCKS_ALIGN) - 1)))
+#define SMALL_REGION_FOR_PTR(ptr) __unsafe_forge_single(small_region_t, (uintptr_t)(ptr) & ~((1 << SMALL_BLOCKS_ALIGN) - 1))
#define SMALL_REGION_OFFSET_FOR_PTR(ptr) ((uintptr_t)(ptr) & ((1 << SMALL_BLOCKS_ALIGN) - 1))
/*
@@ -611,7 +623,7 @@
/*
* Locate the heap base for a pointer known to be within a medium region.
*/
-#define MEDIUM_REGION_FOR_PTR(ptr) ((void *)((uintptr_t)(ptr) & ~((1ull << MEDIUM_BLOCKS_ALIGN) - 1)))
+#define MEDIUM_REGION_FOR_PTR(ptr) __unsafe_forge_single(void *, (uintptr_t)(ptr) & ~((1ull << MEDIUM_BLOCKS_ALIGN) - 1))
#define MEDIUM_REGION_OFFSET_FOR_PTR(ptr) ((uintptr_t)(ptr) & ((1ull << MEDIUM_BLOCKS_ALIGN) - 1))
/*
@@ -723,7 +735,11 @@
typedef struct large_entry_s {
vm_address_t address;
vm_size_t size;
+#if CONFIG_MAGAZINE_DEFERRED_RECLAIM
+ mach_vm_reclaim_id_t reclaim_index;
+#else
boolean_t did_madvise_reusable;
+#endif /* CONFIG_MAGAZINE_DEFERRED_RECLAIM */
} large_entry_t;
#if !CONFIG_LARGE_CACHE && DEBUG_MALLOC
@@ -769,7 +785,7 @@
// Take magazine_lock first, Depot lock when needed for recirc, then szone->{tiny,small}_regions_lock when needed for alloc
_malloc_lock_s magazine_lock MALLOC_CACHE_ALIGN;
// Protection for the crtical section that does allocate_pages outside the magazine_lock
- volatile boolean_t alloc_underway;
+ _malloc_lock_s magazine_alloc_lock;
// One element deep "death row", optimizes malloc/free/malloc for identical size.
void *mag_last_free;