| /* |
| * Copyright (c) 2018-2021 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef PAS_HEAP_CONFIG_UTILS_H |
| #define PAS_HEAP_CONFIG_UTILS_H |
| |
| #include "pas_basic_heap_config_root_data.h" |
| #include "pas_basic_heap_page_caches.h" |
| #include "pas_basic_heap_runtime_config.h" |
| #include "pas_bitfit_page_config_utils.h" |
| #include "pas_heap_config.h" |
| #include "pas_segregated_page_config_utils.h" |
| #include "pas_page_header_placement_mode.h" |
| |
| PAS_BEGIN_EXTERN_C; |
| |
| struct pas_large_heap_physical_page_sharing_cache; |
| typedef struct pas_large_heap_physical_page_sharing_cache pas_large_heap_physical_page_sharing_cache; |
| |
| /* NOTE: always pass pas_heap_config by value to inline functions, using constants if possible. |
| Pass pas_heap_config by pointer to out-of-line functions, using the provided globals if |
| possible. See thingy_heap_config.h and iso_heap_config.h for some valid |
| configurations. */ |
| |
| PAS_API void pas_heap_config_utils_null_activate(void); |
| |
| PAS_API bool pas_heap_config_utils_for_each_shared_page_directory( |
| pas_segregated_heap* heap, |
| bool (*callback)(pas_segregated_shared_page_directory* directory, |
| void* arg), |
| void* arg); |
| |
| PAS_API bool pas_heap_config_utils_for_each_shared_page_directory_remote( |
| pas_enumerator* enumerator, |
| pas_segregated_heap* heap, |
| bool (*callback)(pas_enumerator* enumerator, |
| pas_segregated_shared_page_directory* directory, |
| void* arg), |
| void* arg); |
| |
| typedef struct { |
| pas_heap_config_activate_callback activate; |
| pas_heap_config_get_type_size get_type_size; |
| pas_heap_config_get_type_alignment get_type_alignment; |
| bool check_deallocation; |
| uint8_t small_segregated_min_align_shift; |
| uint8_t small_segregated_sharing_shift; |
| size_t small_segregated_page_size; |
| double small_segregated_wasteage_handicap; |
| bool small_segregated_enable_empty_word_eligibility_optimization; |
| bool small_segregated_use_reversed_current_word; |
| bool enable_view_cache; |
| bool use_small_bitfit; |
| uint8_t small_bitfit_min_align_shift; |
| size_t small_bitfit_page_size; |
| size_t medium_page_size; /* segregated and bitfit must share the same page size. */ |
| size_t granule_size; |
| bool use_medium_segregated; |
| uint8_t medium_segregated_min_align_shift; |
| uint8_t medium_segregated_sharing_shift; |
| double medium_segregated_wasteage_handicap; |
| bool use_medium_bitfit; |
| uint8_t medium_bitfit_min_align_shift; |
| bool use_marge_bitfit; |
| uint8_t marge_bitfit_min_align_shift; |
| size_t marge_bitfit_page_size; |
| } pas_basic_heap_config_arguments; |
| |
| #define PAS_BASIC_HEAP_CONFIG_SEGREGATED_HEAP_FIELDS(name, ...) \ |
| .small_segregated_config = { \ |
| .base = { \ |
| .is_enabled = true, \ |
| .heap_config_ptr = &name ## _heap_config, \ |
| .page_config_ptr = &name ## _heap_config.small_segregated_config.base, \ |
| .page_kind = pas_small_segregated_page_kind, \ |
| .min_align_shift = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_min_align_shift, \ |
| .page_size = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_page_size, \ |
| .granule_size = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_page_size, \ |
| .page_header_size = PAS_BASIC_SEGREGATED_PAGE_HEADER_SIZE( \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_min_align_shift, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_page_size, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_page_size), \ |
| .max_object_size = PAS_MAX_OBJECT_SIZE(PAS_BASIC_SEGREGATED_PAYLOAD_SIZE( \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_min_align_shift, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_page_size, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_page_size)), \ |
| .page_header_for_boundary = name ## _small_segregated_page_header_for_boundary, \ |
| .boundary_for_page_header = name ## _small_segregated_boundary_for_page_header, \ |
| .page_header_for_boundary_remote = name ## _small_segregated_page_header_for_boundary_remote, \ |
| .page_object_payload_offset = PAS_BASIC_SEGREGATED_PAYLOAD_OFFSET( \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_min_align_shift, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_page_size, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_page_size), \ |
| .page_object_payload_size = PAS_BASIC_SEGREGATED_PAYLOAD_SIZE( \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_min_align_shift, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_page_size, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_page_size), \ |
| .page_allocator = name ## _heap_config_allocate_small_segregated_page, \ |
| .create_page_header = name ## _small_segregated_create_page_header, \ |
| .destroy_page_header = name ## _small_segregated_destroy_page_header \ |
| }, \ |
| .variant = pas_small_segregated_page_config_variant, \ |
| .kind = pas_segregated_page_config_kind_ ## name ## _small_segregated, \ |
| .sharing_shift = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_sharing_shift, \ |
| .num_alloc_bits = PAS_BASIC_SEGREGATED_NUM_ALLOC_BITS( \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_min_align_shift, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_page_size), \ |
| .wasteage_handicap = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_wasteage_handicap, \ |
| .dealloc_func = name ## _small_segregated_dealloc_func, \ |
| .use_reversed_current_word = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_use_reversed_current_word, \ |
| .check_deallocation = ((pas_basic_heap_config_arguments){__VA_ARGS__}).check_deallocation, \ |
| .enable_empty_word_eligibility_optimization = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_enable_empty_word_eligibility_optimization, \ |
| .enable_view_cache = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).enable_view_cache, \ |
| .shared_page_directory_selector = \ |
| name ## _small_segregated_page_config_select_shared_page_directory, \ |
| PAS_SEGREGATED_PAGE_CONFIG_SPECIALIZATIONS(name ## _small_segregated_page_config) \ |
| }, \ |
| .medium_segregated_config = { \ |
| .base = { \ |
| .is_enabled = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).use_medium_segregated, \ |
| .heap_config_ptr = &name ## _heap_config, \ |
| .page_config_ptr = &name ## _heap_config.medium_segregated_config.base, \ |
| .page_kind = pas_medium_segregated_page_kind, \ |
| .min_align_shift = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).medium_segregated_min_align_shift, \ |
| .page_size = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).medium_page_size, \ |
| .granule_size = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).granule_size, \ |
| .page_header_size = PAS_BASIC_SEGREGATED_PAGE_HEADER_SIZE( \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).medium_segregated_min_align_shift, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).medium_page_size, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).granule_size), \ |
| .max_object_size = PAS_MAX_OBJECT_SIZE( \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).medium_page_size), \ |
| .page_header_for_boundary = name ## _medium_segregated_page_header_for_boundary, \ |
| .boundary_for_page_header = name ## _medium_segregated_boundary_for_page_header, \ |
| .page_header_for_boundary_remote = \ |
| name ## _medium_segregated_page_header_for_boundary_remote, \ |
| .page_object_payload_offset = 0, \ |
| .page_object_payload_size = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).medium_page_size, \ |
| .page_allocator = name ## _heap_config_allocate_medium_segregated_page, \ |
| .create_page_header = name ## _medium_segregated_create_page_header, \ |
| .destroy_page_header = name ## _medium_segregated_destroy_page_header \ |
| }, \ |
| .variant = pas_medium_segregated_page_config_variant, \ |
| .kind = pas_segregated_page_config_kind_ ## name ## _medium_segregated, \ |
| .sharing_shift = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).medium_segregated_sharing_shift, \ |
| .num_alloc_bits = PAS_BASIC_SEGREGATED_NUM_ALLOC_BITS( \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).medium_segregated_min_align_shift, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).medium_page_size), \ |
| .wasteage_handicap = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).medium_segregated_wasteage_handicap, \ |
| .dealloc_func = name ## _medium_segregated_dealloc_func, \ |
| .use_reversed_current_word = false, \ |
| .check_deallocation = ((pas_basic_heap_config_arguments){__VA_ARGS__}).check_deallocation, \ |
| .enable_empty_word_eligibility_optimization = false, \ |
| .enable_view_cache = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).enable_view_cache, \ |
| .shared_page_directory_selector = \ |
| name ## _medium_segregated_page_config_select_shared_page_directory, \ |
| PAS_SEGREGATED_PAGE_CONFIG_SPECIALIZATIONS(name ## _medium_segregated_page_config) \ |
| }, \ |
| .small_bitfit_config = { \ |
| .base = { \ |
| .is_enabled = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).use_small_bitfit, \ |
| .heap_config_ptr = &name ## _heap_config, \ |
| .page_config_ptr = &name ## _heap_config.small_bitfit_config.base, \ |
| .page_kind = pas_small_bitfit_page_kind, \ |
| .min_align_shift = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_bitfit_min_align_shift, \ |
| .page_size = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_bitfit_page_size, \ |
| .granule_size = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_bitfit_page_size, \ |
| .page_header_size = PAS_BITFIT_PAGE_HEADER_SIZE( \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_bitfit_page_size, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_bitfit_page_size, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_bitfit_min_align_shift), \ |
| .page_header_for_boundary = name ## _small_bitfit_page_header_for_boundary, \ |
| .boundary_for_page_header = name ## _small_bitfit_boundary_for_page_header, \ |
| .page_header_for_boundary_remote = name ## _small_bitfit_page_header_for_boundary_remote, \ |
| .page_object_payload_offset = PAS_BITFIT_PAGE_HEADER_SIZE( \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_bitfit_page_size, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_bitfit_page_size, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_bitfit_min_align_shift), \ |
| .page_object_payload_size = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_bitfit_page_size - \ |
| PAS_BITFIT_PAGE_HEADER_SIZE( \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_bitfit_page_size, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_bitfit_page_size, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_bitfit_min_align_shift), \ |
| .max_object_size = PAS_MAX_BITFIT_OBJECT_SIZE( \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_bitfit_page_size - \ |
| PAS_BITFIT_PAGE_HEADER_SIZE( \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_bitfit_page_size, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_bitfit_page_size, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_bitfit_min_align_shift), \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_bitfit_min_align_shift), \ |
| .page_allocator = name ## _heap_config_allocate_small_bitfit_page, \ |
| .create_page_header = name ## _small_bitfit_create_page_header, \ |
| .destroy_page_header = name ## _small_bitfit_destroy_page_header \ |
| }, \ |
| .variant = pas_small_bitfit_page_config_variant, \ |
| .kind = pas_bitfit_page_config_kind_ ## name ## _small_bitfit, \ |
| PAS_BITFIT_PAGE_CONFIG_SPECIALIZATIONS(name ## _small_bitfit_page_config) \ |
| }, \ |
| .medium_bitfit_config = { \ |
| .base = { \ |
| .is_enabled = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).use_medium_bitfit, \ |
| .heap_config_ptr = &name ## _heap_config, \ |
| .page_config_ptr = &name ## _heap_config.medium_bitfit_config.base, \ |
| .page_kind = pas_medium_bitfit_page_kind, \ |
| .min_align_shift = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).medium_bitfit_min_align_shift, \ |
| .page_size = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).medium_page_size, \ |
| .granule_size = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).granule_size, \ |
| .page_header_size = PAS_BITFIT_PAGE_HEADER_SIZE( \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).medium_page_size, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).granule_size, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).medium_bitfit_min_align_shift), \ |
| .page_header_for_boundary = name ## _medium_bitfit_page_header_for_boundary, \ |
| .boundary_for_page_header = name ## _medium_bitfit_boundary_for_page_header, \ |
| .page_header_for_boundary_remote = name ## _medium_bitfit_page_header_for_boundary_remote, \ |
| .page_object_payload_offset = 0, \ |
| .page_object_payload_size = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).medium_page_size, \ |
| .max_object_size = PAS_MAX_BITFIT_OBJECT_SIZE( \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).medium_page_size, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).medium_bitfit_min_align_shift), \ |
| .page_allocator = name ## _heap_config_allocate_medium_bitfit_page, \ |
| .create_page_header = name ## _medium_bitfit_create_page_header, \ |
| .destroy_page_header = name ## _medium_bitfit_destroy_page_header \ |
| }, \ |
| .variant = pas_medium_bitfit_page_config_variant, \ |
| .kind = pas_bitfit_page_config_kind_ ## name ## _medium_bitfit, \ |
| PAS_BITFIT_PAGE_CONFIG_SPECIALIZATIONS(name ## _medium_bitfit_page_config) \ |
| }, \ |
| .marge_bitfit_config = { \ |
| .base = { \ |
| .is_enabled = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).use_marge_bitfit, \ |
| .heap_config_ptr = &name ## _heap_config, \ |
| .page_config_ptr = &name ## _heap_config.marge_bitfit_config.base, \ |
| .page_kind = pas_marge_bitfit_page_kind, \ |
| .min_align_shift = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).marge_bitfit_min_align_shift, \ |
| .page_size = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).marge_bitfit_page_size, \ |
| .granule_size = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).granule_size, \ |
| .page_header_size = PAS_BITFIT_PAGE_HEADER_SIZE( \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).marge_bitfit_page_size, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).granule_size, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).marge_bitfit_min_align_shift), \ |
| .page_header_for_boundary = name ## _marge_bitfit_page_header_for_boundary, \ |
| .boundary_for_page_header = name ## _marge_bitfit_boundary_for_page_header, \ |
| .page_header_for_boundary_remote = name ## _marge_bitfit_page_header_for_boundary_remote, \ |
| .page_object_payload_offset = 0, \ |
| .page_object_payload_size = \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).marge_bitfit_page_size, \ |
| .max_object_size = PAS_MAX_BITFIT_OBJECT_SIZE( \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).marge_bitfit_page_size, \ |
| ((pas_basic_heap_config_arguments){__VA_ARGS__}).marge_bitfit_min_align_shift), \ |
| .page_allocator = name ## _heap_config_allocate_marge_bitfit_page, \ |
| .create_page_header = name ## _marge_bitfit_create_page_header, \ |
| .destroy_page_header = name ## _marge_bitfit_destroy_page_header \ |
| }, \ |
| .variant = pas_marge_bitfit_page_config_variant, \ |
| .kind = pas_bitfit_page_config_kind_ ## name ## _marge_bitfit, \ |
| PAS_BITFIT_PAGE_CONFIG_SPECIALIZATIONS(name ## _marge_bitfit_page_config) \ |
| }, \ |
| .small_lookup_size_upper_bound = PAS_SMALL_LOOKUP_SIZE_UPPER_BOUND, \ |
| .fast_megapage_kind_func = name ## _heap_config_fast_megapage_kind, \ |
| .small_segregated_is_in_megapage = true, \ |
| .small_bitfit_is_in_megapage = true, \ |
| .page_header_func = name ## _heap_config_page_header, \ |
| |
| #define PAS_BASIC_HEAP_CONFIG(name, ...) ((pas_heap_config){ \ |
| .config_ptr = &name ## _heap_config, \ |
| .kind = pas_heap_config_kind_ ## name, \ |
| .activate_callback = ((pas_basic_heap_config_arguments){__VA_ARGS__}).activate, \ |
| .get_type_size = ((pas_basic_heap_config_arguments){__VA_ARGS__}).get_type_size, \ |
| .get_type_alignment = ((pas_basic_heap_config_arguments){__VA_ARGS__}).get_type_alignment, \ |
| .large_alignment = \ |
| (size_t)1 << ((pas_basic_heap_config_arguments){__VA_ARGS__}).small_segregated_min_align_shift, \ |
| PAS_BASIC_HEAP_CONFIG_SEGREGATED_HEAP_FIELDS(name, __VA_ARGS__) \ |
| .aligned_allocator = name ## _aligned_allocator, \ |
| .aligned_allocator_talks_to_sharing_pool = true, \ |
| .deallocator = NULL, \ |
| .root_data = &name ## _root_data, \ |
| .prepare_to_enumerate = name ## _prepare_to_enumerate, \ |
| .for_each_shared_page_directory = \ |
| pas_heap_config_utils_for_each_shared_page_directory, \ |
| .for_each_shared_page_directory_remote = \ |
| pas_heap_config_utils_for_each_shared_page_directory_remote, \ |
| PAS_HEAP_CONFIG_SPECIALIZATIONS(name ## _heap_config) \ |
| }) |
| |
| typedef struct { |
| bool small_size_aware_logging; |
| bool medium_size_aware_logging; |
| bool verify_before_logging; |
| } pas_basic_heap_config_declarations_arguments; |
| |
| #define PAS_BASIC_HEAP_CONFIG_SEGREGATED_HEAP_DECLARATIONS(name, upcase_name, ...) \ |
| PAS_BASIC_SEGREGATED_PAGE_CONFIG_FORWARD_DECLARATIONS(name ## _small_segregated); \ |
| PAS_BASIC_SEGREGATED_PAGE_CONFIG_FORWARD_DECLARATIONS(name ## _medium_segregated); \ |
| PAS_BASIC_BITFIT_PAGE_CONFIG_FORWARD_DECLARATIONS(name ## _small_bitfit); \ |
| PAS_BASIC_BITFIT_PAGE_CONFIG_FORWARD_DECLARATIONS(name ## _medium_bitfit); \ |
| PAS_BASIC_BITFIT_PAGE_CONFIG_FORWARD_DECLARATIONS(name ## _marge_bitfit); \ |
| PAS_API extern pas_fast_megapage_table name ## _megapage_table; \ |
| PAS_API extern pas_page_header_table name ## _medium_page_header_table; \ |
| PAS_API extern pas_page_header_table name ## _marge_page_header_table; \ |
| PAS_API extern pas_basic_heap_page_caches name ## _page_caches; \ |
| PAS_API extern pas_basic_heap_runtime_config name ## _intrinsic_runtime_config; \ |
| PAS_API extern pas_basic_heap_runtime_config name ## _primitive_runtime_config; \ |
| PAS_API extern pas_basic_heap_runtime_config name ## _typed_runtime_config; \ |
| PAS_API extern pas_basic_heap_runtime_config name ## _flex_runtime_config; \ |
| \ |
| PAS_API extern pas_basic_heap_config_root_data name ## _root_data; \ |
| \ |
| PAS_API void* name ## _heap_config_allocate_small_segregated_page( \ |
| pas_segregated_heap* heap, pas_physical_memory_transaction* transaction); \ |
| PAS_API void* name ## _heap_config_allocate_small_bitfit_page( \ |
| pas_segregated_heap* heap, pas_physical_memory_transaction* transaction); \ |
| PAS_API void* name ## _heap_config_allocate_medium_segregated_page( \ |
| pas_segregated_heap* heap, pas_physical_memory_transaction* transaction); \ |
| PAS_API void* name ## _heap_config_allocate_medium_bitfit_page( \ |
| pas_segregated_heap* heap, pas_physical_memory_transaction* transaction); \ |
| PAS_API void* name ## _heap_config_allocate_marge_bitfit_page( \ |
| pas_segregated_heap* heap, pas_physical_memory_transaction* transaction); \ |
| \ |
| PAS_API void* name ## _prepare_to_enumerate(pas_enumerator* enumerator); \ |
| \ |
| static PAS_ALWAYS_INLINE pas_fast_megapage_kind \ |
| name ## _heap_config_fast_megapage_kind(uintptr_t begin) \ |
| { \ |
| return pas_fast_megapage_table_get(&name ## _megapage_table, begin); \ |
| } \ |
| static PAS_ALWAYS_INLINE pas_page_base* \ |
| name ## _heap_config_page_header(uintptr_t begin) \ |
| { \ |
| pas_heap_config config; \ |
| \ |
| config = (upcase_name ## _HEAP_CONFIG); \ |
| \ |
| if (config.medium_segregated_config.base.is_enabled \ |
| || config.medium_bitfit_config.base.is_enabled) { \ |
| pas_page_base* result; \ |
| \ |
| PAS_ASSERT( \ |
| !config.medium_segregated_config.base.is_enabled || \ |
| !config.medium_bitfit_config.base.is_enabled || \ |
| config.medium_segregated_config.base.page_size \ |
| == config.medium_bitfit_config.base.page_size); \ |
| \ |
| result = pas_page_header_table_get_for_address( \ |
| &name ## _medium_page_header_table, \ |
| config.medium_segregated_config.base.is_enabled \ |
| ? config.medium_segregated_config.base.page_size \ |
| : config.medium_bitfit_config.base.page_size, \ |
| (void*)begin); \ |
| if (result) \ |
| return result; \ |
| } \ |
| \ |
| if (config.marge_bitfit_config.base.is_enabled) { \ |
| return pas_page_header_table_get_for_address( \ |
| &name ## _marge_page_header_table, \ |
| config.marge_bitfit_config.base.page_size, \ |
| (void*)begin); \ |
| } \ |
| \ |
| return NULL; \ |
| } \ |
| \ |
| PAS_BASIC_SEGREGATED_PAGE_CONFIG_DECLARATIONS( \ |
| name ## _small_segregated, (upcase_name ## _HEAP_CONFIG).small_segregated_config, \ |
| .header_placement_mode = pas_page_header_at_head_of_page, \ |
| .size_aware_logging = \ |
| ((pas_basic_heap_config_declarations_arguments){__VA_ARGS__}).small_size_aware_logging, \ |
| .verify_before_logging = \ |
| ((pas_basic_heap_config_declarations_arguments){__VA_ARGS__}).verify_before_logging, \ |
| .header_table = NULL); \ |
| PAS_BASIC_SEGREGATED_PAGE_CONFIG_DECLARATIONS( \ |
| name ## _medium_segregated, (upcase_name ## _HEAP_CONFIG).medium_segregated_config, \ |
| .header_placement_mode = pas_page_header_in_table, \ |
| .size_aware_logging = \ |
| ((pas_basic_heap_config_declarations_arguments){__VA_ARGS__}).medium_size_aware_logging, \ |
| .verify_before_logging = \ |
| ((pas_basic_heap_config_declarations_arguments){__VA_ARGS__}).verify_before_logging, \ |
| .header_table = &name ## _medium_page_header_table); \ |
| \ |
| PAS_BASIC_BITFIT_PAGE_CONFIG_DECLARATIONS( \ |
| name ## _small_bitfit, (upcase_name ## _HEAP_CONFIG).small_bitfit_config, \ |
| .header_placement_mode = pas_page_header_at_head_of_page, \ |
| .header_table = NULL); \ |
| PAS_BASIC_BITFIT_PAGE_CONFIG_DECLARATIONS( \ |
| name ## _medium_bitfit, (upcase_name ## _HEAP_CONFIG).medium_bitfit_config, \ |
| .header_placement_mode = pas_page_header_in_table, \ |
| .header_table = &name ## _medium_page_header_table); \ |
| PAS_BASIC_BITFIT_PAGE_CONFIG_DECLARATIONS( \ |
| name ## _marge_bitfit, (upcase_name ## _HEAP_CONFIG).marge_bitfit_config, \ |
| .header_placement_mode = pas_page_header_in_table, \ |
| .header_table = &name ## _marge_page_header_table); \ |
| \ |
| struct pas_dummy |
| |
| #define PAS_BASIC_HEAP_CONFIG_DECLARATIONS(name, upcase_name, ...) \ |
| PAS_API pas_aligned_allocation_result name ## _aligned_allocator( \ |
| size_t size, \ |
| pas_alignment alignment, \ |
| pas_large_heap* large_heap, \ |
| pas_heap_config* config); \ |
| PAS_HEAP_CONFIG_SPECIALIZATION_DECLARATIONS(name ## _heap_config); \ |
| PAS_BASIC_HEAP_CONFIG_SEGREGATED_HEAP_DECLARATIONS(name, upcase_name, __VA_ARGS__) |
| |
| PAS_END_EXTERN_C; |
| |
| #endif /* PAS_HEAP_CONFIG_UTILS_H */ |