From 15975c24426e14fbc266318d81986e2993f42e8f Mon Sep 17 00:00:00 2001
From: David Lovemore
Date: Wed, 5 Feb 2014 15:04:40 +0000
Subject: [PATCH] Add zone set to cbs nodes for faster zone set allocation.
Copied from Perforce
Change: 184299
ServerID: perforce.ravenbrook.com
---
mps/code/cbs.c | 26 +++++++++++++++++++++++++-
mps/code/mpmst.h | 1 +
2 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/mps/code/cbs.c b/mps/code/cbs.c
index 2f8eb4ff4d1..fcd43dd8aa5 100644
--- a/mps/code/cbs.c
+++ b/mps/code/cbs.c
@@ -27,6 +27,7 @@ typedef struct CBSBlockStruct {
Addr base;
Addr limit;
Size maxSize; /* accurate maximum block size of sub-tree */
+ ZoneSet zones; /* union zone set of all ranges in sub-tree */
} CBSBlockStruct;
#define CBSBlockBase(block) ((block)->base)
@@ -78,6 +79,7 @@ Bool CBSCheck(CBS cbs)
CHECKL(SplayTreeCheck(splayTreeOfCBS(cbs)));
/* nothing to check about splayTreeSize */
CHECKD(MFS, &cbs->blockPoolStruct);
+ CHECKU(Arena, cbs->arena);
CHECKL(BoolCheck(cbs->fastFind));
CHECKL(BoolCheck(cbs->inCBS));
/* No MeterCheck */
@@ -176,7 +178,9 @@ static void cbsUpdateNode(SplayTree tree, SplayNode node,
SplayNode leftChild, SplayNode rightChild)
{
Size maxSize;
+ ZoneSet zones;
CBSBlock block;
+ Arena arena;
AVERT(SplayTree, tree);
AVERT(SplayNode, node);
@@ -188,20 +192,25 @@ static void cbsUpdateNode(SplayTree tree, SplayNode node,
block = cbsBlockOfSplayNode(node);
maxSize = CBSBlockSize(block);
+ arena = cbsOfSplayTree(tree)->arena;
+ zones = ZoneSetOfRange(arena, CBSBlockBase(block), CBSBlockLimit(block));
if (leftChild != NULL) {
Size size = cbsBlockOfSplayNode(leftChild)->maxSize;
if (size > maxSize)
maxSize = size;
+ zones = ZoneSetUnion(zones, cbsBlockOfSplayNode(leftChild)->zones);
}
if (rightChild != NULL) {
Size size = cbsBlockOfSplayNode(rightChild)->maxSize;
if (size > maxSize)
maxSize = size;
+ zones = ZoneSetUnion(zones, cbsBlockOfSplayNode(rightChild)->zones);
}
block->maxSize = maxSize;
+ block->zones = zones;
}
@@ -227,6 +236,7 @@ Res CBSInit(Arena arena, CBS cbs, void *owner, Align alignment,
if (ArgPick(&arg, args, MFSExtendSelf))
extendSelf = arg.val.b;
+ cbs->arena = arena;
SplayTreeInit(splayTreeOfCBS(cbs), &cbsSplayCompare,
fastFind ? &cbsUpdateNode : NULL);
MPS_ARGS_BEGIN(piArgs) {
@@ -804,6 +814,20 @@ static Bool cbsTestNodeInZones(SplayTree tree, SplayNode node,
closure->arena, closure->zoneSet, closure->size);
}
+static Bool cbsTestTreeInZones(SplayTree tree, SplayNode node,
+ void *closureP, Size closureSize)
+{
+ CBSBlock block = cbsBlockOfSplayNode(node);
+ cbsTestNodeInZonesClosure closure = closureP;
+
+ UNUSED(tree);
+ AVER(closureSize == sizeof(cbsTestNodeInZonesClosureStruct));
+ UNUSED(closureSize);
+
+ return block->maxSize >= closure->size &&
+ ZoneSetInter(block->zones, closure->zoneSet) != ZoneSetEMPTY;
+}
+
Bool CBSFindFirstInZones(Range rangeReturn, Range oldRangeReturn,
CBS cbs, Size size,
Arena arena, ZoneSet zoneSet)
@@ -845,7 +869,7 @@ Bool CBSFindFirstInZones(Range rangeReturn, Range oldRangeReturn,
closure.size = size;
found = SplayFindFirst(&node, splayTreeOfCBS(cbs),
&cbsTestNodeInZones,
- &cbsTestTree,
+ &cbsTestTreeInZones,
&closure, sizeof(closure));
if (found) {
CBSBlock block = cbsBlockOfSplayNode(node);
diff --git a/mps/code/mpmst.h b/mps/code/mpmst.h
index 17298fee279..77c480cd5e2 100644
--- a/mps/code/mpmst.h
+++ b/mps/code/mpmst.h
@@ -615,6 +615,7 @@ typedef struct CBSStruct {
SplayTreeStruct splayTree;
STATISTIC_DECL(Count splayTreeSize);
MFSStruct blockPoolStruct; /* FIXME: ref to why this is inlined */
+ Arena arena; /* needed by update method */
Align alignment;
Bool fastFind;
Bool inCBS; /* prevent reentrance */