Loading...
--- libmalloc/libmalloc-374.60.3/src/nanov2_malloc.c
+++ libmalloc/libmalloc-283/src/nanov2_malloc.c
@@ -239,14 +239,13 @@
// Given a block metadata pointer, returns whether the block is active (that is,
// it is being used for allocations, it has allocations that have not been freed,
-// or is waiting to be madvised and is not a guard block).
+// or is waiting to be madvised).
static MALLOC_ALWAYS_INLINE MALLOC_INLINE boolean_t
nanov2_is_block_active(nanov2_block_meta_t block_meta)
{
return block_meta.next_slot != SLOT_NULL
&& block_meta.next_slot != SLOT_MADVISING
- && block_meta.next_slot != SLOT_MADVISED
- && block_meta.next_slot != SLOT_GUARD;
+ && block_meta.next_slot != SLOT_MADVISED;
}
#if OS_VARIANT_RESOLVED
@@ -596,15 +595,15 @@
#if CONFIG_NANO_USES_HYPER_SHIFT
if (os_likely(nano_common_max_magazines_is_ncpu)) {
// Default case is max magazines == physical number of CPUs, which
- // must be > _malloc_cpu_number() >> hyper_shift, so the modulo
+ // must be > _os_cpu_number() >> hyper_shift, so the modulo
// operation is not required.
- return _malloc_cpu_number() >> hyper_shift;
+ return _os_cpu_number() >> hyper_shift;
}
#else // CONFIG_NANO_USES_HYPER_SHIFT
if (os_likely(nano_common_max_magazines_is_ncpu)) {
// Default case is max magazines == logical number of CPUs, which
- // must be > _malloc_cpu_number() so the modulo operation is not required.
- return _malloc_cpu_number();
+ // must be > _os_cpu_number() so the modulo operation is not required.
+ return _os_cpu_number();
}
#endif // CONFIG_NANO_USES_HYPER_SHIFT
@@ -614,62 +613,11 @@
#endif // CONFIG_NANO_USES_HYPER_SHIFT
if (os_likely(_os_cpu_number_override == -1)) {
- return (_malloc_cpu_number() >> shift) % nano_common_max_magazines;
+ return (_os_cpu_number() >> shift) % nano_common_max_magazines;
}
return (_os_cpu_number_override >> shift) % nano_common_max_magazines;
}
#endif // OS_VARIANT_RESOLVED
-
-#pragma mark -
-#pragma mark Guard Blocks
-
-// Converts a given block (specified by absolute block number) in an arena into
-// a guard block. The block will be marked as in-use so that it is not available
-// for allocations and its permissions are set to PROT_READ. Note that
-// PROT_READ is used instead of PROT_NONE because the latter breaks the
-// enumerator, which tries to map the whole region and fails if there are
-// PROT_NONE pages in the range. We can't fix that in the allocator because the
-// code that does the mapping is part of the sampling tools and is simply
-// invoked as a callback from the enumerator.
-static MALLOC_ALWAYS_INLINE MALLOC_INLINE void
-nanov2_create_guard_block(nanozonev2_t *nanozone, nanov2_arena_t *arena,
- nanov2_block_index_t block_index) {
- // Mark the block as in-use in the meta data
- static nanov2_block_meta_t in_use_block = {
- .in_use = 1,
- .next_slot = SLOT_GUARD
- };
- nanov2_meta_index_t block_meta_index =
- nanov2_block_index_to_meta_index(block_index);
- nanov2_arena_metablock_t *block_metap = nanov2_metablock_address_for_ptr(
- nanozone, arena);
- block_metap->arena_block_meta[block_meta_index] = in_use_block;
- void *block_ptr = &arena->blocks[block_index];
-
- // Apply PROT_NONE to the block itself.
- kern_return_t err = mprotect(block_ptr, NANOV2_BLOCK_SIZE, PROT_READ);
- if (err != KERN_SUCCESS) {
- malloc_report(ASL_LEVEL_ERR, "Failed to create guard block at %p (%d)\n",
- block_ptr, err);
- }
-}
-
-// Creates the guard blocks for an arena, if required. The guard blocks are
-// the first and last physical blocks in the arena that are not the metadata
-// block.
-static MALLOC_ALWAYS_INLINE MALLOC_INLINE void
-nanov2_init_guard_blocks(nanozonev2_t *nanozone, nanov2_arena_t *arena)
-{
- if (nanozone->debug_flags & MALLOC_ALL_GUARD_PAGE_FLAGS) {
- // Use the first and last blocks in the arena as guard regions,
- // avoiding the metadata block.
- nanov2_meta_index_t meta_index = nanov2_metablock_meta_index(nanozone);
- nanov2_create_guard_block(nanozone, arena, meta_index == 0 ? 1 : 0);
- nanov2_create_guard_block(nanozone, arena,
- meta_index == NANOV2_BLOCKS_PER_ARENA - 1 ?
- NANOV2_BLOCKS_PER_ARENA - 2 : NANOV2_BLOCKS_PER_ARENA - 1);
- }
-}
#pragma mark -
#pragma mark Allocator Initialization
@@ -1334,7 +1282,7 @@
if (kr) {
return kr;
}
- boolean_t self_zone = mach_task_is_self(task) && (nanozonev2_t *)zone_address == nanozone;
+ boolean_t self_zone = (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 +1434,7 @@
static boolean_t
nanov2_check(nanozonev2_t *nanozone)
{
- // Does nothing
+ // Does nothing, just like Nano V1.
return 1;
}
@@ -1722,7 +1670,7 @@
static void
nanov2_log(malloc_zone_t *zone, void *log_address)
{
- // Does nothing
+ // Does nothing, just like Nano V1.
}
static void
@@ -1751,7 +1699,7 @@
}
static void
-nanov2_null_printer(const char __unused *fmt, ...)
+null_printer(const char __unused *fmt, ...)
{
}
@@ -1760,7 +1708,7 @@
memory_reader_t reader, print_task_printer_t printer,
malloc_statistics_t *stats)
{
- printer = printer ? printer : nanov2_null_printer;
+ printer = printer ? printer : null_printer;
reader = !reader && task == mach_task_self() ? _malloc_default_reader : reader;
kern_return_t err;
@@ -1825,8 +1773,6 @@
case SLOT_MADVISING:
// FALLTHRU
case SLOT_MADVISED:
- // FALLTHRU
- case SLOT_GUARD:
// These blocks have no active content.
break;
case SLOT_FULL:
@@ -2204,7 +2150,8 @@
ptr = nanov2_slot_in_block_ptr(blockp, size_class, slot);
}
- nanov2_free_slot_t *slotp = os_atomic_inject_dependency(ptr,
+ nanov2_free_slot_t *slotp =
+ (nanov2_free_slot_t *)os_atomic_force_dependency_on(ptr,
(unsigned long)old_meta_view.bits);
if (from_free_list) {
// We grabbed the item from the free list. Check the free list canary
@@ -2213,7 +2160,7 @@
// write to it.
uintptr_t guard = os_atomic_load(&slotp->double_free_guard, relaxed);
if ((guard ^ nanozone->slot_freelist_cookie) != (uintptr_t)ptr) {
- malloc_zone_error(MALLOC_ABORT_ON_CORRUPTION, true,
+ malloc_zone_error(MALLOC_ABORT_ON_CORRUPTION, false,
"Heap corruption detected, free list is damaged at %p\n"
"*** Incorrect guard value: %lu\n", ptr, guard);
__builtin_unreachable();
@@ -2512,22 +2459,14 @@
}
// 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 _and_ the initial next arena is safe, 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, 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 ||
- initial_region_next_arena_is_limit) {
- if ((void *)nanozone->current_region_next_arena >=
- nanozone->current_region_limit) {
+ if (nanozone->current_region_next_arena == arena) {
+ if ((void *)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++;
@@ -2535,13 +2474,8 @@
failed = TRUE;
}
} else {
- // 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
- if (!failed) {
- nanov2_init_guard_blocks(nanozone, arena);
+ // Assign the new arena, in the same region.
+ nanozone->current_region_next_arena = arena + 1;
}
}
_malloc_lock_unlock(&nanozone->regions_lock);
@@ -2776,6 +2710,12 @@
// Prevent overwriting the function pointers in basic_zone.
mprotect(nanozone, sizeof(nanozone->basic_zone), PROT_READ);
+ // Nano V2 zone does not support MALLOC_ADD_GUARD_PAGES
+ if (debug_flags & MALLOC_ADD_GUARD_PAGES) {
+ malloc_report(ASL_LEVEL_INFO, "nano does not support guard pages\n");
+ debug_flags &= ~MALLOC_ADD_GUARD_PAGES;
+ }
+
// Set up the remainder of the nanozonev2 structure
nanozone->debug_flags = debug_flags;
nanozone->helper_zone = helper_zone;
@@ -2826,9 +2766,6 @@
nanozone->current_region_next_arena = ((nanov2_arena_t *)region) + 1;
nanozone->current_region_limit = region + 1;
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);
return (malloc_zone_t *)nanozone;
}