mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-26 01:49:19 +00:00
555 lines
17 KiB
C
555 lines
17 KiB
C
/*
|
|
File: MemoryMgr32Patches.c
|
|
|
|
Contains: Process Mgr heap routines that manipulate data blocks according to the
|
|
32-bit memory manager structures. MemoryMgr24Patches.c and
|
|
MemoryMgr32Patches.c are virtually identical in source code. The header
|
|
files each uses, though, determines the how the block header access
|
|
macros are expanded. This (hopefully) makes it easier to maintain given
|
|
the 24/32 duality imposed on us.
|
|
|
|
Written by: David Harrison
|
|
|
|
Copyright: © 1989-1992 by Apple Computer, Inc., all rights reserved.
|
|
|
|
Change History (most recent first):
|
|
|
|
<12> 6/22/92 DTY #1033275 <csd>: Remove last change. The quad alignment is now
|
|
done in MemoryMgrPatches.c.
|
|
<11> 6/12/92 pvh #1032359: Added quad word alignment code in ChipFromFreeBlock
|
|
function so that we are properly aligned with the rest of the
|
|
Memory manager on 68040 Macs.
|
|
<10> 11/22/91 DTY Fix terminating condition in GetProcessMgrHiMaxBlock32. It
|
|
should stop at ProcessMgrHeap->bkLim instead of SYSZONE->bkLim.
|
|
<9> 10/28/91 SAM/KSM Rolled in Regatta change:
|
|
(RMP) Fixed MoveHeap bug where slop wasn't taken into account when
|
|
calculating zcbFree.
|
|
<8> 5/23/91 dba do a style of coercion that MPW 3.2 C likes
|
|
<7> 4/9/91 DFH VL, #83672 : Added GetProcessMgrHiMaxBlock.
|
|
<6> 3/15/91 DFH sad,WS#DFH-910315a: Fixed GetProcessMgrLoFreeBytes to not
|
|
dereference sawInterestingBlock parameter if handleOfInterest is
|
|
nil.
|
|
<5> 3/4/91 DFH JWM,WS#DFH-910226b: Fixed GetSystemHiFreeBytes loop termination.
|
|
Was counting the zone trailer.
|
|
<4> 2/21/91 DFH dba,#82504, #82681, #83168, #83182, #83207: TempNewHandle now
|
|
makes sure there is sufficient memory in the system heap even
|
|
when ProcessMgr zone doesn't need to grow.
|
|
<2> 11/21/90 DFH (with BBM) Fixed GZ parameter adjustments to deal correctly with
|
|
boundary conditions. Also, use ROUTINE_ADDR when setting gzProc,
|
|
to bypass jumptable.
|
|
<0> x/xx/89 DFH New Today.
|
|
|
|
*/
|
|
|
|
#include <types.h>
|
|
#include <memory.h>
|
|
#include <menus.h>
|
|
#include <files.h>
|
|
#include <quickdraw.h>
|
|
#include <windows.h>
|
|
#include <osutils.h>
|
|
#include <devices.h>
|
|
#include <retrace.h>
|
|
#include <errors.h>
|
|
|
|
#include "Glue.h"
|
|
#include "Lomem.h"
|
|
#include "Data.h"
|
|
#include "SysMisc.h"
|
|
#include "Zone.h"
|
|
#include "Zone32.h"
|
|
|
|
#pragma segment zone32_tools
|
|
|
|
/* ZoneMPBlockPtr32. Locate the master pointer block for the given zone.
|
|
* Only needed at startup.
|
|
*/
|
|
Ptr
|
|
ZoneMPBlockPtr32(THz pZone)
|
|
{
|
|
return((Ptr)pZone + SIZEOF_ZONE_HEADER + SIZEOF_BLOCK_HEADER);
|
|
}
|
|
|
|
/* MakeNonRelocatable32. Given a pointer to a block's data, convert the block type
|
|
* to "nonrelocatable".
|
|
* Assumes block is from THEZONE.
|
|
*/
|
|
void
|
|
MakeNonRelocatable32(Ptr pBlock)
|
|
{
|
|
register char sizeCorr;
|
|
|
|
pBlock -= SIZEOF_BLOCK_HEADER;
|
|
sizeCorr = SIZE_CORR((HeapBlockPtr)pBlock);
|
|
CLEAR_BLOCK_ATTRS(pBlock);
|
|
TAGBYTE((HeapBlockPtr)pBlock) = nRelTagVal;
|
|
SIZE_CORR((HeapBlockPtr)pBlock) = sizeCorr;
|
|
BLOCK_HANDLE((HeapBlockPtr)pBlock) = (Handle)THEZONE;
|
|
}
|
|
|
|
/* GetProcessMgrLoFreeBytes32. Find out how many free or purgeable bytes there are below
|
|
* the lowest immovable block in the Process Mgr heap. Size returned is physical byte
|
|
* count. As a side benefit, this routine also tells the caller whether the specified
|
|
* handle was encountered in this low range. Finding the block implies that freeing or
|
|
* shrinking it would donate free space area of the Process Mgr heap into which the
|
|
* system heap can grow.
|
|
*/
|
|
u_size
|
|
GetProcessMgrLoFreeBytes32(Handle handleOfInterest, Boolean *sawInterestingBlock)
|
|
{
|
|
HeapBlockPtr heapBlockPtr, blockOfInterest;
|
|
u_size blockSize, loFreeBytes;
|
|
unsigned int blockTags;
|
|
unsigned int blockFlags;
|
|
|
|
/* Convert Handle to physical block address. This works fine even if the handle
|
|
* has been purged (physical address will not be found in the loop), but of course
|
|
* we are never called with a purged handle, anyway.
|
|
*/
|
|
if (handleOfInterest != nil)
|
|
{
|
|
blockOfInterest = (HeapBlockPtr) (*handleOfInterest - SIZEOF_BLOCK_HEADER);
|
|
*sawInterestingBlock = false;
|
|
}
|
|
else
|
|
blockOfInterest = nil;
|
|
|
|
/* Skip dummy block */
|
|
heapBlockPtr = &ProcessMgrZone->heapData;
|
|
(Ptr)heapBlockPtr += BLOCK_SIZE(heapBlockPtr);
|
|
loFreeBytes = 0;
|
|
|
|
/* Walk the heap. Use infinite for loop instead of while loop, since we are guaranteed
|
|
* to find at least one non-relocatable block (e.g. a master pointer block).
|
|
*/
|
|
for (;;)
|
|
{
|
|
blockTags = (unsigned int) TAGBYTE(heapBlockPtr);
|
|
blockSize = BLOCK_SIZE(heapBlockPtr);
|
|
|
|
/* Are we looking at the interesting block? */
|
|
if (heapBlockPtr == blockOfInterest)
|
|
*sawInterestingBlock = true;
|
|
|
|
/* Count this block in if it is free or purgeable. Else, stop walking. */
|
|
if (blockTags == freeTagVal)
|
|
loFreeBytes += blockSize;
|
|
else if (blockTags == relTagVal)
|
|
{
|
|
blockFlags = (unsigned int) MP_TAGBYTE(heapBlockPtr);
|
|
if ((blockFlags & lockedMPTagFlag) != 0)
|
|
break;
|
|
else if ((blockFlags & purgeableMPTagFlag) != 0)
|
|
loFreeBytes += blockSize;
|
|
}
|
|
else
|
|
break;
|
|
|
|
(Ptr)heapBlockPtr += blockSize;
|
|
}
|
|
|
|
return(loFreeBytes);
|
|
}
|
|
|
|
/* GetSystemHiFreeBytes32. Find out how many free or purgeable bytes there are above
|
|
* the highest immovable block in the system heap. Size returned is physical byte count.
|
|
*/
|
|
u_size
|
|
GetSystemHiFreeBytes32(void)
|
|
{
|
|
HeapBlockPtr heapBlockPtr;
|
|
u_size blockSize, hiFreeBytes;
|
|
unsigned int blockTags;
|
|
unsigned int blockFlags;
|
|
|
|
hiFreeBytes = 0;
|
|
|
|
/* Begin at the beginning */
|
|
heapBlockPtr = &SYSZONE->heapData;
|
|
|
|
/* Walk the heap */
|
|
while (heapBlockPtr < SYSZONE->bkLim)
|
|
{
|
|
blockTags = (unsigned int) TAGBYTE(heapBlockPtr);
|
|
blockSize = BLOCK_SIZE(heapBlockPtr);
|
|
|
|
/* Count this block in if it is free or purgeable. Reset the counter if the
|
|
* if the block is non-relocatable, relocatable but locked, or of some unknown
|
|
* new type, since we require memory above all such blocks.
|
|
*/
|
|
if (blockTags == freeTagVal)
|
|
hiFreeBytes += blockSize;
|
|
else if (blockTags == relTagVal)
|
|
{
|
|
blockFlags = (unsigned int) MP_TAGBYTE(heapBlockPtr);
|
|
if ((blockFlags & lockedMPTagFlag) != 0)
|
|
hiFreeBytes = 0;
|
|
else if ((blockFlags & purgeableMPTagFlag) != 0)
|
|
hiFreeBytes += blockSize;
|
|
}
|
|
else
|
|
hiFreeBytes = 0;
|
|
|
|
(Ptr)heapBlockPtr += blockSize;
|
|
}
|
|
|
|
return(hiFreeBytes);
|
|
}
|
|
|
|
/* ExtendZone32. Extend the given zone upwards cbNeeded bytes by changing the
|
|
* trailer block into a free block and creating a new block right after it. This
|
|
* parallels procedure ZoneAdjustEnd() in ROM.
|
|
* NOTE: This must be extended in blocks of at least MIN_PHYSICAL_SIZE, as we need
|
|
* to create a new free block underneath the current trailer block.
|
|
* A5 world needed: None
|
|
*/
|
|
void
|
|
ExtendZone32(THz theZone, u_size cbNeeded)
|
|
{
|
|
HeapBlockPtr oldBkLim,newBkLim;
|
|
|
|
assert(cbNeeded >= MIN_PHYSICAL_SIZE);
|
|
|
|
/* Get current zone trailer block and calc address of the new one */
|
|
(Ptr)oldBkLim = theZone->bkLim;
|
|
(Ptr)newBkLim = (Ptr)oldBkLim + cbNeeded;
|
|
|
|
/* Enlarge the zone trailer to the amount of the extension */
|
|
CLEAR_BLOCK_ATTRS(oldBkLim);
|
|
BLOCK_SIZE(oldBkLim) = cbNeeded;
|
|
TAGBYTE(oldBkLim) = freeTagVal;
|
|
|
|
/* Init the block header of the new zone trailer */
|
|
CLEAR_BLOCK_ATTRS(newBkLim);
|
|
TAGBYTE(newBkLim) = freeTagVal;
|
|
BLOCK_SIZE(newBkLim) = MIN_PHYSICAL_SIZE;
|
|
|
|
/* Adjust zone header to reflect the added free bytes */
|
|
theZone->zcbFree += cbNeeded;
|
|
theZone->bkLim = (Ptr)newBkLim;
|
|
}
|
|
|
|
/* MoveZone32. Move the Process Mgr zone from here to there.
|
|
* Assumes A5 == PROCESSMGRGLOBALS
|
|
*/
|
|
void
|
|
MoveZone32(THz oldZone, THz newZone)
|
|
{
|
|
HeapBlockPtr pBlock, pMaxBlock;
|
|
u_size cbDelta, oldDummyBlockSize;
|
|
Boolean zoneWentUp;
|
|
|
|
/* Update appropriate locations to reflect new location */
|
|
if (THEZONE == oldZone)
|
|
THEZONE = newZone;
|
|
if (APPLZONE == oldZone)
|
|
APPLZONE = newZone;
|
|
pNullProcess->p_zone = ProcessMgrZone = newZone;
|
|
|
|
/* remember size of current dummy ptr (big if shrinking Process Mgr zone) */
|
|
pBlock = &oldZone->heapData;
|
|
oldDummyBlockSize = BLOCK_SIZE(pBlock);
|
|
|
|
/* Invalidate the rover and purgeptr */
|
|
oldZone->purgePtr = nil;
|
|
oldZone->allocPtr = nil;
|
|
|
|
/* Move the zone header */
|
|
BlockMove(oldZone, newZone, SIZEOF_ZONE_HEADER);
|
|
|
|
/* Set up new dummy nonrelocatable block */
|
|
pBlock = &newZone->heapData;
|
|
CLEAR_BLOCK_ATTRS(pBlock);
|
|
BLOCK_SIZE(pBlock) = MIN_PHYSICAL_SIZE;
|
|
BLOCK_HANDLE(pBlock) = (Handle) newZone;
|
|
TAGBYTE(pBlock) = nRelTagVal;
|
|
|
|
/* Need to know sign and magnitude of move */
|
|
zoneWentUp = (newZone > oldZone);
|
|
cbDelta = (zoneWentUp) ? (unsigned long)newZone - (unsigned long)oldZone : (unsigned long)oldZone - (unsigned long)newZone;
|
|
|
|
/* If the zone was lowered, there is room to make a free block above
|
|
* the dummy block. Have to add on extra slop if old size > MIN_PHYSICAL_SIZE.
|
|
* Also, keep the zone free count in sync with this addition.
|
|
*/
|
|
if (zoneWentUp == false)
|
|
{
|
|
(Ptr)pBlock += MIN_PHYSICAL_SIZE;
|
|
BLOCK_SIZE(pBlock) = cbDelta + (oldDummyBlockSize - MIN_PHYSICAL_SIZE);
|
|
CLEAR_BLOCK_ATTRS(pBlock);
|
|
BLOCK_HANDLE(pBlock) = (Handle) nil;
|
|
TAGBYTE(pBlock) = freeTagVal;
|
|
newZone->zcbFree += BLOCK_SIZE(pBlock); /* <1> was += cbDelta */
|
|
}
|
|
|
|
/* Traverse zone to adjust handle field in the block headers */
|
|
(Ptr)pBlock += BLOCK_SIZE(pBlock);
|
|
pMaxBlock = newZone->bkLim;
|
|
while (pBlock < pMaxBlock)
|
|
{
|
|
if (IS_RELOC_BLOCK(pBlock))
|
|
{
|
|
if (zoneWentUp)
|
|
(Ptr)(BLOCK_HANDLE(pBlock)) -= cbDelta;
|
|
else
|
|
(Ptr)(BLOCK_HANDLE(pBlock)) += cbDelta;
|
|
}
|
|
else
|
|
if (IS_NRELOC_BLOCK(pBlock))
|
|
BLOCK_HANDLE(pBlock) = newZone;
|
|
|
|
/* go to next block */
|
|
(Ptr)pBlock += BLOCK_SIZE(pBlock);
|
|
}
|
|
}
|
|
|
|
/* ShrinkProcessMgrZone32. Try to shrink the Process Mgr heap by cbNeeded bytes. Works
|
|
* by growing the dummy block up (with the GZ proc disabled!), then moving the zone
|
|
* header up to the end of it.
|
|
* NOTE: Does not adjust the system zone! When we return to caller, there is a
|
|
* vacuum between the two zones that should caller should fix with ExtendZone.
|
|
*
|
|
* Returns cbActual (where cbActual >= cbNeeded) on success, zero on failure.
|
|
* A5 world needed: PROCESSMGRGLOBALS.
|
|
*/
|
|
unsigned long
|
|
ShrinkProcessMgrZone32(u_size cbNeeded)
|
|
{
|
|
THz origZone;
|
|
HeapBlockPtr dummyHdrPtr;
|
|
Ptr dummyPtr;
|
|
unsigned long sizeToGrow;
|
|
|
|
/* check param */
|
|
assert((cbNeeded != 0) && (WORD_ALIGNED(cbNeeded)));
|
|
|
|
/* Calculate size that dummy block should grow. Allow for overflow. */
|
|
if ((sizeToGrow = cbNeeded + SIZEOF_SMALLEST_PTR_DATUM) < cbNeeded)
|
|
return(0);
|
|
|
|
/* Try to grow the dummy block to desired size, making sure that
|
|
* the ProcessMgrZone GZ proc is temporarily disabled.
|
|
*/
|
|
origZone = ProcessMgrZone;
|
|
dummyHdrPtr = (HeapBlockPtr)(&origZone->heapData);
|
|
dummyPtr = (Ptr)dummyHdrPtr + SIZEOF_BLOCK_HEADER;
|
|
origZone->gzProc = nil;
|
|
SetPtrSize(dummyPtr, sizeToGrow);
|
|
origZone->gzProc = ROUTINE_ADDR(ProcessMgr_GZProc_Glue);
|
|
|
|
/* Not enough memory ... oh well! */
|
|
if (MEMERROR != noErr)
|
|
return(0);
|
|
|
|
/* Find out how much we actually were given (could be more if filling a large
|
|
* free block), then subtract overhead, to determine the true offset of the new
|
|
* zone header. Save result in cbNeeded.
|
|
*/
|
|
cbNeeded = BLOCK_SIZE(dummyHdrPtr) - (SIZEOF_BLOCK_HEADER + SIZEOF_SMALLEST_PTR_DATUM);
|
|
assert((cbNeeded != 0) && (WORD_ALIGNED(cbNeeded)));
|
|
|
|
/* Calculate new start of zone, and move it there */
|
|
MoveZone(origZone, (Ptr) origZone + cbNeeded);
|
|
|
|
/* tell caller how much we got */
|
|
return(cbNeeded);
|
|
}
|
|
|
|
/* GetLockPtr32. Get a non-relocatable block as close to (but below) ceilingPtr as
|
|
* possible, and stamp it with the signature 'LOCK'.
|
|
* Lock pointer not needed in 32-bit world because need for it means the app is
|
|
* not 32-bit clean.
|
|
*/
|
|
Ptr
|
|
GetLockPtr32(Ptr)
|
|
{
|
|
return(nil);
|
|
}
|
|
|
|
/* GetProcessMgrHiMaxBlock32. Do like MaxBlock() on the Process Mgr zone, but ignore
|
|
* the straddle area part.
|
|
*/
|
|
u_size
|
|
GetProcessMgrHiMaxBlock32(void)
|
|
{
|
|
HeapBlockPtr heapBlockPtr;
|
|
u_size blockSize, hiMaxBlock, thisRangeFree;
|
|
unsigned int blockTags;
|
|
unsigned int blockFlags;
|
|
Boolean aboveStraddle;
|
|
|
|
aboveStraddle = false;
|
|
thisRangeFree = 0;
|
|
hiMaxBlock = 0;
|
|
|
|
/* Skip dummy block */
|
|
heapBlockPtr = &ProcessMgrZone->heapData;
|
|
(Ptr)heapBlockPtr += BLOCK_SIZE(heapBlockPtr);
|
|
|
|
/* Walk the heap */
|
|
while (heapBlockPtr < ProcessMgrZone->bkLim)
|
|
{
|
|
blockTags = (unsigned int) TAGBYTE(heapBlockPtr);
|
|
blockSize = BLOCK_SIZE(heapBlockPtr);
|
|
|
|
/* Count this block in if it is free or purgeable. Reset the counter if the
|
|
* if the block is non-relocatable, relocatable but locked, or of some unknown
|
|
* new type, since we're looking for memory *between* such blocks.
|
|
*/
|
|
if (blockTags == freeTagVal)
|
|
thisRangeFree += blockSize;
|
|
else if (blockTags == relTagVal)
|
|
{
|
|
blockFlags = (unsigned int) MP_TAGBYTE(heapBlockPtr);
|
|
if ((blockFlags & lockedMPTagFlag) != 0)
|
|
{
|
|
if ((thisRangeFree > hiMaxBlock) && (aboveStraddle))
|
|
hiMaxBlock = thisRangeFree;
|
|
aboveStraddle = true;
|
|
thisRangeFree = 0;
|
|
}
|
|
else if ((blockFlags & purgeableMPTagFlag) != 0)
|
|
thisRangeFree += blockSize;
|
|
}
|
|
else
|
|
{
|
|
if ((thisRangeFree > hiMaxBlock) && (aboveStraddle))
|
|
hiMaxBlock = thisRangeFree;
|
|
aboveStraddle = true;
|
|
thisRangeFree = 0;
|
|
}
|
|
|
|
(Ptr)heapBlockPtr += blockSize;
|
|
}
|
|
|
|
/* Allow for block header we'd need */
|
|
if (hiMaxBlock != 0)
|
|
PhysicalToLogicalSize(hiMaxBlock);
|
|
return(hiMaxBlock);
|
|
}
|
|
|
|
/* GetHighestLargeFreeBlock32. This function returns a pointer to a block that
|
|
* is >= size, or nil if one couldn't be located. It will not pass any
|
|
* non-relocatable blocks during it's search. Does not use the lockPtr parameter
|
|
* since ceilings are not supported in 32-bit heaps.
|
|
*/
|
|
FreeBlockAddr
|
|
GetHighestLargeFreeBlock32(u_size size, Ptr lockPtr)
|
|
{
|
|
#pragma unused (lockPtr)
|
|
HeapBlockPtr blockPtr, highestLargeFreeBlock, trailerBlockPtr;
|
|
u_size blockSize;
|
|
|
|
/* Looking for physical blocks now */
|
|
size += SIZEOF_BLOCK_HEADER;
|
|
|
|
/* Start at bottom of heap, and go up to trailerBlock */
|
|
blockPtr = (HeapBlockPtr)&THEZONE->heapData;
|
|
trailerBlockPtr = (HeapBlockPtr)THEZONE->bkLim;
|
|
highestLargeFreeBlock = nil;
|
|
while (blockPtr < trailerBlockPtr)
|
|
{
|
|
blockSize = BLOCK_SIZE(blockPtr);
|
|
|
|
/* Check whether this is a valid block for our purposes */
|
|
if ((IS_FREE_BLOCK(blockPtr) && (blockSize >= size)))
|
|
highestLargeFreeBlock = blockPtr;
|
|
|
|
/* Advance to next block */
|
|
(Ptr)blockPtr += blockSize;
|
|
}
|
|
|
|
return((FreeBlockAddr) highestLargeFreeBlock);
|
|
}
|
|
|
|
/* GetTopBlockSize32. Extract the size of the specified block. Return 0 if address
|
|
* is nil or the block is not the absolute highest in the zone.
|
|
*/
|
|
unsigned long
|
|
GetTopBlockSize32(FreeBlockAddr pTopBlock)
|
|
{
|
|
u_size blockSize;
|
|
|
|
if ((pTopBlock == nil)
|
|
|| ((Ptr)pTopBlock + (blockSize = BLOCK_SIZE((HeapBlockPtr) pTopBlock)) != THEZONE->bkLim) )
|
|
return(0);
|
|
|
|
return(blockSize);
|
|
}
|
|
|
|
/* FreeTop32. Shrink the size of the given free block to the specified value, and
|
|
* create a zone trailer block after the result. Returns address of trailer block.
|
|
*/
|
|
FreeBlockAddr
|
|
FreeTop32(FreeBlockAddr pBlockHdr, u_size newSize)
|
|
{
|
|
/* Resize the free block: only the size field needs to change */
|
|
BLOCK_SIZE((HeapBlockPtr)pBlockHdr) = newSize;
|
|
|
|
/* Advance pBlockHdr to header of block to follow, and init the header */
|
|
*(Ptr*)&pBlockHdr += newSize;
|
|
CLEAR_BLOCK_ATTRS(pBlockHdr);
|
|
TAGBYTE((HeapBlockPtr)pBlockHdr) = freeTagVal;
|
|
BLOCK_SIZE((HeapBlockPtr)pBlockHdr) = MIN_PHYSICAL_SIZE;
|
|
return(pBlockHdr);
|
|
}
|
|
|
|
|
|
/* ChipOffRelocFromFree32. Allocate a relocatable block at the high end of the given
|
|
* free block.
|
|
* Assumes that the free block length is at least sizeNeeded.
|
|
* NOTE: The size correction will be incorrect if the free block is bigger
|
|
* than sizeNeeded, but not big enough to be cleaved. The resulting logical
|
|
* size will be slightly larger than requested.
|
|
*/
|
|
void
|
|
ChipOffRelocFromFree32(FreeBlockAddr pBlock, Handle theHandle, u_size sizeNeeded, short sizeCorrection)
|
|
{
|
|
HeapBlockPtr hbPtr = (HeapBlockPtr) pBlock;
|
|
u_size unusedBytes;
|
|
|
|
sizeNeeded += SIZEOF_BLOCK_HEADER;
|
|
|
|
if ((unusedBytes = BLOCK_SIZE(hbPtr) - sizeNeeded) >= MIN_PHYSICAL_SIZE)
|
|
{
|
|
SIZE_CORR(hbPtr) = 0;
|
|
BLOCK_SIZE(hbPtr) = unusedBytes;
|
|
(Ptr)hbPtr += unusedBytes;
|
|
BLOCK_SIZE(hbPtr) = sizeNeeded;
|
|
}
|
|
else
|
|
{
|
|
sizeNeeded = BLOCK_SIZE(hbPtr);
|
|
sizeCorrection += unusedBytes;
|
|
assert(sizeCorrection <= 15);
|
|
}
|
|
|
|
/* Convert block to relocatable, and set master pointer and size correction */
|
|
CLEAR_BLOCK_ATTRS(hbPtr);
|
|
TAGBYTE(hbPtr) = relTagVal;
|
|
BLOCK_HANDLE(hbPtr) = (Ptr)(theHandle) - (long)THEZONE;
|
|
SIZE_CORR(hbPtr) = sizeCorrection;
|
|
*theHandle = BLOCK_DATA(hbPtr);
|
|
|
|
/* Adjust heap for the loss */
|
|
HEAP_FREE_SPACE(THEZONE) -= sizeNeeded;
|
|
}
|
|
|
|
/* InitVectorTable32. Stuff the function vectors with our values. */
|
|
void
|
|
InitVectorTable32(void)
|
|
{
|
|
vrGetProcessMgrLoFreeBytes = (Ptr) ROUTINE_ADDR(GetProcessMgrLoFreeBytes32);
|
|
vrExtendZone = (Ptr) ROUTINE_ADDR(ExtendZone32);
|
|
vrMoveZone = (Ptr) ROUTINE_ADDR(MoveZone32);
|
|
vrShrinkProcessMgrZone = (Ptr) ROUTINE_ADDR(ShrinkProcessMgrZone32);
|
|
vrGetLockPtr = (Ptr) ROUTINE_ADDR(GetLockPtr32);
|
|
vrGetHighestLargeFreeBlock = (Ptr) ROUTINE_ADDR(GetHighestLargeFreeBlock32);
|
|
vrGetTopBlockSize = (Ptr) ROUTINE_ADDR(GetTopBlockSize32);
|
|
vrFreeTop = (Ptr) ROUTINE_ADDR(FreeTop32);
|
|
vrChipOffRelocFromFree = (Ptr) ROUTINE_ADDR(ChipOffRelocFromFree32);
|
|
vrZoneMPBlockPtr = (Ptr) ROUTINE_ADDR(ZoneMPBlockPtr32);
|
|
vrGetSystemHiFreeBytes = (Ptr) ROUTINE_ADDR(GetSystemHiFreeBytes32);
|
|
vrGetProcessMgrHiMaxBlock = (Ptr) ROUTINE_ADDR(GetProcessMgrHiMaxBlock32);
|
|
}
|