aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code
diff options
context:
space:
mode:
authorRichard Kistruck2010-03-23 01:49:17 +0000
committerRichard Kistruck2010-03-23 01:49:17 +0000
commit0e6aecdbb86b2c9d30e08c155e4131ef1c663958 (patch)
tree801ad57d287ea7d8348baf90d1e1f0a938d580bb /mps/code
parente3177d0c02e16581ed17c0d01a43e5a8140807e1 (diff)
downloademacs-0e6aecdbb86b2c9d30e08c155e4131ef1c663958.tar.gz
emacs-0e6aecdbb86b2c9d30e08c155e4131ef1c663958.zip
mps br/vmem: simple-chunk-return:
arenavm.c -- move chunk-return into new function "VMCompact". (also, in VMArenaFinish, null out arena->primary in VMArenaFinish, so it is not left dangling). arena.c, arenavm.c, mpm.h, mpmst.h, mpmtypes.h: arena->class->compact: ArenaCompact, ArenaTrivCompact, VMCompact trace.c -- traceReclaim calls ArenaCompact! Copied from Perforce Change: 170095 ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code')
-rw-r--r--mps/code/arena.c23
-rw-r--r--mps/code/arenavm.c58
-rw-r--r--mps/code/mpm.h2
-rw-r--r--mps/code/mpmst.h1
-rw-r--r--mps/code/mpmtypes.h1
-rw-r--r--mps/code/plan.txt6
-rw-r--r--mps/code/trace.c2
7 files changed, 77 insertions, 16 deletions
diff --git a/mps/code/arena.c b/mps/code/arena.c
index 21c1759d74a..ac3cec79f09 100644
--- a/mps/code/arena.c
+++ b/mps/code/arena.c
@@ -17,6 +17,11 @@ SRCID(arena, "$Id$");
17#define ArenaControlPool(arena) MV2Pool(&(arena)->controlPoolStruct) 17#define ArenaControlPool(arena) MV2Pool(&(arena)->controlPoolStruct)
18 18
19 19
20/* Forward declarations */
21
22static void ArenaTrivCompact(Arena arena, Trace trace);
23
24
20/* ArenaTrivDescribe -- produce trivial description of an arena */ 25/* ArenaTrivDescribe -- produce trivial description of an arena */
21 26
22static Res ArenaTrivDescribe(Arena arena, mps_lib_FILE *stream) 27static Res ArenaTrivDescribe(Arena arena, mps_lib_FILE *stream)
@@ -63,6 +68,7 @@ DEFINE_CLASS(AbstractArenaClass, class)
63 class->free = NULL; 68 class->free = NULL;
64 class->chunkInit = NULL; 69 class->chunkInit = NULL;
65 class->chunkFinish = NULL; 70 class->chunkFinish = NULL;
71 class->compact = ArenaTrivCompact;
66 class->describe = ArenaTrivDescribe; 72 class->describe = ArenaTrivDescribe;
67 class->sig = ArenaClassSig; 73 class->sig = ArenaClassSig;
68} 74}
@@ -701,6 +707,23 @@ Res ArenaNoExtend(Arena arena, Addr base, Size size)
701} 707}
702 708
703 709
710/* ArenaCompact -- respond (or not) to trace reclaim */
711
712void ArenaCompact(Arena arena, Trace trace)
713{
714 AVERT(Arena, arena);
715 AVERT(Trace, trace);
716 (*arena->class->compact)(arena, trace);
717}
718
719static void ArenaTrivCompact(Arena arena, Trace trace)
720{
721 UNUSED(arena);
722 UNUSED(trace);
723 return;
724}
725
726
704/* Has Addr */ 727/* Has Addr */
705 728
706Bool ArenaHasAddr(Arena arena, Addr addr) 729Bool ArenaHasAddr(Arena arena, Addr addr)
diff --git a/mps/code/arenavm.c b/mps/code/arenavm.c
index dd329b58c5a..3fab5f4d547 100644
--- a/mps/code/arenavm.c
+++ b/mps/code/arenavm.c
@@ -91,6 +91,7 @@ typedef struct VMArenaStruct { /* VM arena structure */
91static void sparePagesPurge(VMArena vmArena); 91static void sparePagesPurge(VMArena vmArena);
92static ArenaClass VMArenaClassGet(void); 92static ArenaClass VMArenaClassGet(void);
93static ArenaClass VMNZArenaClassGet(void); 93static ArenaClass VMNZArenaClassGet(void);
94static void VMCompact(Arena arena, Trace trace);
94 95
95 96
96/* VMChunkCheck -- check the consistency of a VM chunk */ 97/* VMChunkCheck -- check the consistency of a VM chunk */
@@ -540,7 +541,8 @@ static void VMArenaFinish(Arena arena)
540 arenaVM = vmArena->vm; 541 arenaVM = vmArena->vm;
541 542
542 sparePagesPurge(vmArena); 543 sparePagesPurge(vmArena);
543 /* destroy all chunks */ 544 /* destroy all chunks, including the primary */
545 arena->primary = NULL;
544 RING_FOR(node, &arena->chunkRing, next) { 546 RING_FOR(node, &arena->chunkRing, next) {
545 Chunk chunk = RING_ELT(Chunk, chunkRing, node); 547 Chunk chunk = RING_ELT(Chunk, chunkRing, node);
546 vmChunkDestroy(chunk); 548 vmChunkDestroy(chunk);
@@ -1611,24 +1613,51 @@ static void VMFree(Addr base, Size size, Pool pool)
1611 if (arena->spareCommitted > arena->spareCommitLimit) { 1613 if (arena->spareCommitted > arena->spareCommitLimit) {
1612 sparePagesPurge(vmArena); 1614 sparePagesPurge(vmArena);
1613 } 1615 }
1614 /* @@@@ Chunks are never freed. */
1615 1616
1616 /* ... oh yes they are */ 1617 /* Chunks are only freed when ArenaCompact is called. */
1617 {
1618 Ring node, next;
1619 sparePagesPurge(vmArena);
1620 /* Destroy any empty chunks (except the primary). */
1621 RING_FOR(node, &arena->chunkRing, next) {
1622 /*Chunk */chunk = RING_ELT(Chunk, chunkRing, node);
1623 if(chunk != arena->primary
1624 && BTIsResRange(chunk->allocTable, 0, chunk->pages))
1625 vmChunkDestroy(chunk);
1626 }
1627 }
1628 1618
1629 return; 1619 return;
1630} 1620}
1631 1621
1622static void VMCompact(Arena arena, Trace trace)
1623{
1624 VMArena vmArena;
1625 Ring node, next;
1626 DIAG_DECL( Size vmem1; )
1627 DIAG_DECL( Size vmem2; )
1628 DIAG_DECL( Size vmemD; )
1629 DIAG_DECL( Count count; )
1630
1631 vmArena = Arena2VMArena(arena);
1632 AVERT(VMArena, vmArena);
1633 UNUSED(trace); /* it's there for better diag; not used yet */
1634
1635 /* Destroy any empty chunks (except the primary). */
1636 sparePagesPurge(vmArena);
1637 DIAG(
1638 vmem1 = VMArenaReserved(arena);
1639 count = 0;
1640 );
1641 RING_FOR(node, &arena->chunkRing, next) {
1642 Chunk chunk = RING_ELT(Chunk, chunkRing, node);
1643 if(chunk != arena->primary
1644 && BTIsResRange(chunk->allocTable, 0, chunk->pages)) {
1645 vmChunkDestroy(chunk);
1646 DIAG( count += 1; );
1647 }
1648 }
1649 DIAG(
1650 vmem2 = VMArenaReserved(arena);
1651 vmemD = vmem1 - vmem2;
1652
1653 if(vmemD != 0) {
1654 DIAG_SINGLEF(( "VMCompact",
1655 "vmem was $W, released $W, now $W", vmem1, vmemD, vmem2,
1656 NULL));
1657 }
1658 );
1659
1660}
1632 1661
1633mps_res_t mps_arena_vm_growth(mps_arena_t mps_arena, 1662mps_res_t mps_arena_vm_growth(mps_arena_t mps_arena,
1634 size_t mps_desired, size_t mps_minimum) 1663 size_t mps_desired, size_t mps_minimum)
@@ -1675,6 +1704,7 @@ DEFINE_ARENA_CLASS(VMArenaClass, this)
1675 this->free = VMFree; 1704 this->free = VMFree;
1676 this->chunkInit = VMChunkInit; 1705 this->chunkInit = VMChunkInit;
1677 this->chunkFinish = VMChunkFinish; 1706 this->chunkFinish = VMChunkFinish;
1707 this->compact = VMCompact;
1678 this->describe = VMArenaDescribe; 1708 this->describe = VMArenaDescribe;
1679} 1709}
1680 1710
diff --git a/mps/code/mpm.h b/mps/code/mpm.h
index b4189afadcd..371319aeee6 100644
--- a/mps/code/mpm.h
+++ b/mps/code/mpm.h
@@ -570,6 +570,8 @@ extern Size ArenaAvail(Arena arena);
570 570
571extern Res ArenaExtend(Arena, Addr base, Size size); 571extern Res ArenaExtend(Arena, Addr base, Size size);
572 572
573extern void ArenaCompact(Arena arena, Trace trace);
574
573extern Res ArenaFinalize(Arena arena, Ref obj); 575extern Res ArenaFinalize(Arena arena, Ref obj);
574extern Res ArenaDefinalize(Arena arena, Ref obj); 576extern Res ArenaDefinalize(Arena arena, Ref obj);
575 577
diff --git a/mps/code/mpmst.h b/mps/code/mpmst.h
index 23409087808..c5a4fe0e3f3 100644
--- a/mps/code/mpmst.h
+++ b/mps/code/mpmst.h
@@ -567,6 +567,7 @@ typedef struct ArenaClassStruct {
567 ArenaFreeMethod free; 567 ArenaFreeMethod free;
568 ArenaChunkInitMethod chunkInit; 568 ArenaChunkInitMethod chunkInit;
569 ArenaChunkFinishMethod chunkFinish; 569 ArenaChunkFinishMethod chunkFinish;
570 ArenaCompactMethod compact;
570 ArenaDescribeMethod describe; 571 ArenaDescribeMethod describe;
571 Sig sig; 572 Sig sig;
572} ArenaClassStruct; 573} ArenaClassStruct;
diff --git a/mps/code/mpmtypes.h b/mps/code/mpmtypes.h
index fd27f8c2a80..056ac0d2ec9 100644
--- a/mps/code/mpmtypes.h
+++ b/mps/code/mpmtypes.h
@@ -118,6 +118,7 @@ typedef Res (*ArenaAllocMethod)(Addr *baseReturn, Tract *baseTractReturn,
118typedef void (*ArenaFreeMethod)(Addr base, Size size, Pool pool); 118typedef void (*ArenaFreeMethod)(Addr base, Size size, Pool pool);
119typedef Res (*ArenaChunkInitMethod)(Chunk chunk, BootBlock boot); 119typedef Res (*ArenaChunkInitMethod)(Chunk chunk, BootBlock boot);
120typedef void (*ArenaChunkFinishMethod)(Chunk chunk); 120typedef void (*ArenaChunkFinishMethod)(Chunk chunk);
121typedef void (*ArenaCompactMethod)(Arena arena, Trace trace);
121typedef Res (*ArenaDescribeMethod)(Arena arena, mps_lib_FILE *stream); 122typedef Res (*ArenaDescribeMethod)(Arena arena, mps_lib_FILE *stream);
122 123
123 124
diff --git a/mps/code/plan.txt b/mps/code/plan.txt
index faeb16a6791..23bf274ecac 100644
--- a/mps/code/plan.txt
+++ b/mps/code/plan.txt
@@ -15,9 +15,11 @@ The primary chunk is used specially:
15 15
161. Arenacl requires a chunk to store the ArenaStruct in. (Whereas arenavm gets storage by simply mapping a new page). Therefore destroying the primary chunk would (in general) destroy the arena. 161. Arenacl requires a chunk to store the ArenaStruct in. (Whereas arenavm gets storage by simply mapping a new page). Therefore destroying the primary chunk would (in general) destroy the arena.
17 17
182. PageSize is known by chunks, not the arena. When arena needs to know page size, it asks the primary chunk. 182. there's a field arena->primary that stores a pointer to the primary chunk. If the primary chunk ever goes away (eg. at ArenaFinish), this pointer must be nulled out so it is not left dangling.
19 19
203. Various *Check functions only bother to check the primary chunk, and ignore other chunks. 203. PageSize is known by chunks, not the arena. When arena needs to know page size, it asks the primary chunk.
21
224. Various *Check functions only bother to check the primary chunk, and ignore other chunks.
21 23
22 24
23 25
diff --git a/mps/code/trace.c b/mps/code/trace.c
index b4b17c11b49..5cffa818009 100644
--- a/mps/code/trace.c
+++ b/mps/code/trace.c
@@ -813,6 +813,8 @@ static void traceReclaim(Trace trace)
813 PoolTraceEnd(pool, trace); 813 PoolTraceEnd(pool, trace);
814 } 814 }
815 815
816 ArenaCompact(arena, trace); /* let arenavm drop chunks */
817
816 TracePostMessage(trace); /* trace end */ 818 TracePostMessage(trace); /* trace end */
817 /* Immediately pre-allocate messages for next time; failure is okay */ 819 /* Immediately pre-allocate messages for next time; failure is okay */
818 (void)TraceIdMessagesCreate(arena, trace->ti); 820 (void)TraceIdMessagesCreate(arena, trace->ti);