Loading...
--- libmalloc/libmalloc-409.40.6/src/nanov2_malloc.c
+++ libmalloc/libmalloc-409.60.6/src/nanov2_malloc.c
@@ -1127,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_on_free) {
+ if (malloc_zero_policy == MALLOC_ZERO_ON_FREE) {
if (size_class != 0) {
nanov2_bzero((char *)ptr + sizeof(nanov2_free_slot_t),
size - sizeof(nanov2_free_slot_t));
@@ -1157,7 +1157,7 @@
size_t size = nanov2_pointer_size_inline(nanozone, ptr, FALSE,
&size_class, &block_metap);
if (size) {
- if (malloc_zero_on_free) {
+ if (malloc_zero_policy == 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));
@@ -1189,6 +1189,51 @@
_nanov2_free(nanozone, ptr, true);
}
+MALLOC_ALWAYS_INLINE MALLOC_INLINE
+void *
+nanov2_malloc_zero(nanozonev2_t *nanozone, size_t rounded_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) {
+ if (malloc_zero_policy == 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);
+}
+
MALLOC_NOEXPORT void *
nanov2_calloc(nanozonev2_t *nanozone, size_t num_items, size_t size)
{
@@ -1198,49 +1243,23 @@
}
size_t rounded_size = _nano_common_good_size(total_bytes);
if (total_bytes <= 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) {
- 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);
+ return nanov2_malloc_zero(nanozone, rounded_size);
}
// 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_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_malloc_zero(nanozone, rounded_size);
+ }
+
+ // Too big for nano, so delegate to the helper zone.
+ return nanozone->helper_zone->malloc(nanozone->helper_zone, size);
}
#endif // OS_VARIANT_RESOLVED
@@ -2912,7 +2931,8 @@
done:
if (os_likely(ptr)) {
- if (malloc_zero_on_free) {
+ switch (malloc_zero_policy) {
+ case 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;
@@ -2923,15 +2943,20 @@
// 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 {
- if (clear) {
- memset(ptr, '\0', rounded_size);
- } else {
+ break;
+ }
+ case MALLOC_ZERO_NONE:
+ if (!clear) {
// 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;
}
+ // fall through
+ case MALLOC_ZERO_ON_ALLOC:
+ memset(ptr, '\0', rounded_size);
+ break;
}
} else {
malloc_set_errno_fast(MZ_POSIX, ENOMEM);
@@ -3052,7 +3077,12 @@
// Set up the basic_zone portion of the nanozonev2 structure
nanozone->basic_zone.version = 13;
nanozone->basic_zone.size = OS_RESOLVED_VARIANT_ADDR(nanov2_size);
- nanozone->basic_zone.malloc = OS_RESOLVED_VARIANT_ADDR(nanov2_malloc);
+ if (malloc_zero_policy == MALLOC_ZERO_ON_ALLOC) {
+ nanozone->basic_zone.malloc =
+ OS_RESOLVED_VARIANT_ADDR(nanov2_malloc_zero_on_alloc);
+ } else {
+ 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);