| 977 | } extent_split_interior_result_t; |
| 978 | |
| 979 | static extent_split_interior_result_t |
| 980 | extent_split_interior(tsdn_t *tsdn, arena_t *arena, |
| 981 | extent_hooks_t **r_extent_hooks, rtree_ctx_t *rtree_ctx, |
| 982 | /* The result of splitting, in case of success. */ |
| 983 | extent_t **extent, extent_t **lead, extent_t **trail, |
| 984 | /* The mess to clean up, in case of error. */ |
| 985 | extent_t **to_leak, extent_t **to_salvage, |
| 986 | void *new_addr, size_t size, size_t pad, size_t alignment, bool slab, |
| 987 | szind_t szind, bool growing_retained) { |
| 988 | size_t esize = size + pad; |
| 989 | size_t leadsize = ALIGNMENT_CEILING((uintptr_t)extent_base_get(*extent), |
| 990 | PAGE_CEILING(alignment)) - (uintptr_t)extent_base_get(*extent); |
| 991 | assert(new_addr == NULL || leadsize == 0); |
| 992 | if (extent_size_get(*extent) < leadsize + esize) { |
| 993 | return extent_split_interior_cant_alloc; |
| 994 | } |
| 995 | size_t trailsize = extent_size_get(*extent) - leadsize - esize; |
| 996 | |
| 997 | *lead = NULL; |
| 998 | *trail = NULL; |
| 999 | *to_leak = NULL; |
| 1000 | *to_salvage = NULL; |
| 1001 | |
| 1002 | /* Split the lead. */ |
| 1003 | if (leadsize != 0) { |
| 1004 | *lead = *extent; |
| 1005 | *extent = extent_split_impl(tsdn, arena, r_extent_hooks, |
| 1006 | *lead, leadsize, SC_NSIZES, false, esize + trailsize, szind, |
| 1007 | slab, growing_retained); |
| 1008 | if (*extent == NULL) { |
| 1009 | *to_leak = *lead; |
| 1010 | *lead = NULL; |
| 1011 | return extent_split_interior_error; |
| 1012 | } |
| 1013 | } |
| 1014 | |
| 1015 | /* Split the trail. */ |
| 1016 | if (trailsize != 0) { |
| 1017 | *trail = extent_split_impl(tsdn, arena, r_extent_hooks, *extent, |
| 1018 | esize, szind, slab, trailsize, SC_NSIZES, false, |
| 1019 | growing_retained); |
| 1020 | if (*trail == NULL) { |
| 1021 | *to_leak = *extent; |
| 1022 | *to_salvage = *lead; |
| 1023 | *lead = NULL; |
| 1024 | *extent = NULL; |
| 1025 | return extent_split_interior_error; |
| 1026 | } |
| 1027 | } |
| 1028 | |
| 1029 | if (leadsize == 0 && trailsize == 0) { |
| 1030 | /* |
| 1031 | * Splitting causes szind to be set as a side effect, but no |
| 1032 | * splitting occurred. |
| 1033 | */ |
| 1034 | extent_szind_set(*extent, szind); |
| 1035 | if (szind != SC_NSIZES) { |
| 1036 | rtree_szind_slab_update(tsdn, &extents_rtree, rtree_ctx, |
no test coverage detected