mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 14:58:30 +00:00
Make emacs not croak when editing dlmalloc
This commit is contained in:
parent
3c7ae0fc72
commit
fa1e8a3e65
21 changed files with 3019 additions and 2985 deletions
171
third_party/dlmalloc/trees.inc
vendored
Normal file
171
third_party/dlmalloc/trees.inc
vendored
Normal file
|
@ -0,0 +1,171 @@
|
|||
// clang-format off
|
||||
|
||||
/* ------------------------- Operations on trees ------------------------- */
|
||||
|
||||
/* Insert chunk into tree */
|
||||
#define insert_large_chunk(M, X, S) {\
|
||||
tbinptr* H;\
|
||||
bindex_t I;\
|
||||
compute_tree_index(S, I);\
|
||||
H = treebin_at(M, I);\
|
||||
X->index = I;\
|
||||
X->child[0] = X->child[1] = 0;\
|
||||
if (!treemap_is_marked(M, I)) {\
|
||||
mark_treemap(M, I);\
|
||||
*H = X;\
|
||||
X->parent = (tchunkptr)H;\
|
||||
X->fd = X->bk = X;\
|
||||
}\
|
||||
else {\
|
||||
tchunkptr T = *H;\
|
||||
size_t K = S << leftshift_for_tree_index(I);\
|
||||
for (;;) {\
|
||||
if (chunksize(T) != S) {\
|
||||
tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\
|
||||
K <<= 1;\
|
||||
if (*C != 0)\
|
||||
T = *C;\
|
||||
else if (RTCHECK(ok_address(M, C))) {\
|
||||
*C = X;\
|
||||
X->parent = T;\
|
||||
X->fd = X->bk = X;\
|
||||
break;\
|
||||
}\
|
||||
else {\
|
||||
CORRUPTION_ERROR_ACTION(M);\
|
||||
break;\
|
||||
}\
|
||||
}\
|
||||
else {\
|
||||
tchunkptr F = T->fd;\
|
||||
if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\
|
||||
T->fd = F->bk = X;\
|
||||
X->fd = F;\
|
||||
X->bk = T;\
|
||||
X->parent = 0;\
|
||||
break;\
|
||||
}\
|
||||
else {\
|
||||
CORRUPTION_ERROR_ACTION(M);\
|
||||
break;\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
}
|
||||
|
||||
/*
|
||||
Unlink steps:
|
||||
|
||||
1. If x is a chained node, unlink it from its same-sized fd/bk links
|
||||
and choose its bk node as its replacement.
|
||||
2. If x was the last node of its size, but not a leaf node, it must
|
||||
be replaced with a leaf node (not merely one with an open left or
|
||||
right), to make sure that lefts and rights of descendents
|
||||
correspond properly to bit masks. We use the rightmost descendent
|
||||
of x. We could use any other leaf, but this is easy to locate and
|
||||
tends to counteract removal of leftmosts elsewhere, and so keeps
|
||||
paths shorter than minimally guaranteed. This doesn't loop much
|
||||
because on average a node in a tree is near the bottom.
|
||||
3. If x is the base of a chain (i.e., has parent links) relink
|
||||
x's parent and children to x's replacement (or null if none).
|
||||
*/
|
||||
|
||||
#define unlink_large_chunk(M, X) {\
|
||||
tchunkptr XP = X->parent;\
|
||||
tchunkptr R;\
|
||||
if (X->bk != X) {\
|
||||
tchunkptr F = X->fd;\
|
||||
R = X->bk;\
|
||||
if (RTCHECK(ok_address(M, F) && F->bk == X && R->fd == X)) {\
|
||||
F->bk = R;\
|
||||
R->fd = F;\
|
||||
}\
|
||||
else {\
|
||||
CORRUPTION_ERROR_ACTION(M);\
|
||||
}\
|
||||
}\
|
||||
else {\
|
||||
tchunkptr* RP;\
|
||||
if (((R = *(RP = &(X->child[1]))) != 0) ||\
|
||||
((R = *(RP = &(X->child[0]))) != 0)) {\
|
||||
tchunkptr* CP;\
|
||||
while ((*(CP = &(R->child[1])) != 0) ||\
|
||||
(*(CP = &(R->child[0])) != 0)) {\
|
||||
R = *(RP = CP);\
|
||||
}\
|
||||
if (RTCHECK(ok_address(M, RP)))\
|
||||
*RP = 0;\
|
||||
else {\
|
||||
CORRUPTION_ERROR_ACTION(M);\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
if (XP != 0) {\
|
||||
tbinptr* H = treebin_at(M, X->index);\
|
||||
if (X == *H) {\
|
||||
if ((*H = R) == 0) \
|
||||
clear_treemap(M, X->index);\
|
||||
}\
|
||||
else if (RTCHECK(ok_address(M, XP))) {\
|
||||
if (XP->child[0] == X) \
|
||||
XP->child[0] = R;\
|
||||
else \
|
||||
XP->child[1] = R;\
|
||||
}\
|
||||
else\
|
||||
CORRUPTION_ERROR_ACTION(M);\
|
||||
if (R != 0) {\
|
||||
if (RTCHECK(ok_address(M, R))) {\
|
||||
tchunkptr C0, C1;\
|
||||
R->parent = XP;\
|
||||
if ((C0 = X->child[0]) != 0) {\
|
||||
if (RTCHECK(ok_address(M, C0))) {\
|
||||
R->child[0] = C0;\
|
||||
C0->parent = R;\
|
||||
}\
|
||||
else\
|
||||
CORRUPTION_ERROR_ACTION(M);\
|
||||
}\
|
||||
if ((C1 = X->child[1]) != 0) {\
|
||||
if (RTCHECK(ok_address(M, C1))) {\
|
||||
R->child[1] = C1;\
|
||||
C1->parent = R;\
|
||||
}\
|
||||
else\
|
||||
CORRUPTION_ERROR_ACTION(M);\
|
||||
}\
|
||||
}\
|
||||
else\
|
||||
CORRUPTION_ERROR_ACTION(M);\
|
||||
}\
|
||||
}\
|
||||
}
|
||||
|
||||
/* Relays to large vs small bin operations */
|
||||
|
||||
#define insert_chunk(M, P, S)\
|
||||
if (is_small(S)) insert_small_chunk(M, P, S)\
|
||||
else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); }
|
||||
|
||||
#define unlink_chunk(M, P, S)\
|
||||
if (is_small(S)) unlink_small_chunk(M, P, S)\
|
||||
else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); }
|
||||
|
||||
|
||||
/* Relays to internal calls to malloc/free from realloc, memalign etc */
|
||||
|
||||
#if ONLY_MSPACES
|
||||
#define internal_malloc(m, b) mspace_malloc(m, b)
|
||||
#define internal_free(m, mem) mspace_free(m,mem);
|
||||
#else /* ONLY_MSPACES */
|
||||
#if MSPACES
|
||||
#define internal_malloc(m, b)\
|
||||
((m == gm)? dlmalloc(b) : mspace_malloc(m, b))
|
||||
#define internal_free(m, mem)\
|
||||
if (m == gm) dlfree(mem); else mspace_free(m,mem);
|
||||
#else /* MSPACES */
|
||||
#define internal_malloc(m, b) dlmalloc(b)
|
||||
#define internal_free(m, mem) dlfree(mem)
|
||||
#endif /* MSPACES */
|
||||
#endif /* ONLY_MSPACES */
|
Loading…
Add table
Add a link
Reference in a new issue