Removing old cfm build files. Use the CFM_LAST_RITES tag to resurrect. r=macdev

This commit is contained in:
seawood%netscape.com 2003-06-10 22:01:25 +00:00
Родитель b636b51c8e
Коммит d36d169b61
74 изменённых файлов: 0 добавлений и 43979 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,44 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
//
// Specific defines for the Memory allocator
//
#include "MemAllocatorConfig.h"

Просмотреть файл

@ -1,41 +0,0 @@
###
### This file was generated by AnnotateExports (Friday, March 6, 1998 5:46:22 PM) from MemAllocator.exp.
###
### [Un-]Comment-out (do not delete) symbols and annotate with #{code} and #{data} to control export.
### When brand new signatures are to be exported, regenerate this file as described in AnnotateExports.
### Warning: all comments MUST start in the left column, or else stubs will be built wrong.
###
###
### Symbols you may have to hand annotate with #{code} or #{data}...
###
calloc
free
malloc
realloc
###
### Symbols which do not require hand annotation...
###
#{code}
__dl__FPv
__nw__FUl
__dla__FPv
__nwa__FUl
__nwa__FUlRCQ23std9nothrow_t
__nw__FUlRCQ23std9nothrow_t
GC_stderr
GC_stdout
GC_trace_object
MWUnmangle
GC_malloc_atomic
GC_address_to_source
GC_gcollect
GC_generic_init_threads
GC_clear_roots
GC_unregister_fragment
GC_register_fragment

Просмотреть файл

@ -1,7 +0,0 @@
# Build MemAllocatorStubsPPCLib
Evaluate % = ("{{SourceFile}}" =~ /(Å:)¨0Å/)
MakeStub "{{SourceFile}}" -o "{{¨0}}MemAllocatorStubsPPCLib" ¶
-fragname MemoryAllocator ¶
-vercur 400 -verdef 400 -verimp 400

Просмотреть файл

@ -1,7 +0,0 @@
# Build MemAllocatorStubsPPCLib
Evaluate % = ("{{SourceFile}}" =~ /(Å:)¨0Å/)
MakeStub "{{SourceFile}}" -o "{{¨0}}:::dist:client_stubs:MemAllocatorStubsLib" ¶
-fragname MemoryAllocator ¶
-vercur 400 -verdef 400 -verimp 400

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,71 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* must be first in order to correctly pick up TARGET_CARBON define before
* it is set in ConditionalMacros.h */
#include "DefinesMac.h"
#include <Types.h>
#include <stdlib.h>
#include "IDE_Options.h"
#pragma exceptions off
#ifdef DEBUG
/* Debug macros and switches */
#define DEBUG_HEAP_INTEGRITY 1
#define STATS_MAC_MEMORY 0
#define MEM_ASSERT(condition, message) ((condition) ? ((void)0) : DebugStr("\p"message))
#else
/* Non-debug macros and switches */
#define DEBUG_HEAP_INTEGRITY 0
#define STATS_MAC_MEMORY 0
#define MEM_ASSERT(condition, message) ((void)0)
#endif

Просмотреть файл

@ -1,44 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
//
// Debug specific defines for the Memory allocators
//
#define DEBUG 1
#include "MemAllocatorConfig.h"

Просмотреть файл

@ -1,18 +0,0 @@
InitializeMemoryTracker
ExitMemoryTracker
DumpMemoryTrackerState
DumpAllocationSites
NewAllocationSite
TrackItem
ReleaseItem
NewAllocationSet
DisposeAllocationSet
LogAllocationSetState
EnableAllocationSet
DisableAllocationSet
DisableMemoryTracker
EnableMemoryTracker
GetCurrentNativeStackTrace
GetCurrentStackPointer
GetCurrentStackTrace
SetTrackerDataDecoder

Просмотреть файл

@ -1,48 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <stddef.h>
#include "prtypes.h"
NSPR_BEGIN_EXTERN_C
void* Flush_Allocate(size_t, Boolean);
void Flush_Free(void *);
void* Flush_Reallocate(void *, size_t);
NSPR_END_EXTERN_C

Просмотреть файл

@ -1,89 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef __MACMEMALLOCATOR__
#define __MACMEMALLOCATOR__
#include "prtypes.h"
#include <stddef.h>
#include <Types.h>
#warning "This file should not be used"
typedef struct FreeMemoryStats FreeMemoryStats;
struct FreeMemoryStats {
uint32 totalHeapSize;
uint32 totalFreeBytes;
uint32 maxBlockSize;
};
typedef void (*MallocHeapLowWarnProc)(void);
NSPR_BEGIN_EXTERN_C
typedef unsigned char (*MemoryCacheFlusherProc)(size_t size);
typedef void (*PreAllocationHookProc)(void);
extern void InstallPreAllocationHook(PreAllocationHookProc newHook);
extern void InstallMemoryCacheFlusher(MemoryCacheFlusherProc newFlusher);
// Entry into the memory system's cache flushing
extern UInt8 CallCacheFlushers(size_t blockSize);
extern void* reallocSmaller(void* block, size_t newSize);
void memtotal ( size_t blockSize, FreeMemoryStats * stats );
size_t memsize ( void * block );
extern Boolean gMemoryInitialized;
void MacintoshInitializeMemory(void);
void CallFE_LowMemory(void);
Boolean Memory_ReserveInMacHeap(size_t spaceNeeded);
Boolean Memory_ReserveInMallocHeap(size_t spaceNeeded);
Boolean InMemory_ReserveInMacHeap();
size_t Memory_FreeMemoryRemaining();
void InstallGarbageCollectorCacheFlusher(const MemoryCacheFlusherProc inFlusher);
void InstallMallocHeapLowProc( MallocHeapLowWarnProc proc );
NSPR_END_EXTERN_C
#endif

Просмотреть файл

@ -1,75 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#if DEBUG_MAC_MEMORY
#include "xp_tracker.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* Some mac specific routines and constants
*/
#define kNameMaxLength 30
/* allocType */
typedef enum {
kMallocBlock = 'mllc',
kHandleBlock = 'hndl',
kPointerBlock = 'pntr'
} AllocatorType;
/*
* Stack Crawl Cheese
*/
void *GetCurrentStackPointer();
/* walk past any 68K stack frames and try to get a native only trace */
void GetCurrentNativeStackTrace(void **stackCrawl);
/* get a stack crawl from the current stack frame */
void GetCurrentStackTrace(void **stackCrawl);
#ifdef __cplusplus
}
#endif

Просмотреть файл

@ -1,83 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <new>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "prtypes.h"
//##############################################################################
//##############################################################################
// needed because we are not compiling the relevant parts of New.cp
std::nothrow_t nothrow;
void* operator new (size_t size, const std::nothrow_t& ) throw()
{
return malloc( size );
}
void* operator new( size_t size )
{
return operator new ( size, ::nothrow );
}
void operator delete( void* block )
{
free( block );
}
void* operator new[]( size_t size )
{
return operator new(size);
}
void* operator new[] (size_t size, const std::nothrow_t& nt ) throw()
{
return operator new(size, nt);
}
void operator delete[]( void* block )
{
operator delete(block);
}

Просмотреть файл

