DIRECTORY
PrincOps USING[SD],
RTFlags USING[takingStatistics],
RTSD USING[sMapStiStd],
RTSymbolDefs USING[nullHandle],
RTTypesBasicPrivate USING[STDesc, SymbolTableIndex, InitialSTIRangeSize, MapStiStd, LOOPHOLEDTMapStiStd, RSTDesc, RMapStiStd],
SafeStorage USING[TypeIndex],
SafeStoragePrivate USING[PrivateHeapZone];
RTSymbolAccessImpl:
MONITOR
-- protects MapStiStd
IMPORTS RTTypesBasicPrivate, SafeStoragePrivate
EXPORTS RTTypesBasicPrivate
-- Statistics
stats:
RECORD[
nSTIFound: INT ← 0,
nSTDCreatedWhileInitializing: INT ← 0, -- from PrivateHeapZone
nSTDCreatedAfterInitializing: INT ← 0
];
Bump: PROC[p: POINTER TO INT, delta: INT ← 1] =
INLINE {IF RTFlags.takingStatistics THEN p^ ← p^+delta};
lastSTIndex: TypeIndex ← 0;
TooManyTypes: ERROR = CODE;
Bless
MapStiStd:
PUBLIC
ENTRY
PROC = {
ENABLE UNWIND => NULL;
t: LOOPHOLEDTMapStiStd = LOOPHOLE[MapStiStd];
LOOPHOLE[MapStiStd, LOOPHOLEDTMapStiStd] ← NIL;
MapStiStd ← NEW[RMapStiStd[InitialSTIRangeSize]];
LOOPHOLE[
LONG[@PrincOps
.SD[
RTSD.sMapStiStd]],
LONG
POINTER
TO
LONG
POINTER]^
← LOOPHOLE[MapStiStd, LONG POINTER];
FOR i: SymbolTableIndex
IN [1..lastSTIndex]
DO MapStiStd[i] ← NEW[STDesc ← t[i]^] ENDLOOP;
};
FindSTI:
PUBLIC
ENTRY
PROC[std: STDesc, initializing:
BOOL]
RETURNS[i: SymbolTableIndex] = {
ENABLE UNWIND => NULL;
FOR i
IN [1..lastSTIndex]
DO
IF MapStiStd[i].symbolsStamp = std.symbolsStamp
AND (std.bcd =
NIL
OR std.sgi = MapStiStd[i].sgi)
THEN {
IF MapStiStd[i].sth = RTSymbolDefs.nullHandle
THEN {
IF initializing
THEN LOOPHOLE[MapStiStd, LOOPHOLEDTMapStiStd][i].sth ← std.sth
ELSE MapStiStd[i].sth ← std.sth;
};
Bump[@stats.nSTIFound];
RETURN[i];
};
ENDLOOP;
IF lastSTIndex = InitialSTIRangeSize - 1 THEN ERROR TooManyTypes;
i ← lastSTIndex ← lastSTIndex + 1;
IF initializing
THEN {
Bump[@stats.nSTDCreatedWhileInitializing];
LOOPHOLE[MapStiStd, LOOPHOLEDTMapStiStd][i]
← SafeStoragePrivate.PrivateHeapZone.NEW[STDesc ← std];
}
ELSE {
Bump[@stats.nSTDCreatedAfterInitializing];
MapStiStd[i] ← NEW[STDesc ← std];
};
};