<<>> <> <> <> <<>> DIRECTORY GCRoots, RefTab; <<>> GCRootsImpl: CEDAR MONITOR IMPORTS RefTab EXPORTS GCRoots ~ BEGIN <<>> cacheMax: INT = 8; CacheArray: TYPE = ARRAY [0..cacheMax] OF REF INT; cache: REF CacheArray ~ NEW[CacheArray]; --cacheing counts to reduce allocations tab: RefTab.Ref ~ RefTab.Create[]; <<>> ExternalNames: PROC [] = TRUSTED MACHINE CODE { <> "^ExternalNames\n"; "Include XR_GCRoots_Include\n"; "Forget XR_GCRoots_Forget\n"; "Number XR_GCRoots_Number\n"; }; New: PROC [i: INT] RETURNS [REF INT] = { IF i>cacheMax THEN RETURN [NEW[INT ¬ i]] ELSE RETURN [cache[i]] }; Include: PUBLIC PROC [x: REF ANY] = { Action: RefTab.UpdateAction = { IF found THEN new ¬ New[NARROW[val, REF INT]­+1] ELSE new ¬ New[1]; op ¬ store; }; RefTab.Update[tab, x, Action] }; <<>> Forget: PUBLIC PROC [x: REF ANY] = { Action: RefTab.UpdateAction = { IF found THEN { i: INT ~ NARROW[val, REF INT]­; IF i<=1 THEN op ¬ delete ELSE {new ¬ New[i-1]; op ¬ store}; } }; RefTab.Update[tab, x, Action] }; Number: PUBLIC PROC [] RETURNS [INT] = { RETURN [RefTab.GetSize[tab]] }; <<>> ExternalNames[]; FOR i: INT IN [1..cacheMax] DO cache[i] ¬ NEW[INT ¬ i]; ENDLOOP; END.