namespace com;
+// #define DISABLE_MEMMGR
+
import "BinaryTree"
import "OldList"
import "String"
#define REDZONE 0
#endif
+
+#ifdef _DEBUG
+// #define MEMTRACKING
+#endif
+
#ifdef MEMINFO
import "Thread"
static define MAX_MEMORY_LOC = 40;
default:
#define property _property
+#if defined(DISABLE_MEMMGR)
+
+#ifndef ECERE_BOOTSTRAP
+# include <malloc.h>
+#endif
+
+#if defined(__WIN32__)
+#ifdef ECERE_BOOTSTRAP
+uintsize _msize(void * p);
+#endif
+
+# define msize _msize
+#else
+#ifdef ECERE_BOOTSTRAP
+uintsize malloc_usable_size(void * p);
+#endif
+
+# define msize malloc_usable_size
+#endif
+
+#endif
+
#include <stdlib.h>
#include <stdio.h>
#endif
static uint TOTAL_MEM = 0;
-#ifndef MEMINFO
+#if !defined(MEMINFO) && !defined(DISABLE_MEMMGR)
static uint OUTSIDE_MEM = 0;
#endif
MemBlock prev, next;
MemPart part;
uint size;
+#if defined(_DEBUG) && !defined(MEMINFO) && defined(MEMTRACKING)
+ Class _class;
+#endif
};
private class MemPart : struct
}
};
-#ifndef MEMINFO
+#if !defined(MEMINFO) && !defined(DISABLE_MEMMGR)
static BlockPool * pools; //[NUM_POOLS];
/*static uint PosFibonacci(uint number)
return 1<<log2i(number);
}
-#ifndef MEMINFO
+#if !defined(MEMINFO) && !defined(DISABLE_MEMMGR)
static bool memoryInitialized = false;
static void InitMemory()
{
}
#endif
-#ifndef MEMINFO
+#if !defined(MEMINFO) && !defined(DISABLE_MEMMGR)
static void * _mymalloc(unsigned int size)
{
MemBlock block = null;
block = pools[p].Add();
if(block)
{
+#if defined(_DEBUG) && defined(MEMTRACKING)
+ block._class = null;
+#endif
block.size = size;
pools[p].usedSpace += size;
}
TOTAL_MEM += sizeof(class MemBlock) + size;
OUTSIDE_MEM += sizeof(class MemBlock) + size;
block.part = null;
+#if defined(_DEBUG) && defined(MEMTRACKING)
+ block._class = null;
+#endif
block.size = size;
}
}
TOTAL_MEM += size - newBlock.size;
OUTSIDE_MEM += size - newBlock.size;
newPointer = ((struct MemBlock *)newBlock + 1);
+ newBlock.size = size;
}
}
}
}
return newPointer;
}
-#endif
-#ifndef MEMINFO
#undef realloc
#undef crealloc
#undef malloc
static void * _malloc(unsigned int size)
{
+#if defined(DISABLE_MEMMGR) && !defined(MEMINFO)
+ return size ? malloc(size) : null;
+#else
void * pointer;
+
#if !defined(ECERE_BOOTSTRAP)
memMutex.Wait();
#endif
}
#endif
return pointer ? ((byte*)pointer + REDZONE) : null;
+#endif
}
static void * _calloc(int n, unsigned int size)
{
+#if defined(DISABLE_MEMMGR) && !defined(MEMINFO)
+ return size ? calloc(n, size) : null;
+#else
void * pointer;
+
#if !defined(ECERE_BOOTSTRAP)
memMutex.Wait();
#endif
}
#endif
return pointer ? ((byte*)pointer + REDZONE) : null;
+#endif
}
static void * _realloc(void * pointer, unsigned int size)
{
+#if defined(DISABLE_MEMMGR) && !defined(MEMINFO)
+ if(!size) { free(pointer); return null; }
+ return realloc(pointer, size);
+
+#else
if(!size) { _free(pointer); return null; }
+
#if !defined(ECERE_BOOTSTRAP)
memMutex.Wait();
#endif
memMutex.Release();
#endif
return pointer ? ((byte *)pointer + REDZONE) : null;
+#endif
}
static void * _crealloc(void * pointer, unsigned int size)
{
- if(!size) return null;
+#if defined(DISABLE_MEMMGR) && !defined(MEMINFO)
+ uintsize s = pointer ? msize(pointer) : 0;
+ void * p;
+ if(!size) { free(pointer); return null; }
+
+ p = realloc(pointer, size);
+ if(size > s)
+ memset((byte *)p + s, 0, size - s);
+ return p;
+#else
+ if(!size) { _free(pointer); return null; }
+
#if !defined(ECERE_BOOTSTRAP)
memMutex.Wait();
#endif
memMutex.Release();
#endif
return pointer ? ((byte *)pointer + REDZONE) : null;
+#endif
}
static void _free(void * pointer)
{
if(pointer)
{
+#if defined(DISABLE_MEMMGR) && !defined(MEMINFO)
+ free(pointer);
+#else
#if !defined(ECERE_BOOTSTRAP)
if(memMutex != pointer) memMutex.Wait();
#endif
{
if(address[-c-1] != 0xAB)
{
- printf("Buffer Underrun\n");
+ printf("Buffer Underrun (%d bytes before)\n", c+1);
memoryErrorsCount++;
block.OutputStacks(block.freed);
}
if(address[c + size] != 0xAB)
{
- printf("Buffer Overrun\n");
+ printf("Buffer Overrun (%d bytes past block)\n", c);
memoryErrorsCount++;
block.OutputStacks(block.freed);
}
#if !defined(ECERE_BOOTSTRAP)
if(memMutex != pointer) memMutex.Release();
#endif
+
+#endif
}
}
}
}
+public void CheckConsistency()
+{
+#ifdef MEMINFO
+ if(!memBlocks.Check())
+ printf("Memory Blocks Tree Integrity Failed\n");
+#endif
+}
+
public void CheckMemory()
{
#ifdef MEMINFO
{
if(address[-c-1] != 0xAB)
{
- printf("Buffer Underrun\n");
+ printf("Buffer Underrun (%d bytes before)\n", c + 1);
memoryErrorsCount++;
block.OutputStacks(block.freed);
}
if(address[c + size] != 0xAB)
{
- printf("Buffer Overrun\n");
+ printf("Buffer Overrun (%d bytes past)\n", c);
memoryErrorsCount++;
block.OutputStacks(block.freed);
}
_class._vTbl = renew _class._vTbl void *[_class.vTblSize];
// memmove(_class._vTbl + mod.base.vTblSize, _class._vTbl + baseClass.vTblSize, (mod.base.vTblSize - baseClass.vTblSize) * sizeof(void *));
memmove(_class._vTbl + mod.base.vTblSize, _class._vTbl + baseClass.vTblSize, (_class.vTblSize - mod.vTblSize) * sizeof(void *));
+ memcpy(_class._vTbl + baseClass.vTblSize, mod._vTbl + baseClass.vTblSize, (mod.base.vTblSize - baseClass.vTblSize) * sizeof(void *));
updateStart = baseClass.vTblSize;
updateEnd = updateStart + mod.base.vTblSize - baseClass.vTblSize;
if(template.nameSpace)
{
BTNamedLink link = (BTNamedLink)template.nameSpace->classes.FindString(template.name);
- template.nameSpace->classes.Delete((BTNode)link);
+ if(link)
+ template.nameSpace->classes.Delete((BTNode)link);
}
FreeTemplateArgs(template);
template.derivatives.Delete(deriv);
}
- _free(template);
+ if(template.module)
+ template.module.classes.Delete(template);
+ else
+ _free(template);
}
static void FreeTemplates(Class _class)
ClassProperty classProp;
ClassTemplateParameter param;
+ if(_class.templateClass)
+ {
+ // Unregistering templates... Used in IDE to address crash on Ecere classes templatized with imported modules
+ OldLink templateLink;
+ for(templateLink = _class.templateClass.templatized.first; templateLink; templateLink = templateLink.next)
+ {
+ if(templateLink.data == _class)
+ {
+ _class.templateClass.templatized.Delete(templateLink);
+ break;
+ }
+ }
+ FreeTemplate(_class);
+ return;
+ }
+
delete _class._vTbl;
FreeTemplates(_class);
templatedClass.numParams = 0;
templatedClass.derivatives = { };
templatedClass.templatized = { };
+ templatedClass.module = module;
+ templatedClass.count = 0; // TOCHECK: Keeping track of individual templatized classes?
+ templatedClass.prev = null;
+ templatedClass.next = null;
+
+ module.classes.Add(templatedClass);
ComputeClassParameters(templatedClass, templateParams, module);
{
case type:
argument.dataTypeString = CopyString(value);
- argument.dataTypeClass = eSystem_FindClass(_class.module, value);
- if(!argument.dataTypeClass) argument.dataTypeClass = eSystem_FindClass(_class.module.application, value);
- if(!argument.dataTypeClass) argument.dataTypeClass = eSystem_FindClass(findModule, value);
+ argument.dataTypeClass = eSystem_FindClass(findModule, value);
+ if(!argument.dataTypeClass)
+ argument.dataTypeClass = eSystem_FindClass(_class.module, value);
+ if(!argument.dataTypeClass)
+ argument.dataTypeClass = eSystem_FindClass(_class.module.application, value);
break;
case expression:
{
CopyTemplateArg(param, templatedClass.templateArgs[curParamID]);
if(param.type == type && param.defaultArg.dataTypeString)
{
- templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module, param.defaultArg.dataTypeString);
+ templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(findModule, param.defaultArg.dataTypeString);
if(!templatedClass.templateArgs[curParamID].dataTypeClass)
- templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module.application, param.defaultArg.dataTypeString);
+ templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module, param.defaultArg.dataTypeString);
if(!templatedClass.templateArgs[curParamID].dataTypeClass)
- templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(findModule, param.defaultArg.dataTypeString);
+ templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module.application, param.defaultArg.dataTypeString);
}
}
curParamID++;
FreeTemplateArg(templatedClass, param, c);
arg->dataTypeString = CopyString(templateString);
- arg->dataTypeClass = eSystem_FindClass(templatedClass.module, templateString);
+ arg->dataTypeClass = eSystem_FindClass(findModule, templateString);
+ if(!arg->dataTypeClass)
+ arg->dataTypeClass = eSystem_FindClass(templatedClass.module, templateString);
if(!arg->dataTypeClass)
arg->dataTypeClass = eSystem_FindClass(templatedClass.module.application, templateString);
}
CopyTemplateArg(param, templatedClass.templateArgs[curParamID]);
if(param.type == type && param.defaultArg.dataTypeString)
{
- templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module, param.defaultArg.dataTypeString);
+ templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(findModule, param.defaultArg.dataTypeString);
if(!templatedClass.templateArgs[curParamID].dataTypeClass)
- templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module.application, param.defaultArg.dataTypeString);
+ templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module, param.defaultArg.dataTypeString);
if(!templatedClass.templateArgs[curParamID].dataTypeClass)
- templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(findModule, param.defaultArg.dataTypeString);
+ templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module.application, param.defaultArg.dataTypeString);
}
}
curParamID++;
id++;
}
}
- memberClass = eSystem_FindClass(templatedClass.module, className);
// TESTING: Added this here...
+ memberClass = eSystem_FindClass(findModule, className);
if(!memberClass)
- memberClass = eSystem_FindClass(findModule, className);
+ memberClass = eSystem_FindClass(templatedClass.module, className);
if(!memberClass)
memberClass = eSystem_FindClass(templatedClass.module.application, className);
}
allocateClass = null;
memMutex.Release();
#endif
+
+#if defined(_DEBUG) && !defined(MEMINFO) && defined(MEMTRACKING)
+ {
+ MemBlock block = (MemBlock)((byte *)instance - sizeof(class MemBlock));
+ block._class = _class;
+ }
+#endif
+
if(_class.type == normalClass)
{
instance._class = _class;
if(_class && instancePtr && *instancePtr)
{
bool wasApp = false, wasGuiApp = false;
+ Instance oldInstance = *instancePtr;
Instance instance = (Instance)renew *instancePtr byte[_class.structSize];
Class fromClass = instance._class;
*instancePtr = instance;
for(templateLink = _class.templatized.first; templateLink; templateLink = templateLink.next)
{
Class template = templateLink.data;
- template.module = _class.module;
+ if(template.module == oldInstance)
+ template.module = _class.module;
}
}
for(_class = module.classes.first; _class; _class = _class.next)
{
OldLink templateLink;
+ Module oldModule = _class.module;
_class.module = module;
for(templateLink = _class.templatized.first; templateLink; templateLink = templateLink.next)
{
Class template = templateLink.data;
- template.module = _class.module;
+ if(template.module == oldModule)
+ template.module = _class.module;
}
}
}
if(alignment)
{
bool pointerAlignment = alignment == 0xF000F000;
+ bool force64Bits = (_class.module.application.isGUIApp & 2) ? true : false;
+ bool force32Bits = (_class.module.application.isGUIApp & 4) ? true : false;
+ if((force32Bits || force64Bits) && !strcmp(_class.name, "AVLNode") && !strcmp(name, "__ecerePrivateData0"))
+ {
+ if(force64Bits)
+ {
+ type = "byte[32]";
+ size = 32;
+ }
+ if(force32Bits)
+ {
+ type = "byte[16]";
+ size = 16;
+ }
+ }
if(pointerAlignment) alignment = sizeof(void *);
NameSpace * nameSpace;
delete (void *)parentNameSpace.name;
+ /* {
+ BTNamedLink n, next;
+ for(n = (BTNamedLink)parentNameSpace.classes.first; n; n = next)
+ {
+ Class c = n.data;
+
+ next = (BTNamedLink)((BTNode)n).next;
+
+ if(c.templateClass)
+ eClass_Unregister(c);
+ }
+ } */
+
while((nameSpace = (NameSpace *)parentNameSpace.nameSpaces.first))
{
NameSpace_Free(nameSpace);
}
namespace com;
+
+#if defined(_DEBUG) && !defined(MEMINFO) && defined(MEMTRACKING)
+import "Map"
+
+Map<Class, int> blocksByClass { };
+#endif
+
+public void queryMemInfo(char * string)
+{
+#if defined(_DEBUG) && !defined(MEMINFO) && defined(MEMTRACKING)
+ char s[1024];
+ int p;
+ uint numBlocks = 0;
+ //uintsize nonClassBytes = 0;
+ sprintf(s, "Total System Memory Usage: %.02f\n", TOTAL_MEM / 1048576.0f);
+ strcat(string, s);
+
+ for(p = 0; pools && p < NUM_POOLS; p++)
+ {
+ BlockPool * pool = &pools[p];
+ if(pool->totalSize)
+ {
+ numBlocks += pool->totalSize;
+ sprintf(s, "%8d bytes: %d blocks in %d parts (%.02f mb used; taking up %.02f mb space)\n",
+ pool->blockSize, pool->numBlocks, pool->numParts, pool->usedSpace / 1048576.0f, pool->totalSize * pool->blockSpace / 1048576.0f);
+ strcat(string, s);
+ }
+ }
+/*
+
+ blocksByClass.Free();
+ memMutex.Wait();
+ for(p = 0; pools && p < NUM_POOLS; p++)
+ {
+ BlockPool * pool = &pools[p];
+ MemBlock block;
+ for(block = pool->first; block; block = block.next)
+ {
+ Class c = block._class;
+ blocksByClass[c]++;
+ if(!c)
+ nonClassBytes += block.size;
+ }
+ }
+ memMutex.Release();
+
+ //for(c : blocksByClass)
+ {
+ MapIterator<Class, int> it { map = blocksByClass };
+ while(it.Next())
+ {
+ int c = it.data;
+ Class _class = it.key; //&c;
+ uintsize size = _class ? _class.structSize : nonClassBytes;
+ float totalSize = (float)size * (_class ? c : 1) / 1048576.0f;
+ if(totalSize > 1)
+ {
+ sprintf(s, "%s (%d bytes): %d instances (%.02f mb used)\n", _class ? _class.name : "(none)", (int)size, c, totalSize);
+ strcat(string, s);
+ }
+ }
+ }
+*/
+ sprintf(s, "Non-pooled memory: %.02f\n", OUTSIDE_MEM / 1048576.0f);
+ strcat(string, s);
+ sprintf(s, "Total Blocks Count: %d (%.02f mb overhead)\n", numBlocks, (float)sizeof(struct MemBlock) * numBlocks / 1048576.0f);
+ strcat(string, s);
+#ifdef MEMORYGUARD
+ sprintf(s, "MemoryGuard: %d blocks (%.02f mb RedZone, %.02f mb MemInfo)\n", memBlocks.count,
+ numBlocks * 2 * REDZONE / 1048576.0f, sizeof(struct MemInfo) * memBlocks.count / 1048576.0f);
+ strcat(string, s);
+#endif
+#endif
+}