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.