mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-03-25 08:12:11 -07:00
Allowing splayfindfirst to continue to search even if the treetest is not precise, allowing the arena allocator to search for free areas using a zone preference.
Copied from Perforce Change: 184129 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
34f6123413
commit
13341c8a94
2 changed files with 58 additions and 15 deletions
|
|
@ -1746,7 +1746,6 @@ static void VMCompact(Arena arena, Trace trace)
|
|||
vmem1 = VMArenaReserved(arena);
|
||||
|
||||
/* Destroy any empty chunks (except the primary). */
|
||||
sparePagesPurge(vmArena);
|
||||
RING_FOR(node, &arena->chunkRing, next) {
|
||||
Chunk chunk = RING_ELT(Chunk, chunkRing, node);
|
||||
if(chunk != arena->primary
|
||||
|
|
@ -1754,6 +1753,7 @@ static void VMCompact(Arena arena, Trace trace)
|
|||
Addr base = chunk->base;
|
||||
Size size = AddrOffset(chunk->base, chunk->limit);
|
||||
|
||||
sparePagesPurge(vmArena);
|
||||
vmChunkDestroy(chunk);
|
||||
|
||||
vmArena->contracted(arena, base, size);
|
||||
|
|
|
|||
|
|
@ -803,6 +803,7 @@ typedef struct {
|
|||
void *p;
|
||||
Size s;
|
||||
SplayTree tree;
|
||||
Bool found;
|
||||
} SplayFindClosureStruct, *SplayFindClosure;
|
||||
|
||||
static Compare SplayFindFirstCompare(void *key, SplayNode node)
|
||||
|
|
@ -823,15 +824,23 @@ static Compare SplayFindFirstCompare(void *key, SplayNode node)
|
|||
testNode = closure->testNode;
|
||||
testTree = closure->testTree;
|
||||
tree = closure->tree;
|
||||
|
||||
|
||||
if (SplayNodeLeftChild(node) != NULL &&
|
||||
(*testTree)(tree, SplayNodeLeftChild(node), closureP, closureS)) {
|
||||
return CompareLESS;
|
||||
} else if ((*testNode)(tree, node, closureP, closureS)) {
|
||||
closure->found = TRUE;
|
||||
return CompareEQUAL;
|
||||
} else {
|
||||
AVER(SplayNodeRightChild(node) != NULL);
|
||||
AVER((*testTree)(tree, SplayNodeRightChild(node), closureP, closureS));
|
||||
/* If there's a right subtree but it doesn't satisfy the tree test
|
||||
then we want to terminate the splay right now. SplaySplay will
|
||||
return TRUE, so the caller must check closure->found to find out
|
||||
whether the result node actually satisfies testNode. */
|
||||
if (SplayNodeRightChild(node) != NULL &&
|
||||
!(*testTree)(tree, SplayNodeRightChild(node), closureP, closureS)) {
|
||||
closure->found = FALSE;
|
||||
return CompareEQUAL;
|
||||
}
|
||||
return CompareGREATER;
|
||||
}
|
||||
}
|
||||
|
|
@ -859,10 +868,15 @@ static Compare SplayFindLastCompare(void *key, SplayNode node)
|
|||
(*testTree)(tree, SplayNodeRightChild(node), closureP, closureS)) {
|
||||
return CompareGREATER;
|
||||
} else if ((*testNode)(tree, node, closureP, closureS)) {
|
||||
closure->found = TRUE;
|
||||
return CompareEQUAL;
|
||||
} else {
|
||||
AVER(SplayNodeLeftChild(node) != NULL);
|
||||
AVER((*testTree)(tree, SplayNodeLeftChild(node), closureP, closureS));
|
||||
/* See SplayFindFirstCompare. */
|
||||
if (SplayNodeLeftChild(node) != NULL &&
|
||||
!(*testTree)(tree, SplayNodeLeftChild(node), closureP, closureS)) {
|
||||
closure->found = FALSE;
|
||||
return CompareEQUAL;
|
||||
}
|
||||
return CompareLESS;
|
||||
}
|
||||
}
|
||||
|
|
@ -881,12 +895,13 @@ static Compare SplayFindLastCompare(void *key, SplayNode node)
|
|||
*/
|
||||
|
||||
Bool SplayFindFirst(SplayNode *nodeReturn, SplayTree tree,
|
||||
SplayTestNodeMethod testNode,
|
||||
SplayTestTreeMethod testTree,
|
||||
void *closureP, Size closureS)
|
||||
SplayTestNodeMethod testNode,
|
||||
SplayTestTreeMethod testTree,
|
||||
void *closureP, Size closureS)
|
||||
{
|
||||
SplayNode node;
|
||||
SplayFindClosureStruct closureStruct;
|
||||
Bool found;
|
||||
|
||||
AVER(nodeReturn != NULL);
|
||||
AVERT(SplayTree, tree);
|
||||
|
|
@ -903,14 +918,42 @@ Bool SplayFindFirst(SplayNode *nodeReturn, SplayTree tree,
|
|||
closureStruct.testNode = testNode;
|
||||
closureStruct.testTree = testTree;
|
||||
closureStruct.tree = tree;
|
||||
closureStruct.found = FALSE;
|
||||
|
||||
if (SplaySplay(&node, tree, (void *)&closureStruct,
|
||||
&SplayFindFirstCompare)) {
|
||||
*nodeReturn = node;
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
found = SplaySplay(&node, tree, (void *)&closureStruct,
|
||||
&SplayFindFirstCompare) && closureStruct.found;
|
||||
|
||||
while (!found) {
|
||||
SplayNode oldRoot, newRoot;
|
||||
|
||||
oldRoot = SplayTreeRoot(tree);
|
||||
newRoot = SplayNodeRightChild(oldRoot);
|
||||
|
||||
if (newRoot == NULL || !(*testTree)(tree, newRoot, closureP, closureS))
|
||||
return FALSE; /* no suitable nodes in the rest of the tree */
|
||||
|
||||
/* Temporarily chop off the left half-tree, inclusive of root,
|
||||
so that the search excludes any nodes we've seen already. */
|
||||
SplayTreeSetRoot(tree, newRoot);
|
||||
SplayNodeSetRightChild(oldRoot, NULL);
|
||||
|
||||
found = SplaySplay(&node, tree, (void *)&closureStruct,
|
||||
&SplayFindFirstCompare) && closureStruct.found;
|
||||
|
||||
/* Restore the left tree, then rotate left so that the node we
|
||||
just splayed is at the root. Update both. */
|
||||
newRoot = SplayTreeRoot(tree);
|
||||
SplayNodeSetRightChild(oldRoot, newRoot);
|
||||
SplayTreeSetRoot(tree, oldRoot);
|
||||
SplayRotateLeft(&tree->root, tree);
|
||||
if (tree->updateNode != NULL) {
|
||||
SplayNodeUpdate(tree, oldRoot);
|
||||
SplayNodeUpdate(tree, newRoot);
|
||||
}
|
||||
}
|
||||
|
||||
*nodeReturn = node;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue