-- RTZonesImpl.Mesa -- last edited 2-Sep-81 11:14:40 by Willie-Sue Haugeland -- last edited July 7, 1983 10:24 am by Paul Rovner -- Last Edited by: Levin, August 8, 1983 5:45 pm DIRECTORY PrincOps USING [StateVector, SD], PrincOpsUtils USING [MyLocalFrame], RTCommon USING[RepAddrPtr], RTFlags USING[checking, useMicrocode], RTMicrocode USING [GETCANONICALREFERENTTYPE], RTQuanta USING[QuantumSizeDIV, QuantumSizeMULT, LASTAddress, QuantumIndex, PtrToQtmIndex, QuantumSize, QuantumCount, PagesPerQuantum], RTRefCounts USING [StuffMapZiZn, StuffMapQZf, GCMicrocodeExists, ReclaimForQuanta], RTSD USING[sSystemZone], RTTypesBasicPrivate USING[], -- exports only Runs USING[Run, AddInterval, DeleteInterval, RunValue, MapIntervals], SafeStorage USING[Type, GetCanonicalType, nullType, NarrowRefFault], SafeStoragePrivate USING[PermanentPageZone, NotifyAllocatorReady, GetCollectibleQuanta, InsufficientVM], TrapSupport USING[BumpPC], UnsafeStorage USING[UZoneFullProc], UZoneTracker USING[Register, UnRegister], RTZones USING[PZone, ZoneRec, PPrefixedZone, TMapQZf, TMapZiZn, ZoneFullProc, NewPrefixedObject, FreePrefixedObject, NewPrefixedHeapObject, FreePrefixedHeapObject, maxSizeToZnIndex, SetZiNext, RMapQZf, PMapZiZn, nZiMaxInit, PrefixedZone, RMapZiZn, Zone, ZoneLinkage, mzVacant, useSizeToZn, QuantizedSize, ZoneIndex, AllocateZi, ZoneFinger, MapPtrZf, sizeNd, PNode, InusePNode, MapSizeNq, BaseOverhead, AddBlock, PFreeNode, NodeLength], SSTraps USING[], VM USING[Free]; RTZonesImpl: MONITOR -- protects zones LOCKS zn.LOCK USING zn: PZone IMPORTS PrincOpsUtils, RTCommon, RTMicrocode, RTQuanta, RTRefCounts, RTZones, Runs, SafeStorage, SafeStoragePrivate, TrapSupport, UZoneTracker, VM EXPORTS RTTypesBasicPrivate, RTZones, SafeStorage, SafeStoragePrivate, SSTraps, UnsafeStorage = BEGIN OPEN RTQuanta, RTZones, SafeStorage, SafeStoragePrivate, UnsafeStorage; -- Constants checking: BOOLEAN = RTFlags.checking; -- Signals InvalidRef: PUBLIC ERROR[ref: REF ANY] = CODE; InvalidCreateZone: PUBLIC ERROR = CODE; InvalidPointer: PUBLIC ERROR[ptr: LONG POINTER] = CODE; ReferentOnFreeList: SIGNAL[ptr: LONG POINTER] = CODE; -- System (built-in) Zones ((used only until the sun comes up)) rZnSystem: prefixed ZoneRec _ [ new: LOOPHOLE[NewPrefixedObject, UNSPECIFIED], free: LOOPHOLE[FreePrefixedObject, UNSPECIFIED], zi: 1, linkage: [collectible[fullProc: ExtendZone]], -- beware of RC activity and odd REFs. See the START code. freeLists: prefixed[], LOCK: ]; znSystem: PPrefixedZone = @rZnSystem; rZnHeapSystem: prefixed ZoneRec _ [ new: LOOPHOLE[NewPrefixedHeapObject, UNSPECIFIED], free: LOOPHOLE[FreePrefixedHeapObject, UNSPECIFIED], zi: 2, linkage: [heap[fullProc: ExtendUZone]], freeLists: prefixed[], LOCK: ]; znHeapSystem: PPrefixedZone _ @rZnHeapSystem; -- Exported variables -- NOTE These variables hold eternal refs to the built-in zones zoneSystem: PUBLIC ZONE; zoneHeapSystem: PUBLIC UNCOUNTED ZONE; permanentZone: ZONE; mediumSizedZone: PUBLIC ZONE; MapQZf: PUBLIC TMapQZf; -- MapQZf has an entry for each allocated quantum, for both counted and uncounted zones MapZiZn: PUBLIC TMapZiZn _ NIL; -- MapZiZn has an entry for each counted zone (but not for uncounted zones) -- Other global variables defaultZoneFullProc: ZoneFullProc _ ExtendZone; defaultUZoneFullProc: UZoneFullProc _ ExtendUZone; useCanonicalTypeMicroCode: PUBLIC BOOLEAN _ RTFlags.useMicrocode; SizeToZn: PUBLIC REF ARRAY [0..maxSizeToZnIndex] OF ZONE _ NIL; -- XXX MemoryExhausted: PUBLIC ERROR = CODE; GetQuanta: PUBLIC PROC[nQ: QuantumCount] RETURNS[q: QuantumIndex, firstQuantum: BOOLEAN] = { DO { q _ GetQuantaFromOS[nQ ! MemoryExhausted => GOTO failed]; EXIT; EXITS failed => { IF RTRefCounts.ReclaimForQuanta[] # 0 THEN LOOP; -- will call TrimAllZones q _ GetQuantaFromOS[nQ] -- give up entirely if this fails } }; ENDLOOP; firstQuantum _ (q = 0); }; PutQuanta: PUBLIC PROC[q: QuantumIndex, nQ: QuantumCount] = { VM.Free[[page: q * PagesPerQuantum, count: nQ * PagesPerQuantum]]; }; GetQuantaFromOS: PROC[nQ: QuantumCount] RETURNS[q: QuantumIndex] = { RETURN [GetCollectibleQuanta [nQ, nQ ! InsufficientVM => GOTO noVM ].qi ]; EXITS noVM => ERROR MemoryExhausted; }; -- Access to built-in Zones GetHeapSystemZone: PUBLIC PROC RETURNS[UNCOUNTED ZONE] = {RETURN[zoneHeapSystem]}; GetSystemZone: PUBLIC SAFE PROC RETURNS[ZONE] = TRUSTED {RETURN[zoneSystem]}; GetPermanentZone: PUBLIC SAFE PROC RETURNS[ZONE] = TRUSTED {RETURN[permanentZone]}; GetSystemUZone: PUBLIC PROC RETURNS[UNCOUNTED ZONE] = {RETURN[zoneHeapSystem]}; NewZone: PROC[ initialSize: LONG CARDINAL --words-- _ 0] RETURNS[zone: ZONE] = TRUSTED BEGIN zi: ZoneIndex; IF SizeToZn # NIL THEN RETURN[GetSystemZone[]]; zi _ AllocateZi[]; {pzn: PrefixedZone = zoneSystem.NEW[prefixed ZoneRec _ [ new: LOOPHOLE[NewPrefixedObject, UNSPECIFIED], free: LOOPHOLE[FreePrefixedObject, UNSPECIFIED], linkage: [collectible[fullProc: defaultZoneFullProc]], zi: zi, freeLists: prefixed[], LOCK: ]]; InitPrefixedZone[LOOPHOLE[pzn, PPrefixedZone]]; zone _ LOOPHOLE[pzn]; MapZiZn[zi] _ LOOPHOLE[zone, Zone]; -- RTRefCounts.StuffZi[zi, zone]; the package ref }; ExtendZone[zone, initialSize]; END; NewUZone: PUBLIC PROC [ initialSize: LONG CARDINAL --words-- _ 0] RETURNS[UNCOUNTED ZONE] = BEGIN ans: UNCOUNTED ZONE; zi: ZoneIndex = AllocateZi[]; prz: PZone; { pzn: PPrefixedZone = zoneHeapSystem.NEW[prefixed ZoneRec _ [ new: LOOPHOLE[NewPrefixedHeapObject, UNSPECIFIED], free: LOOPHOLE[FreePrefixedHeapObject, UNSPECIFIED], linkage: [heap[fullProc: defaultUZoneFullProc]], zi: zi, freeLists: prefixed[], LOCK: ]]; InitPrefixedZone[pzn]; prz _ pzn; }; ans _ LOOPHOLE[zoneHeapSystem.NEW[PZone _ prz], UNCOUNTED ZONE]; ExtendUZone[ans, initialSize]; UZoneTracker.Register[ans]; RETURN[ans]; END; FreeUZone: PUBLIC PROC[uz: UNCOUNTED ZONE] = { p: LONG POINTER TO PZone _ LOOPHOLE[uz]; prz: PZone _ p^; UZoneTracker.UnRegister[uz]; FinalizeZone[prz]; zoneHeapSystem.FREE[@prz]; zoneHeapSystem.FREE[@p]}; GetCanonicalReferentTypeTrap: PUBLIC PROC[ref: REF ANY] RETURNS[type: Type] = { state: PrincOps.StateVector; kludge: LONG CARDINAL; state _ STATE; -- incantation kludge_ 0; type_ GetCanonicalType[InternalReferentType[LOOPHOLE[ref]]]; TrapSupport.BumpPC[2]; state.dest _ LOOPHOLE[PrincOpsUtils.MyLocalFrame[]]; TRANSFER WITH state -- incantation }; GetCanonicalReferentTypeSDTrap: PUBLIC PROC[ref: REF ANY] RETURNS[type: Type] = {RETURN[GetCanonicalType[InternalReferentType[LOOPHOLE[ref]]]]}; InternalReferentType: PROC[ptr: LONG POINTER] RETURNS[type: Type] = BEGIN mz: ZoneFinger; IF ptr = NIL THEN RETURN[nullType]; mz _ MapPtrZf[ptr]; WITH mz: mz SELECT FROM prefixed => { IF checking THEN { zn: Zone = MapZiZn[mz.zi]; IF mz.zi = 0 OR ((zn # NIL) AND (zn.sr # prefixed)) THEN ERROR ELSE IF LOOPHOLE[(ptr - sizeNd), PNode].state = free THEN ERROR ReferentOnFreeList[ptr]; }; RETURN[LOOPHOLE[LOOPHOLE[(ptr-sizeNd), InusePNode].type, Type]]; }; sub => ERROR; ENDCASE => ERROR; END; IsReferentType: PUBLIC SAFE PROC[ref: REF ANY, type: Type] RETURNS[BOOLEAN] = TRUSTED {RETURN[GetCanonicalType[type] = GetCanonicalReferentType[ref]]}; NarrowRef: PUBLIC SAFE PROC[ref: REF ANY, type: Type] RETURNS[REF ANY] = TRUSTED {IF ref = NIL THEN RETURN[NIL] ELSE IF GetCanonicalType[type] = GetCanonicalReferentType[ref] THEN RETURN[ref] ELSE ERROR NarrowRefFault[ref, type]}; GetCanonicalReferentType: PUBLIC SAFE PROC[ref: REF ANY] RETURNS[type: Type] = TRUSTED { IF useCanonicalTypeMicroCode THEN RETURN[RTMicrocode.GETCANONICALREFERENTTYPE[ref]] ELSE RETURN[GetCanonicalType[DoGetHeapReferentType[LOOPHOLE[ref]]]]}; GetReferentType: PUBLIC SAFE PROC[ref: REF ANY] RETURNS[type: Type] = TRUSTED { RETURN[DoGetHeapReferentType[LOOPHOLE[ref]]]}; GetHeapReferentType: PUBLIC PROC[ptr: LONG POINTER] RETURNS[type: Type] = { RETURN[DoGetHeapReferentType[ptr]]}; DoGetHeapReferentType: PROC[ptr: LONG POINTER] RETURNS[type: Type] = INLINE BEGIN mz: ZoneFinger; IF useCanonicalTypeMicroCode THEN RETURN[RTMicrocode.GETCANONICALREFERENTTYPE[LOOPHOLE[ptr]]]; IF ptr = NIL THEN RETURN[nullType]; mz _ MapPtrZf[ptr]; WITH mz: mz SELECT FROM prefixed => { IF checking THEN { zn: Zone = MapZiZn[mz.zi]; IF mz.zi = 0 OR ((zn # NIL) AND (zn.sr # prefixed)) THEN ERROR ELSE IF LOOPHOLE[(ptr - sizeNd), PNode].state = free THEN ERROR ReferentOnFreeList[ptr]; }; RETURN[LOOPHOLE[LOOPHOLE[(ptr-sizeNd), InusePNode].type, Type]]}; sub => ERROR; ENDCASE => ERROR; END; SetZoneFullProc: PUBLIC SAFE PROC[zone: ZONE, proc: ZoneFullProc] RETURNS[oldProc: ZoneFullProc] = TRUSTED {RETURN[DoSetZoneFullProc[LOOPHOLE[zone], proc]]}; DoSetZoneFullProc: ENTRY PROC[zn: PZone, proc: ZoneFullProc] RETURNS[oldProc: ZoneFullProc] = {ENABLE UNWIND => NULL; WITH zl: zn.linkage SELECT FROM collectible => {oldProc _ zl.fullProc; zl.fullProc _ proc}; ENDCASE => ERROR}; ExtendZone: PUBLIC ZoneFullProc = TRUSTED { nQ: QuantumCount = MapSizeNq[size]; zn: Zone = LOOPHOLE[zone]; qNew: QuantumIndex; firstQuantum: BOOLEAN; [qNew, firstQuantum] _ GetQuanta[nQ]; ExtendZoneWithQuanta[LOOPHOLE[zn], qNew, nQ, firstQuantum]}; SetUZoneFullProc: PUBLIC PROC[zone: UNCOUNTED ZONE, proc: UZoneFullProc] RETURNS[oldProc: UZoneFullProc] = {RETURN[DoSetUZoneFullProc[LOOPHOLE[zone, LONG POINTER TO PZone]^, proc]]}; DoSetUZoneFullProc: ENTRY PROC[zn: PZone, proc: UZoneFullProc] RETURNS[oldProc: UZoneFullProc] = {ENABLE UNWIND => NULL; WITH zl: zn.linkage SELECT FROM heap => {oldProc _ zl.fullProc; zl.fullProc _ proc}; ENDCASE => ERROR}; ExtendUZone: PUBLIC UZoneFullProc = { nQ: QuantumCount = MapSizeNq[size]; zn: PZone = LOOPHOLE[zone, LONG POINTER TO PZone]^; qNew: QuantumIndex; firstQuantum: BOOLEAN; [qNew, firstQuantum] _ GetQuanta[nQ]; ExtendZoneWithQuanta[zn, qNew, nQ, firstQuantum]}; ExtendZoneWithQuanta: ENTRY PROC [zn: PZone, qNew: QuantumIndex, nQ: QuantumCount, firstQuantum: BOOLEAN] = BEGIN ENABLE UNWIND => NULL; IF firstQuantum THEN zn.qFirst _ qNew; WITH zn: zn SELECT FROM quantized => ERROR; prefixed => { overhead: CARDINAL = IF firstQuantum THEN BaseOverhead ELSE 0; FOR q: QuantumIndex IN [qNew..qNew + nQ) DO MapQZf[q] _ [prefixed[zn.zi]]; ENDLOOP; AddBlock[RTCommon.RepAddrPtr[QuantumSizeMULT[qNew] + overhead], QuantumSizeMULT[nQ] - overhead, zn.pfn --@zn.fnd--]}; ENDCASE => ERROR; Runs.AddInterval[@zn.runs, qNew, nQ]; END; -- Exported procedures (within GC only) -- prefixedly an INTERNAL proccedure ReturnQuanta: PUBLIC PROC[pzn: PZone, q: QuantumIndex, nQ: QuantumCount] = { FOR i: QuantumIndex IN [q..q + nQ) DO MapQZf[i] _ mzVacant; ENDLOOP; Runs.DeleteInterval[@pzn.runs, q, nQ]; IF pzn.qFirst IN [q..CARDINAL[q + nQ]) THEN pzn.qFirst _ 0; WITH zl: pzn.linkage SELECT FROM collectible => PutQuanta[q, nQ]; heap => PutQuanta[q, nQ] ENDCASE => ERROR}; -- PRIVATE procedures InitPrefixedZone: PROC[zn: PPrefixedZone] = {zn.fnd.pfnNext _ zn.fnd.pfnPrev _ zn.pfn _ @zn.fnd}; ZoneResidueWords: PROC[zn: PZone] RETURNS[nWords: LONG CARDINAL _ 0] = { IF zn.qFirst # 0 THEN nWords _ BaseOverhead; WITH zn: zn SELECT FROM quantized => ERROR; ENDCASE; RETURN[nWords]}; ZoneFreeWords: PROC[zn: PZone] RETURNS[LONG CARDINAL] = { nWords: LONG CARDINAL _ 0; WITH zn: zn SELECT FROM quantized => ERROR; prefixed => { pfn: PFreeNode _ zn.pfn; DO nWords _ nWords + NodeLength[pfn]; IF (pfn _ pfn.pfnNext) = zn.pfn THEN EXIT; ENDLOOP}; ENDCASE => ERROR; RETURN[nWords]}; ZoneFreeQuanta: PROC[zn: PZone] RETURNS[nQuanta: LONG CARDINAL] = {RETURN[WITH zn: zn SELECT FROM quantized => zn.qLast - zn.qNext, prefixed => 0, ENDCASE => ERROR]}; ZoneFreeObjects: PROC[zn: PZone] RETURNS[nObjects: LONG CARDINAL] = { nObjects _ 0; WITH zn: zn SELECT FROM quantized => ERROR; prefixed => { pfn: PFreeNode _ zn.pfn; DO nObjects _ nObjects + 1; IF (pfn _ pfn.pfnNext) = zn.pfn THEN EXIT; ENDLOOP}; ENDCASE => ERROR; RETURN[nObjects]}; -- NOTE this is not an ENTRY proc!! It is meant to be called while debugging. -- cellsInService includes overhead cells and 1 word for the type code in prefix objects -- overheadCells is applicable for prefixed zones, residueCells for quantized zones -- overheadCells is one word for small objects, 2 for big ones and does not include 1 word for -- the type code in prefix objects SummarizeZone: PUBLIC PROC[zn: PZone] RETURNS[nQuanta, freeQuanta, objectsInService, overheadCells, freeObjects, cellsInService, freeCells, residueCells: LONG CARDINAL] = { CountQuanta: PROC[iFrom, n: Runs.RunValue] ={ nQuanta _ nQuanta + n}; nQuanta _ 0; Runs.MapIntervals[@zn.runs, CountQuanta]; freeQuanta _ ZoneFreeQuanta[zn]; objectsInService _ zn.objectsInService; overheadCells _ zn.overheadCells; freeObjects _ ZoneFreeObjects[zn]; cellsInService _ zn.cellsInService; freeCells _ ZoneFreeWords[zn]; residueCells _ ZoneResidueWords[zn]}; IsZoneEmpty: PUBLIC SAFE PROC[zone: ZONE] RETURNS[BOOLEAN] = TRUSTED {RETURN[DoIsZoneEmpty[LOOPHOLE[zone]]]}; DoIsZoneEmpty: ENTRY PROC[zn: PZone] RETURNS[BOOLEAN] = BEGIN ENABLE UNWIND => NULL; nq: CARDINAL _ 0; CountQuanta: PROC[iFrom, n: Runs.RunValue] = {nq _ nq + n}; Runs.MapIntervals[@zn.runs, CountQuanta]; RETURN[(ZoneFreeWords[zn] + ZoneResidueWords[zn]) = QuantumSizeMULT[nq]]; END; IsUZoneEmpty: PUBLIC PROC[zone: UNCOUNTED ZONE] RETURNS[BOOLEAN] = {RETURN[DoIsZoneEmpty[LOOPHOLE[zone, LONG POINTER TO PZone]^]]}; -- ZoneFinalizerProcess: PROC[zfq: FinalizationQueue] = -- { DO -- zone: ZONE = LOOPHOLE[FQNext[zfq]]; -- TrimZone[zone]; -- IF IsZoneEmpty[zone] THEN FinalizeZone[LOOPHOLE[zone, PZone]]; -- ENDLOOP}; FinalizeZone: ENTRY PROC[zn: PZone] = BEGIN ENABLE UNWIND => NULL; FreeQRun: PROC[iFrom, n: CARDINAL] = {ReturnQuanta[zn, iFrom, n]}; Runs.MapIntervals[@zn.runs, FreeQRun]; MapZiZn[zn.zi] _ NIL; END; Pair: TYPE = MACHINE DEPENDENT RECORD [low, high: CARDINAL]; MaxBank: CARDINAL = LASTAddress/(LONG[LAST[CARDINAL]] + 1); --63 ValidateRef: PUBLIC PROC [ref: REF ANY] = { -- returns happily if the pointer refers to the start of an object -- A ref to someplace in a quantized zone points at the start of -- an object if the ref has the correct modulus with respect to -- the size of the objects in the appropriate sub-zone. This must -- be adjusted for BaseOverhead if the quantum is the one indicated -- by zone.qFirst. -- for a prefixed zone, gotta scan the run that contains the referenced object. IF ref = NIL THEN RETURN; -- NIL is OK IF (LOOPHOLE[ref, LONG CARDINAL] MOD 2 = 1) OR (LOOPHOLE[ref, Pair].high > MaxBank) THEN ERROR InvalidRef[ref]; {qx: QuantumIndex = PtrToQtmIndex[LOOPHOLE[ref, LONG POINTER]]; mz: ZoneFinger = MapQZf[qx]; IF mz = mzVacant THEN ERROR InvalidRef[ref]; -- not even in the quantum map WITH mz: mz SELECT FROM sub => ERROR; prefixed => ValidatePrefixedRef[zn: LOOPHOLE[MapZiZn[mz.zi], PZone], ref: ref]; ENDCASE => ERROR}}; ValidatePrefixedRef: ENTRY PROC [zn: PZone, ref: REF ANY] = { ENABLE UNWIND => NULL; ptr: LONG POINTER = LOOPHOLE[ref]; WITH z: zn SELECT FROM prefixed => {-- look at all of the objects, both allocated and freed FOR r: Runs.Run _ z.runs, r.rnNext UNTIL r = NIL DO lim: PNode = LOOPHOLE[LONG[r.iTo] * QuantumSize]; -- iTo not included pNode: PNode _ LOOPHOLE[LONG[r.iFrom] * QuantumSize]; IF LOOPHOLE[ptr, LONG CARDINAL] >= LOOPHOLE[pNode, LONG CARDINAL] AND LOOPHOLE[ptr, LONG CARDINAL] < LOOPHOLE[lim, LONG CARDINAL] THEN -- this is the run in which we should find the ref {WHILE pNode # lim DO -- look at each object in the run size: LONG CARDINAL = NodeLength[pNode]; IF pNode.state # free AND ptr = pNode + sizeNd THEN RETURN; pNode _ pNode + size; IF LOOPHOLE[ptr, LONG CARDINAL] < LOOPHOLE[pNode, LONG CARDINAL] THEN ERROR InvalidRef[ref]; ENDLOOP; ERROR}; ENDLOOP; ERROR InvalidRef[ref]}; ENDCASE => ERROR}; -- MODULE INITIALIZATION ... this is extremely delicate SetZiNext[3]; -- 0: zoneVacant, 1: zoneSystem, 2: zoneHeapSystem, BEGIN nQ: CARDINAL = LAST[QuantumIndex] - FIRST[QuantumIndex] + 1; MapQZf _ LOOPHOLE[PermanentPageZone.NEW[RMapQZf[nQ]]]; FOR i: CARDINAL IN [0..nQ) DO MapQZf[i] _ mzVacant ENDLOOP; RTRefCounts.StuffMapQZf[MapQZf]; END; useCanonicalTypeMicroCode _ useCanonicalTypeMicroCode AND RTRefCounts.GCMicrocodeExists; InitPrefixedZone[LOOPHOLE[znSystem, PPrefixedZone]]; InitPrefixedZone[LOOPHOLE[znHeapSystem, PPrefixedZone]]; -- ******Until the sun comes up******* LOOPHOLE[zoneSystem, LONG POINTER] _ znSystem; LOOPHOLE[zoneHeapSystem, LONG POINTER] _ @znHeapSystem; LOOPHOLE[MapZiZn, LONG POINTER] _ PermanentPageZone.NEW[PMapZiZn[nZiMaxInit] _ [zones: NULL]]; FOR i: CARDINAL IN [0..nZiMaxInit) DO LOOPHOLE[MapZiZn, LONG POINTER TO PMapZiZn][i] _ 0 ENDLOOP; LOOPHOLE[MapZiZn[rZnSystem.zi], LONG POINTER] _ znSystem; RTRefCounts.StuffMapZiZn[LOOPHOLE[MapZiZn, LONG POINTER TO PMapZiZn]]; -- ******Until the sun comes up******* LOOPHOLE[@PrincOps.SD[RTSD.sSystemZone], POINTER TO LONG POINTER]^ _ LOOPHOLE[zoneSystem, LONG POINTER]; NotifyAllocatorReady[]; -- the allocator is now useable { oldZs: PrefixedZone = LOOPHOLE[zoneSystem]; zs: PrefixedZone = NEW[prefixed ZoneRec _ [ new: oldZs.new, free: oldZs.free, zi: oldZs.zi, linkage: [collectible[fullProc: ExtendZone]], qFirst: oldZs.qFirst, runs: oldZs.runs, cellsInService: oldZs.cellsInService, objectsInService: oldZs.objectsInService, overheadCells: oldZs.overheadCells, freeLists: prefixed[], LOCK: ] ]; InitPrefixedZone[LOOPHOLE[zs, PPrefixedZone]]; IF oldZs.fnd.pfnNext # @oldZs.fnd THEN { zs.fnd.pfnNext _ oldZs.fnd.pfnNext; oldZs.fnd.pfnNext.pfnPrev _ @zs.fnd; zs.fnd.pfnPrev _ oldZs.fnd.pfnPrev; oldZs.fnd.pfnPrev.pfnNext _ @zs.fnd }; LOOPHOLE[zoneSystem, LONG POINTER] _ NIL; zoneSystem _ LOOPHOLE[zs]; -- NOTE stuff this in the SD!! LOOPHOLE[@PrincOps.SD[RTSD.sSystemZone], POINTER TO LONG POINTER]^ _ LOOPHOLE[zoneSystem, LONG POINTER]; }; { mzizn: TMapZiZn = NEW[RMapZiZn[nZiMaxInit] _ [zones: NULL]]; p: LONG POINTER _ LOOPHOLE[MapZiZn]; FOR i: CARDINAL IN [0..nZiMaxInit) DO LOOPHOLE[mzizn, LONG POINTER TO PMapZiZn][i] _ 0 ENDLOOP; LOOPHOLE[MapZiZn, LONG POINTER] _ NIL; MapZiZn _ mzizn; MapZiZn[LOOPHOLE[zoneSystem, Zone].zi] _ LOOPHOLE[zoneSystem, Zone]; -- FreeableSpaceZone.FREE[@p]; RTRefCounts.StuffMapZiZn[LOOPHOLE[MapZiZn, LONG POINTER TO PMapZiZn]]; }; IF useSizeToZn THEN {stz: REF ARRAY [0..maxSizeToZnIndex] OF ZONE = NEW[ARRAY [0..maxSizeToZnIndex] OF ZONE _ ALL[NIL]]; FOR i: [0..maxSizeToZnIndex/2] IN [0..maxSizeToZnIndex/2] DO IF stz[QuantizedSize[i*2]] = NIL THEN stz[QuantizedSize[i*2]] _ NewZone[]; ENDLOOP; mediumSizedZone _ NewZone[initialSize: 100000B]; permanentZone _ NewZone[initialSize: 40000B]; SizeToZn _ stz; -- subsequent calls on the prefixed allocator for any ZONE will use this stuff }; END. Κ ™– "Mesa" style˜Iprocš΄Οcœ2Οk œ žœžœžœžœžœ(žœžœžœžžœEžœžœ%žœœžœJžœIžœpœžœžœ žœ"žœ±žœ žœžœœžœžœžœ žœ›žœgžœžœE œ žœ œžœžœžœžœžœžœžœžœžœžœžœžœžœ@œ0žœž œžœž œ\;œ!žœažœž œžœž œgžœ7œ@œžœžœžœž œžœžœžœžœ žœXœ žœ žœLœœ…žœžœ&žœžœžœžœžœžœœžœžœžœ˜Σ˜šΟn œžœžœ˜(šžœ žœ˜3šžœ˜Jšœ,žœ ˜9Jšžœ˜šžœ ˜Jšžœ$žœžœ˜KJšœ!˜9Jšœ˜—Jšœ˜—Jšžœ˜Jšœ˜Jšœ˜———˜šŸ œžœžœ'˜=Jšžœ@˜BJšœ˜—J˜šŸœžœ˜'šžœ˜šž˜šœ˜šœ˜Jšœžœ˜—Jšœ˜—Jšœ˜—Jšžœ žœ˜$Jšœ˜———J˜Jšθ œœŸœžœžœžœž œžœžœŸ œžœžœžœžœžœžœžœŸœžœžœžœžœžœžœžœŸœžœžœžœž œžœžœŸœžœžœžœ œžœžœžœžœžœ žœžœžœ`žœ0žœž œ žœž œ‡žœžœ&žœžœ2œ2žœŸœžœžœžœžœ œžœž œžœžœ ž œžœvžœ0žœž œ žœž œžœYžœžœž œžœPžœ žœŸ œžœžœž œžœ žœžœžœ žœnžœžœ Ÿœžœžœžœžœžœ@žœžœžœœCžœ9žœ&žœžœ œ Ÿœžœžœžœžœžœžœ'žœŸœžœžœžœžœžœžœžœžœžœ,žœžœžœ&žœ žœDžœ žœžœžœ(žœžœžœžœžœ8žœžœBžœžœžœJžœ žœžœžœŸœžœžœžœžœžœžœžœžœžœ>Ÿ œžœžœžœžœžœžœžœžœžœžœžœžœžœžœžœžœDžœžœžœžœ Ÿœžœžœžœžœžœžœžœžœžœžœ žœžœžœ(žœŸœžœžœžœžœžœžœžœžœžœ Ÿœžœžœžœžœ"Ÿœžœžœžœžœžœ#žœžœ žœžœžœžœžœžœ,žœžœžœ'žœ žœDžœ žœžœžœ*žœžœžœžœžœ:žœžœCžœžœžœGžœžœžœŸœžœžœžœžœžœžœžœžœŸœžœžœ žœžœžœžœžœžœžœJžœžœžœžœ8žœ6žœIžœ#Ÿœžœžœž œžœžœ žœžœžœžœžœŸœžœžœ!žœ žœžœžœžœžœžœCžœžœžœMžœžœžœžœ8žœjŸœžœžœIžœžœžœžœžœžœžœžœžœžœGžœžœžœžœžœžœžœ žœ‘ œ žœžœ2žœ(œ%œŸ œžœžœ8žœžœ žœžœ5žœ žœžœ žœžœžœžœRžœžœœŸœžœOŸœžœ žœ žœžœžœžœžœžœžœžœ žœžœŸ œžœ žœžœžœžœžœ žœžœžœbžœBžœžœžœžœ žœžœžœŸœžœ žœ žœžœ žœžœžœžœ[žœžœŸœžœ žœ žœžœžœžœžœbžœ8žœžœžœžœ žœžœžœNœYœTœ_œ#œŸ œžœžœžœ{žœžœ Ÿ œžœŸ œžœžœžœžœžœžœžœžœžœŸ œžœžœ žœžœžœžœžœžœ žœ Ÿ œžœbžœHžœŸ œžœžœž œžœžœžœ žœžœžœžœžœθœŸ œžœžœžœžœžœžœŸœžœ žœožœžœ žœžœž œžœ žœžœžœžœžœ Ÿ œžœžœžœžœ Cœ Aœ@œCœDœœ Pœ žœžœžœžœ œ žœžœžœžœžœžœžœ!žœžœ9žœžœžœ-žœžœžœœžœžœžœBžœ+žœžœŸœžœžœžœžœžœžœžœ žœžœžœ žœžœžœ8œžœ žœžœžœžœžœœžœžœ&žœžœžœžœžœžœžœžœžœžœžœžœžœžœžœ3œžœ žœ"œžœžœ)žœžœžœžœ<žœžœžœžœžœžœžœžœžœ#žœžœžœ žœžœžœ 9œ6œžœ žœžœžœ!žœžœžœžœžœ žœžœ)žœ:žœ4žœ/žœ!'œžœ)žœ3žœ,žœ žœžœžœžœžœžœ žœžœžœžœžœMžœ žœžœžœ 'œžœ žœžœžœžœžœžœ žœ žœžœ œžœ4žœ–žœ.žœžœ žœΐžœžœžœœžœ žœžœžœžœžœžœ žœ žœžœžœ žœ žœžœžœžœžœžœžœžœžœžœžœžœžœžœ#žœžœ,žœ#žœ žœžœžœžœ žœ žœžœžœžœžœžœžœžœžœžœžœžœžœžœžœ žœ*žœ5œ0œOœžœ˜Ά…—…—T0aΟ