home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-04-21 | 17.7 KB | 589 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: FWMemMgr.cpp
- // Release Version: $ 1.0d1 $
- //
- // Creation Date: 3/28/94
- //
- // Copyright: © 1993, 1994 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #ifndef FWMEMMGR_H
- #include "FWMemMgr.h"
- #endif
-
- #ifndef FWEXCDEF_H
- #include "FWExcDef.h"
- #endif
-
- #ifndef FWMEMTAS_H
- #include "FWMemTas.h"
- #endif
-
- #ifndef FWOBJECH_H
- #include "FWObjecH.h"
- #endif
-
- #if defined(FW_BUILD_MAC) && !defined(__OSUTILS__)
- #include <OSUtils.h>
- #endif
-
- #if defined(FW_BUILD_MAC) && !defined(__MEMORY__)
- #include <Memory.h>
- #endif
-
- #if defined(FW_BUILD_WIN) && !defined(_INC_WINDOWS)
- #include <Windows.h>
- #endif
-
- #if defined(FW_BUILD_WIN) && !defined(_INC_WINDOWSX)
- #include <WindowsX.h>
- #endif
-
- #include <string.h>
-
- #pragma segment MemoryManagerPackage
-
- #if defined(__SC__) && defined(FW_BUILD_WIN)
-
- #if !defined(__LIMITS_H)
- #include <limits.h>
- #endif
-
- #if !defined(__HUGEPTR_H) && defined(FW_BUILD_WIN16)
- #include <hugeptr.h>
- #endif
-
- #endif
-
- _FW_EXCEPTION_IMPLEMENT(FW_XMemoryExhausted, FW_XPrivException)
-
- #define PRIV_CLEAR_MEM_ON_ALLOC
-
- // It'd be cool to let this be set at program startup using InitializationFile setting
- #ifdef PRIV_CLEAR_MEM_ON_ALLOC
- const unsigned char kKnownRawByte = 0;
- #else
- const unsigned char kKnownRawByte = 0x5A;
- #endif
-
- //========================================================================================
- // Global procedures
- //========================================================================================
-
- #ifdef FW_BUILD_MAC
- //----------------------------------------------------------------------------------------
- // SetStackSpace
- //----------------------------------------------------------------------------------------
-
- void SetStackSpace(long numBytes)
- {
- long newLimit;
-
- newLimit = (long)GetCurrentStackBase() - numBytes;
- if ((long)GetApplLimit() > newLimit)
- SetApplLimit((Ptr)newLimit);
- }
- #endif
-
-
- #ifdef FW_BUILD_MAC
- //----------------------------------------------------------------------------------------
- // MacGrowZoneProc
- //----------------------------------------------------------------------------------------
-
- pascal long MacGrowZoneProc(Size /* cbNeeded */)
- {
- Debugger(); // We ran out of fMemory
- return 0;
- }
- #endif
-
- #if defined(FW_BUILD_WIN) && defined(FW_qUsePlatformAlloc)
- //----------------------------------------------------------------------------------------
- // GetPointer
- //----------------------------------------------------------------------------------------
-
- void* GetPointer(HANDLE h)
- {
- return (void*)::GlobalLock(h);
- }
- #endif
-
- #if defined(FW_BUILD_WIN) && defined(FW_qUsePlatformAlloc)
- //----------------------------------------------------------------------------------------
- // GetHandle
- //----------------------------------------------------------------------------------------
-
- HANDLE GetHandle(void* p)
- {
- return p != NULL ? GlobalPtrHandle(p) : NULL;
- }
- #endif
-
- //----------------------------------------------------------------------------------------
- // set_new_handler
- //----------------------------------------------------------------------------------------
-
- FW_PFVV set_new_handler(FW_PFVV handler)
- {
- FW_SPrivMemoryGlobals& globals = FW_CMemoryTaskGlobals::GetMemoryGlobals();
- FW_PFVV oldHandler = globals.gNewHandler;
- globals.gNewHandler = handler;
- return oldHandler;
- }
-
- //========================================================================================
- // CLASS FW_XMemoryExhausted
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // FW_XMemoryExhausted::~FW_XMemoryExhausted
- //----------------------------------------------------------------------------------------
- FW_XMemoryExhausted::~FW_XMemoryExhausted()
- {
- }
-
-
- //========================================================================================
- // CLASS FW_CMemoryManager
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::GetMemoryHeap
- //----------------------------------------------------------------------------------------
-
- FW_CMemoryHeap* FW_CMemoryManager::GetMemoryHeap()
- {
- FW_CMemoryHeap* heap = FW_CMemoryTaskGlobals::GetMemoryGlobals().gMemoryHeap;
- FW_ASSERT(heap != NULL);
-
- return heap;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::DefaultNewHandler
- //----------------------------------------------------------------------------------------
-
- void FW_CMemoryManager::DefaultNewHandler()
- {
- unsigned long lastRequested = FW_CMemoryTaskGlobals::GetMemoryGlobals().gLastRequested;
- FW_THROW(FW_XMemoryExhausted(lastRequested));
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::PrimitiveAllocateBlock
- //----------------------------------------------------------------------------------------
-
- void* FW_CMemoryManager::PrimitiveAllocateBlock(unsigned long n)
- {
- void* p;
-
- #if !defined FW_qUsePlatformAlloc
- p = GetMemoryHeap()->Allocate(n);
- #elif defined FW_BUILD_WIN
- // [?KVV] Windows hack: Zortech IOStream package contains a bug: it only checks
- // the offset part of pointers returned from malloc. This can causes a
- // problem when we use GlobalLock, since it returns pointers that have
- // offset == 0! To work around this bug, we make sure the offset is
- // never zero
- p = (void*) ((char *) GlobalAllocPtr(GHND, n + 1)) + 1);
- #elif defined FW_BUILD_MAC
- p = ::NewPtr((long) n);
- #endif
-
- return p;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::PrimitiveResizeBlock
- //----------------------------------------------------------------------------------------
-
- void* FW_CMemoryManager::PrimitiveResizeBlock(void* p, unsigned long n)
- {
- void* newP;
-
- #if !defined FW_qUsePlatformAlloc
- newP = GetMemoryHeap()->Reallocate(p, n);
- #elif defined FW_BUILD_WIN
- HANDLE h = GetHandle((char*) p - 1);
- ::GlobalUnlock(h);
- HANDLE h2 = ::GlobalReAlloc(h, n + 1, GHND);
-
- if(h2 != NULL)
- newP = (void*) ((char*) GetPointer(h2) + 1);
- else
- newP = NULL;
-
- GetPointer(h);
- #elif defined FW_BUILD_MAC
- void *q = p;
- ::SetPtrSize((Ptr) q, n);
- if (MemError() != noErr)
- {
- q = PrimitiveAllocateBlock(n);
- if (q)
- {
- CopyMemory(p, q, n);
- PrimitiveFreeBlock(p);
- }
- }
- newP = q;
- #endif
-
- return newP;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::PrimitiveGetBlockSize
- //----------------------------------------------------------------------------------------
-
- unsigned long FW_CMemoryManager::PrimitiveGetBlockSize(void* p)
- {
- unsigned long blockSize;
-
- #if !defined FW_qUsePlatformAlloc
- blockSize = GetMemoryHeap()->BlockSize(p);
- #elif defined FW_BUILD_WIN
- HANDLE h = GetHandle((char*) p - 1);
- blockSize = ::GlobalSize(h) - 1;
- #elif defined FW_BUILD_MAC
- blockSize = ::GetPtrSize(p);
- #endif
-
- return blockSize;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::PrimitiveFreeBlock
- //----------------------------------------------------------------------------------------
-
- void FW_CMemoryManager::PrimitiveFreeBlock(void* p)
- {
- #if !defined FW_qUsePlatformAlloc
- GetMemoryHeap()->Free(p);
- #elif defined FW_BUILD_WIN
- GlobalFreePtr((char*) p - 1);
- #elif defined FW_BUILD_MAC
- if (p != NULL)
- ::DisposPtr(p);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::AddOffsetToPointer
- //----------------------------------------------------------------------------------------
-
- void *FW_CMemoryManager::AddOffsetToPointer(void *pointer, unsigned long Offset)
- {
- #if defined(FW_BUILD_MAC) || defined(FW_BUILD_WIN32S)
- return (void *)((char *)pointer + Offset);
- #elif defined(__SC__) && defined(FW_BUILD_WIN16)
- // If 'Offset' is not less than the maximum signed LONG Value, consider it an fError.
- // We could program for these cases, but it is More than likely an fError.
- FW_ASSERT(Offset < (unsigned long)LONG_MAX);
-
- // Symantec C++ note: hugeptr_add(p,o) is a macro that calls the function:
- // hugeptr_add(p, sizeof(*p) * o)
- // Thus, the pointer passed to hugeptr_add() must be 'char *' type.
- char * typedPointer = pointer;
- signed long signedLongOffset = Offset;
-
- // The call to hugeptr_add() is not scoped with '::' because Symantec C++
- // first uses a macro and the macro fails to compile when scoped with '::'.
- return hugeptr_add(typedPointer, signedLongOffset);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::CopyMemory -
- //----------------------------------------------------------------------------------------
- void FW_CMemoryManager::CopyMemory(const void* const source,
- void* const destination,
- unsigned long bytesToMove)
- {
- FW_ASSERT(source != 0);
- FW_ASSERT(destination != 0);
-
- #ifdef FW_BUILD_WIN
- ::hmemcpy((void*)destination, (void*)source, bytesToMove);
- #endif
-
- #ifdef FW_BUILD_MAC
- ::BlockMove(source, destination, bytesToMove);
- #endif
-
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::SetMemory -
- //----------------------------------------------------------------------------------------
- void FW_CMemoryManager::SetMemory(void *aBlock,
- unsigned long bytesToSet,
- unsigned char byteValue)
- {
- FW_ASSERT(aBlock != 0);
-
- #ifdef FW_BUILD_WIN16
- // memset is limited to 64K bytes -- need huge version ???JEL
- FW_ASSERT(bytesToSet <= (size_t)0xFFFFFFFF);
- #endif
-
- //::memset(aBlock, byteValue, (size_t) bytesToSet);
- }
-
- //----------------------------------------------------------------------------------------
- // InitializeRawBlock - Set a raw block of fMemory to known values.
- //----------------------------------------------------------------------------------------
- void FW_CMemoryManager::InitializeRawBlock(void *aBlock, unsigned long sizeBlock)
- {
- #ifdef FW_DEBUG
- SetMemory(aBlock, sizeBlock, kKnownRawByte);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::AllocateBlock - Allocate a non-relocatable block of fMemory.
- //----------------------------------------------------------------------------------------
- void* FW_CMemoryManager::AllocateBlock(unsigned long bytesRequested)
- {
- FW_LOG_OR_TRIGGER_EXCEPTION(FW_XMemoryExhausted, FW_XMemoryExhausted(bytesRequested));
-
- unsigned long bytesNeeded = bytesRequested;
- void* aBlock = PrimitiveAllocateBlock(bytesNeeded);
- if (aBlock == 0)
- FW_THROW(FW_XMemoryExhausted(bytesRequested));
-
- InitializeRawBlock(aBlock, bytesNeeded);
-
- return aBlock;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::ResizeBlock - Resize a non-relocatable block of fMemory. The
- // block may be moved to a new location if necessary.
- //----------------------------------------------------------------------------------------
- void *FW_CMemoryManager::ResizeBlock(void *aBlock, unsigned long bytesRequested)
- {
- FW_LOG_OR_TRIGGER_EXCEPTION(FW_XMemoryExhausted, FW_XMemoryExhausted(bytesRequested));
-
- unsigned long bytesNeeded = bytesRequested;
-
- void *newBlock;
- if (aBlock == 0)
- newBlock = PrimitiveAllocateBlock(bytesNeeded);
- else
- newBlock = PrimitiveResizeBlock(aBlock, bytesNeeded);
-
- if (newBlock == 0)
- FW_THROW(FW_XMemoryExhausted(bytesRequested));
-
- FW_ASSERT(GetBlockSize(newBlock) >= bytesRequested);
-
- return newBlock;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::FreeBlock - Return a non-relocatable block to the free store.
- //----------------------------------------------------------------------------------------
- void FW_CMemoryManager::FreeBlock(void *aBlock)
- {
- if (aBlock != 0)
- PrimitiveFreeBlock(aBlock);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::GetBlockSize - Return the size of a non-relocatable block.
- //----------------------------------------------------------------------------------------
- unsigned long FW_CMemoryManager::GetBlockSize(void *aBlock)
- {
- FW_ASSERT(aBlock != 0);
-
-
- return PrimitiveGetBlockSize(aBlock);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::AllocateSystemHandle -
- //----------------------------------------------------------------------------------------
- FW_PlatformHandle FW_CMemoryManager::AllocateSystemHandle(unsigned long bytesNeeded)
- {
- FW_LOG_OR_TRIGGER_EXCEPTION(FW_XMemoryExhausted, FW_XMemoryExhausted(bytesNeeded));
-
- FW_PlatformHandle aSystemHandle;
-
- #ifdef FW_BUILD_MAC
- aSystemHandle = ::NewHandle(bytesNeeded);
- #endif
- #ifdef FW_BUILD_WIN
- aSystemHandle = ::GlobalAlloc(GMEM_MOVEABLE, bytesNeeded);
- #endif
-
- if (aSystemHandle == 0)
- FW_THROW(FW_XMemoryExhausted(bytesNeeded));
-
- return aSystemHandle;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::ResizeSystemHandle -
- //----------------------------------------------------------------------------------------
- FW_PlatformHandle FW_CMemoryManager::ResizeSystemHandle(FW_PlatformHandle aHandle,
- unsigned long bytesNeeded)
- {
- FW_LOG_OR_TRIGGER_EXCEPTION(FW_XMemoryExhausted, FW_XMemoryExhausted(bytesNeeded));
-
- FW_ASSERT(aHandle != 0);
-
- FW_PlatformHandle newHandle = aHandle;
-
- #ifdef FW_BUILD_MAC
- ::SetHandleSize(aHandle, bytesNeeded);
- #endif
- #ifdef FW_BUILD_WIN
- newHandle = ::GlobalReAlloc(aHandle, bytesNeeded, GMEM_MOVEABLE);
- #endif
-
- if (GetSystemHandleSize(newHandle) < bytesNeeded)
- FW_THROW(FW_XMemoryExhausted( bytesNeeded));
-
- return newHandle;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::FreeSystemHandle -
- //----------------------------------------------------------------------------------------
- void FW_CMemoryManager::FreeSystemHandle(FW_PlatformHandle aHandle)
- {
- FW_ASSERT(aHandle != 0);
-
- #ifdef FW_BUILD_MAC
- ::DisposHandle(aHandle);
- #endif
- #ifdef FW_BUILD_WIN
- ::GlobalFree(aHandle);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::LockSystemHandle -
- //----------------------------------------------------------------------------------------
- void * FW_CMemoryManager::LockSystemHandle(FW_PlatformHandle handle)
- {
- FW_ASSERT(handle != 0);
-
- void* memory;
-
- #ifdef FW_BUILD_MAC
- HLock(handle);
- memory = *handle;
- #endif
- #ifdef FW_BUILD_WIN
- memory = ::GlobalLock(handle);
- #endif
-
- if(memory == NULL)
- FW_THROW(FW_XMemoryExhausted());
-
- return memory;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::UnlockSystemHandle -
- //----------------------------------------------------------------------------------------
- void FW_CMemoryManager::UnlockSystemHandle(FW_PlatformHandle aHandle)
- {
- FW_ASSERT(aHandle != 0);
-
- #ifdef FW_BUILD_MAC
- ::HUnlock(aHandle);
- #endif
- #ifdef FW_BUILD_WIN
- ::GlobalUnlock(aHandle);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::GetSystemHandleSize -
- //----------------------------------------------------------------------------------------
- unsigned long FW_CMemoryManager::GetSystemHandleSize(FW_PlatformHandle aHandle)
- {
- FW_ASSERT(aHandle != 0);
-
- #ifdef FW_BUILD_MAC
- return ::GetHandleSize(aHandle);
- #endif
- #ifdef FW_BUILD_WIN
- return ::GlobalSize(aHandle);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CMemoryManager::CopySystemHandle -
- //----------------------------------------------------------------------------------------
- FW_PlatformHandle FW_CMemoryManager::CopySystemHandle(FW_PlatformHandle aHandle)
- {
- unsigned long size = GetSystemHandleSize(aHandle);
-
- FW_CAcquireLockedSystemHandle<void> sourceLock(aHandle);
- void *sourcePointer = sourceLock.GetPointer();
-
- FW_PlatformHandle newHandle = AllocateSystemHandle(size);
- FW_CAcquireLockedSystemHandle<void> destinationLock(newHandle);
- void *destinationPointer = destinationLock.GetPointer();
-
- CopyMemory(sourcePointer, destinationPointer, size);
-
- return newHandle;
- }
-
- #ifdef FW_NEW_AND_DELETE_NOT_DISABLED
-
- // Currently parts must use OpenDoc's new and delete to avoid mismatching new and delete
- // calls in certain situations. Will be fixed soon.
-
- //========================================================================================
- // C++ Global operator new & delete
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // operator new
- //----------------------------------------------------------------------------------------
- #ifdef __BORLANDC__
- void* cdecl operator new(size_t size)
- #else
- void* operator new(size_t size)
- #endif
- {
-
- FW_SPrivMemoryGlobals& globals = FW_CMemoryTaskGlobals::GetMemoryGlobals();
- void* p;
-
- globals.gLastRequested = size;
-
- while ((p = FW_CMemoryManager::PrimitiveAllocateBlock(size)) == 0)
- {
- if (globals.gNewHandler)
- (*(globals.gNewHandler))();
- else
- return 0;
- }
-
- return p;
- }
-
- //----------------------------------------------------------------------------------------
- // operator delete
- //----------------------------------------------------------------------------------------
- #ifdef __BORLANDC__
- void cdecl operator delete(void *pObject)
- #else
- void operator delete(void *pObject)
- #endif
- {
- FW_CMemoryManager::FreeBlock(pObject);
- }
-
- #endif
-