mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-03-10 08:52:40 -07:00
Ephemerons solve the key-in-value problem for weak key/value pairs. It seems that it's not possible to solve that problem with weak pointers or finalizers. Basically we want a weak key/value pair that implements the rule: The value is reachable, if the key is reachable. The key-in-value problem occurs if all paths to the key go through the value. In this situation, the key is considered reachable only if the value is "externally reachable", i.e. the value is reachable through a path other than through the weak pair. Such weak pairs seem to need an extra phase in the GC algorithm. See [1] for some variants of the algorithm. https://www.haible.de/bruno/papers/cs/weak/WeakDatastructures-writeup.html * mps/code/mpmst.h (SegStruct): Add fields propagationNeeded, marksChanged, and propagationFinished. * mps/code/mpmtypes.h (RANK_LIST): Add EPHEMERON rank. * mps/code/mps.s (mps_rank_ephemeron): New prototype. * mps/code/mpscawl.h (mps_class_aeph, mps_fix_weak_pair) (mps_fix_weak_or_pair, mps_fix_weak_and_pair): New prototypes. * mps/code/mpsi.c (mps_rank_ephemeron): New function. * mps/code/poolawl.c (AEPHSegStruct, AEPHPoolStruct): New. The implementation the ephemeron pool. * mps/code/seg.c (segAbsInit): Initialize propagationNeeded, marksChanged, and propagationFinished. * mps/code/trace.c (traceBandRetreat, tracePropagateToLowerRanks) (moveSegToEndOfGreyRing): New helpers. (TraceRankForAccess): Handle the RankEPHEMERON. (traceFindGrey, traceScanSegRes): Add special handling for ephemeron segments. * mps/test/function/eph1.c: New test file. * mps/test/function/eph2.c: New test file. * mps/test/function/eph3.c: New test file. * mps/test/function/eph4.c: New test file. * mps/test/test/testlib/ephfmt.c: New file. * mps/test/test/testlib/ephfmt.h: New file. * mps/test/test/testlib/manifest: Add ephfmt.c. * mps/test/testsets/passing: Include eph{1,2,3,4}.c.
55 lines
1.5 KiB
C
55 lines
1.5 KiB
C
/*
|
|
TEST_HEADER
|
|
id = $Id$
|
|
summary = test TraceRankForAccess for ephemeron pool
|
|
language = c
|
|
link = testlib.o ephfmt.o
|
|
END_HEADER
|
|
*/
|
|
|
|
#include "ephfmt.h"
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
static void test(mmp mm, void* closure)
|
|
{
|
|
int i, j;
|
|
oop* s = mm->roots;
|
|
memset(s, 0, sizeof(mm->roots));
|
|
s[99] = string_from_cstr(mm->amc_ap, "x");
|
|
s[0] = string_from_cstr(mm->amc_ap, "a");
|
|
s[1] = string_from_cstr(mm->amc_ap, "b");
|
|
s[2] = make_pair(mm->amc_ap, s[0], s[1]);
|
|
s[3] = make_weak_pair(mm->eph_ap, s[0], s[2]);
|
|
s[0] = NULL;
|
|
s[1] = NULL;
|
|
s[2] = NULL;
|
|
|
|
/* The first mps_arena_step scans the AMC segment. The second step
|
|
* scans the AEPH segment. The trace is finished after two steps, if
|
|
* we access the AEPH segment before the third step; otherwise the
|
|
* trace finishes after the third step.
|
|
*
|
|
* Starting the loop at j=0 triggers the "unreachable code" assertion
|
|
* in trace.c:1047.
|
|
*/
|
|
for (j = 1; j < 3; j++) {
|
|
die(mps_arena_start_collect(mm->arena), "mps_arena_start_collect");
|
|
for (i = 0; i < j; i++)
|
|
cdie(mps_arena_step(mm->arena, 0, 0) == 0, "some work done");
|
|
cdie(s[3]->weak_pair.key == NULL, "key reachable");
|
|
cdie(s[3]->weak_pair.value == NULL, "value reachable");
|
|
while (mps_arena_step(mm->arena, 0, 0))
|
|
;
|
|
cdie(mps_arena_step(mm->arena, 0, 0) != 0, "no more work to do");
|
|
cdie(s[3]->weak_pair.key == NULL, "key reachable");
|
|
cdie(s[3]->weak_pair.value == NULL, "value reachable");
|
|
}
|
|
}
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
run_eph_test(test, NULL);
|
|
pass();
|
|
return 0;
|
|
}
|