CountedVMImpl.mesa
Copyright Ó 1985, 1986, 1989, 1991, 1992 by Xerox Corporation. All rights reserved.
Taft, December 10, 1983 3:03 pm
Plass, December 21, 1983 1:33 pm
Russ Atkinson (RRA) August 22, 1985 5:31:08 pm PDT
Doug Wyatt, February 26, 1985 10:20:58 am PST
Carl Hauser, March 24, 1988 3:09:29 pm PST
Michael Plass, August 31, 1992 12:00 pm PDT
Chauser, July 30, 1992 11:17 am PDT
Willie-s, August 6, 1991 1:21 pm PDT
DIRECTORY
CountedVM USING [Handle, Object],
CountedVMSidedoor USING [],
FinalizeOps USING [CallQueue, CreateCallQueue, EnableFinalization, FinalizeProc],
RegisterRefLiteral USING [Create],
VM USING [AddressForPageNumber, Allocate, FalseBool, Free, Interval, LogPageCount, nullInterval, NullInterval, PageCount, PagesForWords, VMPartition, ZeroPageNumber];
CountedVMImpl:
CEDAR
MONITOR
IMPORTS FinalizeOps, RegisterRefLiteral, VM
EXPORTS CountedVM, CountedVMSidedoor
~ BEGIN
Handle: TYPE ~ CountedVM.Handle;
Object: TYPE ~ CountedVM.Object;
allocatedPages: REF INT ¬ NEW[INT ¬ 0];
allocatedObjects: REF INT ¬ NEW[INT ¬ 0];
freedPages: REF INT ¬ NEW[INT ¬ 0];
freedObjects: REF INT ¬ NEW[INT ¬ 0];
statistics: PUBLIC --CountedVMSidedoor-- LIST OF REF ANY = LIST[$allocatedPages, allocatedPages, $allocatedObjects, allocatedObjects, $freedPages, freedPages, $freedObjects, freedObjects];
No ref literals in Cedar Core!
statistics: PUBLIC --CountedVMSidedoor-- LIST OF REF ANY ¬ LIST[MakeAtom["allocatedPages"], allocatedPages, MakeAtom["allocatedObjects"], allocatedObjects, MakeAtom["freedPages"], freedPages, MakeAtom["freedObjects"], freedObjects];
tries:
NAT ¬ 3;
# of times to try to collect extra garbage before giving up
AllocateStat:
ENTRY
PROC [pages:
INT] = {
allocatedObjects ¬ allocatedObjects + 1;
allocatedPages ¬ allocatedPages + pages;
};
Allocate:
PUBLIC
PROC [words:
INT,
partition:
VM.VMPartition ¬ normalVM, subRange:
VM.NullInterval ¬ [0, 0],
start:
VM.ZeroPageNumber ¬ 0, alignment:
VM.LogPageCount ¬ 0, in64K:
VM.FalseBool ¬
FALSE]
RETURNS [h: Handle ¬
NIL] = {
IF words > 0
THEN
TRUSTED {
count: VM.PageCount ~ VM.PagesForWords[words];
FOR i:
NAT
IN [0..tries]
DO
interval:
VM.Interval ~
VM.Allocate[count: count, partition: partition, subRange: subRange, start: start, alignment: alignment, in64K: in64K
<<
This doesn't make much sense in a pcr world....
!
VM.CantAllocate => {
There is a possibility that if we could collect some outstanding goodies that we could get enough VM to make all of this work out OK. If we have performed enough GCs, though, we allow the signal to percolate upwards.
IF i = tries THEN REJECT;
SafeStorage.ReclaimCollectibleObjects[suspendMe: TRUE, traceAndSweep: FALSE];
Process.Pause[Process.MsecToTicks[200]];
LOOP;
}
>>
];
h ¬ NEW[Object ¬ [interval: interval, pointer: VM.AddressForPageNumber[interval.page], words: words]];
[] ¬ FinalizeOps.EnableFinalization[h, fq];
AllocateStat[interval.count];
EXIT;
ENDLOOP;
};
};
SimpleAllocate:
PUBLIC
PROC [words:
INT]
RETURNS [Handle] = {
RETURN[Allocate[words: words]];
};
Free:
PUBLIC
ENTRY
UNSAFE
PROC [handle: Handle] = {
IF handle #
NIL
AND handle.pointer #
NIL
AND handle.words # 0
THEN {
We can try to free this interval
interval: VM.Interval ¬ handle.interval;
handle.pointer ¬ NIL;
handle.words ¬ 0;
handle.interval ¬ VM.nullInterval;
TRUSTED {VM.Free[interval]};
freedObjects ¬ freedObjects + 1;
freedPages ¬ freedPages + interval.count;
};
handle ¬ NIL;
};
Finalize: FinalizeOps
.FinalizeProc ~ {
h: Handle ¬ NARROW[object];
TRUSTED { Free[h] };
};
MakeAtom:
PROC [ s:
STRING ]
RETURNS [
ATOM] ~ {
RETURN[NARROW[RegisterRefLiteral.Create[CODE[ATOM], s]]];
};
fq: FinalizeOps.CallQueue ~ FinalizeOps.CreateCallQueue[Finalize];
END.