fn new_chunk(
        old_size_with_footer: Option<usize>,
        requested_layout: Option<Layout>,
        prev: Option<NonNull<ChunkFooter>>,
    ) -> NonNull<ChunkFooter> {
        unsafe {
            // As a sane default, we want our new allocation to be about twice as
            // big as the previous allocation
            let mut new_size_without_footer =
                if let Some(old_size_with_footer) = old_size_with_footer {
                    let old_size_without_footer = old_size_with_footer - FOOTER_SIZE;
                    old_size_without_footer
                        .checked_mul(2)
                        .unwrap_or_else(|| oom())
                } else {
                    DEFAULT_CHUNK_SIZE_WITHOUT_FOOTER
                };

            // We want to have CHUNK_ALIGN or better alignment
            let mut align = CHUNK_ALIGN;

            // If we already know we need to fulfill some request,
            // make sure we allocate at least enough to satisfy it
            if let Some(requested_layout) = requested_layout {
                align = align.max(requested_layout.align());
                let requested_size = round_up_to(requested_layout.size(), align)
                    .unwrap_or_else(allocation_size_overflow);
                new_size_without_footer = new_size_without_footer.max(requested_size);
            }

            // We want our allocations to play nice with the memory allocator,
            // and waste as little memory as possible.
            // For small allocations, this means that the entire allocation
            // including the chunk footer and mallocs internal overhead is
            // as close to a power of two as we can go without going over.
            // For larger allocations, we only need to get close to a page
            // boundary without going over.
            if new_size_without_footer < PAGE_STRATEGY_CUTOFF {
                new_size_without_footer =
                    (new_size_without_footer + OVERHEAD).next_power_of_two() - OVERHEAD;
            } else {
                new_size_without_footer = round_up_to(new_size_without_footer + OVERHEAD, 0x1000)
                    .unwrap_or_else(|| oom())
                    - OVERHEAD;
            }

            debug_assert_eq!(align % CHUNK_ALIGN, 0);
            debug_assert_eq!(new_size_without_footer % CHUNK_ALIGN, 0);
            let size = new_size_without_footer
                .checked_add(FOOTER_SIZE)
                .unwrap_or_else(allocation_size_overflow);
            let layout = layout_from_size_align(size, align);

            debug_assert!(size >= old_size_with_footer.unwrap_or(0) * 2);

            let data = alloc(layout);
            let data = NonNull::new(data).unwrap_or_else(|| oom());

            // The `ChunkFooter` is at the end of the chunk.
            let footer_ptr = data.as_ptr() as usize + new_size_without_footer;
            debug_assert_eq!((data.as_ptr() as usize) % align, 0);
            debug_assert_eq!(footer_ptr % CHUNK_ALIGN, 0);
            let footer_ptr = footer_ptr as *mut ChunkFooter;

            // The bump pointer is initialized to the end of the range we will
            // bump out of.
            let ptr = Cell::new(NonNull::new_unchecked(footer_ptr as *mut u8));

            ptr::write(
                footer_ptr,
                ChunkFooter {
                    data,
                    layout,
                    prev: Cell::new(prev),
                    ptr,
                },
            );

            NonNull::new_unchecked(footer_ptr)
        }
    }
/// Allocate a new chunk and return its initialized footer.
///
/// If given, `layouts` is a tuple of the current chunk size and the
/// layout of the allocation request that triggered us to fall back to
/// allocating a new chunk of memory.
Allocate a new chunk and return its initialized footer.
If given, `layouts` is a tuple of the current chunk size and the
layout of the allocation request that triggered us to fall back to
allocating a new chunk of memory.
Allocate a new chunk and return its initialized footer . If given ` layouts ` is a tuple of the current chunk size and the layout of the allocation request that triggered us to fall back to allocating a new chunk of memory .
fn new_chunk(
        old_size_with_footer: Option<usize>,
        requested_layout: Option<Layout>,
        prev: Option<NonNull<ChunkFooter>>,
    ) -> NonNull<ChunkFooter> {
        unsafe {
            // As a sane default, we want our new allocation to be about twice as
            // big as the previous allocation
            let mut new_size_without_footer =
                if let Some(old_size_with_footer) = old_size_with_footer {
                    let old_size_without_footer = old_size_with_footer - FOOTER_SIZE;
                    old_size_without_footer
                        .checked_mul(2)
                        .unwrap_or_else(|| oom())
                } else {
                    DEFAULT_CHUNK_SIZE_WITHOUT_FOOTER
                };
            // We want to have CHUNK_ALIGN or better alignment
            let mut align = CHUNK_ALIGN;
            // If we already know we need to fulfill some request,
            // make sure we allocate at least enough to satisfy it
            if let Some(requested_layout) = requested_layout {
                align = align.max(requested_layout.align());
                let requested_size = round_up_to(requested_layout.size(), align)
                    .unwrap_or_else(allocation_size_overflow);
                new_size_without_footer = new_size_without_footer.max(requested_size);
            }
            // We want our allocations to play nice with the memory allocator,
            // and waste as little memory as possible.
            // For small allocations, this means that the entire allocation
            // including the chunk footer and mallocs internal overhead is
            // as close to a power of two as we can go without going over.
            // For larger allocations, we only need to get close to a page
            // boundary without going over.
            if new_size_without_footer < PAGE_STRATEGY_CUTOFF {
                new_size_without_footer =
                    (new_size_without_footer + OVERHEAD).next_power_of_two() - OVERHEAD;
            } else {
                new_size_without_footer = round_up_to(new_size_without_footer + OVERHEAD, 0x1000)
                    .unwrap_or_else(|| oom())
                    - OVERHEAD;
            }
            debug_assert_eq!(align % CHUNK_ALIGN, 0);
            debug_assert_eq!(new_size_without_footer % CHUNK_ALIGN, 0);
            let size = new_size_without_footer
                .checked_add(FOOTER_SIZE)
                .unwrap_or_else(allocation_size_overflow);
            let layout = layout_from_size_align(size, align);
            debug_assert!(size >= old_size_with_footer.unwrap_or(0) * 2);
            let data = alloc(layout);
            let data = NonNull::new(data).unwrap_or_else(|| oom());
            // The `ChunkFooter` is at the end of the chunk.
            let footer_ptr = data.as_ptr() as usize + new_size_without_footer;
            debug_assert_eq!((data.as_ptr() as usize) % align, 0);
            debug_assert_eq!(footer_ptr % CHUNK_ALIGN, 0);
            let footer_ptr = footer_ptr as *mut ChunkFooter;
            // The bump pointer is initialized to the end of the range we will
            // bump out of.
            let ptr = Cell::new(NonNull::new_unchecked(footer_ptr as *mut u8));
            ptr::write(
                footer_ptr,
                ChunkFooter {
                    data,
                    layout,
                    prev: Cell::new(prev),
                    ptr,
                },
            );
            NonNull::new_unchecked(footer_ptr)
        }
    }
