| 932 | } extent_split_interior_result_t; |
| 933 | |
| 934 | static extent_split_interior_result_t |
| 935 | extent_split_interior(tsdn_t *tsdn, arena_t *arena, |
| 936 | extent_hooks_t **r_extent_hooks, rtree_ctx_t *rtree_ctx, |
| 937 | /* The result of splitting, in case of success. */ |
| 938 | extent_t **extent, extent_t **lead, extent_t **trail, |
| 939 | /* The mess to clean up, in case of error. */ |
| 940 | extent_t **to_leak, extent_t **to_salvage, |
| 941 | void *new_addr, size_t size, size_t pad, size_t alignment, bool slab, |
| 942 | szind_t szind, bool growing_retained) { |
| 943 | size_t esize = size + pad; |
| 944 | size_t leadsize = ALIGNMENT_CEILING((uintptr_t)extent_base_get(*extent), |
| 945 | PAGE_CEILING(alignment)) - (uintptr_t)extent_base_get(*extent); |
| 946 | assert(new_addr == NULL || leadsize == 0); |
| 947 | if (extent_size_get(*extent) < leadsize + esize) { |
| 948 | return extent_split_interior_cant_alloc; |
| 949 | } |
| 950 | size_t trailsize = extent_size_get(*extent) - leadsize - esize; |
| 951 | |
| 952 | *lead = NULL; |
| 953 | *trail = NULL; |
| 954 | *to_leak = NULL; |
| 955 | *to_salvage = NULL; |
| 956 | |
| 957 | /* Split the lead. */ |
| 958 | if (leadsize != 0) { |
| 959 | *lead = *extent; |
| 960 | *extent = extent_split_impl(tsdn, arena, r_extent_hooks, |
| 961 | *lead, leadsize, NSIZES, false, esize + trailsize, szind, |
| 962 | slab, growing_retained); |
| 963 | if (*extent == NULL) { |
| 964 | *to_leak = *lead; |
| 965 | *lead = NULL; |
| 966 | return extent_split_interior_error; |
| 967 | } |
| 968 | } |
| 969 | |
| 970 | /* Split the trail. */ |
| 971 | if (trailsize != 0) { |
| 972 | *trail = extent_split_impl(tsdn, arena, r_extent_hooks, *extent, |
| 973 | esize, szind, slab, trailsize, NSIZES, false, |
| 974 | growing_retained); |
| 975 | if (*trail == NULL) { |
| 976 | *to_leak = *extent; |
| 977 | *to_salvage = *lead; |
| 978 | *lead = NULL; |
| 979 | *extent = NULL; |
| 980 | return extent_split_interior_error; |
| 981 | } |
| 982 | } |
| 983 | |
| 984 | if (leadsize == 0 && trailsize == 0) { |
| 985 | /* |
| 986 | * Splitting causes szind to be set as a side effect, but no |
| 987 | * splitting occurred. |
| 988 | */ |
| 989 | extent_szind_set(*extent, szind); |
| 990 | if (szind != NSIZES) { |
| 991 | rtree_szind_slab_update(tsdn, &extents_rtree, rtree_ctx, |
no test coverage detected