<> <> <> <> <> <<>> <> DIRECTORY Allocator USING [bsiEscape, ExtendedHeader, HeaderP, LastAddress, NHeaderP, NormalHeader, QuantumMap, QuantumIndex, wordsPerQuantum, BSIToSizeObj, SizeToBSIObj, BlockSizeIndex], Basics USING [BITAND, HighHalf, LongDiv, LowHalf], SafeStorage USING [nullType, Type, TypeIndex]; AllocatorOps: DEFINITIONS IMPORTS Basics = BEGIN OPEN Allocator; <<>> <> DFHeaderP: TYPE = LONG POINTER TO DoubleFreeHeader; Rover: TYPE = DFHeaderP; DoubleFreeHeader: TYPE = RECORD[ eh: ExtendedHeader, nextFree: DFHeaderP, prevFree: DFHeaderP ]; <<>> nonNullType: SafeStorage.Type = [LAST[SafeStorage.TypeIndex]]; permanentPageZone: UNCOUNTED ZONE; bsiToSize: LONG POINTER TO BSIToSizeObj; sizeToBSI: LONG POINTER TO SizeToBSIObj; quantumMap: QuantumMap; NewObject: PROC[type: SafeStorage.Type, size: CARDINAL, zone: ZONE _ NIL] RETURNS[REF ANY]; -- CLEARED PlausibleRef: PROC[lc: LONG CARDINAL] RETURNS[BOOL] = INLINE { RETURN[ Basics.HighHalf[lc] IN [1..Basics.HighHalf[LastAddress]] AND Basics.BITAND[Basics.LowHalf[lc], 1] = 0 AND quantumMap[AddressToQuantumIndex[lc]] ]; }; AddressToQuantumIndex: PROC[addr: LONG CARDINAL] RETURNS[QuantumIndex] = INLINE { RETURN [Basics.LongDiv[addr, wordsPerQuantum]]; <> }; ReferentType: PROC[ref: REF ANY] RETURNS[SafeStorage.Type] = INLINE { RETURN[IF ref = NIL THEN SafeStorage.nullType ELSE (LOOPHOLE[ref, LONG POINTER TO SafeStorage.Type]-1)^ ]; }; BlockSize: PROC[hp: HeaderP] RETURNS[INT]; REFToHP: PROC[ref: REF ANY] RETURNS[HeaderP] = INLINE { nhp: NHeaderP = LOOPHOLE[ref, NHeaderP] - SIZE[NormalHeader]; IF nhp.blockSizeIndex # bsiEscape THEN RETURN[LOOPHOLE[nhp]] ELSE RETURN[LOOPHOLE[ref, HeaderP] - SIZE[ExtendedHeader]]; }; REFToNHP: PROC[ref: REF ANY] RETURNS[NHeaderP] = INLINE { RETURN[LOOPHOLE[ref, NHeaderP] - SIZE[NormalHeader]]}; NHPToREF: PROC[nhp: NHeaderP] RETURNS[REF ANY] = INLINE { RETURN[LOOPHOLE[nhp + SIZE[NormalHeader], REF ANY]]}; HPToREF: PROC[hp: HeaderP] RETURNS[REF ANY] = INLINE { nhp: NHeaderP = LOOPHOLE[hp]; IF nhp.blockSizeIndex # bsiEscape THEN RETURN[LOOPHOLE[hp + SIZE[NormalHeader]]] ELSE RETURN[LOOPHOLE[hp + SIZE[ExtendedHeader]]]; }; FreeObject: PROC[nhp: NHeaderP]; TAndSFreeObject: PROC[nhp: NHeaderP]; ExpandNormalFreeList: PROC[bsi: BlockSizeIndex]; Initialize: PROC; -- initializes the safe allocator. Reset: PROC; -- called by the TAndS. <> EnterAndCallBack: PROC[proc: PROC]; IsValidRef: PROC[p: LONG POINTER] RETURNS[BOOL]; -- NIL => TRUE <<>> <> <<>> <> <> DoCreateMediumSizedObject: PROC [size: NAT, type: SafeStorage.Type, roverP: LONG POINTER TO--VAR-- Rover, counted: BOOL] RETURNS[p: LONG POINTER _ NIL]; DoFreeMediumSizedObject: PROC[ptr: DFHeaderP, rover: Rover]; <<>> <> <> CreateMediumSizedHeapObject: PROC [size: NAT] RETURNS[p: LONG POINTER _ NIL]; FreeMediumSizedHeapObject: PROC [ptr: DFHeaderP]; END.