fn new_chunk ( old_size_with_footer : Option < usize > , requested_layout : Option < Layout > , prev : Option < NonNull < ChunkFooter > > , ) -> NonNull < ChunkFooter > { unsafe { // As a sane default, we want our new allocation to be about twice as // big as the previous allocation let mut new_size_without_footer = if let Some ( old_size_with_footer ) = old_size_with_footer { let old_size_without_footer = old_size_with_footer - FOOTER_SIZE ; old_size_without_footer . checked_mul ( 2 ) . unwrap_or_else ( | | oom ( ) ) } else { DEFAULT_CHUNK_SIZE_WITHOUT_FOOTER } ; // We want to have CHUNK_ALIGN or better alignment let mut align = CHUNK_ALIGN ; // If we already know we need to fulfill some request, // make sure we allocate at least enough to satisfy it if let Some ( requested_layout ) = requested_layout { align = align . max ( requested_layout . align ( ) ) ; let requested_size = round_up_to ( requested_layout . size ( ) , align ) . unwrap_or_else ( allocation_size_overflow ) ; new_size_without_footer = new_size_without_footer . max ( requested_size ) ; } // We want our allocations to play nice with the memory allocator, // and waste as little memory as possible. // For small allocations, this means that the entire allocation // including the chunk footer and mallocs internal overhead is // as close to a power of two as we can go without going over. // For larger allocations, we only need to get close to a page // boundary without going over. if new_size_without_footer < PAGE_STRATEGY_CUTOFF { new_size_without_footer = ( new_size_without_footer + OVERHEAD ) . next_power_of_two ( ) - OVERHEAD ; } else { new_size_without_footer = round_up_to ( new_size_without_footer + OVERHEAD , 0x1000 ) . unwrap_or_else ( | | oom ( ) ) - OVERHEAD ; } debug_assert_eq ! ( align CHUNK_ALIGN 0 ) ; debug_assert_eq ! ( new_size_without_footer CHUNK_ALIGN 0 ) ; let size = new_size_without_footer . checked_add ( FOOTER_SIZE ) . unwrap_or_else ( allocation_size_overflow ) ; let layout = layout_from_size_align ( size , align ) ; debug_assert ! ( size old_size_with_footer unwrap_or ( 0 ) 2 ) ; let data = alloc ( layout ) ; let data = NonNull :: new ( data ) . unwrap_or_else ( | | oom ( ) ) ; // The `ChunkFooter` is at the end of the chunk. let footer_ptr = data . as_ptr ( ) as usize + new_size_without_footer ; debug_assert_eq ! ( ( data as_ptr ( ) as usize ) align 0 ) ; debug_assert_eq ! ( footer_ptr CHUNK_ALIGN 0 ) ; let footer_ptr = footer_ptr as * mut ChunkFooter ; // The bump pointer is initialized to the end of the range we will // bump out of. let ptr = Cell :: new ( NonNull :: new_unchecked ( footer_ptr as * mut u8 ) ) ; ptr :: write ( footer_ptr , ChunkFooter { data , layout , prev : Cell :: new ( prev ) , ptr , } , ) ; NonNull :: new_unchecked ( footer_ptr ) } }
Allocate a new chunk and return its initialized footer.
Allocate a new chunk and return its initialized footer .
old_size_with_footer
Option<usize>
requested_layout
Option<Layout>
prev
Option<NonNull<ChunkFooter>>
old_size_with_footer
Option<usize>
requested_layout
Option<Layout>
prev
Option<NonNull<ChunkFooter>>