allocate a large request from the best fitting chunk in a treebin
| 2865 | |
| 2866 | // allocate a large request from the best fitting chunk in a treebin |
| 2867 | void* malloc_state::tmalloc_large(size_t nb) |
| 2868 | { |
| 2869 | tchunkptr v = 0; |
| 2870 | size_t rsize = -nb; // Unsigned negation |
| 2871 | tchunkptr t; |
| 2872 | bindex_t idx = compute_tree_index(nb); |
| 2873 | if ((t = *treebin_at(idx)) != 0) |
| 2874 | { |
| 2875 | // Traverse tree for this bin looking for node with size == nb |
| 2876 | size_t sizebits = nb << leftshift_for_tree_index(idx); |
| 2877 | tchunkptr rst = 0; // The deepest untaken right subtree |
| 2878 | for (;;) |
| 2879 | { |
| 2880 | tchunkptr rt; |
| 2881 | size_t trem = t->chunksize() - nb; |
| 2882 | if (trem < rsize) |
| 2883 | { |
| 2884 | v = t; |
| 2885 | if ((rsize = trem) == 0) |
| 2886 | break; |
| 2887 | } |
| 2888 | rt = t->_child[1]; |
| 2889 | t = t->_child[(sizebits >> (spp_size_t_bitsize - 1)) & 1]; |
| 2890 | if (rt != 0 && rt != t) |
| 2891 | rst = rt; |
| 2892 | if (t == 0) |
| 2893 | { |
| 2894 | t = rst; // set t to least subtree holding sizes > nb |
| 2895 | break; |
| 2896 | } |
| 2897 | sizebits <<= 1; |
| 2898 | } |
| 2899 | } |
| 2900 | if (t == 0 && v == 0) |
| 2901 | { |
| 2902 | // set t to root of next non-empty treebin |
| 2903 | binmap_t leftbits = left_bits(idx2bit(idx)) & _treemap; |
| 2904 | if (leftbits != 0) |
| 2905 | { |
| 2906 | binmap_t leastbit = least_bit(leftbits); |
| 2907 | bindex_t i = compute_bit2idx(leastbit); |
| 2908 | t = *treebin_at(i); |
| 2909 | } |
| 2910 | } |
| 2911 | |
| 2912 | while (t != 0) |
| 2913 | { |
| 2914 | // find smallest of tree or subtree |
| 2915 | size_t trem = t->chunksize() - nb; |
| 2916 | if (trem < rsize) |
| 2917 | { |
| 2918 | rsize = trem; |
| 2919 | v = t; |
| 2920 | } |
| 2921 | t = t->leftmost_child(); |
| 2922 | } |
| 2923 | |
| 2924 | // If dv is a better fit, return 0 so malloc will use it |
nothing calls this directly
no test coverage detected