<> <> <> DIRECTORY Allocator USING[bsiEscape, ExtendedHeader, HeaderP, LastAddress, NHeaderP, NormalHeader, QuantumMap, QuantumIndex, wordsPerQuantum, BSIToSizeObj, SizeToBSIObj, BlockSizeIndex], Basics USING[BITAND, 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[ lc> SIZE[NormalHeader] AND Basics.BITAND[Basics.LowHalf[lc], 1] = 0 AND lc < LastAddress AND quantumMap[AddressToQuantumIndex[lc]] ]; }; AddressToQuantumIndex: PROC[addr: LONG CARDINAL] RETURNS[QuantumIndex] = INLINE{IF addr > LastAddress THEN ERROR ELSE RETURN[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.