@ -1,812 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#pragma error "This file is obsolete, but remains for reference reasons"
#include <Memory.h>
#include <Processes.h>
#include "stdlib.h"
#include "TypesAndSwitches.h"
#include "MacMemAllocator.h"
#include "prlog.h"
#if STATS_MAC_MEMORY
#include "prglobal.h"
#include "prfile.h"
#include <unistd.h>
#include <string.h>
#endif
#if DEBUG_MAC_MEMORY
#include "MemoryTracker.h"
extern AllocationSet * gFixedSizeAllocatorSet;
extern AllocationSet * gSmallHeapAllocatorSet;
extern AllocationSet * gLargeBlockAllocatorSet;
#endif
void * gOurApplicationHeapBase;
void * gOurApplicationHeapMax;
Boolean gMemoryInitialized = false;
//##############################################################################
//##############################################################################
#pragma mark DECLARATIONS AND ENUMERATIONS
typedef struct MemoryCacheFlusherProcRec MemoryCacheFlusherProcRec;
struct MemoryCacheFlusherProcRec {
MemoryCacheFlusherProc flushProc;
MemoryCacheFlusherProcRec *next;
};
typedef struct PreAllocationProcRec PreAllocationProcRec;
struct PreAllocationProcRec {
PreAllocationHookProc preAllocProc;
PreAllocationProcRec *next;
};
MemoryCacheFlusherProcRec *gFirstFlusher = NULL;
PreAllocationProcRec *gFirstPreAllocator = NULL;
MallocHeapLowWarnProc gMallocLowProc = NULL;
void CallPreAllocators(void);
void InitializeSubAllocators ( void );
Boolean ReclaimMemory(size_t amountNeeded);
long pascal MallocGrowZoneProc(Size cbNeeded);
#define kMinLargeBlockHeapSize (65 * 1024) /* Min size of the heaps in temp mem try to allocate */
#define kMaxLargeBlockHeapSize (1024 * 1024) /* Max size of the heaps in temp mem try to allocate */
#define kLargeBlockInitialPercentage (65) /* This is the % of the free space in the heap used for the
large block allocation heap */
#define kMallocLowTempMemoryBoundary (256 * 1024) /* This is a boundary point at which we assume we're
running low on temp memory */
#define kHeapEmergencyReserve (64 * 1024) /* Keep 64k free in the app heap for emergencies */
#if GENERATINGCFM
RoutineDescriptor gMallocGrowZoneProcRD = BUILD_ROUTINE_DESCRIPTOR(uppGrowZoneProcInfo, &MallocGrowZoneProc);
#else
#define gMallocGrowZoneProcRD MallocGrowZoneProc
#endif
//##############################################################################
//##############################################################################
#pragma mark FIXED-SIZE ALLOCATION DECLARATIONS
/* The format here is:
DeclareFixedSizeAllocator(blockSize lower bound, # blocks in a heap chunk, # blocks in a tempmem chunk);
DeclareSmallHeapAllocator(first chunk heap size, temp mem chunk heap size );
*/
// the real declarators
DeclareFixedSizeAllocator(4, 2600, 1000);
DeclareFixedSizeAllocator(8, 2000, 1000);
DeclareFixedSizeAllocator(12, 5000, 1000);
DeclareFixedSizeAllocator(16, 4000, 1000);
DeclareFixedSizeAllocator(20, 7000, 3000);
DeclareFixedSizeAllocator(24, 9500, 3000);
DeclareFixedSizeAllocator(28, 3200, 1000);
DeclareFixedSizeAllocator(32, 3400, 1000);
DeclareFixedSizeAllocator(36, 2500, 500);
DeclareFixedSizeAllocator(40, 9300, 5000);
DeclareSmallHeapAllocator(512 * 1024, 256 * 1024);
DeclareLargeBlockAllocator(kLargeBlockInitialPercentage, kMaxLargeBlockHeapSize, kMinLargeBlockHeapSize);
AllocMemoryBlockDescriptor gFastMemSmallSizeAllocators[] = {
DeclareLargeBlockHeapDescriptor(), // 0
DeclareFixedBlockHeapDescriptor(4), // 4
DeclareFixedBlockHeapDescriptor(8), // 8
DeclareFixedBlockHeapDescriptor(12), // 12
DeclareFixedBlockHeapDescriptor(16), // 16
DeclareFixedBlockHeapDescriptor(20), // 20
DeclareFixedBlockHeapDescriptor(24), // 24
DeclareFixedBlockHeapDescriptor(28), // 28
DeclareFixedBlockHeapDescriptor(32), // 32
DeclareFixedBlockHeapDescriptor(36), // 36
DeclareFixedBlockHeapDescriptor(40), // 40
DeclareSmallSmallHeapDescriptor(), // 44
DeclareSmallSmallHeapDescriptor(), // 48
DeclareSmallSmallHeapDescriptor(), // 52
DeclareSmallSmallHeapDescriptor(), // 56
DeclareSmallSmallHeapDescriptor(), // 60
DeclareSmallSmallHeapDescriptor(), // 64
DeclareSmallSmallHeapDescriptor(), // 68
DeclareSmallSmallHeapDescriptor(), // 72
DeclareSmallSmallHeapDescriptor(), // 76
DeclareSmallSmallHeapDescriptor(), // 80
DeclareSmallSmallHeapDescriptor(), // 84
DeclareSmallSmallHeapDescriptor(), // 88
DeclareSmallSmallHeapDescriptor(), // 92
DeclareSmallSmallHeapDescriptor(), // 96
DeclareSmallSmallHeapDescriptor(), // 100
DeclareSmallSmallHeapDescriptor(), // 104
DeclareSmallSmallHeapDescriptor(), // 108
DeclareSmallSmallHeapDescriptor(), // 112
DeclareSmallSmallHeapDescriptor(), // 116
DeclareSmallSmallHeapDescriptor(), // 120
DeclareSmallSmallHeapDescriptor(), // 124
DeclareSmallSmallHeapDescriptor(), // 128
DeclareSmallSmallHeapDescriptor(), // 132
DeclareSmallSmallHeapDescriptor(), // 136
DeclareSmallSmallHeapDescriptor(), // 140
DeclareSmallSmallHeapDescriptor(), // 144
DeclareSmallSmallHeapDescriptor(), // 148
DeclareSmallSmallHeapDescriptor(), // 152
DeclareSmallSmallHeapDescriptor(), // 156
DeclareSmallSmallHeapDescriptor(), // 160
DeclareSmallSmallHeapDescriptor(), // 164
DeclareSmallSmallHeapDescriptor(), // 168
DeclareSmallSmallHeapDescriptor(), // 172
DeclareSmallSmallHeapDescriptor(), // 176
DeclareSmallSmallHeapDescriptor(), // 180
DeclareSmallSmallHeapDescriptor(), // 184
DeclareSmallSmallHeapDescriptor(), // 188
DeclareSmallSmallHeapDescriptor(), // 192
DeclareSmallSmallHeapDescriptor(), // 196
DeclareSmallSmallHeapDescriptor(), // 200
DeclareSmallSmallHeapDescriptor(), // 204
DeclareSmallSmallHeapDescriptor(), // 208
DeclareSmallSmallHeapDescriptor(), // 212
DeclareSmallSmallHeapDescriptor(), // 216
DeclareSmallSmallHeapDescriptor(), // 220
DeclareSmallSmallHeapDescriptor(), // 224
DeclareSmallSmallHeapDescriptor(), // 228
DeclareSmallSmallHeapDescriptor(), // 232
DeclareSmallSmallHeapDescriptor(), // 236
DeclareSmallSmallHeapDescriptor(), // 240
DeclareSmallSmallHeapDescriptor(), // 244
DeclareSmallSmallHeapDescriptor(), // 248
DeclareSmallSmallHeapDescriptor(), // 252
DeclareSmallSmallHeapDescriptor(), // 256
};
//##############################################################################
//##############################################################################
#pragma mark-
#pragma mark INSTRUMENTATION
#if INSTRUMENT_MAC_MEMORY
InstHistogramClassRef gSmallHeapHistogram = 0;
InstHistogramClassRef gLargeHeapHistogram = 0;
static OSErr CreateInstrumentationClasses()
{
OSErr err = noErr;
err = InstCreateHistogramClass(kInstRootClassRef, "MacMemAllocator:SmallHeap:Histogram",
40, 256, 4, kInstEnableClassMask, &gSmallHeapHistogram);
if (err != noErr) return err;
err = InstCreateHistogramClass(kInstRootClassRef, "MacMemAllocator:LargeHeap:Histogram",
256, 10240, 64, kInstEnableClassMask, &gLargeHeapHistogram);
if (err != noErr) return err;
return err;
}
#endif
//##############################################################################
//##############################################################################
#pragma mark-
#pragma mark INITIALIZATION
void MacintoshInitializeMemory(void)
{
UInt32 i;
ProcessSerialNumber thisProcess = { 0, kCurrentProcess };
ProcessInfoRec processInfo;
// Increase the stack space.
// This is because PA_MDL_ParseTag can go into deep recursion when dealing with
// malformed HTML comments (the only occurrence where we bombed).
#ifndef powerc
SetApplLimit(GetApplLimit() - 16384);
#endif
#if !TARGET_CARBON
MaxApplZone();
#endif
for (i = 1; i <= 30; i++)
MoreMasters();
// init our new compact allocators
processInfo.processInfoLength = sizeof(processInfo);
processInfo.processName = NULL;
processInfo.processAppSpec = NULL;
GetProcessInformation(&thisProcess, &processInfo);
gOurApplicationHeapBase = processInfo.processLocation;
gOurApplicationHeapMax = (Ptr)gOurApplicationHeapBase + processInfo.processSize;
#if INSTRUMENT_MAC_MEMORY
if (CreateInstrumentationClasses() != noErr)
{
DebugStr("\pFailed to initialize instrumentation classes");
ExitToShell();
}
#endif
#if DEBUG_MAC_MEMORY || STATS_MAC_MEMORY
InstallMemoryManagerPatches();
#if DEBUG_MAC_MEMORY
// Create some allocation sets to track our allocators
gFixedSizeAllocatorSet = NewAllocationSet ( 0, "Fixed Size Compact Allocator" );
gSmallHeapAllocatorSet = NewAllocationSet ( 0, "Small Heap Allocator" );
gLargeBlockAllocatorSet = NewAllocationSet ( 0, "Large Block Allocator" );
// disable them so we don't get random garbage
DisableAllocationSet ( gFixedSizeAllocatorSet );
DisableAllocationSet ( gSmallHeapAllocatorSet );
DisableAllocationSet ( gLargeBlockAllocatorSet );
#endif
#endif
// intialize the sub allocators
InitializeSubAllocators();
gMemoryInitialized = true;
}
void InitializeSubAllocators ( void )
{
SubHeapAllocationChunk * chunk;
#ifdef MALLOC_IS_NEWPTR
/* Don't allocate memory pools if just using NewPtr */
return;
#endif
/* fixed size allocators */
chunk = FixedSizeAllocChunk ( 0, &gFixedSize4Root );
PR_ASSERT(chunk);
if ( chunk == NULL ) goto fail;
chunk = FixedSizeAllocChunk ( 0, &gFixedSize8Root );
PR_ASSERT(chunk);
if ( chunk == NULL ) goto fail;
chunk = FixedSizeAllocChunk ( 0, &gFixedSize12Root );
PR_ASSERT(chunk);
if ( chunk == NULL ) goto fail;
chunk = FixedSizeAllocChunk ( 0, &gFixedSize16Root );
PR_ASSERT(chunk);
if ( chunk == NULL ) goto fail;
chunk = FixedSizeAllocChunk ( 0, &gFixedSize20Root );
PR_ASSERT(chunk);
if ( chunk == NULL ) goto fail;
chunk = FixedSizeAllocChunk ( 0, &gFixedSize24Root );
PR_ASSERT(chunk);
if ( chunk == NULL ) goto fail;
chunk = FixedSizeAllocChunk ( 0, &gFixedSize28Root );
PR_ASSERT(chunk);
if ( chunk == NULL ) goto fail;
chunk = FixedSizeAllocChunk ( 0, &gFixedSize32Root );
PR_ASSERT(chunk);
if ( chunk == NULL ) goto fail;
chunk = FixedSizeAllocChunk ( 0, &gFixedSize36Root );
PR_ASSERT(chunk);
if ( chunk == NULL ) goto fail;
chunk = FixedSizeAllocChunk ( 0, &gFixedSize40Root );
PR_ASSERT(chunk);
if ( chunk == NULL ) goto fail;
chunk = SmallHeapAllocChunk ( 0, &gSmallHeapRoot );
PR_ASSERT(chunk);
if ( chunk == NULL ) goto fail;
chunk = LargeBlockAllocChunk ( 0, &gLargeBlockRoot );
PR_ASSERT(chunk);
if ( chunk == NULL ) goto fail;
#if DEBUG_MAC_MEMORY && TRACK_EACH_ALLOCATOR
gFixedSize4Root.header.set = NewAllocationSet ( 0, "Fixed Block 4" );
DisableAllocationSet ( gFixedSize4Root.header.set );
gFixedSize8Root.header.set = NewAllocationSet ( 0, "Fixed Block 8" );
DisableAllocationSet ( gFixedSize8Root.header.set );
gFixedSize12Root.header.set = NewAllocationSet ( 0, "Fixed Block 12" );
DisableAllocationSet ( gFixedSize12Root.header.set );
gFixedSize16Root.header.set = NewAllocationSet ( 0, "Fixed Block 16" );
DisableAllocationSet ( gFixedSize16Root.header.set );
gFixedSize20Root.header.set = NewAllocationSet ( 0, "Fixed Block 20" );
DisableAllocationSet ( gFixedSize20Root.header.set );
gFixedSize24Root.header.set = NewAllocationSet ( 0, "Fixed Block 24" );
DisableAllocationSet ( gFixedSize24Root.header.set );
gFixedSize28Root.header.set = NewAllocationSet ( 0, "Fixed Block 28" );
DisableAllocationSet ( gFixedSize28Root.header.set );
gFixedSize32Root.header.set = NewAllocationSet ( 0, "Fixed Block 32" );
DisableAllocationSet ( gFixedSize32Root.header.set );
gFixedSize36Root.header.set = NewAllocationSet ( 0, "Fixed Block 36" );
DisableAllocationSet ( gFixedSize36Root.header.set );
gFixedSize40Root.header.set = NewAllocationSet ( 0, "Fixed Block 40" );
DisableAllocationSet ( gFixedSize40Root.header.set );
gSmallHeapRoot.header.set = NewAllocationSet ( 0, "Small Block" );
DisableAllocationSet ( gSmallHeapRoot.header.set );
gLargeBlockRoot.header.set = NewAllocationSet ( 0, "Large Block" );
DisableAllocationSet ( gLargeBlockRoot.header.set );
#endif
return;
fail:
/* We couldn't initialize one of the sub allocators, so we're screwed */
/* I don't think we need an alert here as we should never hit this case unless */
/* a user really mucks up our heap partition */
ExitToShell();
}
#if STATS_MAC_MEMORY
/* I hate copy and paste */
static void WriteString ( PRFileHandle file, const char * string )
{
long len;
long bytesWritten;
len = strlen( string );
if ( len >= 1024 ) Debugger();
bytesWritten = _OS_WRITE ( file, string, len );
PR_ASSERT(bytesWritten == len);
}
static void WriteFixedAllocatorStats(PRFileHandle outFile, const FixedSizeAllocationRoot *root)
{
char outString[ 1024 ];
WriteString ( outFile, "--------------------------------------------------------------------------------\n" );
sprintf(outString, "Stats for fixed size allocator for blocks of %d-%d bytes\n", root->blockSize - 3, root->blockSize);
WriteString ( outFile, outString );
WriteString ( outFile, "--------------------------------------------------------------------------------\n" );
WriteString ( outFile, " Current Max\n" );
WriteString ( outFile, " ---------- -------\n" );
sprintf( outString, "Num chunks: %10d %10d\n", root->chunksAllocated, root->maxChunksAllocated );
WriteString ( outFile, outString );
sprintf( outString, "Chunk total: %10d %10d\n", root->totalChunkSize, root->maxTotalChunkSize );
WriteString ( outFile, outString );
sprintf( outString, "Num blocks: %10d %10d\n", root->blocksAllocated, root->maxBlocksAllocated );
WriteString ( outFile, outString );
sprintf( outString, "Block space: %10d %10d\n", root->blockSpaceUsed, root->maxBlockSpaceUsed );
WriteString ( outFile, outString );
sprintf( outString, "Blocks used: %10d %10d\n", root->blocksUsed, root->maxBlocksUsed );
WriteString ( outFile, outString );
WriteString ( outFile, " -------\n" );
sprintf( outString, "%s of allocated blocks used: %10.2f\n", "%", 100.0 * root->maxBlocksUsed / root->maxBlocksAllocated );
WriteString ( outFile, outString );
sprintf( outString, "%s of chunk space used: %10.2f\n", "%", 100.0 * root->maxBlockSpaceUsed / root->maxTotalChunkSize );
WriteString ( outFile, outString );
WriteString ( outFile, "\n\n");
}
void DumpAllocatorMemoryStats(PRFileHandle outFile);
void DumpAllocatorMemoryStats(PRFileHandle outFile)
{
/* fixed size allocators */
WriteFixedAllocatorStats( outFile, &gFixedSize4Root );
WriteFixedAllocatorStats( outFile, &gFixedSize8Root );
WriteFixedAllocatorStats( outFile, &gFixedSize12Root );
WriteFixedAllocatorStats( outFile, &gFixedSize16Root );
WriteFixedAllocatorStats( outFile, &gFixedSize20Root );
WriteFixedAllocatorStats( outFile, &gFixedSize24Root );
WriteFixedAllocatorStats( outFile, &gFixedSize32Root );
WriteFixedAllocatorStats( outFile, &gFixedSize36Root );
WriteFixedAllocatorStats( outFile, &gFixedSize40Root );
/*
chunk = SmallHeapAllocChunk ( 0, &gSmallHeapRoot );
PR_ASSERT(chunk);
if ( chunk == NULL ) goto fail;
chunk = LargeBlockAllocChunk ( 0, &gLargeBlockRoot );
PR_ASSERT(chunk);
if ( chunk == NULL ) goto fail;
*/
}
#endif /* STATS_MAC_MEMORY */
//##############################################################################
//##############################################################################
#pragma mark -
#pragma mark INSTALLING MEMORY MANAGER HOOKS
void InstallPreAllocationHook(PreAllocationHookProc newHook)
{
PreAllocationProcRec *preAllocatorRec;
preAllocatorRec = (PreAllocationProcRec *)(NewPtr(sizeof(PreAllocationProcRec)));
if (preAllocatorRec != NULL) {
preAllocatorRec->next = gFirstPreAllocator;
preAllocatorRec->preAllocProc = newHook;
gFirstPreAllocator = preAllocatorRec;
}
}
void InstallMemoryCacheFlusher(MemoryCacheFlusherProc newFlusher)
{
MemoryCacheFlusherProcRec *previousFlusherRec = NULL;
MemoryCacheFlusherProcRec *cacheFlusherRec = gFirstFlusher;
while (cacheFlusherRec != NULL) {
previousFlusherRec = cacheFlusherRec;
cacheFlusherRec = cacheFlusherRec->next;
}
cacheFlusherRec = (MemoryCacheFlusherProcRec *)NewPtrClear(sizeof(MemoryCacheFlusherProcRec));
if (cacheFlusherRec == NULL)
return;
cacheFlusherRec->flushProc = newFlusher;
if (previousFlusherRec != NULL) {
previousFlusherRec->next = cacheFlusherRec;
}
else {
gFirstFlusher = cacheFlusherRec;
}
}
void CallPreAllocators(void)
{
PreAllocationProcRec *currentPreAllocator = gFirstPreAllocator;
while (currentPreAllocator != NULL) {
(*(currentPreAllocator->preAllocProc))();
currentPreAllocator = currentPreAllocator->next;
}
}
static MemoryCacheFlusherProc sGarbageCollectorCacheFlusher = NULL;
/* CallCacheFlushers is only called under extreme conditions now, when an attempt to
allocate a new sub-heap has failed.
The flush procs called here are set up in fredmem.cp:
InstallMemoryCacheFlusher(&ImageCacheMemoryFlusher);
InstallMemoryCacheFlusher(&NetlibCacheMemoryFlusher);
InstallMemoryCacheFlusher(&LayoutCacheMemoryFlusher);
InstallMemoryCacheFlusher(&LibNeoCacheMemoryFlusher);
*/
UInt8 CallCacheFlushers(size_t blockSize)
{
MemoryCacheFlusherProcRec *currentCacheFlusher = gFirstFlusher;
UInt8 result = false;
// we might want to remember which flusher was called last and start
// at the one after, to avoid always flushing the first one (image cache)
// first. But since this is a last-ditch effort to free memory, that's
// probably not worth it.
while (currentCacheFlusher != NULL)
{
result |= (*(currentCacheFlusher->flushProc))(blockSize);
currentCacheFlusher = currentCacheFlusher->next;
}
// We used to try calling the GC if malloc failed, but that's
// a waste of time since the GC never frees segments (bug?)
// and thus won't increase heap space.
return result;
}
void InstallGarbageCollectorCacheFlusher(const MemoryCacheFlusherProc inFlusher)
{
sGarbageCollectorCacheFlusher = inFlusher;
}
void InstallMallocHeapLowProc( MallocHeapLowWarnProc proc )
{
gMallocLowProc = proc;
}
void CallFE_LowMemory(void)
{
if ( gMallocLowProc != NULL )
{
gMallocLowProc();
}
}
//##############################################################################
//##############################################################################
#pragma mark -
#pragma mark SUB HEAP ALLOCATION
SubHeapAllocationChunk * AllocateSubHeap ( SubHeapAllocationRoot * root, Size heapSize, Boolean useTemp )
{
SubHeapAllocationChunk * heapBlock;
Handle tempHandle;
OSErr err;
heapBlock = NULL;
tempHandle = NULL;
#if DEBUG_MAC_MEMORY
DisableMemoryTracker();
#endif
if ( useTemp )
{
tempHandle = TempNewHandle ( heapSize, &err );
if ( tempHandle == NULL )
{
// failed to make temp handle. Let's try a handle in our heap
tempHandle = NewHandle( heapSize );
// ensure that enough free mem is available for emergencies
if ( tempHandle != NULL && MaxBlock() < kHeapEmergencyReserve)
{
// we need to keep some contiguous space free for emergencies. Give up.
DisposeHandle(tempHandle);
tempHandle = NULL;
}
}
if ( tempHandle != NULL && err == noErr )
{
HLockHi ( tempHandle ); // lock the handle hi now to reduce system heap fragmentation
heapBlock = *(SubHeapAllocationChunk **) tempHandle;
}
}
else
{
heapBlock = (SubHeapAllocationChunk *) NewPtr ( heapSize );
}
if ( heapBlock != NULL )
{
heapBlock->root = root;
heapBlock->refCon = tempHandle; // so we can dispose the handle when we're done with the subheap
heapBlock->next = NULL;
heapBlock->usedBlocks = 0;
heapBlock->freeDescriptor.freeRoutine = NULL;
heapBlock->freeDescriptor.refcon = NULL;
// whack this on the root's chunk list
if ( root->lastChunk == NULL )
{
root->firstChunk = heapBlock;
}
else
{
root->lastChunk->next = heapBlock;
}
root->lastChunk = heapBlock;
}
#if DEBUG_MAC_MEMORY
EnableMemoryTracker();
#endif
return heapBlock;
}
void FreeSubHeap ( SubHeapAllocationRoot * root, SubHeapAllocationChunk * chunk )
{
Handle tempHandle;
SubHeapAllocationChunk * list;
SubHeapAllocationChunk * prev;
SubHeapAllocationChunk * next;
if ( chunk != NULL )
{
// run through the root's chunk list and remove our block
prev = NULL;
list = root->firstChunk;
while ( list != NULL )
{
next = list->next;
if ( list == chunk )
{
break;
}
prev = list;
list = next;
}
if ( list != NULL )
{
if ( prev != NULL )
{
prev->next = next;
}
if ( root->firstChunk == list )
{
root->firstChunk = next;
}
if ( root->lastChunk == list )
{
root->lastChunk = prev;
}
}
tempHandle = (Handle) chunk->refCon;
if ( tempHandle != NULL )
{
DisposeHandle ( tempHandle );
}
else
{
DisposePtr ( (Ptr) chunk );
}
}
}
//##############################################################################
//##############################################################################
#pragma mark -
#pragma mark MEMORY UTILS
Boolean gInMemory_ReserveInMacHeap = false;
Boolean InMemory_ReserveInMacHeap()
{
return gInMemory_ReserveInMacHeap;
}
Boolean ReclaimMemory(size_t amountNeeded)
{
Boolean result;
result = CallCacheFlushers(amountNeeded);
return result;
}
Boolean Memory_ReserveInMacHeap(size_t spaceNeeded)
{
Boolean result = true;
gInMemory_ReserveInMacHeap = true;
if (MaxBlock() < spaceNeeded)
result = ReclaimMemory(spaceNeeded);
gInMemory_ReserveInMacHeap = false;
return result;
}
Boolean Memory_ReserveInMallocHeap(size_t spaceNeeded)
{
Boolean result = true;
Size freeMem;
gInMemory_ReserveInMacHeap = true;
freeMem = MaxBlock();
if (freeMem < spaceNeeded)
result = ReclaimMemory(spaceNeeded);
gInMemory_ReserveInMacHeap = false;
return result;
}
size_t Memory_FreeMemoryRemaining()
{
size_t mainHeap;
size_t mallocHeap;
mainHeap = FreeMem();
mallocHeap = FreeMem();
return (mainHeap < mallocHeap) ? mainHeap : mallocHeap;
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,387 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <Types.h>
#include <Memory.h>
#include <stdlib.h>
#pragma error "This file is obsolete, but remains for reference reasons"
#include "MacMemAllocator.h"
/* You probably only want to use this for debugging. It's useful to see leaks
with ZoneRanger.
*/
/* #define MALLOC_IS_NEWPTR 1 */
/* Turn this on to check for block overwrites, heap corruption, bad frees, etc */
#define DEBUG_HEAP_INTEGRITY DEBUG
/* Turn this on to track memory allocations. If you do this, you will have to
allocate a lot more memory to the app (symptoms of too little are bogus
shared library errors on startup)
*/
#define DEBUG_MAC_MEMORY 0
/* This setting is really obsoleted by STATS_MAC_MEMORY, which gives better stats */
#define TRACK_EACH_ALLOCATOR 0
/* Turn this on to track amount of memory allocated and performance of the allocators
If you turn this on, it's better to not define DEBUG_HEAP_INTEGRITY, because
that setting causes each allocation to be 8-12 bytes larger, which messes
up the stats. I've been careful with STATS_MAC_MEMORY to not have it affect
block size at all.
STATS_MAC_MEMORY can be turned on independently of the other debugging settings.
It will cause the creation of a text file, "MemoryStats.txt", in the app
directory, on quit. Its overhead is very low.
*/
#define STATS_MAC_MEMORY 0
/* Turn this on to use Apple's Instrumentation Lib to instrument block allocations
Currently, it collects histogram data on the frequency of allocations of
different sizes for the small and large allocators.
*/
/* #define INSTRUMENT_MAC_MEMORY 1 */
#if INSTRUMENT_MAC_MEMORY
#include "Instrumentation.h"
#include "InstrumentationMacros.h"
#endif
#if DEBUG_MAC_MEMORY
#include "xp_tracker.h"
#endif
//##############################################################################
//##############################################################################
typedef struct SubHeapAllocationRoot SubHeapAllocationRoot;
typedef struct SubHeapAllocationChunk SubHeapAllocationChunk;
enum {
kMaxTableAllocatedBlockSize = 256
};
typedef void *(* AllocMemoryBlockProcPtr)(size_t blockSize, void *refcon);
typedef void (* FreeMemoryBlockProcPtr)(void *freeBlock, void *refcon);
typedef size_t (* BlockSizeProcPtr)(void *freeBlock, void *refcon);
typedef void (* HeapFreeSpaceProcPtr)(size_t blockSize, FreeMemoryStats * stats, void *refcon);
typedef SubHeapAllocationChunk * (* AllocMemoryChunkProcPtr)(size_t blockSize, void *refcon);
struct AllocMemoryBlockDescriptor {
AllocMemoryBlockProcPtr blockAllocRoutine;
AllocMemoryChunkProcPtr chunkAllocRoutine;
HeapFreeSpaceProcPtr heapFreeSpaceRoutine;
SubHeapAllocationRoot *root;
};
typedef struct AllocMemoryBlockDescriptor AllocMemoryBlockDescriptor;
struct FreeMemoryBlockDescriptor {
FreeMemoryBlockProcPtr freeRoutine;
BlockSizeProcPtr sizeRoutine;
void *refcon;
};
typedef struct FreeMemoryBlockDescriptor FreeMemoryBlockDescriptor;
//##############################################################################
//##############################################################################
#if DEBUG_HEAP_INTEGRITY
typedef UInt32 MemoryBlockTag;
#endif
typedef struct MemoryBlockHeader MemoryBlockHeader;
struct MemoryBlockHeader {
FreeMemoryBlockDescriptor *blockFreeRoutine;
#if DEBUG_HEAP_INTEGRITY // || STATS_MAC_MEMORY -- see comment in DumpMemoryStats()
size_t blockSize;
#endif
#if DEBUG_HEAP_INTEGRITY
MemoryBlockTag headerTag;
MemoryBlockHeader *next;
MemoryBlockHeader *prev;
#endif
};
#if DEBUG_HEAP_INTEGRITY
typedef struct MemoryBlockTrailer MemoryBlockTrailer;
struct MemoryBlockTrailer {
MemoryBlockTag trailerTag;
};
#define MEMORY_BLOCK_TAILER_SIZE sizeof(struct MemoryBlockTrailer)
#else
#define MEMORY_BLOCK_TAILER_SIZE 0
#endif
//##############################################################################
//##############################################################################
#pragma mark SUB HEAP ALLOCATOR
struct SubHeapAllocationRoot {
SubHeapAllocationChunk * firstChunk;
SubHeapAllocationChunk * lastChunk;
#if DEBUG_MAC_MEMORY && TRACK_EACH_ALLOCATOR
AllocationSet * set;
#endif
};
struct SubHeapAllocationChunk {
SubHeapAllocationRoot * root;
SubHeapAllocationChunk * next;
void * refCon;
SInt32 usedBlocks;
UInt32 heapSize;
FreeMemoryBlockDescriptor freeDescriptor;
};
// The following two entry points for sub heap allocations
extern SubHeapAllocationChunk * AllocateSubHeap ( SubHeapAllocationRoot * root, Size heapSize, Boolean useTemp );
extern void FreeSubHeap ( SubHeapAllocationRoot * root, SubHeapAllocationChunk * chunk );
#if DEBUG_MAC_MEMORY && TRACK_EACH_ALLOCATOR
#define DECLARE_SUBHEAP_ROOT() { NULL, NULL, NULL }
#else
#define DECLARE_SUBHEAP_ROOT() { NULL, NULL }
#endif
//##############################################################################
//##############################################################################
#pragma mark LARGE BLOCK ALLOCATOR
typedef struct LargeBlockHeader LargeBlockHeader;
struct LargeBlockHeader {
LargeBlockHeader * next;
LargeBlockHeader * prev;
size_t logicalSize;
MemoryBlockHeader header;
};
typedef struct LargeBlockAllocationChunk LargeBlockAllocationChunk;
typedef struct LargeBlockAllocationRoot LargeBlockAllocationRoot;
struct LargeBlockAllocationChunk {
SubHeapAllocationChunk header;
UInt32 totalFree;
LargeBlockHeader * tail;
LargeBlockHeader head[];
};
struct LargeBlockAllocationRoot {
SubHeapAllocationRoot header;
UInt32 baseChunkPercentage;
UInt32 idealTempChunkSize;
UInt32 smallestTempChunkSize;
};
void *LargeBlockAlloc(size_t blockSize, void *refcon);
void LargeBlockFree(void *block, void *refcon);
SubHeapAllocationChunk * LargeBlockAllocChunk ( size_t blockSize, void *refcon );
size_t LargeBlockSize (void *freeBlock, void *refcon);
void LargeBlockHeapFree(size_t blockSize, FreeMemoryStats * stats, void * refcon);
extern LargeBlockAllocationRoot gLargeBlockRoot;
#define DeclareLargeBlockAllocator(basePercentage,idealTmpSize,smallestTmpSize) \
LargeBlockAllocationRoot gLargeBlockRoot = { DECLARE_SUBHEAP_ROOT(), basePercentage, idealTmpSize, smallestTmpSize }
#define DeclareLargeBlockHeapDescriptor() \
{ &LargeBlockAlloc, &LargeBlockAllocChunk, &LargeBlockHeapFree, (SubHeapAllocationRoot *)&gLargeBlockRoot }
//##############################################################################
//##############################################################################
#pragma mark FIXED SIZED ALLOCATOR DEFINITIONS
typedef struct FixedMemoryFreeBlockHeader FixedMemoryFreeBlockHeader;
struct FixedMemoryFreeBlockHeader {
MemoryBlockHeader header;
FixedMemoryFreeBlockHeader * next;
};
typedef struct FixedSizeAllocationChunk FixedSizeAllocationChunk;
typedef struct FixedSizeAllocationRoot FixedSizeAllocationRoot;
struct FixedSizeAllocationChunk {
SubHeapAllocationChunk header;
#if STATS_MAC_MEMORY
UInt32 chunkSize;
UInt32 numBlocks;
#endif
FixedMemoryFreeBlockHeader * freeList;
FixedMemoryFreeBlockHeader memory[];
};
struct FixedSizeAllocationRoot {
SubHeapAllocationRoot header;
UInt32 baseChunkBlockCount;
UInt32 tempChunkBlockCount;
UInt32 blockSize;
#if STATS_MAC_MEMORY
UInt32 chunksAllocated;
UInt32 maxChunksAllocated;
UInt32 totalChunkSize;
UInt32 maxTotalChunkSize;
UInt32 blocksAllocated;
UInt32 maxBlocksAllocated;
UInt32 blocksUsed;
UInt32 maxBlocksUsed;
UInt32 blockSpaceUsed;
UInt32 maxBlockSpaceUsed;
#endif
};
void *FixedSizeAlloc(size_t blockSize, void *refcon);
void FixedSizeFree(void *block, void *refcon);
SubHeapAllocationChunk * FixedSizeAllocChunk ( size_t blockSize, void *refcon );
size_t FixedBlockSize (void *freeBlock, void *refcon);
void FixedBlockHeapFree(size_t blockSize, FreeMemoryStats * stats, void * refcon);
/* When STATS_MAC_MEMORY, the extra fields in the FixedSizeAllocationRoot will be zeroed on initialization */
#define DeclareFixedSizeAllocator(blockSize,baseCount,tempCount) \
extern FixedSizeAllocationRoot gFixedSize##blockSize##Root; \
FixedSizeAllocationRoot gFixedSize##blockSize##Root = { DECLARE_SUBHEAP_ROOT(), baseCount, tempCount, blockSize }
#define DeclareFixedBlockHeapDescriptor(blockSize) \
{ &FixedSizeAlloc, &FixedSizeAllocChunk, &FixedBlockHeapFree, (SubHeapAllocationRoot *)&gFixedSize##blockSize##Root }
//##############################################################################
//##############################################################################
#pragma mark SMALL HEAP ALLOCATOR DEFINITIONS
typedef struct SmallHeapBlock SmallHeapBlock;
struct SmallHeapBlock {
SmallHeapBlock *prevBlock;
UInt32 blockSize;
union {
struct {
SmallHeapBlock *nextFree;
SmallHeapBlock *prevFree;
} freeInfo;
struct {
UInt32 filler;
MemoryBlockHeader freeProc;
} inUseInfo;
} info;
};
enum {
kBlockInUseFlag = 0x80000000,
kDefaultSmallHeadMinSize = 4L,
kDefaultSmallHeapBins = 64L,
kMaximumBinBlockSize = kDefaultSmallHeadMinSize + 4L * kDefaultSmallHeapBins - 1
};
typedef struct SmallHeapChunk SmallHeapChunk;
typedef struct SmallHeapRoot SmallHeapRoot;
struct SmallHeapRoot {
SubHeapAllocationRoot header;
UInt32 baseChunkHeapSize;
UInt32 tempChunkHeapSize;
};
struct SmallHeapChunk {
SubHeapAllocationChunk header;
SmallHeapChunk * nextChunk;
SmallHeapBlock * overflow;
SmallHeapBlock * bins[kDefaultSmallHeapBins];
SmallHeapBlock memory[];
};
#define DeclareSmallHeapAllocator(baseSize, tempSize) \
extern SmallHeapRoot gSmallHeapRoot; \
SmallHeapRoot gSmallHeapRoot = { DECLARE_SUBHEAP_ROOT(), baseSize, tempSize }
#define DeclareSmallSmallHeapDescriptor() \
{ &SmallHeapAlloc, &SmallHeapAllocChunk, &SmallBlockHeapFree, (SubHeapAllocationRoot *)&gSmallHeapRoot }
void *SmallHeapAlloc(size_t blockSize, void *refcon);
void SmallHeapFree(void *address, void *refcon);
SubHeapAllocationChunk * SmallHeapAllocChunk ( size_t blockSize, void *refcon );
size_t SmallBlockSize (void *freeBlock, void *refcon);
void SmallBlockHeapFree(size_t blockSize, FreeMemoryStats * stats, void * refcon);
//##############################################################################
//##############################################################################
#pragma mark LOW LEVEL ALLOCATORS
// Client Provides a table to small block allocators
extern AllocMemoryBlockDescriptor gFastMemSmallSizeAllocators[];
// VerifyMallocHeapIntegrity will report any block headers or
// trailers that have been overwritten.
extern void InstallMemoryManagerPatches();
extern void VerifyMallocHeapIntegrity();
static void TagReferencedBlocks();
extern void DumpMemoryStats();
//##############################################################################
//##############################################################################
#ifdef DEBUG_HEAP_INTEGRITY
extern UInt32 gVerifyHeapOnEveryMalloc;
extern UInt32 gVerifyHeapOnEveryFree;
extern UInt32 gFillUsedBlocksWithPattern;
extern UInt32 gFillFreeBlocksWithPattern;
extern UInt32 gDontActuallyFreeMemory;
extern SInt32 gFailToAllocateAfterNMallocs;
extern SInt32 gTagReferencedBlocks;
#endif
#if INSTRUMENT_MAC_MEMORY
extern InstHistogramClassRef gSmallHeapHistogram;
extern InstHistogramClassRef gLargeHeapHistogram;
#endif

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,296 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#pragma error "This file is obsolete, but remains for reference reasons"
#include <Types.h>
#include <Memory.h>
#include <stdlib.h>
#define DEBUG_MAC_MEMORY 0
#define STATS_MAC_MEMORY 0
//##############################################################################
//##############################################################################
enum {
kMaxTableAllocatedBlockSize = 256,
kRecordingDepthOfStackLevels = 3
};
typedef void *(* AllocMemoryBlockProcPtr)(size_t blockSize, void *refcon);
typedef void (* FreeMemoryBlockProcPtr)(void *freeBlock, void *refcon);
struct AllocMemoryBlockDescriptor {
AllocMemoryBlockProcPtr allocRoutine;
void *refcon;
};
typedef struct AllocMemoryBlockDescriptor AllocMemoryBlockDescriptor;
struct FreeMemoryBlockDescriptor {
FreeMemoryBlockProcPtr freeRoutine;
void *refcon;
};
typedef struct FreeMemoryBlockDescriptor FreeMemoryBlockDescriptor;
//##############################################################################
//##############################################################################
#if DEBUG_MAC_MEMORY
typedef UInt32 MemoryBlockTag;
#endif
typedef struct MemoryBlockHeader MemoryBlockHeader;
struct MemoryBlockHeader {
FreeMemoryBlockDescriptor *blockFreeRoutine;
#if DEBUG_MAC_MEMORY || STATS_MAC_MEMORY
size_t blockSize;
#endif
#if DEBUG_MAC_MEMORY
MemoryBlockHeader *next;
MemoryBlockHeader *prev;
UInt32 blockNum;
void *whoAllocated[kRecordingDepthOfStackLevels];
MemoryBlockTag headerTag;
#endif
};
#if DEBUG_MAC_MEMORY
typedef struct MemoryBlockTrailer MemoryBlockTrailer;
struct MemoryBlockTrailer {
MemoryBlockTag trailerTag;
};
#define MEMORY_BLOCK_TAILER_SIZE sizeof(struct MemoryBlockTrailer)
#else
#define MEMORY_BLOCK_TAILER_SIZE 0
#endif
//##############################################################################
//##############################################################################
#pragma mark STANDARD (SLOW!) ALLOCATOR DEFINITIONS
void *StandardAlloc(size_t blockSize, void *refcon);
void StandardFree(void *block, void *refcon);
//##############################################################################
//##############################################################################
#pragma mark FIXED SIZED (COMPACT) ALLOCATOR DEFINITIONS
typedef struct FixedSizeCompactAllocationChunk FixedSizeCompactAllocationChunk;
typedef struct FixedSizeCompactAllocationRoot FixedSizeCompactAllocationRoot;
struct FixedSizeCompactAllocationChunk {
FixedSizeCompactAllocationChunk *next;
FixedSizeCompactAllocationRoot *root;
UInt32 chunkUsage;
};
struct FixedSizeCompactAllocationRoot {
FixedSizeCompactAllocationChunk *firstChunk;
UInt32 blockSize;
FreeMemoryBlockDescriptor *freeDescriptorTable;
};
void *FixedSizeCompactAlloc(size_t blockSize, void *refcon);
void FixedSizeCompactFree(void *block, void *refcon);
#define DeclareFixedSizeCompactAllocator(blockSize) \
FreeMemoryBlockDescriptor FixedSizeCompact##blockSize##AllocationFreeDescriptors[] = { \
{ &FixedSizeCompactFree, (void *)((0L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 0 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((1L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 1 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((2L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 2 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((3L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 3 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((4L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 4 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((5L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 5 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((6L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 6 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((7L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 7 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((8L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 8 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((9L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 9 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((10L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 10 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((11L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 11 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((12L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 12 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((13L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 13 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((14L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 14 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((15L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 15 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((16L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 16 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((17L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 17 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((18L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 18 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((19L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 19 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((20L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 20 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((21L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 21 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((22L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 22 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((23L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 23 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((24L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 24 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((25L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 25 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((26L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 26 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((27L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 27 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((28L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 28 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((29L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 29 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((30L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 30 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) },\
{ &FixedSizeCompactFree, (void *)((31L << 16) | (sizeof(FixedSizeCompactAllocationChunk) + 31 * (blockSize + sizeof(MemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE))) }\
};\
FixedSizeCompactAllocationRoot gFixedSizeCompact##blockSize##Root = { NULL, blockSize, FixedSizeCompact##blockSize##AllocationFreeDescriptors }\
//##############################################################################
//##############################################################################
#pragma mark FIXED SIZED (FAST) ALLOCATOR DEFINITIONS
typedef struct FixedSizeFastMemoryBlockHeader FixedSizeFastMemoryBlockHeader;
struct FixedSizeFastMemoryBlockHeader {
FixedSizeFastMemoryBlockHeader *nextFree;
MemoryBlockHeader realHeader;
};
typedef struct FixedSizeFastAllocationChunk FixedSizeFastAllocationChunk;
struct FixedSizeFastAllocationChunk {
FixedSizeFastAllocationChunk *next;
};
typedef struct FixedSizeFastAllocationRoot FixedSizeFastAllocationRoot;
struct FixedSizeFastAllocationRoot {
FixedSizeFastAllocationChunk *firstChunk;
FixedSizeFastMemoryBlockHeader *firstFree;
UInt32 blockSize;
UInt32 blocksPerChunk;
FreeMemoryBlockDescriptor *freeDescriptor;
};
void *FixedSizeFastAlloc(size_t blockSize, void *refcon);
void FixedSizeFastFree(void *block, void *refcon);
#define DeclareFixedSizeFastAllocator(blockSize, blocksPerChunk) \
extern FixedSizeFastAllocationRoot gFixedSizeFast##blockSize##Root; \
FreeMemoryBlockDescriptor FixedSizeFast##blockSize##AllocationFreeDescriptor = { &FixedSizeFastFree, (void *)&gFixedSizeFast##blockSize##Root}; \
FixedSizeFastAllocationRoot gFixedSizeFast##blockSize##Root = { NULL, NULL, blockSize, blocksPerChunk, &FixedSizeFast##blockSize##AllocationFreeDescriptor }
//##############################################################################
//##############################################################################
#pragma mark SMALL HEAP ALLOCATOR DEFINITIONS
typedef struct SmallHeapBlock SmallHeapBlock;
struct SmallHeapBlock {
SmallHeapBlock *prevBlock;
UInt32 blockSize;
union {
struct {
SmallHeapBlock *nextFree;
SmallHeapBlock *prevFree;
} freeInfo;
struct {
UInt32 filler;
MemoryBlockHeader freeProc;
} inUseInfo;
} info;
};
enum {
kBlockInUseFlag = 0x80000000,
kDefaultSmallHeadMinSize = 4L,
kDefaultSmallHeapBins = 64L,
kMaximumBinBlockSize = kDefaultSmallHeadMinSize + 4L * kDefaultSmallHeapBins - 1,
kSmallHeapSize = 256 * 1024
};
typedef struct SmallHeapChunk SmallHeapChunk;
typedef struct SmallHeapRoot SmallHeapRoot;
struct SmallHeapRoot {
FreeMemoryBlockDescriptor *blockFreeRoutine;
SmallHeapChunk *firstChunk;
SmallHeapBlock *overflow;
SmallHeapBlock *bins[kDefaultSmallHeapBins];
};
struct SmallHeapChunk {
SmallHeapChunk *nextChunk;
};
#define DeclareSmallHeapAllocator() \
extern SmallHeapRoot gSmallHeapRoot; \
FreeMemoryBlockDescriptor SmallHeapAllocationFreeDescriptor = { &SmallHeapFree, (void *)&gSmallHeapRoot}; \
SmallHeapRoot gSmallHeapRoot = { &SmallHeapAllocationFreeDescriptor }
void *SmallHeapAlloc(size_t blockSize, void *refcon);
void SmallHeapFree(void *address, void *refcon);
//##############################################################################
//##############################################################################
// Clients must provide the following two entry points.
extern AllocMemoryBlockDescriptor gFastMemSmallSizeAllocators[];
extern Ptr AllocateRawMemory(Size blockSize);
extern void FreeRawMemory(Ptr reclaimedRawBlock);
// VerifyMallocHeapIntegrity will report any block headers or
// trailers that have been overwritten.
extern void InstallMemoryManagerPatches();
extern void VerifyMallocHeapIntegrity();
static void TagReferencedBlocks();
extern void DumpAllocHeap();
//##############################################################################
//##############################################################################
#ifdef DEBUG_MAC_MEMORY
extern UInt32 gVerifyHeapOnEveryMalloc;
extern UInt32 gVerifyHeapOnEveryFree;
extern UInt32 gFillUsedBlocksWithPattern;
extern UInt32 gFillFreeBlocksWithPattern;
extern UInt32 gTrackLeaks;
extern UInt32 gDontActuallyFreeMemory;
extern SInt32 gFailToAllocateAfterNMallocs;
extern SInt32 gReportActiveBlocks;
extern SInt32 gReportLeaks;
#endif

Просмотреть файл

@ -1,788 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <new.h> // for placement new
#include <MacTypes.h>
#include <Memory.h>
#include <Errors.h>
#include <Processes.h>
#include <CodeFragments.h>
#if __profile__
#include <Profiler.h>
#endif
#include "nsMemAllocator.h"
#include "nsFixedSizeAllocator.h"
#include "nsSmallHeapAllocator.h"
#include "nsLargeHeapAllocator.h"
#include "nsAllocatorManager.h"
/* prototypes */
#ifdef __cplusplus
extern "C" {
#endif
pascal OSErr __initialize(const CFragInitBlock *theInitBlock);
pascal void __terminate(void);
pascal OSErr __MemInitialize(const CFragInitBlock *theInitBlock);
pascal void __MemTerminate(void);
#ifdef __cplusplus
}
#endif
//--------------------------------------------------------------------
nsHeapZoneHeader::nsHeapZoneHeader(Ptr zonePtr, Size ptrSize)
: mNextHeapZone(nil)
, mZoneHandle(nil)
, mChunkCount(0)
, mHeapZone(nil)
#if DEBUG_HEAP_INTEGRITY
, mSignature(kHeapZoneSignature)
#endif
// This ctor is used for zones in our heap, which are allocated with
// NewPtr
//--------------------------------------------------------------------
{
SetupHeapZone(zonePtr, ptrSize);
}
//--------------------------------------------------------------------
nsHeapZoneHeader::nsHeapZoneHeader(Handle zoneHandle, Size handleSize)
: mNextHeapZone(nil)
, mZoneHandle(zoneHandle)
, mChunkCount(0)
, mHeapZone(nil)
#if DEBUG_HEAP_INTEGRITY
, mSignature(kHeapZoneSignature)
#endif
// This ctor is used for zones in temporary memory, which are allocated
// with TempNewHandle
//--------------------------------------------------------------------
{
// handle should be locked here
SetupHeapZone(*zoneHandle, handleSize);
}
//--------------------------------------------------------------------
nsHeapZoneHeader::~nsHeapZoneHeader()
//--------------------------------------------------------------------
{
if (mZoneHandle)
::DisposeHandle(mZoneHandle);
else
::DisposePtr((Ptr)this);
MEM_ASSERT(::MemError() == noErr, "Error on Mac memory dispose");
}
//--------------------------------------------------------------------
void nsHeapZoneHeader::SetupHeapZone(Ptr zonePtr, Size ptrSize)
//--------------------------------------------------------------------
{
Ptr zoneStart = zonePtr + sizeof(nsHeapZoneHeader);
Ptr endZone = zonePtr + ptrSize;
#if !TARGET_CARBON
::InitZone(nil, kHeapZoneMasterPointers, endZone, zoneStart);
#endif
mHeapZone = (THz)zoneStart;
#if !TARGET_CARBON
// set the current zone back to the application zone, because InitZone changes it
::SetZone(::ApplicationZone());
#endif
}
//--------------------------------------------------------------------
Ptr nsHeapZoneHeader::AllocateZonePtr(Size ptrSize)
//--------------------------------------------------------------------
{
#if !TARGET_CARBON
::SetZone(mHeapZone);
#endif
Ptr thePtr = ::NewPtr(ptrSize);
#if !TARGET_CARBON
::SetZone(::ApplicationZone());
#endif
mChunkCount += (thePtr != nil);
return thePtr;
}
//--------------------------------------------------------------------
void nsHeapZoneHeader::DisposeZonePtr(Ptr thePtr, Boolean &outWasLastChunk)
//--------------------------------------------------------------------
{
#if !TARGET_CARBON
MEM_ASSERT(::PtrZone(thePtr) == mHeapZone, "Ptr disposed from wrong zone!");
#endif
::DisposePtr(thePtr);
mChunkCount --;
outWasLastChunk = (mChunkCount == 0);
}
//--------------------------------------------------------------------
/* static */ nsHeapZoneHeader* nsHeapZoneHeader::GetZoneFromPtr(Ptr subheapPtr)
//--------------------------------------------------------------------
{
#if !TARGET_CARBON
THz ptrZone = ::PtrZone(subheapPtr);
MEM_ASSERT(ptrZone && (::MemError() == noErr), "Problem getting zone from ptr");
return (nsHeapZoneHeader *)((char *)ptrZone - sizeof(nsHeapZoneHeader));
#else
return NULL;
#endif
}
#pragma mark -
const SInt32 nsAllocatorManager::kNumMasterPointerBlocks = 30;
const SInt32 nsAllocatorManager::kApplicationStackSizeIncrease = (32 * 1024);
const float nsAllocatorManager::kHeapZoneHeapPercentage = 0.5;
const SInt32 nsAllocatorManager::kSmallHeapByteRange = 16;
nsAllocatorManager* nsAllocatorManager::sAllocatorManager = nil;
//--------------------------------------------------------------------
nsAllocatorManager::nsAllocatorManager()
: mFixedSizeAllocators(nil)
, mSmallBlockAllocators(nil)
, mLargeAllocator(nil)
, mFirstHeapZone(nil)
, mLastHeapZone(nil)
//--------------------------------------------------------------------
{
mMinSmallBlockSize = 165; //128; //44; // some magic numbers for now
mMinLargeBlockSize = 261; //512; //256;
mNumFixedSizeAllocators = mMinSmallBlockSize / 4;
mNumSmallBlockAllocators = 1 + (mMinLargeBlockSize - mMinSmallBlockSize) / kSmallHeapByteRange;
}
//--------------------------------------------------------------------
nsAllocatorManager::~nsAllocatorManager()
//--------------------------------------------------------------------
{
for (SInt32 i = 0; i < mNumFixedSizeAllocators; i ++)
{
// because we used NewPtr and placement new, we have to destruct thus
mFixedSizeAllocators[i]->~nsMemAllocator();
DisposePtr((Ptr)mFixedSizeAllocators[i]);
}
DisposePtr((Ptr)mFixedSizeAllocators);
for (SInt32 i = 0; i < mNumSmallBlockAllocators; i ++)
{
// because we used NewPtr and placement new, we have to destruct thus
mSmallBlockAllocators[i]->~nsMemAllocator();
DisposePtr((Ptr)mSmallBlockAllocators[i]);
}
DisposePtr((Ptr)mSmallBlockAllocators);
mLargeAllocator->~nsMemAllocator();
DisposePtr((Ptr)mLargeAllocator);
}
//--------------------------------------------------------------------
OSErr nsAllocatorManager::InitializeAllocators()
//--------------------------------------------------------------------
{
//can't use new yet!
mFixedSizeAllocators = (nsMemAllocator **)NewPtrClear(mNumFixedSizeAllocators * sizeof(nsMemAllocator*));
if (mFixedSizeAllocators == nil)
return memFullErr;
mSmallBlockAllocators = (nsMemAllocator **)NewPtrClear(mNumSmallBlockAllocators * sizeof(nsMemAllocator*));
if (mSmallBlockAllocators == nil)
return memFullErr;
for (SInt32 i = 0; i < mNumFixedSizeAllocators; i ++)
{
mFixedSizeAllocators[i] = (nsMemAllocator *)NewPtr(sizeof(nsFixedSizeAllocator));
if (mFixedSizeAllocators[i] == nil)
return memFullErr;
new (mFixedSizeAllocators[i]) nsFixedSizeAllocator(i * 4 + (i > 0) * 1, (i + 1) * 4);
}
for (SInt32 i = 0; i < mNumSmallBlockAllocators; i ++)
{
mSmallBlockAllocators[i] = (nsMemAllocator *)NewPtr(sizeof(nsSmallHeapAllocator));
if (mSmallBlockAllocators[i] == nil)
return memFullErr;
SInt32 minBytes = mMinSmallBlockSize + i * kSmallHeapByteRange; // lower bound of block size
new (mSmallBlockAllocators[i]) nsSmallHeapAllocator(minBytes, minBytes + kSmallHeapByteRange - 1);
}
mLargeAllocator = (nsMemAllocator *)NewPtr(sizeof(nsLargeHeapAllocator));
if (mLargeAllocator == nil)
return memFullErr;
new (mLargeAllocator) nsLargeHeapAllocator(mMinLargeBlockSize, 0x7FFFFFFF);
// make the heap zone for our subheaps
UInt32 heapZoneSize;
heapZoneSize = (UInt32)(kHeapZoneHeapPercentage * ::FreeMem());
heapZoneSize = ( ( heapZoneSize + 3 ) & ~3 ); // round up to a multiple of 4 bytes
nsHeapZoneHeader *firstZone = MakeNewHeapZone(heapZoneSize, heapZoneSize);
if (!firstZone)
return memFullErr;
return noErr;
}
//--------------------------------------------------------------------
nsMemAllocator* nsAllocatorManager::GetAllocatorForBlockSize(size_t blockSize)
//--------------------------------------------------------------------
{
if (blockSize < mMinSmallBlockSize)
return mFixedSizeAllocators[ (blockSize == 0) ? 0 : ((blockSize + 3) >> 2) - 1 ];
if (blockSize < mMinLargeBlockSize)
return mSmallBlockAllocators[ ((blockSize - mMinSmallBlockSize + kSmallHeapByteRange) / kSmallHeapByteRange) - 1 ];
//return mSmallBlockAllocators[ ((blockSize + (kSmallHeapByteRange - 1)) / kSmallHeapByteRange) - mNumFixedSizeAllocators ];
return mLargeAllocator;
}
//--------------------------------------------------------------------
size_t nsAllocatorManager::GetBlockSize(void *thisBlock)
//--------------------------------------------------------------------
{
nsMemAllocator* allocator = GetAllocatorFromBlock(thisBlock);
#if DEBUG_HEAP_INTEGRITY
MEM_ASSERT(allocator && allocator->IsGoodAllocator(), "Failed to get allocator for block");
#endif
switch (allocator->GetAllocatorType())
{
case nsMemAllocator::eAllocatorTypeFixed:
return ((nsFixedSizeAllocator*)allocator)->AllocatorGetBlockSize(thisBlock);
case nsMemAllocator::eAllocatorTypeSmall:
return ((nsSmallHeapAllocator*)allocator)->AllocatorGetBlockSize(thisBlock);
case nsMemAllocator::eAllocatorTypeLarge:
return ((nsLargeHeapAllocator*)allocator)->AllocatorGetBlockSize(thisBlock);
}
return 0;
}
//--------------------------------------------------------------------
nsHeapZoneHeader* nsAllocatorManager::MakeNewHeapZone(Size zoneSize, Size minZoneSize)
//--------------------------------------------------------------------
{
if (mFirstHeapZone == nil)
{
Ptr firstZonePtr = ::NewPtr(zoneSize);
if (!firstZonePtr) return nil;
mFirstHeapZone = new (firstZonePtr) nsHeapZoneHeader(firstZonePtr, zoneSize);
mLastHeapZone = mFirstHeapZone;
}
else
{
OSErr err;
Handle tempMemHandle = ::TempNewHandle(zoneSize, &err);
while (!tempMemHandle && zoneSize > minZoneSize)
{
zoneSize -= (128 * 1024);
tempMemHandle = ::TempNewHandle(zoneSize, &err);
}
if (!tempMemHandle) return nil;
// first, lock the handle hi
HLockHi(tempMemHandle);
nsHeapZoneHeader *newZone = new (*tempMemHandle) nsHeapZoneHeader(tempMemHandle, zoneSize);
mLastHeapZone->SetNextZone(newZone);
mLastHeapZone = newZone;
}
return mLastHeapZone;
}
// block size multiple. All blocks should be multiples of this size,
// to reduce heap fragmentation
const Size nsAllocatorManager::kChunkSizeMultiple = 2 * 1024;
const Size nsAllocatorManager::kMaxChunkSize = 48 * 1024;
const Size nsAllocatorManager::kMacMemoryPtrOvehead = 16; // this overhead is documented in IM:Memory 2-22
const Size nsAllocatorManager::kTempMemHeapZoneSize = 1024 * 1024; // 1MB temp handles
const Size nsAllocatorManager::kTempMemHeapMinZoneSize = 256 * 1024; // min 256K handle
//--------------------------------------------------------------------
Ptr nsAllocatorManager::AllocateSubheap(Size preferredSize, Size &outActualSize)
//--------------------------------------------------------------------
{
nsHeapZoneHeader *thisHeapZone = mFirstHeapZone;
// calculate an ideal chunk size by rounding up
preferredSize = kChunkSizeMultiple * ((preferredSize + (kChunkSizeMultiple - 1)) / kChunkSizeMultiple);
// take into account the memory manager's pointer overhead (16 btyes), to avoid fragmentation
preferredSize += ((preferredSize / kChunkSizeMultiple) - 1) * kMacMemoryPtrOvehead;
outActualSize = preferredSize;
while (thisHeapZone)
{
Ptr subheapPtr = thisHeapZone->AllocateZonePtr(preferredSize);
if (subheapPtr)
return subheapPtr;
thisHeapZone = thisHeapZone->GetNextZone();
}
// we failed to allocate. Let's make a new heap zone
UInt32 prefZoneSize = preferredSize + sizeof(nsHeapZoneHeader) + 512; // for zone overhead
UInt32 zoneSize = (kTempMemHeapZoneSize > prefZoneSize) ? kTempMemHeapZoneSize : prefZoneSize;
UInt32 minZoneSize = (kTempMemHeapMinZoneSize > prefZoneSize) ? kTempMemHeapMinZoneSize : prefZoneSize;
thisHeapZone = MakeNewHeapZone(zoneSize, minZoneSize);
if (thisHeapZone)
return thisHeapZone->AllocateZonePtr(preferredSize);
return nil;
}
//--------------------------------------------------------------------
void nsAllocatorManager::FreeSubheap(Ptr subheapPtr)
//--------------------------------------------------------------------
{
nsHeapZoneHeader *ptrHeapZone = nsHeapZoneHeader::GetZoneFromPtr(subheapPtr);
#if DEBUG_HEAP_INTEGRITY
MEM_ASSERT(ptrHeapZone->IsGoodZone(), "Got bad heap zone header");
#endif
Boolean lastChunk;
ptrHeapZone->DisposeZonePtr(subheapPtr, lastChunk);
if (lastChunk)
{
// remove from the list
nsHeapZoneHeader *prevZone = nil;
nsHeapZoneHeader *nextZone = nil;
nsHeapZoneHeader *thisZone = mFirstHeapZone;
while (thisZone)
{
nextZone = thisZone->GetNextZone();
if (thisZone == ptrHeapZone)
break;
prevZone = thisZone;
thisZone = nextZone;
}
if (thisZone)
{
if (prevZone)
prevZone->SetNextZone(nextZone);
if (mFirstHeapZone == thisZone)
mFirstHeapZone = nextZone;
if (mLastHeapZone == thisZone)
mLastHeapZone = prevZone;
}
// dispose it
ptrHeapZone->~nsHeapZoneHeader(); // this disposes the ptr/handle
}
}
//--------------------------------------------------------------------
/* static */ OSErr nsAllocatorManager::InitializeMacMemory(SInt32 inNumMasterPointerBlocks,
SInt32 inAppStackSizeInc)
//--------------------------------------------------------------------
{
if (sAllocatorManager) return noErr;
// increase the stack size by 32k. Someone is bound to have fun with
// recursion
#if !TARGET_CARBON
SetApplLimit(GetApplLimit() - inAppStackSizeInc);
MaxApplZone();
#endif
for (SInt32 i = 1; i <= inNumMasterPointerBlocks; i++)
MoreMasters();
// initialize our allocator object. We have to do this through NewPtr
// and placement new, because we can't call new yet.
OSErr err;
Ptr allocatorManager = NewPtr(sizeof(nsAllocatorManager));
if (!allocatorManager) return memFullErr;
// use placement new. The constructor can throw
sAllocatorManager = new (allocatorManager) nsAllocatorManager;
err = sAllocatorManager->InitializeAllocators();
if (err != noErr)
return err;
return noErr;
}
//--------------------------------------------------------------------
/* static */ nsAllocatorManager * nsAllocatorManager::CreateAllocatorManager()
//--------------------------------------------------------------------
{
if (sAllocatorManager) return sAllocatorManager;
if (InitializeMacMemory(kNumMasterPointerBlocks, kApplicationStackSizeIncrease) != noErr)
{
#ifdef DEBUG
::DebugStr("\pAllocator Manager initialization failed");
#endif
::ExitToShell();
}
return sAllocatorManager;
}
#if STATS_MAC_MEMORY
//--------------------------------------------------------------------
void nsAllocatorManager::DumpMemoryStats()
//--------------------------------------------------------------------
{
UInt32 i;
PRFileDesc *outFile;
// Enter a valid, UNIX-style full path on your system to get this
// to work.
outFile = PR_Open("MemoryStats.txt", PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE, 0644);
if ( outFile == NULL )
{
return;
}
WriteString(outFile, "\n\n--------------------------------------------------------------------------------\n");
WriteString(outFile, "Max heap usage chart (* = 1024 bytes)\n");
WriteString(outFile, "--------------------------------------------------------------------------------\n\n");
UInt32 totHeapUsed = 0;
for (i = 0; i < mNumFixedSizeAllocators; i ++)
{
mFixedSizeAllocators[i]->DumpHeapUsage(outFile);
totHeapUsed += mFixedSizeAllocators[i]->GetMaxHeapUsage();
}
for (i = 0; i < mNumSmallBlockAllocators; i ++)
{
mSmallBlockAllocators[i]->DumpHeapUsage(outFile);
totHeapUsed += mSmallBlockAllocators[i]->GetMaxHeapUsage();
}
char outString[256];
sprintf(outString, "Total heap space used by allocators: %ldk\n", totHeapUsed / 1024);
WriteString(outFile, "--------------------------------------------------------------------------------\n");
WriteString(outFile, outString);
WriteString(outFile, "--------------------------------------------------------------------------------\n\n");
for (i = 0; i < mNumFixedSizeAllocators; i ++)
{
mFixedSizeAllocators[i]->DumpMemoryStats(outFile);
}
for (i = 0; i < mNumSmallBlockAllocators; i ++)
{
mSmallBlockAllocators[i]->DumpMemoryStats(outFile);
}
mLargeAllocator->DumpMemoryStats(outFile);
PR_Close(outFile);
}
//--------------------------------------------------------------------
void WriteString(PRFileDesc *file, const char * string)
//--------------------------------------------------------------------
{
long len;
long bytesWritten;
len = strlen ( string );
if ( len >= 1024 ) Debugger();
bytesWritten = PR_Write(file, string, len);
}
#endif
#pragma mark -
//--------------------------------------------------------------------
void *std::malloc(size_t blockSize)
//--------------------------------------------------------------------
{
// local static copy is slightly faster
static nsAllocatorManager* sManager;
if (!sManager)
sManager = nsAllocatorManager::GetAllocatorManager();
nsMemAllocator *allocator = sManager->GetAllocatorForBlockSize(blockSize);
MEM_ASSERT(allocator && allocator->IsGoodAllocator(), "This allocator ain't no good");
#if DEBUG_HEAP_INTEGRITY
void *newBlock;
// we are switching here, instead of using virtual methods, for performance
switch (allocator->GetAllocatorType())
{
case nsMemAllocator::eAllocatorTypeFixed:
newBlock = ((nsFixedSizeAllocator*)allocator)->AllocatorMakeBlock(blockSize);
break;
case nsMemAllocator::eAllocatorTypeSmall:
newBlock = ((nsSmallHeapAllocator*)allocator)->AllocatorMakeBlock(blockSize);
break;
case nsMemAllocator::eAllocatorTypeLarge:
newBlock = ((nsLargeHeapAllocator*)allocator)->AllocatorMakeBlock(blockSize);
break;
}
if (newBlock)
{
MemoryBlockHeader *blockHeader = MemoryBlockHeader::GetHeaderFromBlock(newBlock);
static UInt32 sBlockID = 0;
blockHeader->blockID = sBlockID++;
}
#if 0
else
{
DebugStr("\pAllocation failure");
}
#endif
return newBlock;
#else
// we are switching here, instead of using virtual methods, for performance
switch (allocator->GetAllocatorType())
{
case nsMemAllocator::eAllocatorTypeFixed:
return ((nsFixedSizeAllocator*)allocator)->AllocatorMakeBlock(blockSize);
case nsMemAllocator::eAllocatorTypeSmall:
return ((nsSmallHeapAllocator*)allocator)->AllocatorMakeBlock(blockSize);
case nsMemAllocator::eAllocatorTypeLarge:
return ((nsLargeHeapAllocator*)allocator)->AllocatorMakeBlock(blockSize);
}
return nil;
//return allocator->AllocatorMakeBlock(blockSize);
#endif
}
//--------------------------------------------------------------------
void std::free(void *deadBlock)
//--------------------------------------------------------------------
{
if (!deadBlock) return;
nsMemAllocator *allocator = nsAllocatorManager::GetAllocatorFromBlock(deadBlock);
MEM_ASSERT(allocator && allocator->IsGoodAllocator(), "Can't get block's allocator on free. The block is hosed");
switch (allocator->GetAllocatorType())
{
case nsMemAllocator::eAllocatorTypeFixed:
((nsFixedSizeAllocator*)allocator)->AllocatorFreeBlock(deadBlock);
break;
case nsMemAllocator::eAllocatorTypeSmall:
((nsSmallHeapAllocator*)allocator)->AllocatorFreeBlock(deadBlock);
break;
case nsMemAllocator::eAllocatorTypeLarge:
((nsLargeHeapAllocator*)allocator)->AllocatorFreeBlock(deadBlock);
break;
}
}
//--------------------------------------------------------------------
void* std::realloc(void* block, size_t newSize)
//--------------------------------------------------------------------
{
void *newBlock = nil;
if (block)
{
nsMemAllocator *allocator = nsAllocatorManager::GetAllocatorFromBlock(block);
MEM_ASSERT(allocator && allocator->IsGoodAllocator(), "Can't get block's allocator on realloc. The block is hosed");
switch (allocator->GetAllocatorType())
{
case nsMemAllocator::eAllocatorTypeFixed:
newBlock = ((nsFixedSizeAllocator*)allocator)->AllocatorResizeBlock(block, newSize);
break;
case nsMemAllocator::eAllocatorTypeSmall:
newBlock = ((nsSmallHeapAllocator*)allocator)->AllocatorResizeBlock(block, newSize);
break;
case nsMemAllocator::eAllocatorTypeLarge:
newBlock = ((nsLargeHeapAllocator*)allocator)->AllocatorResizeBlock(block, newSize);
break;
}
if (newBlock) return newBlock;
}
newBlock = malloc(newSize);
if (!newBlock) return nil;
if (block)
{
size_t oldSize = nsAllocatorManager::GetBlockSize(block);
BlockMoveData(block, newBlock, newSize < oldSize ? newSize : oldSize);
free(block);
}
return newBlock;
}
//--------------------------------------------------------------------
void *std::calloc(size_t nele, size_t elesize)
//--------------------------------------------------------------------
{
size_t space = nele * elesize;
void *newBlock = malloc(space);
if (newBlock)
memset(newBlock, 0, space);
return newBlock;
}
#pragma mark -
/*----------------------------------------------------------------------------
__MemInitialize
Note the people can call malloc() or new() before we come here,
so we can't rely on this being called before we do allocation.
----------------------------------------------------------------------------*/
pascal OSErr __MemInitialize(const CFragInitBlock *theInitBlock)
{
OSErr err = __initialize(theInitBlock);
if (err != noErr) return err;
#if __profile__
if (ProfilerInit(collectDetailed, bestTimeBase, 500, 20) != noErr)
ExitToShell();
#endif
return noErr;
}
/*----------------------------------------------------------------------------
__MemTerminate
Code frag Terminate routine. We could do more tear-down here, but we
cannot be sure that anyone else doesn't still need to reference
memory that we are managing. So we can't just free all the heaps.
We rely on the Proess Manager to free handles that we left in temp
mem (see IM: Memory).
----------------------------------------------------------------------------*/
pascal void __MemTerminate(void)
{
#if __profile__
ProfilerDump("\pMemory Tester.prof");
ProfilerTerm();
#endif
#if STATS_MAC_MEMORY
nsAllocatorManager::GetAllocatorManager()->DumpMemoryStats();
#endif
__terminate();
}

Просмотреть файл

@ -1,188 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <MacTypes.h>
#if STATS_MAC_MEMORY
#include "prio.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if STATS_MAC_MEMORY
void WriteString(PRFileDesc *file, const char * string);
#endif
#ifdef __cplusplus
}
#endif
//--------------------------------------------------------------------
class nsHeapZoneHeader
{
public:
nsHeapZoneHeader(Ptr zonePtr, Size ptrSize);
nsHeapZoneHeader(Handle zoneHandle, Size handleSize);
~nsHeapZoneHeader();
nsHeapZoneHeader * GetNextZone() { return mNextHeapZone; }
void SetNextZone(nsHeapZoneHeader *nextZone) { mNextHeapZone = nextZone; }
Ptr AllocateZonePtr(Size ptrSize);
void DisposeZonePtr(Ptr thePtr, Boolean &outWasLastChunk);
#if DEBUG_HEAP_INTEGRITY
Boolean IsGoodZone() { return (mSignature == kHeapZoneSignature); }
#endif
static nsHeapZoneHeader* GetZoneFromPtr(Ptr subheapPtr);
protected:
void SetupHeapZone(Ptr zonePtr, Size zoneSize);
enum
{
kHeapZoneMasterPointers = 24 // this number doesn't really matter, because we never
// allocate handles in our heap zones
};
#if DEBUG_HEAP_INTEGRITY
enum {
kHeapZoneSignature = 'HZne'
};
OSType mSignature;
#endif
nsHeapZoneHeader *mNextHeapZone;
Handle mZoneHandle; // the handle containing the zone. Nil if Ptr in app heap
UInt32 mChunkCount; // how many chunks are allocated in this zone
THz mHeapZone;
};
class nsAllocatorManager
{
public:
static const SInt32 kNumMasterPointerBlocks;
static const SInt32 kApplicationStackSizeIncrease;
static const float kHeapZoneHeapPercentage;
static const SInt32 kTempMemHeapZoneSize;
static const SInt32 kTempMemHeapMinZoneSize;
static const Size kChunkSizeMultiple;
static const Size kMaxChunkSize;
static const SInt32 kSmallHeapByteRange;
static nsAllocatorManager* GetAllocatorManager() { return sAllocatorManager ? sAllocatorManager : CreateAllocatorManager(); }
nsAllocatorManager();
~nsAllocatorManager();
OSErr InitializeAllocators();
static OSErr InitializeMacMemory(SInt32 inNumMasterPointerBlocks,
SInt32 inAppStackSizeInc);
inline nsMemAllocator* GetAllocatorForBlockSize(size_t blockSize);
static nsMemAllocator* GetAllocatorFromBlock(void *thisBlock)
{
MemoryBlockHeader *blockHeader = MemoryBlockHeader::GetHeaderFromBlock(thisBlock);
#if DEBUG_HEAP_INTEGRITY
MEM_ASSERT(blockHeader->HasHeaderTag(kUsedBlockHeaderTag), "Bad block header tag");
MEM_ASSERT(blockHeader->owningChunk->IsGoodChunk(), "Block has bad chunk pointer");
#endif
return (blockHeader->owningChunk->GetOwningAllocator());
}
static size_t GetBlockSize(void *thisBlock);
Ptr AllocateSubheap(Size preferredSize, Size &outActualSize);
void FreeSubheap(Ptr subheapPtr);
#if STATS_MAC_MEMORY
void DumpMemoryStats();
#endif
static nsAllocatorManager* CreateAllocatorManager();
protected:
static const Size kMacMemoryPtrOvehead;
nsHeapZoneHeader * MakeNewHeapZone(Size zoneSize, Size minZoneSize);
private:
SInt32 mNumFixedSizeAllocators;
SInt32 mNumSmallBlockAllocators;
UInt32 mMinSmallBlockSize; // blocks >= this size come out of the small block allocator
UInt32 mMinLargeBlockSize; // blocks >= this size come out of the large allocator
nsMemAllocator** mFixedSizeAllocators; // array of pointers to allocator objects
nsMemAllocator** mSmallBlockAllocators; // array of pointers to allocator objects
nsMemAllocator* mLargeAllocator;
nsHeapZoneHeader* mFirstHeapZone; // first of a linked list of heap zones
nsHeapZoneHeader* mLastHeapZone; // last of a linked list of heap zones
THz mHeapZone; // the heap zone for our memory heaps
static nsAllocatorManager *sAllocatorManager;
};

Просмотреть файл

@ -1,279 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <new.h> // for placement new
#include <MacMemory.h>
#include "nsMemAllocator.h"
#include "nsAllocatorManager.h"
#include "nsFixedSizeAllocator.h"
const UInt32 FixedMemoryBlock::kFixedSizeBlockOverhead = sizeof(FixedMemoryBlockHeader) + MEMORY_BLOCK_TAILER_SIZE;
//--------------------------------------------------------------------
nsFixedSizeAllocator::nsFixedSizeAllocator(size_t minBlockSize, size_t maxBlockSize)
: nsMemAllocator(eAllocatorTypeFixed, minBlockSize, maxBlockSize)
, mChunkWithSpace(nil)
//--------------------------------------------------------------------
{
mBaseChunkSize = mTempChunkSize = (nsAllocatorManager::kChunkSizeMultiple);
}
//--------------------------------------------------------------------
nsFixedSizeAllocator::~nsFixedSizeAllocator()
//--------------------------------------------------------------------
{
}
//--------------------------------------------------------------------
nsHeapChunk* nsFixedSizeAllocator::FindChunkWithSpace(size_t blockSize) const
//--------------------------------------------------------------------
{
if (mChunkWithSpace && mChunkWithSpace->GetFreeList())
return mChunkWithSpace;
nsFixedSizeHeapChunk* chunk = (nsFixedSizeHeapChunk *)mFirstChunk;
// Try to find an existing chunk with a free block.
while (chunk != nil)
{
if (chunk->GetFreeList() != nil)
return chunk;
chunk = (nsFixedSizeHeapChunk *)chunk->GetNextChunk();
}
return nil;
}
//--------------------------------------------------------------------
void *nsFixedSizeAllocator::AllocatorMakeBlock(size_t blockSize)
//--------------------------------------------------------------------
{
nsFixedSizeHeapChunk* chunk = (nsFixedSizeHeapChunk *)FindChunkWithSpace(blockSize);
if (chunk == nil)
{
chunk = (nsFixedSizeHeapChunk *)AllocateChunk(blockSize);
if (!chunk) return nil;
mChunkWithSpace = chunk;
}
FixedMemoryBlock* blockHeader = chunk->FetchFirstFree();
#if DEBUG_HEAP_INTEGRITY
blockHeader->SetHeaderTag(kUsedBlockHeaderTag);
blockHeader->SetTrailerTag(GetAllocatorBlockSize(), kUsedBlockTrailerTag);
blockHeader->ZapBlockContents(blockSize, kUsedMemoryFillPattern);
UInt32 paddedSize = (blockSize + 3) & ~3;
blockHeader->SetPaddingBytes(paddedSize - blockSize);
blockHeader->FillPaddingBytes(mMaxBlockSize);
#endif
#if STATS_MAC_MEMORY
blockHeader->blockHeader.header.logicalBlockSize = blockSize;
AccountForNewBlock(blockSize);
#endif
return (void *)&blockHeader->memory;
}
//--------------------------------------------------------------------
void nsFixedSizeAllocator::AllocatorFreeBlock(void *freeBlock)
//--------------------------------------------------------------------
{
FixedMemoryBlock* blockHeader = FixedMemoryBlock::GetBlockHeader(freeBlock);
#if DEBUG_HEAP_INTEGRITY
MEM_ASSERT(blockHeader->HasHeaderTag(kUsedBlockHeaderTag), "Bad block header");
MEM_ASSERT(blockHeader->GetTrailerTag(GetAllocatorBlockSize()) == kUsedBlockTrailerTag, "Bad block trailer");
MEM_ASSERT(blockHeader->CheckPaddingBytes(GetAllocatorBlockSize()), "Block bounds have been overwritten");
blockHeader->ZapBlockContents(GetAllocatorBlockSize(), kFreeMemoryFillPattern);
#endif
#if STATS_MAC_MEMORY
AccountForFreedBlock(blockHeader->blockHeader.header.logicalBlockSize);
#endif
nsFixedSizeHeapChunk* chunk = blockHeader->GetOwningChunk();
#if DEBUG_HEAP_INTEGRITY
blockHeader->SetHeaderTag(kFreeBlockHeaderTag);
blockHeader->SetTrailerTag(GetAllocatorBlockSize(), kFreeBlockTrailerTag);
#endif
chunk->ReturnToFreeList(blockHeader);
// if this chunk is completely empty and it's not the first chunk then free it
if ( chunk->IsEmpty() && chunk != mFirstChunk )
{
if (chunk == mChunkWithSpace)
mChunkWithSpace = nil;
FreeChunk(chunk);
}
else
{
mChunkWithSpace = chunk; // we know is has some space now
}
}
//--------------------------------------------------------------------
void *nsFixedSizeAllocator::AllocatorResizeBlock(void *block, size_t newSize)
//--------------------------------------------------------------------
{
// let blocks shrink to at most 16 bytes below this allocator's block size
if (newSize > mMaxBlockSize || newSize <= mMaxBlockSize - kMaxBlockResizeSlop)
return nil;
FixedMemoryBlock* blockHeader = FixedMemoryBlock::GetBlockHeader(block);
#if DEBUG_HEAP_INTEGRITY
MEM_ASSERT(blockHeader->HasHeaderTag(kUsedBlockHeaderTag), "Bad block header");
MEM_ASSERT(blockHeader->GetTrailerTag(GetAllocatorBlockSize()) == kUsedBlockTrailerTag, "Bad block trailer");
MEM_ASSERT(blockHeader->CheckPaddingBytes(mMaxBlockSize), "Block bounds have been overwritten");
// if we shrunk the block to below this allocator's normal size range, then these
// padding bytes won't be any use. But they are tested using mBlockSize, so we
// have to udpate them anyway.
UInt32 paddedSize = (newSize + 3) & ~3;
blockHeader->SetPaddingBytes(paddedSize - newSize);
blockHeader->FillPaddingBytes(mMaxBlockSize);
#endif
#if STATS_MAC_MEMORY
AccountForResizedBlock(blockHeader->blockHeader.header.logicalBlockSize, newSize);
blockHeader->blockHeader.header.logicalBlockSize = newSize;
#endif
return block;
}
//--------------------------------------------------------------------
size_t nsFixedSizeAllocator::AllocatorGetBlockSize(void *thisBlock)
//--------------------------------------------------------------------
{
return mMaxBlockSize;
}
//--------------------------------------------------------------------
nsHeapChunk *nsFixedSizeAllocator::AllocateChunk(size_t requestedBlockSize)
//--------------------------------------------------------------------
{
Size actualChunkSize;
// adapt the chunk size if we have already allocated a number of chunks, and it's not above a max size
if (mNumChunks > 4 && mBaseChunkSize < nsAllocatorManager::kMaxChunkSize)
mBaseChunkSize *= 2;
Ptr chunkMemory = nsAllocatorManager::GetAllocatorManager()->AllocateSubheap(mBaseChunkSize, actualChunkSize);
if (!chunkMemory) return nil;
// use placement new to initialize the chunk in the memory block
nsHeapChunk *newHeapChunk = new (chunkMemory) nsFixedSizeHeapChunk(this, actualChunkSize);
if (newHeapChunk)
AddToChunkList(newHeapChunk);
return newHeapChunk;
}
//--------------------------------------------------------------------
void nsFixedSizeAllocator::FreeChunk(nsHeapChunk *chunkToFree)
//--------------------------------------------------------------------
{
RemoveFromChunkList(chunkToFree);
// we used placement new to make it, so we have to delete like this
nsFixedSizeHeapChunk *thisChunk = (nsFixedSizeHeapChunk *)chunkToFree;
thisChunk->~nsFixedSizeHeapChunk();
nsAllocatorManager::GetAllocatorManager()->FreeSubheap((Ptr)thisChunk);
}
#pragma mark -
//--------------------------------------------------------------------
nsFixedSizeHeapChunk::nsFixedSizeHeapChunk(
nsMemAllocator *inOwningAllocator,
Size heapSize) :
nsHeapChunk(inOwningAllocator, heapSize)
//--------------------------------------------------------------------
{
nsFixedSizeAllocator *allocator = (nsFixedSizeAllocator *)mOwningAllocator;
UInt32 blockSize = allocator->GetAllocatorBlockSize();
UInt32 allocBlockSize = blockSize + FixedMemoryBlock::kFixedSizeBlockOverhead;
// work out how much we can actually store in the heap
UInt32 numBlocks = (heapSize - sizeof(nsFixedSizeHeapChunk)) / allocBlockSize;
mHeapSize = numBlocks * allocBlockSize;
// build the free list for this chunk
UInt32 blockCount = numBlocks - 1; // -1 because we do the last one by hand
FixedMemoryBlock *freePtr = mMemory;
FixedMemoryBlock *nextFree;
mFreeList = freePtr;
do
{
nextFree = (FixedMemoryBlock *) ((UInt32)freePtr + allocBlockSize);
freePtr->SetOwningChunk(this);
freePtr->SetNextFree(nextFree);
freePtr = nextFree;
}
while (--blockCount);
freePtr->SetOwningChunk(this);
freePtr->SetNextFree(nil);
}

Просмотреть файл

@ -1,218 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <string.h>
class nsMemAllocator;
class nsFixedSizeHeapChunk;
struct FixedMemoryBlockHeader
{
#if DEBUG_HEAP_INTEGRITY
UInt16 blockFlags; // unused at present
UInt16 blockPadding;
#endif
MemoryBlockHeader header; // this must be the last variable before memory
};
struct FixedMemoryBlock
{
static FixedMemoryBlock* GetBlockHeader(void *block)
{ return (FixedMemoryBlock *)((char *)block - sizeof(FixedMemoryBlockHeader)); }
FixedMemoryBlock* GetNextFree()
{ return next; }
void SetNextFree(FixedMemoryBlock *nextFree)
{ next = nextFree; }
void SetOwningChunk(nsHeapChunk *inOwningChunk)
{ blockHeader.header.owningChunk = inOwningChunk; }
nsFixedSizeHeapChunk* GetOwningChunk()
{ return (nsFixedSizeHeapChunk *)blockHeader.header.owningChunk; }
#if DEBUG_HEAP_INTEGRITY
enum {
kBlockPaddingBytes = 'ðððð'
};
void SetPaddingBytes(UInt32 padding) { blockHeader.blockPadding = padding; }
void FillPaddingBytes(UInt32 blockSize) {
long *lastLong = (long *)((char *)&memory + blockSize - sizeof(long));
UInt32 mask = (1 << (8 * blockHeader.blockPadding)) - 1;
*lastLong &= ~mask;
*lastLong |= (mask & kBlockPaddingBytes);
}
Boolean CheckPaddingBytes(UInt32 blockSize) {
long *lastLong = (long *)((char *)&memory + blockSize - sizeof(long));
UInt32 mask = (1 << (8 * blockHeader.blockPadding)) - 1;
return (*lastLong & mask) == (mask & kBlockPaddingBytes);
}
UInt32 GetPaddingBytes() { return blockHeader.blockPadding; }
void ZapBlockContents(UInt32 blockSize, UInt8 pattern)
{
memset(&memory, pattern, blockSize);
}
// inline, so won't crash if this is a bad block
Boolean HasHeaderTag(MemoryBlockTag inHeaderTag)
{ return blockHeader.header.headerTag == inHeaderTag; }
void SetHeaderTag(MemoryBlockTag inHeaderTag)
{ blockHeader.header.headerTag = inHeaderTag; }
void SetTrailerTag(UInt32 blockSize, MemoryBlockTag theTag)
{
MemoryBlockTrailer *trailer = (MemoryBlockTrailer *)((char *)&memory + blockSize);
trailer->trailerTag = theTag;
}
MemoryBlockTag GetTrailerTag(UInt32 blockSize)
{
MemoryBlockTrailer *trailer = (MemoryBlockTrailer *)((char *)&memory + blockSize);
return trailer->trailerTag;
}
#endif
static const UInt32 kFixedSizeBlockOverhead;
FixedMemoryBlockHeader blockHeader;
union {
FixedMemoryBlock* next;
void* memory;
};
};
class nsFixedSizeHeapChunk : public nsHeapChunk
{
public:
nsFixedSizeHeapChunk(nsMemAllocator *inOwningAllocator, Size heapSize);
~nsFixedSizeHeapChunk() {}
FixedMemoryBlock* GetFreeList() const { return mFreeList; }
void SetFreeList(FixedMemoryBlock *nextFree) { mFreeList = nextFree; }
FixedMemoryBlock* FetchFirstFree()
{
FixedMemoryBlock* firstFree = mFreeList;
mFreeList = firstFree->GetNextFree();
mUsedBlocks ++;
return firstFree;
}
void ReturnToFreeList(FixedMemoryBlock *freeBlock)
{
freeBlock->SetNextFree(mFreeList);
mFreeList = freeBlock;
mUsedBlocks --;
}
protected:
#if STATS_MAC_MEMORY
UInt32 chunkSize;
UInt32 numBlocks;
#endif
FixedMemoryBlock *mFreeList;
FixedMemoryBlock mMemory[];
};
//--------------------------------------------------------------------
class nsFixedSizeAllocator : public nsMemAllocator
{
private:
typedef nsMemAllocator Inherited;
public:
nsFixedSizeAllocator(size_t minBlockSize, size_t maxBlockSize);
~nsFixedSizeAllocator();
void * AllocatorMakeBlock(size_t blockSize);
void AllocatorFreeBlock(void *freeBlock);
void * AllocatorResizeBlock(void *block, size_t newSize);
size_t AllocatorGetBlockSize(void *thisBlock);
nsHeapChunk* AllocateChunk(size_t requestedBlockSize);
void FreeChunk(nsHeapChunk *chunkToFree);
inline nsHeapChunk* FindChunkWithSpace(size_t blockSize) const;
UInt32 GetAllocatorBlockSize() { return mMaxBlockSize; }
protected:
enum {
kMaxBlockResizeSlop = 16
};
nsFixedSizeHeapChunk *mChunkWithSpace; // cheap optimization
#if STATS_MAC_MEMORY
UInt32 mChunksAllocated;
UInt32 mMaxChunksAllocated;
UInt32 mTotalChunkSize;
UInt32 mMaxTotalChunkSize;
UInt32 mBlocksAllocated;
UInt32 mMaxBlocksAllocated;
UInt32 mBlocksUsed;
UInt32 mMaxBlocksUsed;
UInt32 mBlockSpaceUsed;
UInt32 mMaxBlockSpaceUsed;
#endif
};

Просмотреть файл

@ -1,104 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <string.h>
#include <stdlib.h>
#define GC_DEBUG
#include "gc.h"
// GC implementation of malloc/free, for testing purposes
//--------------------------------------------------------------------
void *malloc(size_t blockSize)
//--------------------------------------------------------------------
{
#ifdef GC_DEBUG
return GC_MALLOC(blockSize);
#else
if (blockSize <= 10000)
return GC_MALLOC(blockSize);
else
return GC_malloc_ignore_off_page(blockSize);
#endif
}
//--------------------------------------------------------------------
void free(void *deadBlock)
//--------------------------------------------------------------------
{
if (deadBlock != NULL)
GC_FREE(deadBlock);
}
//--------------------------------------------------------------------
void* realloc(void* block, size_t newSize)
//--------------------------------------------------------------------
{
#ifdef GC_DEBUG
return GC_REALLOC(block, newSize);
#else
size_t oldSize = GC_size(block);
void * newBlock = block;
if (newSize <= 10000)
return(GC_REALLOC(block, newSize));
if (newSize <= oldSize)
return(block);
newBlock = GC_malloc_ignore_off_page(newSize);
if (newBlock == NULL)
return NULL;
memcpy(newBlock, block, oldSize);
GC_FREE(block);
return(newBlock);
#endif
}
//--------------------------------------------------------------------
void *calloc(size_t nele, size_t elesize)
//--------------------------------------------------------------------
{
// GC_MALLOC returns cleared blocks for us.
size_t space = nele * elesize;
return GC_MALLOC(space);
}

Просмотреть файл

@ -1,84 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <Files.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "gc.h"
#include "gc_fragments.h"
#include "generic_threads.h"
#ifndef GC_LEAK_DETECTOR
void MWUnmangle(const char *mangled_name, char *unmangled_name, size_t buffersize);
// stub implementations, when GC leak detection isn't on. these are needed so that
// NSStdLib has something to export for these functions, even when the GC isn't used.
void GC_register_fragment(char* dataStart, char* dataEnd,
char* codeStart, char* codeEnd,
const FSSpec* fragmentSpec) {}
void GC_unregister_fragment(char* dataStart, char* dataEnd,
char* codeStart, char* codeEnd) {}
void GC_clear_roots() {}
void GC_generic_init_threads() {}
void GC_gcollect() {}
FILE* GC_stdout = NULL;
FILE* GC_stderr = NULL;
int GC_address_to_source(char* codeAddr, char symbolName[256], char fileName[256], UInt32* fileOffset)
{
return 0;
}
GC_PTR GC_malloc_atomic(size_t size_in_bytes) { return NULL; }
void MWUnmangle(const char *mangled_name, char *unmangled_name, size_t buffersize)
{
strncpy(unmangled_name, mangled_name, buffersize);
}
// TODO: move these to gc.h.
void GC_mark_object(GC_PTR object, GC_word mark);
void GC_trace_object(GC_PTR object, int verbose);
void GC_mark_object(GC_PTR object, GC_word mark) {}
void GC_trace_object(GC_PTR object, int verbose) {}
#endif

Просмотреть файл

@ -1,544 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <new.h> // for placement new
#include <MacMemory.h>
#include "nsMemAllocator.h"
#include "nsAllocatorManager.h"
#include "nsLargeHeapAllocator.h"
const UInt32 LargeBlockHeader::kLargeBlockOverhead = sizeof(LargeBlockHeader) + MEMORY_BLOCK_TAILER_SIZE;
//--------------------------------------------------------------------
nsLargeHeapAllocator::nsLargeHeapAllocator(size_t minBlockSize, size_t maxBlockSize)
: nsMemAllocator(eAllocatorTypeLarge, minBlockSize, maxBlockSize)
//--------------------------------------------------------------------
{
mBaseChunkSize = mTempChunkSize = (64 * 1024);
}
//--------------------------------------------------------------------
nsLargeHeapAllocator::~nsLargeHeapAllocator()
//--------------------------------------------------------------------
{
}
//--------------------------------------------------------------------
void * nsLargeHeapAllocator::AllocatorMakeBlock(size_t blockSize)
//--------------------------------------------------------------------
{
nsLargeHeapChunk* chunk = (nsLargeHeapChunk *)mFirstChunk;
LargeBlockHeader *theBlock = nil;
UInt32 allocSize = GetPaddedBlockSize(blockSize);
// walk through all of our chunks, trying to allocate memory from somewhere
while (chunk)
{
if (chunk->GetLargestFreeBlock() >= allocSize)
{
theBlock = chunk->GetSpaceForBlock(blockSize);
if (theBlock)
break;
}
chunk = (nsLargeHeapChunk *)chunk->GetNextChunk();
}
if (!theBlock)
{
chunk = (nsLargeHeapChunk *)AllocateChunk(blockSize);
if (!chunk) return nil;
theBlock = chunk->GetSpaceForBlock(blockSize);
}
if (theBlock)
{
theBlock->SetLogicalSize(blockSize);
#if STATS_MAC_MEMORY
theBlock->header.logicalBlockSize = blockSize; // yes, it is stored in 2 places in this allocator
AccountForNewBlock(blockSize);
#endif
return &(theBlock->memory);
}
return nil;
}
//--------------------------------------------------------------------
void *nsLargeHeapAllocator::AllocatorResizeBlock(void *block, size_t newSize)
//--------------------------------------------------------------------
{
LargeBlockHeader *blockHeader = LargeBlockHeader::GetBlockHeader(block);
nsLargeHeapChunk *chunk = blockHeader->GetOwningChunk();
#if DEBUG_HEAP_INTEGRITY
MEM_ASSERT(blockHeader->HasHeaderTag(kUsedBlockHeaderTag), "Bad block header on realloc");
MEM_ASSERT(blockHeader->HasTrailerTag(blockHeader->GetBlockSize(), kUsedBlockTrailerTag), "Bad block trailer on realloc");
MEM_ASSERT(blockHeader->CheckPaddingBytes(), "Block has overwritten its bounds");
#endif
UInt32 newAllocSize = (newSize + 3) & ~3;
// we can resize this block to any size, provided it fits.
if (newAllocSize < blockHeader->GetBlockSize()) // shrinking
{
return chunk->ShrinkBlock(blockHeader, newSize);
}
else if (newAllocSize > blockHeader->GetBlockSize()) // growing
{
return chunk->GrowBlock(blockHeader, newSize);
}
else
{
return chunk->ResizeBlockInPlace(blockHeader, newSize);
}
return nil;
}
//--------------------------------------------------------------------
void nsLargeHeapAllocator::AllocatorFreeBlock(void *freeBlock)
//--------------------------------------------------------------------
{
LargeBlockHeader *blockHeader = LargeBlockHeader::GetBlockHeader(freeBlock);
#if DEBUG_HEAP_INTEGRITY
MEM_ASSERT(blockHeader->HasHeaderTag(kUsedBlockHeaderTag), "Bad block header on free");
MEM_ASSERT(blockHeader->HasTrailerTag(blockHeader->GetBlockSize(), kUsedBlockTrailerTag), "Bad block trailer on free");
MEM_ASSERT(blockHeader->CheckPaddingBytes(), "Block overwrote bounds");
blockHeader->ZapBlockContents(kFreeMemoryFillPattern);
#endif
#if STATS_MAC_MEMORY
AccountForFreedBlock(blockHeader->header.logicalBlockSize);
#endif
nsLargeHeapChunk *chunk = blockHeader->GetOwningChunk();
chunk->ReturnBlock(blockHeader);
#if DEBUG_HEAP_INTEGRITY
blockHeader->SetHeaderTag(kFreeBlockHeaderTag);
#endif
// if this chunk is completely empty and it's not the first chunk then free it
if (chunk->IsEmpty() && chunk != mFirstChunk)
FreeChunk(chunk);
}
//--------------------------------------------------------------------
size_t nsLargeHeapAllocator::AllocatorGetBlockSize(void *thisBlock)
//--------------------------------------------------------------------
{
LargeBlockHeader* blockHeader = (LargeBlockHeader *)((char *)thisBlock - sizeof(LargeBlockHeader));
return blockHeader->GetLogicalSize();
}
//--------------------------------------------------------------------
nsHeapChunk *nsLargeHeapAllocator::AllocateChunk(size_t requestedBlockSize)
//--------------------------------------------------------------------
{
Size chunkSize = mBaseChunkSize, actualChunkSize;
size_t paddedBlockSize = (( requestedBlockSize + 3 ) & ~3) + 3 * LargeBlockHeader::kLargeBlockOverhead + sizeof(nsLargeHeapChunk);
if (paddedBlockSize > chunkSize)
chunkSize = paddedBlockSize;
Ptr chunkMemory = nsAllocatorManager::GetAllocatorManager()->AllocateSubheap(chunkSize, actualChunkSize);
if (!chunkMemory) return nil;
// use placement new to initialize the chunk in the memory block
nsHeapChunk *newHeapChunk = new (chunkMemory) nsLargeHeapChunk(this, actualChunkSize);
if (newHeapChunk)
AddToChunkList(newHeapChunk);
return newHeapChunk;
}
//--------------------------------------------------------------------
void nsLargeHeapAllocator::FreeChunk(nsHeapChunk *chunkToFree)
//--------------------------------------------------------------------
{
RemoveFromChunkList(chunkToFree);
// we used placement new to make it, so we have to delete like this
nsLargeHeapChunk *thisChunk = (nsLargeHeapChunk *)chunkToFree;
thisChunk->~nsLargeHeapChunk();
nsAllocatorManager::GetAllocatorManager()->FreeSubheap((Ptr)thisChunk);
}
#pragma mark -
//--------------------------------------------------------------------
nsLargeHeapChunk::nsLargeHeapChunk(
nsMemAllocator *inOwningAllocator,
Size heapSize) :
nsHeapChunk(inOwningAllocator, heapSize)
//--------------------------------------------------------------------
{
heapSize -= sizeof(nsLargeHeapChunk); // subtract heap overhead
// mark how much we can actually store in the heap
mHeapSize = heapSize - 3 * sizeof(LargeBlockHeader);
// the head block is zero size and is never free
mHead->SetPrevBlock((LargeBlockHeader *) -1L);
// we have a free block in the middle
LargeBlockHeader *freeBlock = mHead->SkipDummyBlock();
mHead->SetNextBlock(freeBlock);
mHead->SetLogicalSize(0);
#if DEBUG_HEAP_INTEGRITY
mHead->SetPaddingBytes(0);
mHead->SetHeaderTag(kDummyBlockHeaderTag);
mHead->header.blockID = -1;
#endif
freeBlock->SetPrevBlock(nil);
freeBlock->SetNextBlock( (LargeBlockHeader *) ( (UInt32)freeBlock + heapSize - 2 * LargeBlockHeader::kLargeBlockOverhead) );
// and then a zero sized allocated block at the end
mTail = freeBlock->GetNextBlock();
mTail->SetNextBlock(nil);
mTail->SetPrevBlock(freeBlock);
mTotalFree = mLargestFreeBlock = freeBlock->GetBlockHeapUsageSize();
}
//--------------------------------------------------------------------
nsLargeHeapChunk::~nsLargeHeapChunk()
//--------------------------------------------------------------------
{
}
//--------------------------------------------------------------------
LargeBlockHeader* nsLargeHeapChunk::GetSpaceForBlock(UInt32 blockSize)
//--------------------------------------------------------------------
{
UInt32 allocSize = ((blockSize + 3) & ~3) + LargeBlockHeader::kLargeBlockOverhead;
if (allocSize > mLargestFreeBlock) return nil;
//Boolean expectFailure = (allocSize > mTotalFree);
/* scan through the blocks in this chunk looking for a big enough free block */
/* we never allocate the head block */
LargeBlockHeader *prevBlock = GetHeadBlock();
LargeBlockHeader *blockHeader = prevBlock->GetNextBlock();
do
{
if (blockHeader->IsFreeBlock())
{
UInt32 freeBlockSize = blockHeader->GetBlockHeapUsageSize();
if (freeBlockSize >= allocSize)
break;
}
prevBlock = blockHeader;
blockHeader = blockHeader->GetNextBlock();
}
while (blockHeader);
// if we failed to find a block, return nil
if (!blockHeader)
return nil;
// is there space at the end of this block for a free block?
if ( ( blockHeader->GetBlockHeapUsageSize() - allocSize ) > LargeBlockHeader::kLargeBlockOverhead )
{
LargeBlockHeader *freeBlock = (LargeBlockHeader *) ( (char *) blockHeader + allocSize );
freeBlock->SetPrevBlock(nil);
freeBlock->SetNextBlock(blockHeader->GetNextBlock());
freeBlock->GetNextBlock()->SetPrevBlock(freeBlock);
blockHeader->SetNextBlock(freeBlock);
}
// allocate this block
blockHeader->SetPrevBlock(prevBlock);
blockHeader->SetOwningChunk(this);
#if DEBUG_HEAP_INTEGRITY
blockHeader->SetHeaderTag(kUsedBlockHeaderTag);
blockHeader->SetTrailerTag(blockHeader->GetBlockSize(), kUsedBlockTrailerTag);
blockHeader->SetPaddingBytes(((blockSize + 3) & ~3) - blockSize);
blockHeader->ZapBlockContents(kUsedMemoryFillPattern);
blockHeader->FillPaddingBytes();
#endif
mTotalFree -= blockHeader->GetBlockHeapUsageSize();
IncrementUsedBlocks();
UpdateLargestFreeBlock(); // we could optimize this
//MEM_ASSERT(!expectFailure, "I though this would fail!");
return blockHeader;
}
//--------------------------------------------------------------------
void *nsLargeHeapChunk::GrowBlock(LargeBlockHeader *growBlock, size_t newSize)
//--------------------------------------------------------------------
{
LargeBlockHeader* freeBlock = growBlock->GetNextBlock();
// is the block following this block a free block?
if (!freeBlock->IsFreeBlock())
return nil;
// round the block size up to a multiple of four and add space for the header and trailer
UInt32 newAllocSize = ( ( newSize + 3 ) & ~3 ) + LargeBlockHeader::kLargeBlockOverhead;
UInt32 oldAllocSize = growBlock->GetBlockHeapUsageSize();
/* is it big enough? */
UInt32 freeBlockSize = freeBlock->GetBlockHeapUsageSize();
if (freeBlockSize + oldAllocSize < newAllocSize)
return nil;
// grow this block
#if STATS_MAC_MEMORY
UInt32 oldLogicalSize = growBlock->GetLogicalSize();
#endif
MEM_ASSERT(growBlock->logicalSize < newSize, "Wrong block size on grow block");
growBlock->SetLogicalSize(newSize);
mTotalFree -= freeBlock->GetBlockHeapUsageSize();
// is there still space at the end of this block for a free block?
if ( freeBlockSize + oldAllocSize - newAllocSize > LargeBlockHeader::kLargeBlockOverhead )
{
LargeBlockHeader* smallFree = (LargeBlockHeader *)((char*)growBlock + newAllocSize);
smallFree->SetPrevBlock(nil);
smallFree->SetNextBlock(freeBlock->GetNextBlock());
smallFree->GetNextBlock()->SetPrevBlock(smallFree);
growBlock->SetNextBlock(smallFree);
mTotalFree += smallFree->GetBlockHeapUsageSize();
#if DEBUG_HEAP_INTEGRITY
smallFree->header.headerTag = kFreeBlockHeaderTag;
#endif
}
else
{
growBlock->SetNextBlock(freeBlock->GetNextBlock());
freeBlock->GetNextBlock()->SetPrevBlock(growBlock);
}
#if DEBUG_HEAP_INTEGRITY
growBlock->SetTrailerTag(growBlock->GetBlockSize(), kUsedBlockTrailerTag);
growBlock->SetPaddingBytes(((newSize + 3) & ~3) - newSize);
growBlock->FillPaddingBytes();
#endif
#if STATS_MAC_MEMORY
GetOwningAllocator()->AccountForResizedBlock(oldLogicalSize, newSize);
#endif
UpdateLargestFreeBlock(); // we could optimize this
return (void *)(&growBlock->memory);
}
//--------------------------------------------------------------------
void *nsLargeHeapChunk::ShrinkBlock(LargeBlockHeader *growBlock, size_t newSize)
//--------------------------------------------------------------------
{
// round the block size up to a multiple of four and add space for the header and trailer
UInt32 newAllocSize = ((newSize + 3) & ~3) + LargeBlockHeader::kLargeBlockOverhead;
size_t oldAllocSize = growBlock->GetBlockHeapUsageSize();
LargeBlockHeader* nextBlock = growBlock->GetNextBlock();
LargeBlockHeader* smallFree = nil; // Where the recovered freeblock will go
// shrink this block
#if STATS_MAC_MEMORY
UInt32 oldLogicalSize = growBlock->GetLogicalSize();
#endif
MEM_ASSERT(oldAllocSize > newAllocSize, "Wrong bock size on shrink block");
growBlock->SetLogicalSize(newSize);
// is the block following this block a free block?
if (nextBlock->IsFreeBlock())
{
// coalesce the freed space with the following free block
smallFree = (LargeBlockHeader *)((char *)growBlock + newAllocSize);
mTotalFree -= nextBlock->GetBlockHeapUsageSize();
smallFree->SetNextBlock(nextBlock->GetNextBlock());
}
// or is there enough space at the end of this block for a new free block?
else if ( oldAllocSize - newAllocSize > LargeBlockHeader::kLargeBlockOverhead )
{
smallFree = (LargeBlockHeader *)((char *)growBlock + newAllocSize);
smallFree->SetNextBlock(nextBlock);
}
if (smallFree)
{
// Common actions for both cases
smallFree->SetPrevBlock(nil);
smallFree->GetNextBlock()->SetPrevBlock(smallFree);
growBlock->SetNextBlock(smallFree);
mTotalFree += smallFree->GetBlockHeapUsageSize();
#if DEBUG_HEAP_INTEGRITY
smallFree->header.headerTag = kFreeBlockHeaderTag;
#endif
}
#if DEBUG_HEAP_INTEGRITY
growBlock->SetTrailerTag(growBlock->GetBlockSize(), kUsedBlockTrailerTag);
growBlock->SetPaddingBytes(((newSize + 3) & ~3) - newSize);
growBlock->FillPaddingBytes();
#endif
#if STATS_MAC_MEMORY
GetOwningAllocator()->AccountForResizedBlock(oldLogicalSize, newSize);
#endif
UpdateLargestFreeBlock(); // we could optimize this
return (void *)(&growBlock->memory);
}
//--------------------------------------------------------------------
void* nsLargeHeapChunk::ResizeBlockInPlace(LargeBlockHeader *theBlock, size_t newSize)
//--------------------------------------------------------------------
{
theBlock->SetLogicalSize(newSize);
#if DEBUG_HEAP_INTEGRITY
UInt32 newAllocSize = (newSize + 3) & ~3;
theBlock->SetPaddingBytes(newAllocSize - newSize);
theBlock->FillPaddingBytes();
#endif
#if STATS_MAC_MEMORY
GetOwningAllocator()->AccountForResizedBlock(theBlock->header.logicalBlockSize, newSize);
theBlock->header.logicalBlockSize = newSize;
#endif
UpdateLargestFreeBlock(); // we could optimize this
return (void *)(&theBlock->memory);
}
//--------------------------------------------------------------------
void nsLargeHeapChunk::ReturnBlock(LargeBlockHeader *deadBlock)
//--------------------------------------------------------------------
{
// we might want to coalesce this block with it's prev or next neighbor
LargeBlockHeader *prev = deadBlock->prev;
LargeBlockHeader *next = deadBlock->next;
if (prev->IsFreeBlock())
{
mTotalFree -= prev->GetBlockHeapUsageSize();
prev->next = deadBlock->next;
deadBlock = prev;
if (next->IsFreeBlock())
{
mTotalFree -= next->GetBlockHeapUsageSize();
deadBlock->next = next->next;
next->next->prev = deadBlock;
}
else
{
next->prev = deadBlock;
}
}
else if (next->IsFreeBlock() )
{
mTotalFree -= next->GetBlockHeapUsageSize();
deadBlock->next = next->next;
next->next->prev = deadBlock;
}
deadBlock->prev = nil;
mTotalFree += deadBlock->GetBlockHeapUsageSize();
UpdateLargestFreeBlock(); // we could optimize this
DecrementUsedBlocks();
}
//--------------------------------------------------------------------
void nsLargeHeapChunk::UpdateLargestFreeBlock()
//--------------------------------------------------------------------
{
LargeBlockHeader *thisBlock = mHead->GetNextBlock(); // head block is a dummy block
UInt32 curMaxSize = 0;
while (thisBlock != mTail)
{
if (thisBlock->IsFreeBlock())
{
UInt32 blockSize = thisBlock->GetBlockHeapUsageSize();
if (blockSize > curMaxSize)
curMaxSize = blockSize;
}
thisBlock = thisBlock->GetNextBlock();
}
mLargestFreeBlock = curMaxSize;
}

Просмотреть файл

@ -1,191 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <string.h>
class nsMemAllocator;
class nsLargeHeapChunk;
//--------------------------------------------------------------------
struct LargeBlockHeader
{
static LargeBlockHeader *GetBlockHeader(void *block) { return (LargeBlockHeader *)((char *)block - sizeof(LargeBlockHeader)); }
Boolean IsFreeBlock() { return prev == nil; }
UInt32 GetBlockSize() { return ((UInt32)next - (UInt32)this - kLargeBlockOverhead); }
UInt32 GetBlockHeapUsageSize() { return ((UInt32)next - (UInt32)this); }
void SetLogicalSize(UInt32 inSize) { logicalSize = inSize; }
UInt32 GetLogicalSize() { return logicalSize; }
LargeBlockHeader* SkipDummyBlock() { return (LargeBlockHeader *)((UInt32)this + kLargeBlockOverhead); }
LargeBlockHeader* GetNextBlock() { return next; }
LargeBlockHeader* GetPrevBlock() { return prev; }
void SetNextBlock(LargeBlockHeader *inNext) { next = inNext; }
void SetPrevBlock(LargeBlockHeader *inPrev) { prev = inPrev; }
void SetOwningChunk(nsHeapChunk *chunk) { header.owningChunk = chunk; }
nsLargeHeapChunk* GetOwningChunk() { return (nsLargeHeapChunk *)(header.owningChunk); }
#if DEBUG_HEAP_INTEGRITY
enum {
kBlockPaddingBytes = 'ðððð'
};
void SetPaddingBytes(UInt32 padding) { paddingBytes = padding; }
void FillPaddingBytes() {
long *lastLong = (long *)((char *)&memory + GetBlockSize() - sizeof(long));
UInt32 mask = (1 << (8 * paddingBytes)) - 1;
*lastLong &= ~mask;
*lastLong |= (mask & kBlockPaddingBytes);
}
Boolean CheckPaddingBytes() {
long *lastLong = (long *)((char *)&memory + GetBlockSize() - sizeof(long));
UInt32 mask = (1 << (8 * paddingBytes)) - 1;
return (*lastLong & mask) == (mask & kBlockPaddingBytes);
}
UInt32 GetPaddingBytes() { return paddingBytes; }
void ZapBlockContents(UInt8 pattern) { memset(&memory, pattern, GetBlockSize()); }
// inline, so won't crash if this is a bad block
Boolean HasHeaderTag(MemoryBlockTag inHeaderTag)
{ return header.headerTag == inHeaderTag; }
void SetHeaderTag(MemoryBlockTag inHeaderTag)
{ header.headerTag = inHeaderTag; }
void SetTrailerTag(UInt32 blockSize, MemoryBlockTag theTag)
{
MemoryBlockTrailer *trailer = (MemoryBlockTrailer *)((char *)&memory + blockSize);
trailer->trailerTag = theTag;
}
Boolean HasTrailerTag(UInt32 blockSize, MemoryBlockTag theTag)
{
MemoryBlockTrailer *trailer = (MemoryBlockTrailer *)((char *)&memory + blockSize);
return (trailer->trailerTag == theTag);
}
#endif
static const UInt32 kLargeBlockOverhead;
LargeBlockHeader *next;
LargeBlockHeader *prev;
#if DEBUG_HEAP_INTEGRITY
UInt32 paddingBytes;
#endif
UInt32 logicalSize;
MemoryBlockHeader header; // this must be the last variable before memory
char memory[];
};
//--------------------------------------------------------------------
class nsLargeHeapAllocator : public nsMemAllocator
{
private:
typedef nsMemAllocator Inherited;
public:
nsLargeHeapAllocator(size_t minBlockSize, size_t maxBlockSize);
~nsLargeHeapAllocator();
void * AllocatorMakeBlock(size_t blockSize);
void AllocatorFreeBlock(void *freeBlock);
void * AllocatorResizeBlock(void *block, size_t newSize);
size_t AllocatorGetBlockSize(void *thisBlock);
nsHeapChunk* AllocateChunk(size_t requestedBlockSize);
void FreeChunk(nsHeapChunk *chunkToFree);
UInt32 GetPaddedBlockSize(UInt32 blockSize) { return ((blockSize + 3) & ~3) + LargeBlockHeader::kLargeBlockOverhead; }
protected:
UInt32 mBaseChunkPercentage;
UInt32 mBestTempChunkSize;
UInt32 mSmallestTempChunkSize;
};
//--------------------------------------------------------------------
class nsLargeHeapChunk : public nsHeapChunk
{
public:
nsLargeHeapChunk( nsMemAllocator *inOwningAllocator,
Size heapSize);
~nsLargeHeapChunk();
LargeBlockHeader* GetHeadBlock() { return mHead; }
LargeBlockHeader* GetSpaceForBlock(UInt32 roundedBlockSize);
void * GrowBlock(LargeBlockHeader *growBlock, size_t newSize);
void * ShrinkBlock(LargeBlockHeader *shrinkBlock, size_t newSize);
void * ResizeBlockInPlace(LargeBlockHeader *theBlock, size_t newSize);
void ReturnBlock(LargeBlockHeader *deadBlock);
UInt32 GetLargestFreeBlock() { return mLargestFreeBlock; }
protected:
void UpdateLargestFreeBlock();
UInt32 mTotalFree;
UInt32 mLargestFreeBlock; // heap useage for largest block we can allocate
LargeBlockHeader* mTail;
LargeBlockHeader mHead[];
};

Просмотреть файл

@ -1,292 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <stdio.h>
#include <MacMemory.h>
#include "nsMemAllocator.h"
#include "nsAllocatorManager.h"
//--------------------------------------------------------------------
nsHeapChunk::nsHeapChunk(nsMemAllocator *inOwningAllocator, Size heapSize)
: mOwningAllocator(inOwningAllocator)
, mNextChunk(nil)
, mHeapSize(heapSize)
, mUsedBlocks(0)
#if DEBUG_HEAP_INTEGRITY
, mSignature(kChunkSignature)
#endif
//--------------------------------------------------------------------
{
}
//--------------------------------------------------------------------
nsHeapChunk::~nsHeapChunk()
//--------------------------------------------------------------------
{
}
#pragma mark -
//--------------------------------------------------------------------
nsMemAllocator::nsMemAllocator(EAllocatorType allocatorType, size_t minBlockSize, size_t maxBlockSize)
: mAllocatorType(allocatorType)
, mFirstChunk(nil)
, mLastChunk(nil)
, mNumChunks(0)
, mMinBlockSize(minBlockSize)
, mMaxBlockSize(maxBlockSize)
#if DEBUG_HEAP_INTEGRITY
, mSignature(kMemAllocatorSignature)
#endif
#if STATS_MAC_MEMORY
, mCurBlockCount(0)
, mMaxBlockCount(0)
, mCurBlockSpaceUsed(0)
, mMaxBlockSpaceUsed(0)
, mCurHeapSpaceUsed(0)
, mMaxHeapSpaceUsed(0)
, mCurSubheapCount(0)
, mMaxSubheapCount(0)
, mCountHistogram(NULL)
#endif
//--------------------------------------------------------------------
{
#if STATS_MAC_MEMORY
mCountHistogram = (UInt32 *)NewPtrClear(sizeof(UInt32) * (maxBlockSize - minBlockSize + 1));
// failure is ok
#endif
}
//--------------------------------------------------------------------
nsMemAllocator::~nsMemAllocator()
//--------------------------------------------------------------------
{
#if STATS_MAC_MEMORY
if (mCountHistogram)
DisposePtr((Ptr)mCountHistogram);
#endif
}
#pragma mark -
//--------------------------------------------------------------------
void nsMemAllocator::AddToChunkList(nsHeapChunk *inNewChunk)
//--------------------------------------------------------------------
{
if (mLastChunk)
mLastChunk->SetNextChunk(inNewChunk);
else
mFirstChunk = inNewChunk;
mLastChunk = inNewChunk;
mNumChunks ++;
#if STATS_MAC_MEMORY
mCurSubheapCount ++;
if (mCurSubheapCount > mMaxSubheapCount)
mMaxSubheapCount = mCurSubheapCount;
mCurHeapSpaceUsed += inNewChunk->GetChunkSize();
if (mCurHeapSpaceUsed > mMaxHeapSpaceUsed)
mMaxHeapSpaceUsed = mCurHeapSpaceUsed;
#endif
}
//--------------------------------------------------------------------
void nsMemAllocator::RemoveFromChunkList(nsHeapChunk *inChunk)
//--------------------------------------------------------------------
{
nsHeapChunk *prevChunk = nil;
nsHeapChunk *nextChunk = nil;
nsHeapChunk *thisChunk = mFirstChunk;
while (thisChunk)
{
nextChunk = thisChunk->GetNextChunk();
if (thisChunk == inChunk)
break;
prevChunk = thisChunk;
thisChunk = nextChunk;
}
if (thisChunk)
{
if (prevChunk)
prevChunk->SetNextChunk(nextChunk);
if (mFirstChunk == thisChunk)
mFirstChunk = nextChunk;
if (mLastChunk == thisChunk)
mLastChunk = prevChunk;
}
mNumChunks --;
#if STATS_MAC_MEMORY
mCurSubheapCount --;
mCurHeapSpaceUsed -= inChunk->GetChunkSize();
#endif
}
#pragma mark -
#if STATS_MAC_MEMORY
//--------------------------------------------------------------------
void nsMemAllocator::AccountForNewBlock(size_t logicalSize)
//--------------------------------------------------------------------
{
mCurBlockCount ++;
if (mCurBlockCount > mMaxBlockCount)
mMaxBlockCount = mCurBlockCount;
mCurBlockSpaceUsed += logicalSize;
if (mCurBlockSpaceUsed > mMaxBlockSpaceUsed)
mMaxBlockSpaceUsed = mCurBlockSpaceUsed;
if (mCountHistogram)
{
mCountHistogram[logicalSize - mMinBlockSize]++;
}
}
//--------------------------------------------------------------------
void nsMemAllocator::AccountForResizedBlock(size_t oldLogicalSize, size_t newLogicalSize)
//--------------------------------------------------------------------
{
mCurBlockSpaceUsed -= oldLogicalSize;
mCurBlockSpaceUsed += newLogicalSize;
if (mCurBlockSpaceUsed > mMaxBlockSpaceUsed)
mMaxBlockSpaceUsed = mCurBlockSpaceUsed;
}
//--------------------------------------------------------------------
void nsMemAllocator::AccountForFreedBlock(size_t logicalSize)
//--------------------------------------------------------------------
{
mCurBlockCount --;
mCurBlockSpaceUsed -= logicalSize;
}
//--------------------------------------------------------------------
void nsMemAllocator::DumpHeapUsage(PRFileDesc *outFile)
//--------------------------------------------------------------------
{
char outString[ 1024 ];
sprintf(outString, "%04ld ", mMaxBlockSize);
WriteString(outFile, outString);
char *p = outString;
SInt32 numStars = mMaxHeapSpaceUsed / 1024;
if (numStars > 1021)
numStars = 1021;
for (SInt32 i = 0; i < numStars; i ++)
*p++ = '*';
if (numStars == 1021)
*p++ = 'É';
*p++ = '\n';
*p = '\0';
WriteString(outFile, outString);
}
//--------------------------------------------------------------------
void nsMemAllocator::DumpMemoryStats(PRFileDesc *outFile)
//--------------------------------------------------------------------
{
char outString[ 1024 ];
sprintf(outString, "Stats for heap of blocks %ld - %ld bytes\n", mMinBlockSize, mMaxBlockSize);
WriteString ( outFile, "\n\n--------------------------------------------------------------------------------\n" );
WriteString(outFile, outString);
WriteString ( outFile, "--------------------------------------------------------------------------------\n" );
WriteString ( outFile, " Current Max\n" );
WriteString ( outFile, " ---------- -------\n" );
sprintf( outString, "Num chunks: %10d %10d\n", mCurSubheapCount, mMaxSubheapCount);
WriteString ( outFile, outString );
sprintf( outString, "Chunk total: %10d %10d\n", mCurHeapSpaceUsed, mMaxHeapSpaceUsed);
WriteString ( outFile, outString );
sprintf( outString, "Block space: %10d %10d\n", mCurBlockSpaceUsed, mMaxBlockSpaceUsed );
WriteString ( outFile, outString );
sprintf( outString, "Blocks used: %10d %10d\n", mCurBlockCount, mMaxBlockCount );
WriteString ( outFile, outString );
WriteString ( outFile, " -------\n" );
sprintf( outString, "%s of allocated space used: %10.2f\n", "%", 100.0 * mMaxBlockSpaceUsed / mMaxHeapSpaceUsed );
WriteString ( outFile, outString );
if (mCountHistogram)
{
WriteString ( outFile, "\n\n");
WriteString ( outFile, "Block size Total allocations\n------------------------------\n" );
for (UInt32 i = mMinBlockSize; i <= mMaxBlockSize; i ++)
{
sprintf(outString,"%5d %10d\n", i, mCountHistogram[i - mMinBlockSize]);
WriteString ( outFile, outString );
}
WriteString(outFile, "------------------------------\n");
}
WriteString ( outFile, "\n\n");
}
#endif

Просмотреть файл

@ -1,243 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <stddef.h>
#if STATS_MAC_MEMORY
#include "prio.h"
#endif
class nsMemAllocator;
class nsHeapChunk;
enum {
kFreeBlockHeaderTag = 'FREE',
kFreeBlockTrailerTag = 'free',
kUsedBlockHeaderTag = 'USED',
kUsedBlockTrailerTag = 'used',
kDummyBlockHeaderTag = 'D\'oh',
kRefdBlockHeaderTag = 'REFD',
kRefdBlockTrailerTag = 'refd',
kUsedMemoryFillPattern = 0xDB,
kFreeMemoryFillPattern = 0xEF //if you don't want to crash hard, change to 0x04 or 0x05,
};
typedef UInt32 MemoryBlockTag;
struct MemoryBlockHeader
{
nsHeapChunk *owningChunk;
#if STATS_MAC_MEMORY
// it sucks putting an extra data member in here which affects stats, but there is no other
// way to store the logical size of each block.
size_t logicalBlockSize;
#endif
#if DEBUG_HEAP_INTEGRITY
//MemoryBlockHeader *next;
//MemoryBlockHeader *prev;
UInt32 blockID;
MemoryBlockTag headerTag; // put this as the last thing before memory
#endif
static MemoryBlockHeader* GetHeaderFromBlock(void *block) { return (MemoryBlockHeader*)((char *)block - sizeof(MemoryBlockHeader)); }
#if DEBUG_HEAP_INTEGRITY
// inline, so won't crash if this is a bad block
Boolean HasHeaderTag(MemoryBlockTag inHeaderTag) { return (headerTag == inHeaderTag); }
void SetHeaderTag(MemoryBlockTag inHeaderTag) { headerTag = inHeaderTag; }
#else
// stubs
Boolean HasHeaderTag(MemoryBlockTag inHeaderTag){ return true; }
void SetHeaderTag(MemoryBlockTag inHeaderTag){}
#endif
};
struct MemoryBlockTrailer {
MemoryBlockTag trailerTag;
};
#if DEBUG_HEAP_INTEGRITY
#define MEMORY_BLOCK_TAILER_SIZE sizeof(struct MemoryBlockTrailer)
#else
#define MEMORY_BLOCK_TAILER_SIZE 0
#endif /* DEBUG_HEAP_INTEGRITY */
//--------------------------------------------------------------------
class nsHeapChunk
{
public:
nsHeapChunk(nsMemAllocator *inOwningAllocator, Size heapSize);
~nsHeapChunk();
nsHeapChunk* GetNextChunk() const { return mNextChunk; }
void SetNextChunk(nsHeapChunk *inChunk) { mNextChunk = inChunk; }
nsMemAllocator* GetOwningAllocator() const { return mOwningAllocator; }
void IncrementUsedBlocks() { mUsedBlocks ++; }
void DecrementUsedBlocks() { mUsedBlocks -- ; MEM_ASSERT(mUsedBlocks >= 0, "Bad chunk block count"); }
Boolean IsEmpty() const { return mUsedBlocks == 0; }
UInt32 GetChunkSize() { return mHeapSize; }
#if DEBUG_HEAP_INTEGRITY
Boolean IsGoodChunk() { return mSignature == kChunkSignature; }
#endif
protected:
#if DEBUG_HEAP_INTEGRITY
enum {
kChunkSignature = 'Chnk'
};
OSType mSignature;
#endif
nsMemAllocator *mOwningAllocator;
nsHeapChunk *mNextChunk;
UInt32 mUsedBlocks;
UInt32 mHeapSize;
};
//--------------------------------------------------------------------
class nsMemAllocator
{
public:
enum EAllocatorType {
eAllocatorTypeFixed,
eAllocatorTypeSmall,
eAllocatorTypeLarge
};
public:
nsMemAllocator(EAllocatorType allocatorType, size_t minBlockSize, size_t maxBlockSize);
~nsMemAllocator();
EAllocatorType GetAllocatorType() const { return mAllocatorType; }
Boolean IsGoodAllocator()
#if DEBUG_HEAP_INTEGRITY
{ return mSignature == kMemAllocatorSignature; }
#else
{ return true; }
#endif
protected:
void AddToChunkList(nsHeapChunk *inNewChunk);
void RemoveFromChunkList(nsHeapChunk *inChunk);
enum {
kMemAllocatorSignature = 'ARSE' // Allocators R Supremely Efficient
};
#if DEBUG_HEAP_INTEGRITY
OSType mSignature; // signature for debugging
#endif
nsHeapChunk *mFirstChunk; // pointer to first subheap managed by this allocator
nsHeapChunk *mLastChunk; // pointer to last subheap managed by this allocator
UInt32 mMinBlockSize; // smallest block normally handled by this allocator (inclusive)
UInt32 mMaxBlockSize; // largest block handled by this allocator (inclusive)
UInt32 mNumChunks; // number of chunks in list
UInt32 mBaseChunkSize; // size of subheap allocated at startup
UInt32 mTempChunkSize; // size of additional subheaps
const EAllocatorType mAllocatorType;
#if STATS_MAC_MEMORY
public:
void AccountForNewBlock(size_t logicalSize);
void AccountForFreedBlock(size_t logicalSize);
void AccountForResizedBlock(size_t oldLogicalSize, size_t newLogicalSize);
void DumpMemoryStats(PRFileDesc *statsFile);
void DumpHeapUsage(PRFileDesc *statsFile);
UInt32 GetMaxHeapUsage() { return mMaxHeapSpaceUsed; }
private:
UInt32 mCurBlockCount; // number of malloc blocks allocated now
UInt32 mMaxBlockCount; // max number of malloc blocks allocated
UInt32 mCurBlockSpaceUsed; // sum of logical size of allocated blocks
UInt32 mMaxBlockSpaceUsed; // max of sum of logical size of allocated blocks
UInt32 mCurHeapSpaceUsed; // sum of physical size of allocated chunks
UInt32 mMaxHeapSpaceUsed; // max of sum of logical size of allocated chunks
UInt32 mCurSubheapCount; // current number of subheaps allocated by this allocator
UInt32 mMaxSubheapCount; // max number of subheaps allocated by this allocator
UInt32* mCountHistogram; // cumulative hist of frequencies
// the difference between mCurBlockSpaceUsed and mCurHeapSpaceUsed is
// the allocator overhead, which consists of:
//
// 1. Block overhead (rounding, headers & trailers)
// 2. Unused block space in chunks
// 3. Chunk overhead (rounding, headers & trailers)
//
// This is a reasonable measure of the space efficiency of these allocators
#endif
};

Просмотреть файл

@ -1,104 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <MacMemory.h>
#include <string.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
void *malloc(size_t blockSize);
void free(void *deadBlock);
void* realloc(void* block, size_t newSize);
void *calloc(size_t nele, size_t elesize);
#ifdef __cplusplus
}
#endif
// NewPtr implementation of malloc/free, for testing purposes
//--------------------------------------------------------------------
void *malloc(size_t blockSize)
//--------------------------------------------------------------------
{
return (void *)::NewPtr(blockSize);
}
//--------------------------------------------------------------------
void free(void *deadBlock)
//--------------------------------------------------------------------
{
if (deadBlock)
::DisposePtr((Ptr)deadBlock);
}
//--------------------------------------------------------------------
void* realloc(void* block, size_t newSize)
//--------------------------------------------------------------------
{
::SetPtrSize((Ptr)block, newSize);
if (MemError() == noErr)
return block;
void* newBlock = ::NewPtr(newSize);
if (!newBlock) return nil;
BlockMoveData(block, newBlock, newSize); // might copy off the end of block,
// but who cares?
return newBlock;
}
//--------------------------------------------------------------------
void *calloc(size_t nele, size_t elesize)
//--------------------------------------------------------------------
{
size_t space = nele * elesize;
void *newBlock = ::malloc(space);
if (newBlock)
memset(newBlock, 0, space);
return newBlock;
}

Просмотреть файл

@ -1,676 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <new.h> // for placement new
#include <MacMemory.h>
#include "nsMemAllocator.h"
#include "nsAllocatorManager.h"
#include "nsSmallHeapAllocator.h"
const UInt32 SmallHeapBlock::kBlockOverhead = sizeof(SmallHeapBlock) + MEMORY_BLOCK_TAILER_SIZE;
//--------------------------------------------------------------------
nsSmallHeapAllocator::nsSmallHeapAllocator(size_t minBlockSize, size_t maxBlockSize)
: nsMemAllocator(eAllocatorTypeSmall, minBlockSize, maxBlockSize)
, mChunkWithSpace(nil)
//--------------------------------------------------------------------
{
// this gets rounded up when we allocate chunks
mBaseChunkSize = mTempChunkSize = 64 * (mMaxBlockSize + SmallHeapBlock::kBlockOverhead); //(nsAllocatorManager::kChunkSizeMultiple);
}
//--------------------------------------------------------------------
nsSmallHeapAllocator::~nsSmallHeapAllocator()
//--------------------------------------------------------------------
{
}
//--------------------------------------------------------------------
void *nsSmallHeapAllocator::AllocatorMakeBlock(size_t blockSize)
//--------------------------------------------------------------------
{
// try the cheap way first
if (mChunkWithSpace)
{
void *foundBlock = mChunkWithSpace->GetSpaceForBlock(blockSize);
if (foundBlock) return foundBlock;
}
nsSmallHeapChunk *chunk = (nsSmallHeapChunk *)mFirstChunk;
// walk through all of our chunks, trying to allocate memory from somewhere
while (chunk)
{
void *theBlock = chunk->GetSpaceForBlock(blockSize);
if (theBlock)
return theBlock;
chunk = (nsSmallHeapChunk *)chunk->GetNextChunk();
} // while (chunk != nil)
chunk = (nsSmallHeapChunk *)AllocateChunk(blockSize);
if (!chunk) return nil;
mChunkWithSpace = chunk;
return chunk->GetSpaceForBlock(blockSize);
}
//--------------------------------------------------------------------
void nsSmallHeapAllocator::AllocatorFreeBlock(void *freeBlock)
//--------------------------------------------------------------------
{
SmallHeapBlock *deadBlock = SmallHeapBlock::GetBlockHeader(freeBlock);
#if DEBUG_HEAP_INTEGRITY
MEM_ASSERT(deadBlock->HasHeaderTag(kUsedBlockHeaderTag), "Bad block header on free");
MEM_ASSERT(deadBlock->HasTrailerTag(deadBlock->GetBlockSize(), kUsedBlockTrailerTag), "Bad block trailer on free");
MEM_ASSERT(deadBlock->CheckPaddingBytes(), "Block has overwritten its bounds");
deadBlock->ZapBlockContents(kFreeMemoryFillPattern);
#endif
nsSmallHeapChunk *chunk = deadBlock->GetOwningChunk();
#if DEBUG_HEAP_INTEGRITY
deadBlock->SetHeaderTag(kFreeBlockHeaderTag);
deadBlock->SetTrailerTag(deadBlock->GetBlockSize(), kFreeBlockTrailerTag);
#endif
chunk->ReturnBlock(deadBlock);
// if this chunk is completely empty and it's not the first chunk then free it
if (chunk->IsEmpty() && chunk!= mFirstChunk)
{
if (chunk == mChunkWithSpace)
mChunkWithSpace = nil;
FreeChunk(chunk);
}
else
{
mChunkWithSpace = chunk; // we know is has some space now, probably
}
}
//--------------------------------------------------------------------
void *nsSmallHeapAllocator::AllocatorResizeBlock(void *block, size_t newSize)
//--------------------------------------------------------------------
{
SmallHeapBlock *blockHeader = SmallHeapBlock::GetBlockHeader(block);
nsSmallHeapChunk *chunk = blockHeader->GetOwningChunk();
#if DEBUG_HEAP_INTEGRITY
MEM_ASSERT(blockHeader->HasHeaderTag(kUsedBlockHeaderTag), "Bad block header on realloc");
MEM_ASSERT(blockHeader->HasTrailerTag(blockHeader->GetBlockSize(), kUsedBlockTrailerTag), "Bad block trailer on realloc");
MEM_ASSERT(blockHeader->CheckPaddingBytes(), "Block has overwritten its bounds");
#endif
UInt32 newAllocSize = (newSize + 3) & ~3;
// we can resize this block to any size, provided it fits.
if (newAllocSize < blockHeader->GetBlockSize()) // shrinking
{
return chunk->ShrinkBlock(blockHeader, newSize);
}
else if (newAllocSize > blockHeader->GetBlockSize()) // growing
{
return chunk->GrowBlock(blockHeader, newSize);
}
else
{
return chunk->ResizeBlockInPlace(blockHeader, newSize);
}
return nil;
}
//--------------------------------------------------------------------
size_t nsSmallHeapAllocator::AllocatorGetBlockSize(void *thisBlock)
//--------------------------------------------------------------------
{
SmallHeapBlock *allocBlock = SmallHeapBlock::GetBlockHeader(thisBlock);
#if DEBUG_HEAP_INTEGRITY
MEM_ASSERT(allocBlock->HasHeaderTag(kUsedBlockHeaderTag), "Bad block header on get block size");
#endif
return allocBlock->GetBlockSize();
}
//--------------------------------------------------------------------
nsHeapChunk *nsSmallHeapAllocator::AllocateChunk(size_t blockSize)
//--------------------------------------------------------------------
{
UInt32 minChunkSize = ((blockSize + 3) & ~3) + sizeof(nsSmallHeapChunk) + 3 * SmallHeapBlock::kBlockOverhead;
if (minChunkSize < mBaseChunkSize)
minChunkSize = mBaseChunkSize;
Size actualChunkSize;
Ptr chunkMemory = nsAllocatorManager::GetAllocatorManager()->AllocateSubheap(mBaseChunkSize, actualChunkSize);
if (!chunkMemory) return nil;
// use placement new to initialize the chunk in the memory block
nsHeapChunk *newHeapChunk = new (chunkMemory) nsSmallHeapChunk(this, actualChunkSize);
if (newHeapChunk)
AddToChunkList(newHeapChunk);
return newHeapChunk;
}
//--------------------------------------------------------------------
void nsSmallHeapAllocator::FreeChunk(nsHeapChunk *chunkToFree)
//--------------------------------------------------------------------
{
RemoveFromChunkList(chunkToFree);
// we used placement new to make it, so we have to delete like this
nsSmallHeapChunk *thisChunk = (nsSmallHeapChunk *)chunkToFree;
thisChunk->~nsSmallHeapChunk();
nsAllocatorManager::GetAllocatorManager()->FreeSubheap((Ptr)thisChunk);
}
#pragma mark -
//--------------------------------------------------------------------
nsSmallHeapChunk::nsSmallHeapChunk(
nsMemAllocator *inOwningAllocator,
Size heapSize)
: nsHeapChunk(inOwningAllocator, heapSize)
, mOverflow(nil)
, mTotalFree(0)
//--------------------------------------------------------------------
{
// init the bin ptrs
for (UInt32 count = 0; count < kDefaultSmallHeapBins; ++count )
mBins[count] = nil;
// mark how much we can actually store in the heap
heapSize -= sizeof(nsSmallHeapChunk); // subtract heap overhead
mHeapSize = heapSize - 3 * SmallHeapBlock::kBlockOverhead;
SmallHeapBlock *newRawBlockHeader = mMemory;
// The first few bytes of the block are a dummy header
// which is a block of size zero that is always allocated.
// This allows our coalesce code to work without modification
// on the edge case of coalescing the first real block.
newRawBlockHeader->SetPrevBlock(nil);
newRawBlockHeader->SetBlockSize(0);
newRawBlockHeader->SetBlockUsed();
newRawBlockHeader->SetOwningChunk(nil);
SmallHeapBlock *newFreeOverflowBlock = newRawBlockHeader->GetNextBlock();
newFreeOverflowBlock->SetPrevBlock(newRawBlockHeader);
newFreeOverflowBlock->SetBlockSize(heapSize - 3 * SmallHeapBlock::kBlockOverhead);
// The same is true for the last few bytes in the block as well.
SmallHeapBlock *newRawBlockTrailer = (SmallHeapBlock *)(((Ptr)newRawBlockHeader) + heapSize - SmallHeapBlock::kBlockOverhead);
newRawBlockTrailer->SetPrevBlock(newFreeOverflowBlock);
newRawBlockTrailer->SetBlockSize(0xFFFFFFFF);
newRawBlockTrailer->SetBlockUsed();
newRawBlockTrailer->SetOwningChunk(nil);
AddBlockToFreeList(newFreeOverflowBlock);
#if DEBUG_HEAP_INTEGRITY
mInitialFree = mTotalFree;
#endif
}
//--------------------------------------------------------------------
nsSmallHeapChunk::~nsSmallHeapChunk()
//--------------------------------------------------------------------
{
MEM_ASSERT(mUsedBlocks != 0 || mTotalFree == mInitialFree, "Bad free measure");
}
//--------------------------------------------------------------------
void *nsSmallHeapChunk::GetSpaceForBlock(size_t blockSize)
//--------------------------------------------------------------------
{
// Round up allocation to nearest 4 bytes.
UInt32 roundedBlockSize = (blockSize + 3) & ~3;
MEM_ASSERT(roundedBlockSize <= nsSmallHeapChunk::kMaximumBlockSize, "Block is too big for this allocator!");
if (mTotalFree < roundedBlockSize) return nil;
//Boolean expectFailure = (mTotalFree < roundedBlockSize);
// Try to find the best fit in one of the bins.
UInt32 startingBinNum = (roundedBlockSize - kDefaultSmallHeadMinSize) >> 2;
SmallHeapBlock **currentBin = GetBins(startingBinNum);
SmallHeapBlock *currentBinValue = *currentBin;
SmallHeapBlock *allocatedBlock = nil;
// If the current bin has something in it,
// then use it for our allocation.
if (currentBinValue)
{
RemoveBlockFromFreeList(currentBinValue);
MEM_ASSERT(currentBinValue->GetBlockSize() >= roundedBlockSize, "Got a smaller block than requested");
allocatedBlock = currentBinValue;
goto done;
}
// Otherwise, try to carve up an existing larger block.
UInt32 remainingBins = kDefaultSmallHeapBins - startingBinNum - 1;
SmallHeapBlock *blockToCarve = nil;
while (remainingBins--)
{
currentBin++;
currentBinValue = *currentBin;
if (currentBinValue != nil)
{
blockToCarve = currentBinValue;
break;
}
}
// Try carving up up a block from the overflow bin.
if (blockToCarve == nil)
blockToCarve = GetOverflow();
while (blockToCarve != nil)
{
SInt32 blockToCarveSize = blockToCarve->GetBlockSize();
// If the owerflow block is big enough to house the
// allocation, then use it.
if (blockToCarveSize >= roundedBlockSize)
{
// Remove the block from the free list... we will
// be using it for the allocation...
RemoveBlockFromFreeList(blockToCarve);
// If taking our current allocation out of
// the overflow block would still leave enough
// room for another allocation out of the
// block, then split the block up.
SInt32 leftovers = blockToCarveSize - roundedBlockSize - SmallHeapBlock::kBlockOverhead;
if (leftovers >= kDefaultSmallHeadMinSize)
{
SmallHeapBlock *nextBlock = blockToCarve->GetNextBlock();
// Create a new block out of the leftovers
SmallHeapBlock *leftoverBlock = (SmallHeapBlock *)((char *)blockToCarve + roundedBlockSize + SmallHeapBlock::kBlockOverhead);
// Add the block to linked list of blocks in this raw
// allocation chunk.
nextBlock->SetPrevBlock(leftoverBlock);
blockToCarve->SetBlockSize(roundedBlockSize);
blockToCarve->SetBlockUsed();
leftoverBlock->SetPrevBlock(blockToCarve);
leftoverBlock->SetBlockSize(leftovers);
// And add the block to a free list, which will either be
// one of the sized bins or the overflow list, depending
// on its size.
AddBlockToFreeList(leftoverBlock);
}
// else...
// if we didn't carve up the block, then we are returning a block that is bigger
// than the requested size. That's fine, we just need to be careful about where
// to put the trailer tag, because we only know the allocated size, and not the
// requested size.
allocatedBlock = blockToCarve;
goto done;
}
blockToCarve = blockToCarve->GetNextFree();
}
return nil;
done:
allocatedBlock->SetOwningChunk(this);
#if DEBUG_HEAP_INTEGRITY
allocatedBlock->SetHeaderTag(kUsedBlockHeaderTag);
allocatedBlock->SetTrailerTag(allocatedBlock->GetBlockSize(), kUsedBlockTrailerTag);
allocatedBlock->ZapBlockContents(kUsedMemoryFillPattern);
allocatedBlock->SetPaddingBytes(roundedBlockSize - blockSize);
allocatedBlock->FillPaddingBytes();
#endif
#if STATS_MAC_MEMORY
allocatedBlock->SetLogicalBlockSize(blockSize);
GetOwningAllocator()->AccountForNewBlock(blockSize);
#endif
//MEM_ASSERT(!expectFailure, "I though this would fail!");
IncrementUsedBlocks();
return &allocatedBlock->memory;
}
//--------------------------------------------------------------------
void *nsSmallHeapChunk::GrowBlock(SmallHeapBlock *growBlock, size_t newSize)
//--------------------------------------------------------------------
{
UInt32 newAllocSize = (newSize + 3) & ~3;
SmallHeapBlock *blockToCarve = growBlock->GetNextBlock();
if (! blockToCarve->IsBlockUsed())
{
UInt32 oldPhysicalSize = growBlock->GetBlockHeapUsage();
UInt32 newPhysicalSize = SmallHeapBlock::kBlockOverhead + newAllocSize;
UInt32 blockToCarveSize = blockToCarve->GetBlockSize();
UInt32 blockToCarvePhysicalSize = blockToCarve->GetBlockHeapUsage();
SInt32 leftovers = (SInt32)oldPhysicalSize + blockToCarvePhysicalSize - newPhysicalSize;
// enough space to grow into the free block?
if (leftovers < 0)
return nil;
// Remove the block from the free list... we will
// be using it for the allocation...
RemoveBlockFromFreeList(blockToCarve);
// If taking our current allocation out of
// the overflow block would still leave enough
// room for another allocation out of the
// block, then split the block up.
if (leftovers >= kDefaultSmallHeadMinSize + SmallHeapBlock::kBlockOverhead)
{
// Create a new block out of the leftovers
SmallHeapBlock* leftoverBlock = (SmallHeapBlock *)((char *)growBlock + newPhysicalSize);
SmallHeapBlock* nextBlock = blockToCarve->GetNextBlock();
// Add the block to linked list of blocks in this raw allocation chunk.
nextBlock->SetPrevBlock(leftoverBlock);
growBlock->SetBlockSize(newAllocSize);
leftoverBlock->SetPrevBlock(growBlock);
leftoverBlock->SetBlockSize(leftovers - SmallHeapBlock::kBlockOverhead);
// And add the block to a free list, which will either be
// one of the sized bins or the overflow list, depending
// on its size.
AddBlockToFreeList(leftoverBlock);
}
else
{
SmallHeapBlock* nextBlock = blockToCarve->GetNextBlock();
nextBlock->SetPrevBlock(growBlock);
// If we're using the entire free block, then because growBlock->blockSize
// is used to calculate the start of the next block, it must be
// adjusted so that still does this.
growBlock->SetBlockSize(growBlock->GetBlockSize() + blockToCarvePhysicalSize);
}
#if DEBUG_HEAP_INTEGRITY
growBlock->SetPaddingBytes(newAllocSize - newSize);
growBlock->FillPaddingBytes();
growBlock->SetTrailerTag(growBlock->GetBlockSize(), kUsedBlockTrailerTag);
#endif
#if STATS_MAC_MEMORY
GetOwningAllocator()->AccountForResizedBlock(growBlock->GetLogicalBlockSize(), newSize);
growBlock->SetLogicalBlockSize(newSize);
#endif
return (void *)(&growBlock->memory);
}
return nil;
}
//--------------------------------------------------------------------
void *nsSmallHeapChunk::ShrinkBlock(SmallHeapBlock *shrinkBlock, size_t newSize)
//--------------------------------------------------------------------
{
UInt32 newAllocSize = (newSize + 3) & ~3;
UInt32 oldSize = shrinkBlock->GetBlockSize();
UInt32 oldPhysicalSize = shrinkBlock->GetBlockHeapUsage();
UInt32 newPhysicalSize = SmallHeapBlock::kBlockOverhead + newAllocSize;
SInt32 leftovers = (SInt32)oldPhysicalSize - newPhysicalSize;
MEM_ASSERT(leftovers > 0, "Should have some leftovers here");
SmallHeapBlock *nextBlock = shrinkBlock->GetNextBlock();
if (! nextBlock->IsBlockUsed())
{
// coalesce
leftovers += nextBlock->GetBlockHeapUsage(); // augmented leftovers.
RemoveBlockFromFreeList(nextBlock);
nextBlock = nextBlock->GetNextBlock();
}
else
{
// enough space to turn into a free block?
if (leftovers < SmallHeapBlock::kBlockOverhead + kDefaultSmallHeadMinSize)
return (void *)(&shrinkBlock->memory);
}
// Create a new block out of the leftovers (or augmented leftovers)
SmallHeapBlock *leftoverBlock = (SmallHeapBlock *)((char *)shrinkBlock + newPhysicalSize);
// Add the block to linked list of blocks in this raw
// allocation chunk.
nextBlock->SetPrevBlock(leftoverBlock);
shrinkBlock->SetBlockSize(newAllocSize);
leftoverBlock->SetPrevBlock(shrinkBlock);
leftoverBlock->SetBlockSize(leftovers - SmallHeapBlock::kBlockOverhead);
// And add the block to a free list, which will either be
// one of the sized bins or the overflow list, depending
// on its size.
AddBlockToFreeList(leftoverBlock);
#if DEBUG_HEAP_INTEGRITY
shrinkBlock->SetPaddingBytes(newAllocSize - newSize);
shrinkBlock->FillPaddingBytes();
shrinkBlock->SetTrailerTag(shrinkBlock->GetBlockSize(), kUsedBlockTrailerTag);
#endif
#if STATS_MAC_MEMORY
GetOwningAllocator()->AccountForResizedBlock(shrinkBlock->GetLogicalBlockSize(), newSize);
shrinkBlock->SetLogicalBlockSize(newSize);
#endif
return (void *)(&shrinkBlock->memory);
}
//--------------------------------------------------------------------
void* nsSmallHeapChunk::ResizeBlockInPlace(SmallHeapBlock *theBlock, size_t newSize)
//--------------------------------------------------------------------
{
#if DEBUG_HEAP_INTEGRITY
UInt32 newAllocSize = (newSize + 3) & ~3;
theBlock->SetPaddingBytes(newAllocSize - newSize);
theBlock->FillPaddingBytes();
#endif
#if STATS_MAC_MEMORY
GetOwningAllocator()->AccountForResizedBlock(theBlock->GetLogicalBlockSize(), newSize);
theBlock->SetLogicalBlockSize(newSize);
#endif
return (void *)(&theBlock->memory);
}
//--------------------------------------------------------------------
void nsSmallHeapChunk::ReturnBlock(SmallHeapBlock *deadBlock)
//--------------------------------------------------------------------
{
SmallHeapBlock *nextBlock = deadBlock->GetNextBlock();
SmallHeapBlock *prevBlock = deadBlock->GetPrevBlock();
#if STATS_MAC_MEMORY
GetOwningAllocator()->AccountForFreedBlock(deadBlock->GetLogicalBlockSize());
#endif
// If the block after us is free, then coalesce with it.
if (! nextBlock->IsBlockUsed())
{
RemoveBlockFromFreeList(nextBlock);
deadBlock->SetBlockSize( deadBlock->GetBlockSize() + nextBlock->GetBlockHeapUsage());
nextBlock = nextBlock->GetNextBlock();
}
// If the block before us is free, then coalesce with it.
if (! prevBlock->IsBlockUsed())
{
RemoveBlockFromFreeList(prevBlock);
prevBlock->SetBlockSize( ((Ptr)nextBlock - (Ptr)prevBlock) - SmallHeapBlock::kBlockOverhead);
AddBlockToFreeList(prevBlock);
deadBlock = prevBlock;
}
else
{
AddBlockToFreeList(deadBlock);
}
nextBlock->SetPrevBlock(deadBlock);
DecrementUsedBlocks();
}
//--------------------------------------------------------------------
void nsSmallHeapChunk::RemoveBlockFromFreeList(SmallHeapBlock *removeBlock)
//--------------------------------------------------------------------
{
UInt32 blockSize = removeBlock->GetBlockSize();
SmallHeapBlock *nextFree = removeBlock->GetNextFree();
SmallHeapBlock *prevFree = removeBlock->GetPrevFree();
if (nextFree != nil)
nextFree->SetPrevFree(prevFree);
if (prevFree != nil)
prevFree->SetNextFree(nextFree);
else
{
if (blockSize > kMaximumBinBlockSize)
mOverflow = nextFree;
else
{
UInt32 nextBlockBin = (blockSize - kDefaultSmallHeadMinSize) >> 2;
MEM_ASSERT(blockSize >= kDefaultSmallHeadMinSize, "Bad block size");
MEM_ASSERT(nextBlockBin < kDefaultSmallHeapBins, "Bad bin index");
mBins[nextBlockBin] = nextFree;
}
}
removeBlock->SetBlockUsed();
mTotalFree -= removeBlock->GetBlockHeapUsage();
}
//--------------------------------------------------------------------
void nsSmallHeapChunk::AddBlockToFreeList(SmallHeapBlock *addBlock)
//--------------------------------------------------------------------
{
mTotalFree += addBlock->GetBlockHeapUsage();
addBlock->SetBlockUnused();
UInt32 blockSize = addBlock->GetBlockSize();
addBlock->SetPrevFree(nil);
if (blockSize > kMaximumBinBlockSize)
{
SmallHeapBlock *tempBlock = mOverflow;
addBlock->SetNextFree(tempBlock);
if (tempBlock) tempBlock->SetPrevFree(addBlock);
mOverflow = addBlock;
}
else
{
UInt32 nextBlockBin = (blockSize - kDefaultSmallHeadMinSize) >> 2;
MEM_ASSERT(blockSize >= kDefaultSmallHeadMinSize, "Bad block size");
MEM_ASSERT(nextBlockBin < kDefaultSmallHeapBins, "Bad bin index");
SmallHeapBlock *tempBlock = mBins[nextBlockBin];
addBlock->SetNextFree(tempBlock);
if (tempBlock) tempBlock->SetPrevFree(addBlock);
mBins[nextBlockBin] = addBlock;
}
}

Просмотреть файл

@ -1,221 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <string.h>
class nsMemAllocator;
class nsSmallHeapChunk;
struct SmallHeapBlock
{
enum {
kBlockPaddingBytes = 'ðððð',
kBlockInUseFlag = 0x8000,
kBlockPaddingMask = 0x0003
};
static const UInt32 kBlockOverhead;
static SmallHeapBlock* GetBlockHeader(void *block) { return (SmallHeapBlock *)((char *)block - sizeof(SmallHeapBlock)); }
SmallHeapBlock* GetNextBlock() { return (SmallHeapBlock *)((UInt32)this + GetBlockHeapUsage()); }
SmallHeapBlock* GetPrevBlock() { return prevBlock; }
void SetPrevBlock(SmallHeapBlock *prev) { prevBlock = prev; }
void SetBlockSize(UInt32 inBlockSize) { blockSize = inBlockSize; }
UInt32 GetBlockSize() { return blockSize; }
UInt32 GetBlockHeapUsage() { return (GetBlockSize() + kBlockOverhead); }
Boolean IsBlockUsed() { return (blockFlags & kBlockInUseFlag) != 0; }
void SetBlockUsed() { blockFlags = 0; blockFlags |= kBlockInUseFlag; }
void SetBlockUnused() { blockFlags &= ~kBlockInUseFlag; }
void SetNextFree(SmallHeapBlock *next) { info.freeInfo.nextFree = next; }
void SetPrevFree(SmallHeapBlock *prev) { info.freeInfo.prevFree = prev; }
SmallHeapBlock* GetNextFree() { return info.freeInfo.nextFree; }
SmallHeapBlock* GetPrevFree() { return info.freeInfo.prevFree; }
void SetOwningChunk(nsHeapChunk *inOwningChunk) { info.inUseInfo.freeProc.owningChunk = inOwningChunk; }
nsSmallHeapChunk* GetOwningChunk() { return (nsSmallHeapChunk *)info.inUseInfo.freeProc.owningChunk; }
#if DEBUG_HEAP_INTEGRITY
void SetPaddingBytes(UInt32 padding) { blockFlags &= ~kBlockPaddingMask; blockFlags |= padding; }
void FillPaddingBytes() {
UInt32 padding = blockFlags & kBlockPaddingMask;
long *lastLong = (long *)((char *)&memory + blockSize - sizeof(long));
UInt32 mask = (1 << (8 * padding)) - 1;
*lastLong &= ~mask;
*lastLong |= (mask & kBlockPaddingBytes);
}
Boolean CheckPaddingBytes() {
UInt32 padding = blockFlags & kBlockPaddingMask;
long *lastLong = (long *)((char *)&memory + blockSize - sizeof(long));
UInt32 mask = (1 << (8 * padding)) - 1;
return (*lastLong & mask) == (mask & kBlockPaddingBytes);
}
UInt32 GetPaddingBytes() { return (blockFlags & kBlockPaddingMask); }
void ZapBlockContents(UInt8 pattern) { memset(&memory, pattern, blockSize); }
// inline, so won't crash if this is a bad block
Boolean HasHeaderTag(MemoryBlockTag inHeaderTag)
{ return info.inUseInfo.freeProc.headerTag == inHeaderTag; }
void SetHeaderTag(MemoryBlockTag inHeaderTag)
{ info.inUseInfo.freeProc.headerTag = inHeaderTag; }
void SetTrailerTag(UInt32 blockSize, MemoryBlockTag theTag)
{
MemoryBlockTrailer *trailer = (MemoryBlockTrailer *)((char *)&memory + blockSize);
trailer->trailerTag = theTag;
}
Boolean HasTrailerTag(UInt32 blockSize, MemoryBlockTag theTag)
{
MemoryBlockTrailer *trailer = (MemoryBlockTrailer *)((char *)&memory + blockSize);
return (trailer->trailerTag == theTag);
}
#endif
#if STATS_MAC_MEMORY
size_t GetLogicalBlockSize() { return info.inUseInfo.freeProc.logicalBlockSize; }
void SetLogicalBlockSize(size_t blockSize) { info.inUseInfo.freeProc.logicalBlockSize = blockSize; }
#endif
private:
SmallHeapBlock *prevBlock;
UInt16 blockFlags; // the top bit is the in use flag, the bottom 3 bits padding bytes
UInt16 blockSize;
union {
struct {
SmallHeapBlock *nextFree;
SmallHeapBlock *prevFree;
} freeInfo;
struct {
UInt32 filler;
MemoryBlockHeader freeProc; // this must be the last variable before memory
} inUseInfo;
} info;
public:
char memory[];
};
//--------------------------------------------------------------------
class nsSmallHeapAllocator : public nsMemAllocator
{
friend class nsSmallHeapChunk;
private:
typedef nsMemAllocator Inherited;
public:
nsSmallHeapAllocator(size_t minBlockSize, size_t maxBlockSize);
~nsSmallHeapAllocator();
void * AllocatorMakeBlock(size_t blockSize);
void AllocatorFreeBlock(void *freeBlock);
void * AllocatorResizeBlock(void *block, size_t newSize);
size_t AllocatorGetBlockSize(void *thisBlock);
nsHeapChunk* AllocateChunk(size_t blockSize);
void FreeChunk(nsHeapChunk *chunkToFree);
protected:
nsSmallHeapChunk* mChunkWithSpace; // cheap optimization
};
//--------------------------------------------------------------------
class nsSmallHeapChunk : public nsHeapChunk
{
public:
nsSmallHeapChunk(nsMemAllocator *inOwningAllocator, Size heapSize);
~nsSmallHeapChunk();
void * GetSpaceForBlock(UInt32 roundedBlockSize);
void ReturnBlock(SmallHeapBlock *deadBlock);
void * GrowBlock(SmallHeapBlock *growBlock, size_t newSize);
void * ShrinkBlock(SmallHeapBlock *shrinkBlock, size_t newSize);
void * ResizeBlockInPlace(SmallHeapBlock *shrinkBlock, size_t newSize);
protected:
enum {
kDefaultSmallHeadMinSize = 4L,
kDefaultSmallHeapBins = 128L,
kMaximumBinBlockSize = kDefaultSmallHeadMinSize + 4L * kDefaultSmallHeapBins - 1,
kMaximumBlockSize = 0xFFFF
};
SmallHeapBlock** GetBins(UInt32 binIndex)
{
MEM_ASSERT(binIndex < kDefaultSmallHeapBins, "Bad bin index!");
return mBins + binIndex;
}
SmallHeapBlock* GetOverflow() { return mOverflow; }
void RemoveBlockFromFreeList(SmallHeapBlock *removeBlock);
void AddBlockToFreeList(SmallHeapBlock *addBlock);
UInt32 mTotalFree;
#if DEBUG
UInt32 mInitialFree;
#endif
SmallHeapBlock* mOverflow;
SmallHeapBlock* mBins[kDefaultSmallHeapBins];
SmallHeapBlock mMemory[];
};

Просмотреть файл

@ -1,431 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
//----------------------------------------------------------------------------------------
/*
A set of classes for giving the memory allocators a thorough workout.
CMemoryBlock
This class manages a single memory block, which is allocated with
malloc(). The block is filled with a patter, and tag words put at
each end. The various operators allow you to change the block size;
for each change, the block is realloc'd and the tag words replaced.
Before each operation, the block contents are checked to ensure that
no-one wrote over them.
CMemoryTester
This class manages an array of CMemoryBlocks. In DoMemoryTesting(), it
allocates about 200 block with random sizes in a wide range, then
makes them bigger, smaller, frees some, allocates some more, and resizes
them again.
Its destructor frees the blocks.
CMemoryTesterPeriodical
This is a periodical that runs the memory tests. In the current implementaion,
it manages an array of CMemoryTesters. On each idle, it allocates a new
CMemoryTester, and does the testing. That CMemoryTester is put in an
array to keep track of it (but the memory is not freed yet). So on every
idle it "leaks" all the blocks managed by the tester. Memory soon gets
used up.
At some point an allocation will fail, and CMemoryBlock throws an exception.
This is caught by the CMemoryTesterPeriodical, which then frees up all the
CMemoryTesters. Next time around, it all starts again.
How to use:
Hook up your periodical in a convenient place like CFrontApp::Initialize():
CMemoryTesterPeriodical *tester = new CMemoryTesterPeriodical();
tester->StartIdling();
The app starts to run real slow, and if you watch memory use in the Finder,
you will see it fluctuate wildly as the periodical leaks lots of memory,
frees it all, then leaks it again. Since this is running on a periodical,
you can be browsing the web at the same time, albeit slowly.
If any errors are detected (e.g. the block tags have been overwritten),
then you will assert.
*/
//----------------------------------------------------------------------------------------
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <LArrayIterator.h>
#include "CMemoryWorkout.h"
#define kMinSize 8
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
//----------------------------------------------------------------------------------------
CMemoryBlock::CMemoryBlock()
: mBlockData(NULL)
, mBlockSize(0)
//----------------------------------------------------------------------------------------
{
}
//----------------------------------------------------------------------------------------
CMemoryBlock::CMemoryBlock(UInt32 inBlockSize)
: mBlockSize(inBlockSize)
//----------------------------------------------------------------------------------------
{
if (mBlockSize < kMinSize)
mBlockSize = kMinSize;
mBlockData = (char *)malloc(mBlockSize);
ThrowIfNil_(mBlockData);
InsertCheckBlocks();
}
//----------------------------------------------------------------------------------------
CMemoryBlock::~CMemoryBlock()
//----------------------------------------------------------------------------------------
{
if (GetBlockData())
{
Boolean isGood = QuickCheckBlock();
Assert_(isGood);
}
free(mBlockData);
}
//----------------------------------------------------------------------------------------
long *CMemoryBlock::GetBlockStartPtr()
//----------------------------------------------------------------------------------------
{
return (long *)mBlockData;
}
//----------------------------------------------------------------------------------------
long *CMemoryBlock::GetBlockEndPtr()
//----------------------------------------------------------------------------------------
{
if (!mBlockData) return nil;
char *dataEnd = mBlockData + mBlockSize;
return (long *)(dataEnd - sizeof(long));
}
//----------------------------------------------------------------------------------------
Boolean CMemoryBlock::QuickCheckBlock()
//----------------------------------------------------------------------------------------
{
ThrowIfNil_(mBlockData);
long *startCheckPtr = GetBlockStartPtr();
long *endCheckPtr = GetBlockEndPtr();
return (*startCheckPtr == eBlockStartMarker && *endCheckPtr == eBlockEndMarker);
}
//----------------------------------------------------------------------------------------
Boolean CMemoryBlock::ThoroughCheckBlock()
//----------------------------------------------------------------------------------------
{
if (!QuickCheckBlock())
return false;
return true; // I'm too lazy to do the whole thing
}
//----------------------------------------------------------------------------------------
void CMemoryBlock::InsertCheckBlocks()
//----------------------------------------------------------------------------------------
{
ThrowIfNil_(mBlockData);
memset(mBlockData, eBlockFillPattern, mBlockSize);
long *startCheckPtr = GetBlockStartPtr();
long *endCheckPtr = GetBlockEndPtr();
*startCheckPtr = eBlockStartMarker;
*endCheckPtr = eBlockEndMarker;
}
//----------------------------------------------------------------------------------------
void CMemoryBlock::ChangeBlockSize(UInt32 newSize)
//----------------------------------------------------------------------------------------
{
ThrowIfNil_(mBlockData);
Assert_(QuickCheckBlock());
mBlockSize = MAX(newSize, kMinSize);
mBlockData = (char *)realloc((void *)mBlockData, mBlockSize);
ThrowIfNil_(mBlockData);
InsertCheckBlocks();
}
//----------------------------------------------------------------------------------------
void CMemoryBlock::operator++(int)
//----------------------------------------------------------------------------------------
{
ChangeBlockSize(mBlockSize + 1);
}
//----------------------------------------------------------------------------------------
void CMemoryBlock::operator--(int)
//----------------------------------------------------------------------------------------
{
ChangeBlockSize(mBlockSize - 1);
}
//----------------------------------------------------------------------------------------
void CMemoryBlock::operator+=(UInt32 incSize)
//----------------------------------------------------------------------------------------
{
ChangeBlockSize(mBlockSize + incSize);
}
//----------------------------------------------------------------------------------------
void CMemoryBlock::operator-=(UInt32 decSize)
//----------------------------------------------------------------------------------------
{
if (decSize > mBlockSize)
decSize = 0;
UInt32 newSize = mBlockSize - decSize;
ChangeBlockSize(newSize > kMinSize ? newSize : kMinSize);
}
#pragma mark -
//----------------------------------------------------------------------------------------
CMemoryTester::CMemoryTester()
: mBlocksArray(sizeof(CMemoryBlock *))
//----------------------------------------------------------------------------------------
{
}
//----------------------------------------------------------------------------------------
CMemoryTester::~CMemoryTester()
//----------------------------------------------------------------------------------------
{
LArrayIterator iter(mBlocksArray);
CMemoryBlock *theBlock;
while (iter.Next(&theBlock) && theBlock)
{
delete theBlock;
}
mBlocksArray.RemoveItemsAt(mBlocksArray.GetCount(), LArray::index_First);
}
//----------------------------------------------------------------------------------------
void CMemoryTester::DoMemoryTesting()
//----------------------------------------------------------------------------------------
{
// let's make some objects with random sizes
for (Int32 i = 0; i < 10; i ++)
{
CMemoryBlock *newBlock = new CMemoryBlock( 1024 * (::Random() & 0x05FF) + (::Random() & 0x7FFF));
mBlocksArray.InsertItemsAt(1, LArray::index_Last, &newBlock);
}
for (Int32 i = 0; i < 100; i ++)
{
CMemoryBlock *newBlock = new CMemoryBlock( 1024 * (::Random() & 0x07F) + (::Random() & 0x7FFF));
mBlocksArray.InsertItemsAt(1, LArray::index_Last, &newBlock);
}
for (Int32 i = 0; i < 3000; i ++)
{
CMemoryBlock *newBlock = new CMemoryBlock(::Random() & 0x009F);
mBlocksArray.InsertItemsAt(1, LArray::index_Last, &newBlock);
}
/* now let's resize them
LArrayIterator iter(mBlocksArray);
CMemoryBlock *theBlock;
while (iter.Next(&theBlock) && theBlock)
{
(*theBlock)++;
}
iter.ResetTo(LArrayIterator::index_BeforeStart);
while (iter.Next(&theBlock) && theBlock)
{
(*theBlock)++;
}
iter.ResetTo(LArrayIterator::index_BeforeStart);
while (iter.Next(&theBlock) && theBlock)
{
(*theBlock)++;
}
iter.ResetTo(LArrayIterator::index_BeforeStart);
while (iter.Next(&theBlock) && theBlock)
{
(*theBlock) -= 10;
}
iter.ResetTo(LArrayIterator::index_BeforeStart);
while (iter.Next(&theBlock) && theBlock)
{
(*theBlock) += (::Random() & 0x07FF);
}
iter.ResetTo(LArrayIterator::index_BeforeStart);
while (iter.Next(&theBlock) && theBlock)
{
(*theBlock) += 0; // resize to same size
}
// now let's free every other block, and then reallocate them
iter.ResetTo(LArrayIterator::index_BeforeStart);
ArrayIndexT n = LArray::index_First;
while (iter.Next(&theBlock) && theBlock)
{
if ((n & 1) == 0)
{
delete theBlock;
theBlock = new CMemoryBlock(::Random() & 0x09F);
mBlocksArray.AssignItemsAt(1, n, &theBlock);
}
n++;
}
// now let's free every other block, and then reallocate them
iter.ResetTo(LArrayIterator::index_BeforeStart);
n = LArray::index_First;
while (iter.Next(&theBlock) && theBlock)
{
if ((n & 1) == 1)
{
delete theBlock;
theBlock = new CMemoryBlock(::Random() & 0x09F);
mBlocksArray.AssignItemsAt(1, n, &theBlock);
}
n++;
}
*/
/*
iter.ResetTo(LArrayIterator::index_BeforeStart);
while (iter.Next(&theBlock) && theBlock)
{
(*theBlock) -= (::Random() & 0x07FF);
}
*/
}
//----------------------------------------------------------------------------------------
CMemoryTesterPeriodical::CMemoryTesterPeriodical()
: LPeriodical()
, mTestersArray(sizeof(CMemoryTester *))
//----------------------------------------------------------------------------------------
{
}
//----------------------------------------------------------------------------------------
CMemoryTesterPeriodical::~CMemoryTesterPeriodical()
//----------------------------------------------------------------------------------------
{
FreeTesters();
}
//----------------------------------------------------------------------------------------
void CMemoryTesterPeriodical::FreeTesters()
//----------------------------------------------------------------------------------------
{
LArrayIterator iter(mTestersArray);
CMemoryTester *theTester;
while (iter.Next(&theTester) && theTester)
{
delete theTester;
}
mTestersArray.RemoveItemsAt(mTestersArray.GetCount(), LArray::index_First);
}
//----------------------------------------------------------------------------------------
void CMemoryTesterPeriodical::SpendTime(const EventRecord & /*inMacEvent */)
//----------------------------------------------------------------------------------------
{
try
{
CMemoryTester *tester = new CMemoryTester();
mTestersArray.InsertItemsAt(1, LArray::index_Last, &tester);
tester->DoMemoryTesting();
// leak the damn thing
}
catch (...)
{
DebugStr("\pWe ran out of memory. Free up time.");
FreeTesters();
}
}

Просмотреть файл

@ -1,129 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
//----------------------------------------------------------------------------------------
/*
CMemoryWorkout.h
See the .cp file for an explanation of what this stuff does.
*/
//----------------------------------------------------------------------------------------
#include <LPeriodical.h>
#include <LArray.h>
class CMemoryBlock
{
private:
enum
{
eBlockStartMarker = 'SMFR',
eBlockEndMarker = 'smfr'
};
enum
{
eBlockFillPattern = '0xBA'
};
public:
CMemoryBlock();
CMemoryBlock(UInt32 inBlockSize);
~CMemoryBlock();
Boolean QuickCheckBlock();
Boolean ThoroughCheckBlock();
void operator++(int);
void operator--(int);
void operator+=(UInt32 incSize);
void operator-=(UInt32 decSize);
protected:
char *GetBlockData() { return mBlockData; }
UInt32 GetBlockSize() { return mBlockSize; }
void ChangeBlockSize(UInt32 newSize);
void InsertCheckBlocks();
long *GetBlockStartPtr();
long *GetBlockEndPtr();
char *mBlockData;
UInt32 mBlockSize;
};
//----------------------------------------------------------------------------------------
class CMemoryTester
{
public:
CMemoryTester();
~CMemoryTester();
void DoMemoryTesting();
protected:
LArray mBlocksArray;
};
//----------------------------------------------------------------------------------------
class CMemoryTesterPeriodical : public LPeriodical
{
public:
CMemoryTesterPeriodical();
~CMemoryTesterPeriodical();
virtual void SpendTime(const EventRecord &inMacEvent);
private:
void FreeTesters();
LArray mTestersArray;
};

Просмотреть файл

@ -1,89 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <iostream>
#if __profile__
#include <Profiler.h>
#include <Processes.h>
#endif
#include "CMemoryWorkout.h"
void main(void)
{
#if __profile__
if (ProfilerInit(collectDetailed, bestTimeBase, 500, 20) != noErr)
ExitToShell();
#endif
// if you comment out the std::cout << calls below for profiling
// reasons, you need to called InitGraf because I use Random()
//::InitGraf(&qd.thePort);
std::cout << "Starting up";
CMemoryTester *tester = new CMemoryTester;
for (UInt32 i = 0; i < 1; i ++)
{
std::cout << i << std::endl;
try
{
tester->DoMemoryTesting();
}
catch(...)
{
std::cout << "Caught exception";
}
}
delete tester;
#if __profile__
ProfilerDump("\pMemoryTester.prof");
ProfilerTerm();
#endif
}

Двоичные данные
lib/mac/MacMemoryAllocator/test/MemoryTest.mcp

Двоичный файл не отображается.

Просмотреть файл

@ -1,76 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef _MoreMixedMode_
#define _MoreMixedMode_
/*
In a .h file, global (procedure declaration):
extern RoutineDescriptor foo_info;
PROCDECL(extern,foo);
In the .h file, class scoped (member declaration):
static RoutineDescriptor foo_info;
PROCDECL(static,foo);
In the .cp file, global (procedure definition):
RoutineDescriptor foo_info = RoutineDescriptor (foo);
PROCEDURE(foo,uppFooType);
In the .cp file, class scoped (member definition):
RoutineDescriptor Foo::foo_info = RoutineDescriptor (Bar::foo);
PROCDEF(Foo::,Bar::,foo,uppFooType);
References to the function:
foo_info
PROCPTR(foo)
*/
#include "MixedMode.h"
#if GENERATINGCFM
# define PROCPTR(NAME) NAME##_info
# define PROCDECL(MOD,NAME) MOD RoutineDescriptor PROCPTR(NAME);
# define PROCDEF(S1,S2,NAME,INFO) RoutineDescriptor S1##PROCPTR(NAME) = BUILD_ROUTINE_DESCRIPTOR (INFO, S2##NAME);
# define PROCEDURE(NAME,INFO) RoutineDescriptor PROCPTR(NAME) = BUILD_ROUTINE_DESCRIPTOR (INFO, NAME);
#else
# define PROCPTR(NAME) NAME
# define PROCDECL(MOD,NAME)
# define PROCDEF(S1,S2,NAME,INFO)
# define PROCEDURE(NAME,INFO)
#endif
#endif // _MoreMixedMode_

Просмотреть файл

@ -1,52 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#pragma once
#include <stdlib.h>
#include "prtypes.h"
typedef enum MemoryPriority { fcNone, fcLow, fcMedium, fcHigh, fcTop } MemoryPriority;
#define NEW( CLASS ) ( new CLASS )
#define DELETE( OBJECT ) delete OBJECT
PR_BEGIN_EXTERN_C
extern void* Flush_Allocate( size_t size, int zero );
extern void* Flush_Reallocate( void* item, size_t size );
extern void Flush_Free( void* item );
PR_END_EXTERN_C

Просмотреть файл

@ -1,243 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifdef mktime
#undef mktime
#undef ctime
#undef localtime
_C_LIB_DECL /* declarations */
time_t mktime(struct tm *);
char *ctime(const time_t *);
struct tm *localtime(const time_t *);
_END_C_LIB_DECL
#endif
#ifndef UNIXMINUSMACTIME
#define UNIXMINUSMACTIME 2082844800UL
#endif
#include <time.h>
#ifndef __OSUTILS__
#include <OSUtils.h>
#endif
#ifndef __TOOLUTILS__
#include <ToolUtils.h>
#endif
#include "xp_mcom.h" /* prototypes for GetTimeMac, Mactime, Macmktime, Macctime, Maclocaltime, Macgmtime */
#undef ctime
#undef mktime
// Because serial port and SLIP conflict with ReadXPram calls,
// we cache the call here
// The symptoms are the
void MyReadLocation(MachineLocation * loc);
long GMTDelta();
void MyReadLocation(MachineLocation * loc)
{
static MachineLocation storedLoc; // InsideMac, OSUtilities, page 4-20
static Boolean didReadLocation = false;
if (!didReadLocation)
{
ReadLocation(&storedLoc);
didReadLocation = true;
}
*loc = storedLoc;
}
#if 0
Boolean DaylightSavings()
{
MachineLocation loc;
unsigned char dlsDelta;
MyReadLocation(&loc);
dlsDelta = loc.u.dlsDelta;
return (dlsDelta != 0);
}
#endif
// This routine is copied straight out of stdio sources.
// The only difference is that we use MyReadLocation instead of ReadLocation.
struct tm *(gmtime)(const time_t *tod)
{ /* convert to Greenwich Mean Time (UTC) */
MachineLocation myLocation;
long int internalGmtDelta;
time_t ltime;
MyReadLocation(&myLocation);
internalGmtDelta = myLocation.u.gmtDelta & 0x00ffffff;
if (internalGmtDelta & 0x00800000)
internalGmtDelta = internalGmtDelta | 0xff000000;
ltime = (*tod) - internalGmtDelta;
return (localtime(&(ltime)));
}
// We need to do this, because we wrap localtime as a macro in
#ifdef localtime
#undef localtime
#endif
struct tm *localtime(const time_t *tp)
{
DateTimeRec dtr;
MachineLocation loc;
static struct tm statictime;
static const short monthday[12] =
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
SecondsToDate(*tp, &dtr);
statictime.tm_sec = dtr.second;
statictime.tm_min = dtr.minute;
statictime.tm_hour = dtr.hour;
statictime.tm_mday = dtr.day;
statictime.tm_mon = dtr.month - 1;
statictime.tm_year = dtr.year - 1900;
statictime.tm_wday = dtr.dayOfWeek - 1;
statictime.tm_yday = monthday[statictime.tm_mon]
+ statictime.tm_mday - 1;
if (2 < statictime.tm_mon && !(statictime.tm_year & 3))
++statictime.tm_yday;
MyReadLocation(&loc);
statictime.tm_isdst = loc.u.dlsDelta;
return(&statictime);
}
// current local time = GMTDelta() + GMT
// GMT = local time - GMTDelta()
long GMTDelta()
{
MachineLocation loc;
long gmtDelta;
MyReadLocation(&loc);
gmtDelta = loc.u.gmtDelta & 0x00FFFFFF;
if ((gmtDelta & 0x00800000) != 0)
gmtDelta |= 0xFF000000;
return gmtDelta;
}
// This routine simulates stdclib time(), time in seconds since 1.1.1970
// The time is in GMT
time_t GetTimeMac()
{
unsigned long maclocal;
// Get Mac local time
GetDateTime(&maclocal);
// Get Mac GMT
maclocal -= GMTDelta();
// return unix GMT
return (maclocal - UNIXMINUSMACTIME);
}
// Returns the GMT times
time_t Mactime(time_t *timer)
{
time_t t = GetTimeMac();
if (timer != NULL)
*timer = t;
return t;
}
time_t Macmktime (struct tm *timeptr)
{
time_t theTime;
// ¥¥¥ HACK to work around the bug in mktime
int negativeDiff = 0;
if (timeptr->tm_sec < 0)
{
negativeDiff += timeptr->tm_sec;
timeptr->tm_sec = 0;
}
if (timeptr->tm_min < 0)
{
negativeDiff += timeptr->tm_min*60;
timeptr->tm_min = 0;
}
if (timeptr->tm_hour < 0)
{
negativeDiff += timeptr->tm_hour*60*60;
timeptr->tm_hour = 0;
}
if (timeptr->tm_mday < 0)
{
negativeDiff += timeptr->tm_mday*60*60*24;
timeptr->tm_mday = 0;
}
// local/Mac
theTime = mktime(timeptr);
// mktime does not care what the daylightsavings flag is
timeptr->tm_isdst = 0;//DaylightSavings();
theTime += negativeDiff;
// GMT/Mac
theTime -= GMTDelta();
// unix/GMT
return theTime - UNIXMINUSMACTIME;
}
//
char * Macctime(const time_t * t)
{
// GMT Mac
time_t macTime = *t + UNIXMINUSMACTIME;
// local Mac
macTime += GMTDelta();
return ctime(&macTime);
}
struct tm *Maclocaltime(const time_t * t)
{
// GMT Mac
time_t macLocal = *t + UNIXMINUSMACTIME;
// local Mac
macLocal += GMTDelta();
return localtime(&macLocal);
}
// -> unix GMT
struct tm *Macgmtime (const time_t *clock)
{
// GMT Mac
time_t macGMT = *clock + UNIXMINUSMACTIME;
return localtime(&macGMT);
}

Просмотреть файл

@ -1,54 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#error "You should now include <strstream.h> from CWPro4"
#include "xp_mcom.h"
#include <sstream.h>
typedef basic_ostringstream<char, char_traits<char> > template_ostrstream;
class ostrstream : public template_ostrstream
{
public:
inline const char* str() const
{
string astr = template_ostrstream::str();
const char* cstr = astr.c_str();
return XP_STRDUP(cstr);
};
};

Просмотреть файл

@ -1,63 +0,0 @@
__dc_arr
__del_arr
__new_arr
__init_arr
__copy
__vt__Q23std13bad_exception # std::bad_exception::__vt
#__vt__Q23std9exception # std::exception::__vt
#what__Q23std9exceptionCFv # std::exception::what() const
#__ct__Q23std9exceptionFv # std::exception::exception()
#__dt__Q23std9exceptionFv # std::exception::~exception()
what__Q23std13bad_exceptionCFv # std::bad_exception::what() const
__end__catch
__throw
__unexpected
__dt__Q23std13bad_exceptionFv # std::bad_exception::~bad_exception()
__unregister_fragment
__register_fragment
__global_destructor_chain
__destroy_global_chain
__register_global_object
__register_atexit
__destroy_new_array2
__destroy_new_array
__destroy_arr
__construct_array
__dt__26__partial_array_destructorFv # __partial_array_destructor::~__partial_array_destructor()
__construct_new_array
__throw_catch_compare
unexpected__3stdFv # std::unexpected()
set_unexpected__3stdFPFv_v # std::set_unexpected(void (*)(void))
terminate__3stdFv # std::terminate()
set_terminate__3stdFPFv_v # std::set_terminate(void (*)(void))
#__vt__Q23std8bad_cast # std::bad_cast::__vt
__vt__Q23std10bad_typeid # std::bad_typeid::__vt
what__Q23std10bad_typeidCFv # std::bad_typeid::what() const
#what__Q23std8bad_castCFv # std::bad_cast::what() const
__dynamic_cast
#__dt__Q23std8bad_castFv # std::bad_cast::~bad_cast()
__get_typeid
__dt__Q23std10bad_typeidFv # std::bad_typeid::~bad_typeid()
nothrow__3std
#__dla__FPv # __dla(void*)
#__nwa__FUlRCQ23std9nothrow_t # __nwa(unsigned long,const std::nothrow_t&)
#__nwa__FUl # __nwa(unsigned long)
#__dl__FPv # operator delete(void*)
#__nw__FUlRCQ23std9nothrow_t # operator new(unsigned long,const std::nothrow_t&)
#__nw__FUl # operator new(unsigned long)
#_prealloc_newpool__3stdFUl # std::_prealloc_newpool(unsigned long)
#_set_newnonptrmax__3stdFUl # std::_set_newnonptrmax(unsigned long)
#_set_newpoolsize__3stdFUl # std::_set_newpoolsize(unsigned long)
__throws_bad_alloc__3std # std::__throws_bad_alloc
#__vt__Q23std9bad_alloc # std::bad_alloc::__vt
__new_handler__3std # std::__new_handler
#what__Q23std9bad_allocCFv # std::bad_alloc::what() const
__del_hdl
__new_hdl
set_new_handler__3stdFPFv_v # std::set_new_handler(void (*)(void))
__throw_bad_alloc__3stdFv # std::__throw_bad_alloc()
#__dt__Q23std9bad_allocFv # std::bad_alloc::~bad_alloc()
#__ptmf_null
#longjmp
#__terminate
#__initialize

Просмотреть файл

@ -1,30 +0,0 @@
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
# Build NSRuntimeStubs
Evaluate % = ("{{SourceFile}}" =~ /(Å:)¨0Å/)
MakeStub "{{SourceFile}}" -o "{{¨0}}:::dist:client_stubs:NSRuntimeStubs" ¶
-fragname NSRuntime ¶
-vercur 0 -verdef 0 -verimp 0
exit 1

Просмотреть файл

@ -1,42 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "DefinesMac.h"
#include "IDE_Options.h"
#include "ansi_prefix.mac.h"
#define NEWMODE NEWMODE_NONE

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,44 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#define DEBUG
#include "DefinesMac.h"
#include "IDE_Options.h"
#include "ansi_prefix.mac.h"
#define NEWMODE NEWMODE_NONE

Просмотреть файл

@ -1,2 +0,0 @@
# only export this when _not_ building for Carbon.
qd

Просмотреть файл

@ -1,10 +0,0 @@
#library
__PROFILE_EXIT
__PROFILE_ENTRY
#utils
ProfileStart
ProfileStop
ProfileSuspend
ProfileResume
ProfileInProgress

Просмотреть файл

@ -1,50 +0,0 @@
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifdef __cplusplus
extern "C" {
#endif
extern void ProfileStart();
extern void ProfileStop();
extern void ProfileSuspend();
extern void ProfileResume();
extern Boolean ProfileInProgress();
#ifdef __cplusplus
}
#endif

Просмотреть файл

@ -1,129 +0,0 @@
/*
GC_profiler.cpp
Experimental hack to clear stack frames upon entry, to make a conservative
garbage collector more accurate.
*/
#include <Profiler.h>
#pragma profile off
/**
* Instruction constants. To clear the stack frame accurately,
* we "interpret" the caller's prologue to see which stack locations
* are already in use to save non-volatile registers. this is pretty
* specific to Metrowerks generated PowerPC code.
*/
const unsigned MFLR_R0 = 0x7C0802A6;
const unsigned STW = 0x24; // 0b100100 == 0x24
const unsigned STMW = 0x2F; // 0b101111 == 0x2F
const unsigned R1 = 0x01;
/**
* Multiplicative hash, from Knuth 6.4.
*/
const unsigned GOLDEN_RATIO = 0x9E3779B9U;
/**
* A PowerPC store instruction has this form.
*/
struct store {
unsigned opcode : 6;
unsigned source : 5;
unsigned destination : 5;
signed offset : 16;
};
struct stack_frame {
stack_frame* next; // savedSP
void* savedCR;
void* savedLR;
void* reserved0;
void* reserved1;
void* savedTOC;
};
struct offset_cache {
void* savedLR;
signed min_offset;
};
asm stack_frame* getStackFrame()
{
mr r3,sp
blr
}
static unsigned long long hits = 1, misses = 1;
static double hit_ratio = 1.0;
static const CACHE_BITS = 12;
static const CACHE_SIZE = (1 << CACHE_BITS); // 4096 elements should be enough.
static const CACHE_SHIFT = (32 - CACHE_BITS); // only consider upper CACHE_BITS of the hashed value.
static const CACHE_MASK = (CACHE_SIZE - 1); // only consider lower CACHE_BITS of the hashed value.
static struct cache_entry {
void* savedLR;
signed minOffset;
const char* functionName;
} offset_cache[CACHE_SIZE];
/**
* This routine clears the newly reserved stack space in the caller's frame.
* This is done so that the stack won't contain any garbage pointers which
* can cause undue retention of garbage.
*/
pascal void __PROFILE_ENTRY(char* functionName)
{
stack_frame* myLinkage = getStackFrame()->next;
stack_frame* callersLinkage = myLinkage->next;
signed minOffset = 0;
// see if we've scanned this routine before, by consulting a direct-mapped cache.
// we're just hashing the caller's address, using the Knuth's venerable multiplicative
// hash function.
void* savedLR = myLinkage->savedLR;
unsigned h = ((reinterpret_cast<unsigned>(savedLR) >> 2) * GOLDEN_RATIO) >> CACHE_SHIFT;
// unsigned h = ((reinterpret_cast<unsigned>(savedLR) >> 2) * GOLDEN_RATIO) & CACHE_MASK;
cache_entry& entry = offset_cache[h];
if (entry.savedLR == savedLR) {
minOffset = entry.minOffset;
// ++hits;
} else {
// scan the caller's prologue, looking for stw instructions. stores to negative
// offsets off of sp will tell us where the beginning of the unitialized
// frame begins. stmw instructions are also considered.
// start scanning at the first instruction before the call.
unsigned* pc = -2 + reinterpret_cast<unsigned*>(savedLR);
while (*pc != MFLR_R0) {
store* instruction = reinterpret_cast<store*>(pc--);
unsigned opcode = instruction->opcode;
if ((opcode == STW || opcode == STMW) && instruction->destination == R1) {
signed offset = instruction->offset;
if (offset < minOffset)
minOffset = offset;
}
}
// cache the minimum offset value, to avoid rescanning the instructions on
// subsequent invocations.
entry.savedLR = savedLR;
entry.minOffset = minOffset;
entry.functionName = functionName;
// ++misses;
}
// hit_ratio = (double)hits / (double)misses;
// clear the space between the linkage area the caller has reserved
// for us, and the caller's saved non-volatile registers.
signed* ptr = reinterpret_cast<signed*>(myLinkage + 1);
signed* end = reinterpret_cast<signed*>(minOffset + reinterpret_cast<char*>(callersLinkage));
while (ptr < end) *ptr++ = 0;
}
pascal void __PROFILE_EXIT()
{
}

Просмотреть файл

@ -1,90 +0,0 @@
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifdef DEBUG
#include <profiler.h>
#include <Events.h>
#include "ProfilerUtils.h"
//---------------------------------------------
static Boolean sProfileInProgress = false;
void ProfileStart()
{
if (! sProfileInProgress)
{
sProfileInProgress = true;
if (ProfilerInit(collectDetailed, microsecondsTimeBase, 5000, 500))
return;
ProfilerSetStatus(true);
}
}
//---------------------------------------------
void ProfileStop()
{
if (sProfileInProgress)
{
ProfilerDump("\pMozilla Profile");
ProfilerTerm();
sProfileInProgress = false;
}
}
//---------------------------------------------
void ProfileSuspend()
{
if (sProfileInProgress)
ProfilerSetStatus(false);
}
//---------------------------------------------
void ProfileResume()
{
if (sProfileInProgress)
ProfilerSetStatus(true);
}
//---------------------------------------------
Boolean ProfileInProgress()
{
return sProfileInProgress;
}
#endif //DEBUG

Просмотреть файл

@ -1,62 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Mozilla browser.
*
* The Initial Developer of the Original Code is Netscape
* Communications, Inc. Portions created by Netscape are
* Copyright (C) 1999, Mozilla. All Rights Reserved.
*
* Contributor(s):
* Patrick Beard <beard@netscape.com>
*/
/*
NSStartup.c
*/
#include <CodeFragments.h>
#include <stdio.h>
#include <string.h>
#include "gc_fragments.h"
extern char __code_start__[]; /* (defined by linker) */
extern char __code_end__[]; /* (defined by linker) */
extern char __data_start__[]; /* (defined by linker) */
extern char __data_end__[]; /* (defined by linker) */
/* standard __initialize/__terminate routines. */
extern pascal OSErr __initialize(const CFragInitBlock* initBlock);
extern pascal void __terminate(void);
pascal OSErr __NSInitialize(const CFragInitBlock* initBlock);
pascal void __NSTerminate(void);
pascal OSErr __NSInitialize(const CFragInitBlock* initBlock)
{
// let the GC know about this library.
GC_register_fragment(__data_start__, __data_end__ + sizeof(char*),
__code_start__, __code_end__,
initBlock->fragLocator.u.onDisk.fileSpec);
return __initialize(initBlock);
}
pascal void __NSTerminate()
{
__terminate();
// remove this library's global roots.
GC_unregister_fragment(__data_start__, __data_end__ + sizeof(char*),
__code_start__, __code_end__);
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,43 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "IDE_Options.h"
/* Common defines for NSStartup */
/* Turn this on to use the GC based leak detector. */
/* #define GC_LEAK_DETECTOR 1 */

Просмотреть файл

@ -1,101 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Conrad Carlen <ccarlen@netscape.com>
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsComponentResContext.h"
#include <Resources.h>
short nsComponentResourceContext::sCompResRefNum = kResFileNotOpened;
pascal OSErr __NSInitialize(const CFragInitBlock *theInitBlock);
pascal OSErr __NSInitializeWithResources(const CFragInitBlock *theInitBlock);
pascal void __NSTerminate(void);
pascal void __NSTerminateWithResources(void);
//****************************************************************************************
// Fragment Init and Termination
//****************************************************************************************
pascal OSErr __NSInitializeWithResources(const CFragInitBlock *theInitBlock)
{
OSErr err = __NSInitialize(theInitBlock);
if (err)
return err;
short saveResFile = ::CurResFile();
short refNum = ::FSpOpenResFile(theInitBlock->fragLocator.u.onDisk.fileSpec, fsRdPerm);
nsComponentResourceContext::sCompResRefNum = refNum;
::UseResFile(saveResFile);
return ::ResError();
}
pascal void __NSTerminateWithResources(void)
{
if (nsComponentResourceContext::sCompResRefNum != kResFileNotOpened)
::CloseResFile(nsComponentResourceContext::sCompResRefNum);
__NSTerminate();
}
//****************************************************************************************
// nsComponentResourceContext
//****************************************************************************************
nsComponentResourceContext::nsComponentResourceContext() :
mSavedResRefNum(kResFileNotOpened)
{
}
nsComponentResourceContext::~nsComponentResourceContext()
{
if (mSavedResRefNum != kResFileNotOpened)
::UseResFile(mSavedResRefNum);
}
Boolean nsComponentResourceContext::BecomeCurrent()
{
if (sCompResRefNum == kResFileNotOpened)
return false;
mSavedResRefNum = ::CurResFile();
::UseResFile(sCompResRefNum);
return ::ResError() == noErr;
}

Просмотреть файл

@ -1,70 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Conrad Carlen <ccarlen@netscape.com>
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsComponentResContext_h__
#define nsComponentResContext_h__
#include <CodeFragments.h>
/*
* Allows use of resources from the component's resource fork.
*
* Specify __NSInitializeWithResources and __NSTerminateWithResources
* as the entry points of the component and then code within that
* component can use this class.
*
*/
class nsComponentResourceContext
{
friend pascal OSErr __NSInitializeWithResources(const CFragInitBlock *theInitBlock);
friend pascal void __NSTerminateWithResources(void);
public:
nsComponentResourceContext();
~nsComponentResourceContext();
Boolean BecomeCurrent(); // TRUE if success
private:
static short sCompResRefNum;
short mSavedResRefNum;
};
#endif // nsComponentResources_h__

Просмотреть файл

@ -1,23 +0,0 @@
InstLogTraceEventWithDataStructure
InstCreateMagnitudeClass
InstLogTraceEvent
InstCreateSplitHistogramClass
InstUpdateGrowth
InstCreateDataDescriptor
InstDisposeDataDescriptors
InstUpdateMagnitudeAbsolute
InstLogTraceEventWithData
InstCreateTallyClass
InstUpdateTally
InstDisposeDataDescriptor
InstUpdateHistogram
InstCreateDataDescriptors
InstCreateHistogramClass
InstDisposeClass
InstCreatePathClass
InstDisableClass
InstCreateEventTag
InstEnableClass
InstUpdateMagnitudeDelta
InstCreateGrowthClass
InstCreateTraceClass

Просмотреть файл

@ -1,7 +0,0 @@
InstallConsole
RemoveConsole
WriteCharsToConsole
ReadCharsFromConsole
SIOUXHandleOneEvent
SIOUXIsAppWindow
SIOUXSettings

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,672 +0,0 @@
get__11EnvironmentFPCc # Environment::get(const char*)
__dt__11EnvironmentFv # Environment::~Environment()
__ct__11EnvironmentFv # Environment::Environment()
#FSRefParentAndFilename_fopen
#FSRef_fopen
FSp_fopen
__MacOSErrNo
__aborting
__acoshl
__acosl
__asinhl
__asinl
__assertion_failed
__atan2l
__atanhl
__atanl
__ceill
__copysignl
__coshl
__cosl
__ct__Q23std10_MSLstringFRCQ23std59basic_string<c,Q23std14char_traits<c>,Q23std12allocator<c>>
__ct__Q23std4_BCDFr
__ct__Q23std7__nInitFv
__ct__Q23std7__wInitFv
__ct__Q33std8ios_base4InitFv
__ctype_map
__double_epsilon
__double_huge
__double_max
__double_min
__dt__Q23std12strstreambufFv
__dt__Q23std7__nInitFv
__dt__Q23std7__wInitFv
__dt__Q23std8ios_baseFv
__erfcl
__erfl
__exp2l
__expl
__expm1l
__extended_epsilon
__extended_huge
__extended_max
__extended_min
__fabsl
__fdiml
__files
__float_huge
__float_nan
__floorl
__fmaxl
__fminl
__fmodl
__fread
__frexpl
__fwrite
__gammal
__get_char
__get_file_modes
__getcreator
__gettype
__handle_open
__hypotl
__ldexpl
__lgammal
__log10l
__log1pl
__log2l
__logbl
__logl
__lower_map
__modfl
#__msl_get_system_encoding
#__msl_path2fsr
#__msl_path2splitfsr
#__msl_system_has_new_file_apis
#__msl_text2unicode
#__msl_unicode2text
__nearbyintl
__nextafterl
__path2fss
__powl
__put_char
__remainderl
__remquol
__rintl
__roundl
__sinhl
__sinl
__sqrtl
__system7present
__tanhl
__tanl
__temp_file_mode
__truncl
__upper_map
__vt__Q23std12strstreambuf
__vt__Q23std8ios_base
__wctype_map
__wlower_map
__wupper_map
_fcreator
_filelength
_fseek
_ftell
_ftype
_gcvt
_heapmin
_itoa
_itow
_strcasecmp
_strcmpi
_strdate
_strdup
_stricmp
_strlwr
_strncasecmp
_strncmpi
_strnicmp
_strnset
_strrev
_strset
_strspnp
_strupr
_ultoa
_wcsdup
_wcsicmp
_wcslwr
_wcsnicmp
_wcsnset
_wcsrev
_wcsset
_wcsspnp
_wcsupr
_wstrrev
_wtoi
abort
abs
access
acosf
acoshf
allocated__Q23std12strstreambuf
asctime
asinf
asinhf
atan2f
atanf
atanhf
atexit
atof
atoi
atol
bsearch
btowc
ceilf
cerr__3std
chdir
chmod
cin__3std
clearerr
clock
clog__3std
close
copy_ios_base__Q23std8ios_baseFRCQ23std8ios_base
copysignf
cosf
coshf
cout__3std
creat
ctime
cuserid
difftime
div
erfcf
erff
errno
exec
exit
exp2f
expf
expm1f
fabsf
fclose
fcntl
fdimf
fdopen
feof
ferror
fflush
fgetc
fgetpos
fgets
fgetwc
fgetws
filelength
fileno
floorf
fmaxf
fminf
fmodf
fopen
fprintf
fputc
fputs
fputwc
fputws
fread
freeze__Q23std12strstreambufFb
freopen
frexpf
frozen__Q23std12strstreambuf
fscanf
fseek
fsetpos
fstat
ftell
fwide
fwprintf
fwrite
fwscanf
gammaf
gcvt
getc
getchar
getcwd
getenv
getlogin
gets
getwc
getwchar
gmtime
heapmin
hypotf
imbue__Q23std8ios_baseFRCQ23std6locale
index___Q23std8ios_base
init__Q23std12strstreambufFPclPc
init__Q23std8ios_baseFPv
isatty
iswctype
itoa
itow
iword__Q23std8ios_baseFi
labs
ldexpf
ldiv
lgammaf
llabs
lldiv
llrint
llrintf
llrintl
llround
llroundf
llroundl
localeconv
localtime
log10f
log1pf
log2f
logbf
logf
lrint
lrintf
lrintl
lround
lroundf
lroundl
lseek
mblen
mbrlen
mbrtowc
mbsrtowcs
mbstowcs
mbtowc
memchr
memcmp
memcpy
memmove
memset
mkdir
mktime
must_round__Q23std4_BCDCFUl
nearbyintf
nextafter
ninit_cnt_s__Q23std7__nInit
open
overflow__Q23std12strstreambufFi
pbackfail__Q23std12strstreambufFi
perror
powf
printf
putc
putchar
puts
putwc
putwchar
pword__Q23std8ios_baseFi
qsort
raise
rand
read
register_callback__Q23std8ios_baseFPFQ33std8ios_base5eventRQ23std8ios_basei_vi
remainderf
remove
remquof
rename
rewind
rintf
rmdir
roundf
scalbln
scalblnf
scalblnl
scalbn
scalbnf
scalbnl
scanf
seekoff__Q23std12strstreambufFlQ33std8ios_base7seekdirQ33std8ios_base8openmode
seekpos__Q23std12strstreambufFQ23std7fpos<i>Q33std8ios_base8openmode
setbuf
setbuf__Q23std12strstreambufFPcl
setlocale
setvbuf
signal
sinf
sinhf
sleep
snprintf
sprintf
sqrtf
srand
sscanf
stat
strcasecmp
strcat
strchr
strcmp
strcmpi
strcoll
strcpy
strcspn
strdate
strdup
strerror
strftime
stricmp
strlen
strlwr
strncasecmp
strncat
strncmp
strncmpi
strncpy
strnicmp
strnset
strpbrk
strrchr
strrev
strset
strspn
strspnp
strstr
strtod
strtok
strtol
strtold
strtoll
strtoul
strtoull
strupr
strxfrm
swprintf
swscanf
sync_with_stdio__Q23std8ios_baseFb
tanf
tanhf
time
tmpfile
tmpnam
to_long_double__Q23std4_BCDCFv
to_string__Q23std4_BCDCFiRi
towctrans
truncf
ttyname
ultoa
umask
uname
underflow__Q23std12strstreambufFv
ungetc
ungetwc
unlink
utime
utimes
vfprintf
vfscanf
vfwprintf
vfwscanf
vprintf
vscanf
vsnprintf
vsprintf
vsscanf
vswprintf
vswscanf
vwprintf
vwscanf
watof
watoi
watol
wcerr__3std
wcin__3std
wclog__3std
wcout__3std
wcrtomb
wcscat
wcschr
wcscmp
wcscoll
wcscpy
wcscspn
wcsdup
wcsftime
wcsicmp
wcslen
wcslwr
wcsncat
wcsncmp
wcsncpy
wcsnicmp
wcsnset
wcspbrk
wcsrchr
wcsrev
wcsrtombs
wcsset
wcsspn
wcsspnp
wcsstr
wcstod
wcstok
wcstol
wcstoll
wcstombs
wcstoul
wcstoull
wcsupr
wcsxfrm
wctob
wctomb
wctrans
wctype
winit_cnt_s__Q23std7__wInit
wmemchr
wmemcmp
wmemcpy
wmemmove
wmemset
wprintf
write
wscanf
wstrrev
wtoi
InitializeMacToolbox
#__ptmf_null
#__vec_longjmp
#longjmp
#__terminate
#__initialize
#__destroy_new_array3
#__destroy_new_array2
#__destroy_new_array
#__NSTerminate
#__NSInitialize
#vec_free
#vec_realloc
#vec_calloc
#vec_malloc
#__malloc_free_all
#__pool_free_all
calloc
realloc
free
malloc
#__pool_alloc_clear
#__pool_realloc
#__pool_free
#__pool_alloc
#__msize
#__report_on_heap
#__report_on_pool_heap
#deallocate_from_fixed_pools
#allocate_from_fixed_pools
#__init_pool_obj
nothrow
__dla__FPv # operator delete[](void*)
__nwa__FUlRCQ23std9nothrow_t # operator new[](unsigned long,const std::nothrow_t&)
__nwa__FUl # operator new[](unsigned long)
__dl__FPv # operator delete(void*)
__nw__FUl # operator new(unsigned long)
__nw__FUlRCQ23std9nothrow_t # operator new(unsigned long,const std::nothrow_t&)
GC_stderr
GC_stdout
GC_trace_object
GC_mark_object
MWUnmangle
GC_malloc_atomic
GC_address_to_source
GC_gcollect
GC_generic_init_threads
GC_clear_roots
GC_unregister_fragment
GC_register_fragment
#__sys_pointer_size
#__sys_free
#__sys_alloc
FSpDirectoryCopy
FSpFilteredDirectoryCopy
DirectoryCopy
FilteredDirectoryCopy
FSpFileCopy
FileCopy
FSpCreateResFileCompat
FSpOpenResFileCompat
FSpExchangeFilesCompat
FSpCatMoveCompat
FSpRenameCompat
FSpRstFLockCompat
FSpSetFLockCompat
FSpSetFInfoCompat
FSpGetFInfoCompat
FSpDeleteCompat
FSpDirCreateCompat
FSpCreateCompat
FSpOpenRFCompat
FSpOpenDFCompat
FSMakeFSSpecCompat
LocationFromFullPath
FSpLocationFromFullPath
FSpGetFullPath
GetFullPath
FSpIterateDirectory
IterateDirectory
FSpDTCopyComment
DTCopyComment
FSpDTGetComment
DTGetComment
FSpDTSetComment
DTSetComment
DTGetIcon
FSpDTGetAPPL
DTGetAPPL
FSpDTXGetAPPL
DTXGetAPPL
DTOpen
GetUGEntry
FSpUnshare
Unshare
FSpShare
Share
VolumeMount
GetVolMountInfo
GetVolMountInfoSize
FSpMoveRename
HMoveRename
FSpCopyFile
HCopyFile
HMapName
HMapID
FSpSetDirAccess
HSetDirAccess
FSpGetDirAccess
HGetDirAccess
HGetLogInInfo
FSpSetForeignPrivs
SetForeignPrivs
FSpGetForeignPrivs
GetForeignPrivs
UnlockRange
LockRange
FlushFile
DeleteFileIDRef
FSpCreateFileIDRef
CreateFileIDRef
FSpResolveFileIDRef
ResolveFileIDRef
ExchangeFiles
FSpCreateMinimum
HCreateMinimum
HGetVolParms
GetUGEntries
RetrieveAFPXVolMountInfo
BuildAFPXVolMountInfo
RetrieveAFPVolMountInfo
BuildAFPVolMountInfo
FSpMoveRenameCompat
HMoveRenameCompat
FSpCopyDirectoryAccess
CopyDirectoryAccess
FSpGetFileLocation
GetFileLocation
CopyFork
FSWriteVerify
FSWriteNoCache
FSReadNoCache
FSpOpenRFAware
HOpenRFAware
FSpOpenAware
HOpenAware
FSpCopyFileMgrAttributes
CopyFileMgrAttributes
FSpClearHasBeenInited
ClearHasBeenInited
FSpClearHasCustomIcon
ClearHasCustomIcon
FSpSetHasCustomIcon
SetHasCustomIcon
FSpClearIsStationery
ClearIsStationery
FSpSetIsStationery
SetIsStationery
FSpClearNameLocked
ClearNameLocked
FSpSetNameLocked
SetNameLocked
FSpClearIsInvisible
ClearIsInvisible
FSpSetIsInvisible
SetIsInvisible
FSpChangeFDFlags
ChangeFDFlags
FSpChangeCreatorType
ChangeCreatorType
FSpBumpDate
BumpDate
FSpGetFileSize
GetFileSize
FSpCheckObjectLock
CheckObjectLock
DeleteDirectory
DeleteDirectoryContents
GetDirItems
GetObjectLocation
GetFilenameFromPathname
GetParentID
FSpGetIOACUser
GetIOACUser
GetDirName
FSpGetDirectoryID
GetDirectoryID
FSpSetDInfo
SetDInfo
FSpGetDInfo
GetDInfo
SetDefault
OnLine
GetVolFileSystemID
CheckVolLock
XGetVInfo
HGetVInfo
DetermineVRefNum
GetCatInfoNoName
XGetVolumeInfoNoName
GetVolumeInfoNoName
GetTempBuffer
TruncPString
CreatorTypeFileSearch
NameFileSearch
PBCatSearchSyncCompat
IndexedSearch

Просмотреть файл

@ -1,26 +0,0 @@
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Build NSStdLibStubs
Evaluate % = ("{{SourceFile}}" =~ /(Å:)¨0Å/)
MakeStub "{{SourceFile}}" -o "{{¨0}}:::dist:client_stubs:NSStdLibStubs" ¶
-fragname NSStdLib ¶
-vercur 400 -verdef 400 -verimp 400

Просмотреть файл

@ -1,41 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* Non debug specific defines for NSStdLib */
#include "MacPrefix.h"
#include "NSStdLibConfig.h"

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,26 +0,0 @@
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
# Build NSStdLibStubs
Evaluate % = ("{{SourceFile}}" =~ /(Å:)¨0Å/)
MakeStub "{{SourceFile}}" -o "{{¨0}}:::dist:client_stubs:NSStdLibStubs" ¶
-fragname NSStdLib ¶
-vercur 400 -verdef 400 -verimp 400

Просмотреть файл

@ -1,44 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* Common defines for both debug & non-debug versions NSStdLib */
#define _MSL_IMP_EXP __declspec(export)
// So we can continue to run on 8.6
#define _MSL_USE_NEW_FILE_APIS 0
#define _MSL_USE_OLD_FILE_APIS 1

Просмотреть файл

@ -1,43 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* Debug specific defines for the NSStdLib */
#include "MacPrefix_debug.h"
#include "NSStdLibConfig.h"

Просмотреть файл

@ -1,8 +0,0 @@
# GC exports.
GC_add_roots
GC_remove_roots
GC_clear_roots
GC_generic_init_threads
GC_gcollect
GC_stdout
GC_stderr

Просмотреть файл

@ -1,10 +0,0 @@
#library
__PROFILE_EXIT
__PROFILE_ENTRY
#utils
ProfileStart
ProfileStop
ProfileSuspend
ProfileResume
ProfileInProgress

Просмотреть файл

@ -1,4 +0,0 @@
InitializeSIOUX
IsSIOUXWindow
SIOUXHandleOneEvent
SIOUXSettings

Просмотреть файл

@ -1,70 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
Definitions for all routines normally found in string.h, but not there in the Metrowerks
ANSII headers.
*/
#ifndef __MACTYPES__
#include <MacTypes.h>
#endif
#ifndef __QUICKDRAW__
#include <Quickdraw.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern char *strdup(const char *source);
extern int strcasecmp(const char*, const char*);
extern int strncasecmp(const char*, const char*, int length);
extern void InitializeMacToolbox(void); // also calls InitializeSIOUX(false) if DEBUG.
#if DEBUG
extern void InitializeSIOUX(unsigned char isStandAlone);
extern Boolean IsSIOUXWindow(WindowPtr inWindow);
#endif /* DEBUG */
#ifdef __cplusplus
}
#endif

Просмотреть файл

@ -1,332 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick C. Beard <beard@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
////////////////////////////////////////////////////////////////////////////////
// Console stubs that send all console output to the Mac OS X Console.app, or
// to the terminal, if Mozilla is launched from the command line.
////////////////////////////////////////////////////////////////////////////////
#include <console.h>
#include <size_t.h>
#include <string.h>
#include <CFURL.h>
#include <CFBundle.h>
#include <CFString.h>
#include <MacErrors.h>
#include <Gestalt.h>
#include <CodeFragments.h>
#include <Fonts.h>
#include <TextEdit.h>
#include <Controls.h>
#include <SIOUX.h>
#include <SIOUXWindows.h>
#include <console_io.h>
#include <stdlib.h>
static CFBundleRef getBundle(CFStringRef frameworkPath)
{
CFBundleRef bundle = NULL;
// Make a CFURLRef from the CFString representation of the bundle's path.
// See the Core Foundation URL Services chapter for details.
CFURLRef bundleURL = CFURLCreateWithFileSystemPath(NULL, frameworkPath, kCFURLPOSIXPathStyle, true);
if (bundleURL != NULL) {
bundle = CFBundleCreate(NULL, bundleURL);
if (bundle != NULL)
CFBundleLoadExecutable(bundle);
CFRelease(bundleURL);
}
return bundle;
}
static void* getSystemFunction(CFStringRef functionName)
{
static CFBundleRef systemBundle = getBundle(CFSTR("/System/Library/Frameworks/System.framework"));
if (systemBundle) return CFBundleGetFunctionPointerForName(systemBundle, functionName);
return NULL;
}
// Useful Carbon-CFM debugging tool, printf that goes to the system console.
typedef int (*io_proc_ptr) (int fd, void* buffer, long count);
#if TARGET_CARBON
static io_proc_ptr system_read = (io_proc_ptr) getSystemFunction(CFSTR("read"));
static io_proc_ptr system_write = (io_proc_ptr) getSystemFunction(CFSTR("write"));
#else
static io_proc_ptr system_read = 0;
static io_proc_ptr system_write = 0;
#endif
/*
* The following four functions provide the UI for the console package.
* Users wishing to replace SIOUX with their own console package need
* only provide the four functions below in a library.
*/
static CFragConnectionID gConsoleLibrary;
static void* find_symbol(CFragConnectionID connection, StringPtr symName)
{
Ptr symAddr;
if (FindSymbol(gConsoleLibrary, symName, &symAddr, NULL) == noErr)
return symAddr;
return NULL;
}
/*
* extern short InstallConsole(short fd);
*
* Installs the Console package, this function will be called right
* before any read or write to one of the standard streams.
*
* short fd: The stream which we are reading/writing to/from.
* returns short: 0 no error occurred, anything else error.
*/
short InstallConsole(short fd)
{
long version;
OSErr err = Gestalt(gestaltSystemVersion, &version);
if (err == noErr && version < 0x00001000) {
// load the "NSConsole" library.
err = GetSharedLibrary("\pNSConsole", kCompiledCFragArch, kReferenceCFrag,
&gConsoleLibrary, NULL, NULL);
if (err == noErr) {
atexit(&RemoveConsole);
// transfer the SIOUX settings.
tSIOUXSettings *sioux_settings = (tSIOUXSettings*) find_symbol(gConsoleLibrary, "\pSIOUXSettings");
if (sioux_settings) {
*sioux_settings = SIOUXSettings;
short (*install_console) (short) = (short (*) (short)) find_symbol(gConsoleLibrary, "\pInstallConsole");
if (install_console)
return install_console(fd);
}
}
}
return 0;
}
/*
* extern void RemoveConsole(void);
*
* Removes the console package. It is called after all other streams
* are closed and exit functions (installed by either atexit or _atexit)
* have been called. Since there is no way to recover from an error,
* this function doesn't need to return any.
*/
void RemoveConsole()
{
if (gConsoleLibrary) {
void (*remove_console) (void) = (void (*) (void)) find_symbol(gConsoleLibrary, "\pInstallConsole");
if (remove_console)
remove_console();
CloseConnection(&gConsoleLibrary);
gConsoleLibrary = NULL;
}
}
/*
* extern long WriteCharsToConsole(char *buffer, long n);
*
* Writes a stream of output to the Console window. This function is
* called by write.
*
* char *buffer: Pointer to the buffer to be written.
* long n: The length of the buffer to be written.
* returns short: Actual number of characters written to the stream,
* -1 if an error occurred.
*/
long WriteCharsToConsole(char *buffer, long n)
{
if (gConsoleLibrary) {
static long (*write_chars) (char*, long) = (long (*) (char*, long)) find_symbol(gConsoleLibrary, "\pWriteCharsToConsole");
if (write_chars)
return write_chars(buffer, n);
} else {
for (char* cr = strchr(buffer, '\r'); cr; cr = strchr(cr + 1, '\r'))
*cr = '\n';
if (system_write) return system_write(1, buffer, n);
}
return 0;
}
/*
* extern long ReadCharsFromConsole(char *buffer, long n);
*
* Reads from the Console into a buffer. This function is called by
* read.
*
* char *buffer: Pointer to the buffer which will recieve the input.
* long n: The maximum amount of characters to be read (size of
* buffer).
* returns short: Actual number of characters read from the stream,
* -1 if an error occurred.
*/
long ReadCharsFromConsole(char *buffer, long n)
{
if (gConsoleLibrary) {
static long (*read_chars) (char*, long) = (long (*) (char*, long)) find_symbol(gConsoleLibrary, "\pReadCharsFromConsole");
if (read_chars)
return read_chars(buffer, n);
} else {
if (system_read) return system_read(0, buffer, n);
}
return -1;
}
extern char *__ttyname(long fildes)
{
if (fildes >= 0 && fildes <= 2)
return "console";
return (0L);
}
int kbhit(void)
{
return 0;
}
int getch(void)
{
return 0;
}
void clrscr()
{
/* Could send the appropriate VT100 sequence here... */
}
tSIOUXSettings SIOUXSettings = {
true, true, true, false, true, false, NULL,
4, 80, 24, 0, 0, kFontIDMonaco,
9, normal, true, true, false
};
short SIOUXHandleOneEvent(EventRecord *userevent)
{
if (gConsoleLibrary) {
static short (*handle_event) (EventRecord*) = (short (*) (EventRecord*)) find_symbol(gConsoleLibrary, "\pSIOUXHandleOneEvent");
if (handle_event)
return handle_event(userevent);
}
return false;
}
Boolean SIOUXIsAppWindow(WindowPtr window)
{
if (gConsoleLibrary) {
static Boolean (*is_app_window) (WindowPtr) = (Boolean (*) (WindowPtr)) find_symbol(gConsoleLibrary, "\pSIOUXIsAppWindow");
if (is_app_window)
return is_app_window(window);
}
return false;
}
/**
* Lower level console implementation. Let's us distinguish stdout from stderr.
*/
static int check_console()
{
static short status = (InstallConsole(0) == 0);
return status;
}
using namespace std;
int __read_console(__file_handle handle, unsigned char * buffer, size_t * count, __idle_proc idle_proc)
{
if (!check_console())
return(__io_error);
fflush(stdout);
long n = *count;
if (gConsoleLibrary) {
static long (*read_chars) (char*, long) = (long (*) (char*, long)) find_symbol(gConsoleLibrary, "\pReadCharsFromConsole");
if (read_chars)
n = read_chars((char*)buffer, n);
else
n = -1;
} else {
if (system_read)
n = system_read(handle, buffer, n);
else
n = -1;
}
*count = n;
return (n == -1 ? __io_error : __no_io_error);
}
int __write_console(__file_handle handle, unsigned char * buffer, size_t * count, __idle_proc idle_proc)
{
if (!check_console())
return(__io_error);
long n = *count;
if (gConsoleLibrary) {
static long (*write_chars) (char*, long) = (long (*) (char*, long)) find_symbol(gConsoleLibrary, "\pWriteCharsToConsole");
if (write_chars)
n = write_chars((char*)buffer, n);
else
n = -1;
} else {
if (system_write) {
for (char* cr = strchr((char*)buffer, '\r'); cr; cr = strchr(cr + 1, '\r'))
*cr = '\n';
n = system_write(handle, buffer, n);
} else {
n = -1;
}
}
*count = n;
return (n == -1 ? __io_error : __no_io_error);
}
int __close_console(__file_handle handle)
{
return(__no_io_error);
}

Просмотреть файл

@ -1,238 +0,0 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "macstdlibextras.h"
#include <MacTypes.h>
#include <Memory.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <Quickdraw.h>
#include <TextServices.h>
#include <Movies.h>
#if !defined(__MSL__) || (__MSL__ < 0x7001)
int strcmpcore(const char*, const char*, int, int);
/*
size_t strlen(const char *source)
{
size_t currentLength = 0;
if (source == NULL)
return currentLength;
while (*source++ != '\0')
currentLength++;
return currentLength;
}
*/
int strcmpcore(const char *str1, const char *str2, int caseSensitive, int length)
{
char currentChar1, currentChar2;
int compareLength = (length >= 0);
while (1) {
if (compareLength) {
if ( length <= 0 )
return 0;
length--;
}
currentChar1 = *str1;
currentChar2 = *str2;
if (!caseSensitive) {
if ((currentChar1 >= 'a') && (currentChar1 <= 'z'))
currentChar1 += ('A' - 'a');
if ((currentChar2 >= 'a') && (currentChar2 <= 'z'))
currentChar2 += ('A' - 'a');
}
if (currentChar1 == '\0')
break;
if (currentChar1 != currentChar2)
return currentChar1 - currentChar2;
str1++;
str2++;
}
return currentChar1 - currentChar2;
}
/*
int strcmp(const char *str1, const char *str2)
{
return strcmpcore(str1, str2, true, -1);
}
*/
int strcasecmp(const char *str1, const char *str2)
{
/* This doesnÕt really belong here; but since it uses strcmpcore, weÕll keep it. */
return strcmpcore(str1, str2, false, -1);
}
int strncasecmp(const char *str1, const char *str2, int length)
{
/* This doesnÕt really belong here; but since it uses strcmpcore, weÕll keep it. */
return strcmpcore(str1, str2, false, length);
}
char *strdup(const char *source)
{
char *newAllocation;
size_t stringLength;
/*
#ifdef DEBUG
PR_ASSERT(source);
#endif
*/
stringLength = strlen(source) + 1;
/* since this gets freed by an XP_FREE, it must do an XP_ALLOC */
/* newAllocation = (char *)XP_ALLOC(stringLength); */
newAllocation = (char *)malloc(stringLength);
if (newAllocation == NULL)
return NULL;
BlockMoveData(source, newAllocation, stringLength);
return newAllocation;
}
#endif // !defined(__MSL__) || (__MSL__ < 0x7001)
#pragma mark -
void InitializeMacToolbox(void)
{
// once only, macintosh specific initialization
static Boolean alreadyInitialized = false;
if (!alreadyInitialized)
{
long CMMavail = 0;
alreadyInitialized = true;
#if !TARGET_CARBON
// pinkerton - don't need to init toolbox under Carbon. They finally do that for us!
InitGraf(&qd.thePort);
InitFonts();
InitWindows();
InitMenus();
TEInit();
InitDialogs(0);
InitCursor();
Gestalt(gestaltContextualMenuAttr, &CMMavail);
if ((CMMavail == gestaltContextualMenuTrapAvailable) &&
((long)InitContextualMenus != kUnresolvedCFragSymbolAddress))
InitContextualMenus();
InitTSMAwareApplication();
#endif
// init QuickTime if we have it
if ((long)EnterMovies != kUnresolvedCFragSymbolAddress)
EnterMovies();
#if DEBUG
InitializeSIOUX(false);
#endif
}
}
#pragma mark -
#if DEBUG
#include <SIOUX.h>
void InitializeSIOUX(unsigned char isStandAlone)
{
SIOUXSettings.initializeTB = isStandAlone;
SIOUXSettings.standalone = isStandAlone;
SIOUXSettings.setupmenus = isStandAlone;
SIOUXSettings.autocloseonquit = true;
SIOUXSettings.asktosaveonclose = false;
SIOUXSettings.showstatusline = false;
if (isStandAlone)
{
SIOUXSettings.toppixel = 42;
SIOUXSettings.leftpixel = 6;
SIOUXSettings.rows = 40;
SIOUXSettings.columns = 82;
}
else
{
SIOUXSettings.toppixel = 480;
SIOUXSettings.leftpixel = 4;
SIOUXSettings.rows = 20;
SIOUXSettings.columns = 100;
}
//InstallConsole();
}
Boolean IsSIOUXWindow(WindowPtr inWindow)
{
return SIOUXIsAppWindow(inWindow);
}
#endif

Просмотреть файл

@ -1,134 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Mozilla browser.
*
* The Initial Developer of the Original Code is Netscape
* Communications, Inc. Portions created by Netscape are
* Copyright (C) 1999, Mozilla. All Rights Reserved.
*
* Contributor(s):
* Patrick Beard <beard@netscape.com>
*/
/*
This file must precede sysenv.c in the link order, so that this implementation of
getenv() will override Metrowerks' standard, useless version.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
/**
* Provide a simple environment variable table, that gets loaded once per run of a program.
*/
class Environment {
public:
Environment();
~Environment();
char* get(const char* name);
private:
struct Variable {
Variable* mNext;
char* mName;
char* mValue;
Variable(const char* name, const char* value)
: mNext(NULL), mName(NULL), mValue(NULL)
{
mName = new char[::strlen(name) + 1];
if (mName != NULL)
::strcpy(mName, name);
if (value != NULL) {
mValue = new char[::strlen(value) + 1];
if (mValue != NULL)
::strcpy(mValue, value);
}
}
~Variable() {
if (mName) delete[] mName;
if (mValue) delete[] mValue;
}
};
Variable* mVariables;
};
Environment::Environment()
: mVariables(NULL)
{
// opens "ENVIRONMENT" file in current application's directory.
FILE* f = ::fopen("ENVIRONMENT", "r");
if (f != NULL) {
char line[1024];
while (::fgets(line, sizeof(line), f) != NULL) {
// allow comments starting with "#" or "//"
if (line[0] == '#' || (line[0] == '/' && line[1] == '/'))
continue;
// trim trailing linefeed.
int len = ::strlen(line);
if (line[len - 1] == '\n')
line[--len] = '\0';
// ignore leading white space.
char* name = line;
while (isspace(*name)) ++name;
// look for value.
char* value = "1";
char* eq = ::strchr(name, '=');
if (eq != NULL) {
value = eq + 1;
*eq = '\0';
}
Variable* var = new Variable(name, value);
var->mNext = mVariables;
mVariables = var;
}
::fclose(f);
}
}
Environment::~Environment()
{
Variable* var = mVariables;
while (var != NULL) {
Variable* next = var->mNext;
delete var;
var = next;
}
}
char* Environment::get(const char* name)
{
Variable** link = &mVariables;
Variable* var = *link;
while (var != NULL) {
if (::strcmp(var->mName, name) == 0)
return var->mValue;
link = &var->mNext;
var = *link;
}
return NULL;
}
char* std::getenv(const char * name)
{
static Environment env;
return env.get(name);
}