ecere/com/instance; containers: MemTracking code
[sdk] / ecere / src / com / instance.ec
index 7b95aaf..24e718e 100644 (file)
@@ -31,6 +31,11 @@ import "Mutex"
 #define REDZONE 0
 #endif
 
+
+#ifdef _DEBUG
+// #define MEMTRACKING
+#endif
+
 #ifdef MEMINFO
 import "Thread"
 static define MAX_MEMORY_LOC = 40;
@@ -711,6 +716,9 @@ private class MemBlock : struct
    MemBlock prev, next;
    MemPart part;
    uint size;
+#if defined(_DEBUG) && !defined(MEMINFO) && defined(MEMTRACKING)
+   Class _class;
+#endif
 };
 
 private class MemPart : struct
@@ -1227,6 +1235,9 @@ static void * _mymalloc(unsigned int size)
          block = pools[p].Add();
          if(block)
          {
+#if defined(_DEBUG) && defined(MEMTRACKING)
+            block._class = null;
+#endif
             block.size = size;
             pools[p].usedSpace += size;
          }
@@ -1239,6 +1250,9 @@ static void * _mymalloc(unsigned int 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;
          }
       }
@@ -1308,6 +1322,7 @@ static void * _myrealloc(void * pointer, unsigned int size)
             TOTAL_MEM += size - newBlock.size;
             OUTSIDE_MEM += size - newBlock.size;
             newPointer = ((struct MemBlock *)newBlock + 1);
+            newBlock.size = size;
          }
       }
    }
@@ -1817,7 +1832,7 @@ static void _free(void * pointer)
                   }
                   if(address[c + size] != 0xAB)
                   {
-                     printf("Buffer Overrun (%d bytes past block of %d)\n", c);
+                     printf("Buffer Overrun (%d bytes past block)\n", c);
                      memoryErrorsCount++;
                      block.OutputStacks(block.freed);
                   }
@@ -2112,6 +2127,7 @@ static void FixDerivativesBase(Class base, Class mod)
             _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;
@@ -2942,7 +2958,8 @@ static void FreeTemplate(Class template)
    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);
 
@@ -2957,7 +2974,10 @@ static void FreeTemplate(Class template)
       template.derivatives.Delete(deriv);
    }
 
-   _free(template);
+   if(template.module)
+      template.module.classes.Delete(template);
+   else
+      _free(template);
 }
 
 static void FreeTemplates(Class _class)
@@ -2992,6 +3012,22 @@ public dllexport void eClass_Unregister(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);
@@ -3356,6 +3392,12 @@ public dllexport Class eSystem_FindClass(Module module, const char * name)
                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);
 
@@ -3590,9 +3632,11 @@ static void ComputeClassParameters(Class templatedClass, const char * templatePa
             {
                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:
                {
@@ -3690,11 +3734,11 @@ static void ComputeClassParameters(Class templatedClass, const char * templatePa
             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++;
@@ -3818,7 +3862,9 @@ static void ComputeClassParameters(Class templatedClass, const char * templatePa
                      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);
                   }
@@ -3870,11 +3916,11 @@ static void ComputeClassParameters(Class templatedClass, const char * templatePa
                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++;
@@ -3972,10 +4018,10 @@ static void ComputeClassParameters(Class templatedClass, const char * templatePa
                         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);
                }
@@ -4551,6 +4597,14 @@ public dllexport void * eInstance_New(Class _class)
       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;
@@ -4573,6 +4627,7 @@ public dllexport void eInstance_Evolve(Instance * instancePtr, 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;
@@ -4641,7 +4696,8 @@ public dllexport void eInstance_Evolve(Instance * instancePtr, Class _class)
             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;
             }
          }
 
@@ -4650,11 +4706,13 @@ public dllexport void eInstance_Evolve(Instance * instancePtr, Class _class)
             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;
                }
             }
          }
@@ -5171,6 +5229,21 @@ public dllexport DataMember eClass_AddDataMember(Class _class, const char * name
          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 *);
 
@@ -5613,6 +5686,19 @@ static void NameSpace_Free(NameSpace parentNameSpace)
    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);
@@ -7163,3 +7249,77 @@ public uint16 * UTF8toUTF16(const char * source, int * wordCount)
 }
 
 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
+}