import "String"
import "dataTypes"
+//#define JUST_CHECK_LEAKS
+//#define JUST_CHECK_BOUNDARIES
+
+
#if defined(ECERE_BOOTSTRAP) || defined(ECERE_STATIC)
#define dllexport
#if !defined(ECERE_BOOTSTRAP)
#define REDZONE 256
#endif
*/
-#ifndef REDZONE
+
+#if defined(JUST_CHECK_LEAKS) || !defined(REDZONE)
+#undef REDZONE
#define REDZONE 0
#endif
ClassTemplateArgument * templateArgs;
Class templateClass;
OldList templatized;
- int numParams;
+ int numParams; // TOTAL number of params including all base classes; use templateParams.count for this level
bool isInstanceClass;
bool byValueSystemClass;
MemBlock prev, next;
MemPart part;
uint size;
-#if defined(_DEBUG) && !defined(MEMINFO) && defined(MEMTRACKING)
+#if !defined(MEMINFO) && defined(MEMTRACKING)
Class _class;
#endif
};
void Remove(MemBlock block)
{
+ MemPart part = block.part;
/*if(blockSize == 28)
printf("BlockPool::Remove (%d)\n", blockSize);*/
if(block.prev)
printf("Setting new free block: part = %x\n", block.part);
}*/
- block.part.blocksUsed--;
+ part.blocksUsed--;
numBlocks--;
- block.part.pool->usedSpace -= block.size;
+ part.pool->usedSpace -= block.size;
- if(!block.part.blocksUsed && numBlocks && totalSize > numBlocks + numBlocks / 2)
+ if(!part.blocksUsed && numBlocks && totalSize > numBlocks + numBlocks / 2)
{
MemBlock next = free, prev = null;
- MemPart part = block.part;
free = null;
totalSize -= part.size;
/*if(blockSize == 28)
break;
current = current * 3 / 2;
if(current == 1) current = 2;
+ if(current & 7) current += 8 - (current & 7);
}
return pos;
}
{
current = current * 3 / 2;
if(current == 1) current = 2;
+ if(current & 7) current += 8 - (current & 7);
}
return (uint)current;
}
return (uint)current;
current = current * 3 / 2;
if(current == 1) current = 2;
+ if(current & 7) current += 8 - (current & 7);
}
return (uint)current;
}
block = pools[p].Add();
if(block)
{
-#if defined(_DEBUG) && defined(MEMTRACKING)
+#if defined(MEMTRACKING)
block._class = null;
#endif
block.size = size;
TOTAL_MEM += sizeof(class MemBlock) + size;
OUTSIDE_MEM += sizeof(class MemBlock) + size;
block.part = null;
-#if defined(_DEBUG) && defined(MEMTRACKING)
+#if defined(MEMTRACKING)
block._class = null;
#endif
block.size = size;
if(block)
{
+#if defined(JUST_CHECK_LEAKS) || defined(JUST_CHECK_BOUNDARIES)
+ memcpy((byte *)pointer + REDZONE, (byte *)block.key, Min(block.size, size));
+ free((byte *)block.key - REDZONE);
+ memBlocks.Remove(block);
+ free(block);
+#else
if(block.freed)
{
memcpy((byte *)pointer + REDZONE, block.oldmem, Min(block.size, size));
memset((byte *)block.key - REDZONE, 0xEC, block.size + REDZONE * 2);
block.freed = true;
}
+#endif
}
if(!recurse && !stack.recurse)
if(block)
{
+#if defined(JUST_CHECK_LEAKS) || defined(JUST_CHECK_BOUNDARIES)
+ memcpy((byte *)pointer + REDZONE, (byte *)block.key, Min(block.size, size));
+ free((byte *)block.key - REDZONE);
+ memBlocks.Remove(block);
+ free(block);
+#else
if(block.freed)
{
memcpy((byte *)pointer + REDZONE, block.oldmem, Min(block.size, size));
memset((byte *)block.key - REDZONE, 0xEC, block.size + REDZONE * 2);
block.freed = true;
}
+#endif
}
if(!recurse && !stack.recurse)
}
block.freed = true;
+#if defined(JUST_CHECK_LEAKS) || defined(JUST_CHECK_BOUNDARIES)
+ free((byte *)block.key - REDZONE);
+ memBlocks.Remove(block);
+ free(block);
+#else
block.oldmem = (byte *)malloc(block.size + REDZONE * 2);
if(block.oldmem)
{
memset((byte *)block.key - REDZONE, 0xEC, block.size + REDZONE * 2);
memcpy(block.freeLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
+#endif
}
stack.recurse = false;
}
// _class.memberID = _class.startMemberID = (base && (type == normalClass || type == noHeadClass || type == structClass)) ? base.memberID : 0;
if(type == normalClass || type == noHeadClass)
+ {
// Use 'memberOffset' for nohead class as the members get added without padding
_class.offset = (base && (base.templateClass ? (type == normalClass ? base.templateClass.structSize : base.templateClass.memberOffset) : (type == normalClass ? base.structSize : base.memberOffset)) && base.type != systemClass) ? (base.templateClass ? base.templateClass.structSize : base.structSize) : ((type == noHeadClass) ? 0 : sizeof(class Instance));
+ if(_class.structAlignment && (_class.offset % _class.structAlignment))
+ _class.offset += _class.structAlignment - _class.offset % _class.structAlignment;
+ }
else
_class.offset = 0; // Force set to 0
}
{
NameSpace * ns = _class.nameSpace;
- while(ns->parent &&
+ while(ns != nameSpace &&
+ ns->parent &&
!ns->classes.first &&
!ns->functions.first &&
!ns->defines.first &&
{
case type:
delete (void *)template.templateArgs[id].dataTypeString;
+ template.templateArgs[id].dataTypeClass = null;
break;
case identifier:
delete (void *)template.templateArgs[id].memberString;
{
case type:
delete (void *)template.templateArgs[id].dataTypeString;
+ template.templateArgs[id].dataTypeClass = null;
break;
case identifier:
delete (void *)template.templateArgs[id].memberString;
if(link)
template.nameSpace->classes.Delete((BTNode)link);
}
- FreeTemplateArgs(template);
- delete (void *)template.fullName;
- delete (void *)template.name;
- delete (void *)template.templateArgs;
- delete (void *)template.dataTypeString;
+ FreeTemplatesDerivatives(template);
+ FreeTemplateArgs(template);
while((deriv = template.derivatives.first))
{
template.derivatives.Delete(deriv);
}
+ delete (void *)template.fullName;
+ delete (void *)template.name;
+ delete template.templateArgs;
+ delete (void *)template.dataTypeString;
+
if(template.module)
template.module.classes.Delete(template);
else
}
FreeTemplateArgs(_class);
- //if(_class.templateArgs)
- //printf("Deleting Template args for %s\n", _class.name);
delete _class.templateArgs;
delete (void *)_class.dataTypeString;
FreeTemplates(_class);
- FreeTemplateArgs(_class);
- delete _class.templateArgs;
-
while((template = _class.templatized.first))
{
FreeTemplate(template.data);
else if(ch >= 'A' && ch <= 'Z')
ch -= ('A'- 10);
else
- {
- if(endString)
- *endString = string + c;
// Invalid character
break;
- }
if(ch < base)
{
value *= base;
value += ch;
}
else
- {
- if(endString)
- *endString = string + c;
// Invalid character
break;
- }
}
+ if(endString)
+ *endString = string + c;
+
return sign*value;
}
else if(ch >= 'A' && ch <= 'Z')
ch -= ('A' - 10);
else
- {
- if(endString)
- *endString = string + c;
// Invalid character
break;
- }
if(ch < base)
{
value *= base;
value += ch;
}
else
- {
- if(endString)
- *endString = string + c;
// Invalid character
break;
- }
}
+ if(endString)
+ *endString = string + c;
return sign*value;
}
{
int id = p;
Class sClass;
+ // NOTE: This struct 'arg' here is only to build up templateString
ClassTemplateArgument arg;
for(sClass = expClass.base; sClass; sClass = sClass.base) id += sClass.templateParams.count;
arg = expClass.templateArgs[id];
{
if(cParam.type == type && arg.dataTypeString && !strcmp(cParam.name, arg.dataTypeString))
{
- arg.dataTypeString = templatedClass.templateArgs[p].dataTypeString;
- arg.dataTypeClass = templatedClass.templateArgs[p].dataTypeClass;
+ arg = templatedClass.templateArgs[p];
break;
}
}
{
FreeTemplateArg(templatedClass, param, c);
+ // TRICKY: This copies from equivalent parameters
arg->dataTypeString = templatedClass.templateArgs[p].dataTypeString;
arg->dataTypeClass = templatedClass.templateArgs[p].dataTypeClass;
CopyTemplateArg(cParam, arg);
if(method.vid >= _class.vTblSize)
printf("error: virtual methods overriding failure\n");
else
- _class._vTbl[method.vid] = function ? function : (void *)DefaultFunction;
+ _class._vTbl[method.vid] = function ? function : null; //(void *)DefaultFunction;
for(deriv = _class.derivatives.first; deriv; deriv = deriv.next)
{
Class derivClass = deriv.data;
Method method
{
name = CopyString(name),
- function = function ? function : DefaultFunction;
+ function = function ? function : null; //DefaultFunction;
_class = _class;
dataTypeString = CopyString(type);
memberAccess = declMode;
if(method.vid >= _class.vTblSize)
printf("error: virtual methods overriding failure\n");
else
- _class._vTbl[method.vid] = function ? function : (void *)DefaultFunction;
+ _class._vTbl[method.vid] = function ? function : null; //(void *)DefaultFunction;
}
else
base = null;
Method method
{
name = CopyString(name);
- function = function ? function : DefaultFunction;
+ function = function ? function : null; //DefaultFunction;
type = virtualMethod;
_class = _class;
vid = _class.vTblSize++;
};
_class.methods.Add((BTNode)method);
_class._vTbl = renew _class._vTbl void *[_class.vTblSize];
- _class._vTbl[method.vid] = function ? function : (void *)DefaultFunction;
+ _class._vTbl[method.vid] = function ? function : null; //(void *)DefaultFunction;
// TODO: Fix derived classes
if(_class.derivatives.first || _class.templatized.first)
- FixDerivativeVirtualMethod(_class, name, method.vid, function ? function : (void *)DefaultFunction, type);
+ FixDerivativeVirtualMethod(_class, name, method.vid, function ? function : null /*(void *)DefaultFunction*/, type);
return method;
}
}
size *= 3;
}
instance = _calloc(1, size);
+ if(!instance && size)
+ printf("Failed to allocate memory instantiating %s object!\n", _class.name);
+ else if(!size)
+ printf("Warning: 0 size instantiating %s object!\n", _class.name);
}
#ifdef MEMINFO
allocateClass = null;
memMutex.Release();
#endif
-#if defined(_DEBUG) && !defined(MEMINFO) && defined(MEMTRACKING)
+#if !defined(MEMINFO) && defined(MEMTRACKING)
{
MemBlock block = (MemBlock)((byte *)instance - sizeof(class MemBlock));
block._class = _class;
}
#endif
- if(_class.type == normalClass)
+ if(instance && _class.type == normalClass)
{
instance._class = _class;
// Copy the virtual table initially
instance._vTbl = _class._vTbl;
}
- if(!ConstructInstance(instance, _class, null))
+ if(instance && !ConstructInstance(instance, _class, null))
{
_free(instance);
instance = null;
memcpy(instance._vTbl, instance._class._vTbl,
sizeof(int(*)()) * instance._class.vTblSize);
}
- instance._vTbl[method.vid] = function ? function : (void *)DefaultFunction;
+ instance._vTbl[method.vid] = function ? function : null; //(void *)DefaultFunction;
}
}
}
}
}
- if(pointerAlignment) alignment = sizeof(void *);
+ if(pointerAlignment) alignment = force64Bits ? 8 : force32Bits ? 4 : sizeof(void *);
if(pointerAlignment && _class.structAlignment <= 4)
_class.pointerAlignment = 1;
_class.structAlignment = Max(_class.structAlignment, alignment);
+ if(_class.offset % alignment)
+ {
+ _class.structSize += alignment - (_class.offset % alignment);
+ _class.offset += alignment - (_class.offset % alignment);
+ }
if(_class.memberOffset % alignment)
_class.memberOffset += alignment - (_class.memberOffset % alignment);
}
if(alignment)
{
bool pointerAlignment = alignment == 0xF000F000;
- if(pointerAlignment) alignment = sizeof(void *);
+ bool force64Bits = false; //(member._class.module.application.isGUIApp & 2) ? true : false;
+ bool force32Bits = false; //(member._class.module.application.isGUIApp & 4) ? true : false;
+ if(pointerAlignment) alignment = force64Bits ? 8 : force32Bits ? 4 : sizeof(void *);
if(pointerAlignment && member.structAlignment <= 4)
member.pointerAlignment = 1;
namespace com;
-#if defined(_DEBUG) && !defined(MEMINFO) && defined(MEMTRACKING)
+#if !defined(MEMINFO) && defined(MEMTRACKING)
import "Map"
Map<Class, int> blocksByClass { };
+Map<Class, uintsize> sizeByClass { };
#endif
public void queryMemInfo(char * string)
{
-#if defined(_DEBUG) && !defined(MEMINFO) && defined(MEMTRACKING)
+#if !defined(MEMINFO) && defined(MEMTRACKING) && !defined(DISABLE_MEMMGR)
char s[1024];
int p;
uint numBlocks = 0;
- //uintsize nonClassBytes = 0;
+ uintsize totalMemUsed = 0;
sprintf(s, "Total System Memory Usage: %.02f\n", TOTAL_MEM / 1048576.0f);
strcat(string, s);
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);
+ totalMemUsed += pool->usedSpace;
strcat(string, s);
}
}
-/*
+
blocksByClass.Free();
+ sizeByClass.Free();
memMutex.Wait();
for(p = 0; pools && p < NUM_POOLS; p++)
{
{
Class c = block._class;
blocksByClass[c]++;
- if(!c)
- nonClassBytes += block.size;
+ sizeByClass[c] += block.size;
}
}
memMutex.Release();
{
int c = it.data;
Class _class = it.key; //&c;
- uintsize size = _class ? _class.structSize : nonClassBytes;
- float totalSize = (float)size * (_class ? c : 1) / 1048576.0f;
+ uintsize size = sizeByClass[_class];
+ float totalSize = (float) size / 1048576.0f;
if(totalSize > 1)
{
sprintf(s, "%s (%d bytes): %d instances (%.02f mb used)\n", _class ? _class.name : "(none)", (int)size, c, totalSize);
}
}
}
-*/
+
sprintf(s, "Non-pooled memory: %.02f\n", OUTSIDE_MEM / 1048576.0f);
strcat(string, s);
+ sprintf(s, "Total Memory in use: %.02f\n", (float)(totalMemUsed + 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