aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code
diff options
context:
space:
mode:
authorNick Barnes2003-01-03 12:58:12 +0000
committerNick Barnes2003-01-03 12:58:12 +0000
commitbddcae1d08135891526a056f8fd44f6316bd4aa2 (patch)
treea135d6dc8c0c5faefe04e705eb8faa3436054138 /mps/code
parent5344376ca7da0d72959dcba15d7de2df298b3b77 (diff)
downloademacs-bddcae1d08135891526a056f8fd44f6316bd4aa2.tar.gz
emacs-bddcae1d08135891526a056f8fd44f6316bd4aa2.zip
Add mps_arena_start_collect(): starting an incremental world collection.
Copied from Perforce Change: 37576 ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code')
-rw-r--r--mps/code/mpm.h1
-rw-r--r--mps/code/mps.h1
-rw-r--r--mps/code/mpsi.c10
-rw-r--r--mps/code/trace.c100
4 files changed, 79 insertions, 33 deletions
diff --git a/mps/code/mpm.h b/mps/code/mpm.h
index d3845e00174..a3106830fed 100644
--- a/mps/code/mpm.h
+++ b/mps/code/mpm.h
@@ -475,6 +475,7 @@ extern Bool (ArenaStep)(Globals globals, double interval);
475extern void ArenaClamp(Globals globals); 475extern void ArenaClamp(Globals globals);
476extern void ArenaRelease(Globals globals); 476extern void ArenaRelease(Globals globals);
477extern void ArenaPark(Globals globals); 477extern void ArenaPark(Globals globals);
478extern Res ArenaStartCollect(Globals globals);
478extern Res ArenaCollect(Globals globals); 479extern Res ArenaCollect(Globals globals);
479extern Bool ArenaHasAddr(Arena arena, Addr addr); 480extern Bool ArenaHasAddr(Arena arena, Addr addr);
480 481
diff --git a/mps/code/mps.h b/mps/code/mps.h
index ab49c39ed24..731ebe4925b 100644
--- a/mps/code/mps.h
+++ b/mps/code/mps.h
@@ -238,6 +238,7 @@ typedef struct mps_fmt_fixed_s {
238extern void mps_arena_clamp(mps_arena_t); 238extern void mps_arena_clamp(mps_arena_t);
239extern void mps_arena_release(mps_arena_t); 239extern void mps_arena_release(mps_arena_t);
240extern void mps_arena_park(mps_arena_t); 240extern void mps_arena_park(mps_arena_t);
241extern mps_res_t mps_arena_start_collect(mps_arena_t);
241extern mps_res_t mps_arena_collect(mps_arena_t); 242extern mps_res_t mps_arena_collect(mps_arena_t);
242extern mps_bool_t mps_arena_step(mps_arena_t, double); 243extern mps_bool_t mps_arena_step(mps_arena_t, double);
243extern void mps_space_clamp(mps_space_t); 244extern void mps_space_clamp(mps_space_t);
diff --git a/mps/code/mpsi.c b/mps/code/mpsi.c
index 9aa143057c8..58777f5cdd8 100644
--- a/mps/code/mpsi.c
+++ b/mps/code/mpsi.c
@@ -341,6 +341,16 @@ void mps_space_park(mps_space_t mps_space)
341} 341}
342 342
343 343
344mps_res_t mps_arena_start_collect(mps_space_t mps_space)
345{
346 Res res;
347 Arena arena = (Arena)mps_space;
348 ArenaEnter(arena);
349 res = ArenaStartCollect(ArenaGlobals(arena));
350 ArenaLeave(arena);
351 return res;
352}
353
344mps_res_t mps_arena_collect(mps_space_t mps_space) 354mps_res_t mps_arena_collect(mps_space_t mps_space)
345{ 355{
346 Res res; 356 Res res;
diff --git a/mps/code/trace.c b/mps/code/trace.c
index 35463338f6c..32bca0d9b54 100644
--- a/mps/code/trace.c
+++ b/mps/code/trace.c
@@ -1507,6 +1507,37 @@ static void traceQuantum(Trace trace)
1507 && (trace->emergency || traceWorkClock(trace) < pollEnd)); 1507 && (trace->emergency || traceWorkClock(trace) < pollEnd));
1508} 1508}
1509 1509
1510/* traceStartCollectAll: start a trace which condemns everything in
1511 * the arena. */
1512
1513static Res traceStartCollectAll(Trace *traceReturn, Arena arena)
1514{
1515 Trace trace;
1516 Res res;
1517 double finishingTime;
1518
1519 AVERT(Arena, arena);
1520 AVER(arena->busyTraces == TraceSetEMPTY);
1521
1522 res = TraceCreate(&trace, arena);
1523 AVER(res == ResOK); /* succeeds because no other trace is busy */
1524 res = traceCondemnAll(trace);
1525 if (res != ResOK) /* should try some other trace, really @@@@ */
1526 goto failCondemn;
1527 finishingTime = ArenaAvail(arena)
1528 - trace->condemned * (1.0 - TraceTopGenMortality);
1529 if (finishingTime < 0)
1530 /* Run out of time, should really try a smaller collection. @@@@ */
1531 finishingTime = 0.0;
1532 TraceStart(trace, TraceTopGenMortality, finishingTime);
1533 *traceReturn = trace;
1534 return ResOK;
1535
1536failCondemn:
1537 TraceDestroy(trace);
1538 return res;
1539}
1540
1510 1541
1511/* TracePoll -- Check if there's any tracing work to be done */ 1542/* TracePoll -- Check if there's any tracing work to be done */
1512 1543
@@ -1537,22 +1568,12 @@ Bool TracePoll(Globals globals)
1537 AVER(TraceWorkFactor >= 0); 1568 AVER(TraceWorkFactor >= 0);
1538 AVER(sSurvivors + tTracePerScan * TraceWorkFactor <= (double)SizeMAX); 1569 AVER(sSurvivors + tTracePerScan * TraceWorkFactor <= (double)SizeMAX);
1539 sConsTrace = (Size)(sSurvivors + tTracePerScan * TraceWorkFactor); 1570 sConsTrace = (Size)(sSurvivors + tTracePerScan * TraceWorkFactor);
1540 dynamicDeferral = (double)sConsTrace - (double)ArenaAvail(arena); 1571 dynamicDeferral = (double)ArenaAvail(arena) - (double)sConsTrace;
1541 1572
1542 if (dynamicDeferral > 0.0) { /* start full GC */ 1573 if (dynamicDeferral < 0.0) { /* start full GC */
1543 double finishingTime; 1574 res = traceStartCollectAll(&trace, arena);
1544 1575 if (res != ResOK)
1545 res = TraceCreate(&trace, arena); 1576 goto failStart;
1546 AVER(res == ResOK); /* succeeds because no other trace is busy */
1547 res = traceCondemnAll(trace);
1548 if (res != ResOK) /* should try some other trace, really @@@@ */
1549 goto failCondemn;
1550 finishingTime = ArenaAvail(arena)
1551 - trace->condemned * (1.0 - TraceTopGenMortality);
1552 if (finishingTime < 0)
1553 /* Run out of time, should really try a smaller collection. @@@@ */
1554 finishingTime = 0.0;
1555 TraceStart(trace, TraceTopGenMortality, finishingTime);
1556 done = TRUE; 1577 done = TRUE;
1557 } else { /* Find the nursery most over its capacity. */ 1578 } else { /* Find the nursery most over its capacity. */
1558 Ring node, nextNode; 1579 Ring node, nextNode;
@@ -1600,11 +1621,12 @@ Bool TracePoll(Globals globals)
1600 1621
1601failCondemn: 1622failCondemn:
1602 TraceDestroy(trace); 1623 TraceDestroy(trace);
1624failStart:
1603 return FALSE; 1625 return FALSE;
1604} 1626}
1605 1627
1606 1628
1607/* ArenaClamp -- clamp the arena (no new collections) */ 1629/* ArenaClamp -- clamp the arena (no optional collection increments) */
1608 1630
1609void ArenaClamp(Globals globals) 1631void ArenaClamp(Globals globals)
1610{ 1632{
@@ -1613,7 +1635,8 @@ void ArenaClamp(Globals globals)
1613} 1635}
1614 1636
1615 1637
1616/* ArenaRelease -- release the arena (allow new collections) */ 1638/* ArenaRelease -- release the arena (allow optional collection
1639 * increments) */
1617 1640
1618void ArenaRelease(Globals globals) 1641void ArenaRelease(Globals globals)
1619{ 1642{
@@ -1623,7 +1646,7 @@ void ArenaRelease(Globals globals)
1623} 1646}
1624 1647
1625 1648
1626/* ArenaClamp -- finish all collections and clamp the arena */ 1649/* ArenaPark -- finish all current collections and clamp the arena */
1627 1650
1628void ArenaPark(Globals globals) 1651void ArenaPark(Globals globals)
1629{ 1652{
@@ -1646,34 +1669,45 @@ void ArenaPark(Globals globals)
1646 } 1669 }
1647} 1670}
1648 1671
1672/* ArenaStartCollect -- start a collection of everything in the
1673 * arena; leave unclamped. */
1649 1674
1650/* ArenaCollect -- collect everything in arena */ 1675Res ArenaStartCollect(Globals globals)
1651
1652Res ArenaCollect(Globals globals)
1653{ 1676{
1654 Trace trace; 1677 Arena arena;
1655 Res res; 1678 Res res;
1679 Trace trace;
1656 1680
1657 AVERT(Globals, globals); 1681 AVERT(Globals, globals);
1682 arena = GlobalsArena(globals);
1683
1658 ArenaPark(globals); 1684 ArenaPark(globals);
1685 res = traceStartCollectAll(&trace, arena);
1686 if (res != ResOK)
1687 goto failStart;
1688 ArenaRelease(globals);
1689 return ResOK;
1659 1690
1660 res = TraceCreate(&trace, GlobalsArena(globals)); 1691failStart:
1661 AVER(res == ResOK); /* should be a trace available -- we're parked */ 1692 ArenaRelease(globals);
1693 return res;
1694}
1662 1695
1663 res = traceCondemnAll(trace); 1696/* ArenaCollect -- collect everything in arena; leave clamped */
1697
1698Res ArenaCollect(Globals globals)
1699{
1700 Res res;
1701
1702 AVERT(Globals, globals);
1703 res = ArenaStartCollect(globals);
1664 if (res != ResOK) 1704 if (res != ResOK)
1665 goto failBegin; 1705 return res;
1666 1706
1667 TraceStart(trace, 0.0, 0.0);
1668 ArenaPark(globals); 1707 ArenaPark(globals);
1669 return ResOK; 1708 return ResOK;
1670
1671failBegin:
1672 TraceDestroy(trace);
1673 return res;
1674} 1709}
1675 1710
1676
1677/* C. COPYRIGHT AND LICENSE 1711/* C. COPYRIGHT AND LICENSE
1678 * 1712 *
1679 * Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>. 1713 * Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.