--- /dev/null
+/***************************************************************************
+ * Installs handlers for malloc(), realloc() and free() *
+ * *
+ * Copyright (C) 2006 by Niko Välimäki *
+ * *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "HeapProfiler.h"
+
+// Static data
+unsigned long HeapProfiler::consumption = 0, HeapProfiler::maxConsumption = 0;
+AllocatedBlocks HeapProfiler::blocks;
+
+// Override initialising hook from the C library.
+void (*__malloc_initialize_hook) (void) = HeapProfiler::InitHooks;
+
+// Variables to save original hooks.
+void *(*HeapProfiler::old_malloc_hook)(size_t, const void *);
+void (*HeapProfiler::old_free_hook)(void *, const void *);
+void *(*HeapProfiler::old_realloc_hook)(void *, size_t, const void *);
+
+unsigned long HeapProfiler::GetMaxHeapConsumption() {
+ return maxConsumption;
+}
+
+unsigned long HeapProfiler::GetHeapConsumption() {
+ return consumption;
+}
+
+void HeapProfiler::InitHooks(void) {
+ old_malloc_hook = __malloc_hook;
+ old_free_hook = __free_hook;
+ old_realloc_hook = __realloc_hook;
+ __malloc_hook = HeapProfiler::MallocHook;
+ __free_hook = HeapProfiler::FreeHook;
+ __realloc_hook = HeapProfiler::ReallocHook;
+}
+
+
+void *HeapProfiler::MallocHook (size_t size, const void *caller) {
+ void *result;
+
+ /* Restore all old hooks */
+ __malloc_hook = old_malloc_hook;
+ __free_hook = old_free_hook;
+ __realloc_hook = old_realloc_hook;
+
+ /* Call recursively */
+ result = malloc (size);
+
+ blocks[result] = (unsigned long)size;
+
+ consumption += (unsigned long)size;
+ if (consumption > maxConsumption)
+ maxConsumption = consumption;
+
+ #ifdef DEBUG_HEAPPROFILER
+ std::cout << "malloc(" << size << ") called from " << caller << " returns " << result << " (" << consumption << ", max " << maxConsumption << ")" << std::endl;
+ #endif
+
+ /* Save underlying hooks */
+ old_malloc_hook = __malloc_hook;
+ old_free_hook = __free_hook;
+ old_realloc_hook = __realloc_hook;
+
+ /* Restore our own hooks */
+ __malloc_hook = HeapProfiler::MallocHook;
+ __free_hook = HeapProfiler::FreeHook;
+ __realloc_hook = HeapProfiler::ReallocHook;
+
+ return result;
+}
+
+void HeapProfiler::FreeHook (void *ptr, const void *caller) {
+
+ /* Restore all old hooks */
+ __malloc_hook = old_malloc_hook;
+ __free_hook = old_free_hook;
+ __realloc_hook = old_realloc_hook;
+
+ /* Call recursively */
+ free (ptr);
+
+ AllocatedBlocks::iterator result = blocks.find(ptr);
+ if (result != blocks.end())
+ {
+ #ifdef DEBUG_HEAPPROFILER
+ std::cout << "found: " << (*result).second << std::endl;
+ #endif
+ consumption -= (*result).second;
+ blocks.erase(result);
+ } else {
+ #ifdef DEBUG_HEAPPROFILER
+ std::cout << "not found" << std::endl;
+ #endif
+ }
+
+ #ifdef DEBUG_HEAPPROFILER
+ std::cout << "free(" << ptr << ") called from " << caller << " (" << consumption << ", max " << maxConsumption << ")" << std::endl;
+ #endif
+
+ /* Save underlying hooks */
+ old_malloc_hook = __malloc_hook;
+ old_free_hook = __free_hook;
+ old_realloc_hook = __realloc_hook;
+
+ /* Restore our own hooks */
+ __malloc_hook = HeapProfiler::MallocHook;
+ __free_hook = HeapProfiler::FreeHook;
+ __realloc_hook = HeapProfiler::ReallocHook;
+}
+
+
+void *HeapProfiler::ReallocHook (void *ptr, size_t size, const void *caller) {
+ void *newptr;
+
+ /* Restore all old hooks */
+ __malloc_hook = old_malloc_hook;
+ __free_hook = old_free_hook;
+ __realloc_hook = old_realloc_hook;
+
+ /* Call recursively */
+ newptr = realloc(ptr, size);
+
+ AllocatedBlocks::iterator result = blocks.find(ptr);
+ if (result != blocks.end())
+ {
+ #ifdef DEBUG_HEAPPROFILER
+ std::cout << "found: " << (*result).second << std::endl;
+ #endif
+ consumption -= (*result).second;
+ blocks.erase(result);
+ } else {
+ #ifdef DEBUG_HEAPPROFILER
+ std::cout << "not found" << std::endl;
+ #endif
+ }
+
+ blocks[newptr] = (unsigned long)size;
+ consumption += (unsigned long)size;
+ if (consumption > maxConsumption)
+ maxConsumption = consumption;
+
+ #ifdef DEBUG_HEAPPROFILER
+ std::cout << "realloc(" << ptr << ", " << size << ") called from " << caller << ", result " << newptr << " (" << consumption << ", max " << maxConsumption << ")" << std::endl;
+ #endif
+
+ /* Save underlying hooks */
+ old_malloc_hook = __malloc_hook;
+ old_free_hook = __free_hook;
+ old_realloc_hook = __realloc_hook;
+
+ /* Restore our own hooks */
+ __malloc_hook = HeapProfiler::MallocHook;
+ __free_hook = HeapProfiler::FreeHook;
+ __realloc_hook = HeapProfiler::ReallocHook;
+
+ return newptr;
+}
+
--- /dev/null
+/***************************************************************************
+ * Installs handlers for malloc(), realloc() and free() *
+ * *
+ * Copyright (C) 2006 by Niko Välimäki *
+ * *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef _HEAPPROFILER_H_
+#define _HEAPPROFILER_H_
+
+#include <map>
+#include <iostream>
+#include <malloc.h>
+
+//#define DEBUG_HEAPPROFILER
+
+typedef std::map<void *, unsigned long> AllocatedBlocks;
+
+class HeapProfiler
+{
+public:
+ static unsigned long GetMaxHeapConsumption();
+ static unsigned long GetHeapConsumption();
+
+ // Prototypes for hooks
+ static void InitHooks(void);
+ static void *MallocHook(size_t, const void *);
+ static void FreeHook(void *, const void *);
+ static void *ReallocHook(void *, size_t, const void *);
+
+private:
+ static unsigned long consumption, maxConsumption;
+ // Variables to save original hooks.
+ static void *(*old_malloc_hook)(size_t, const void *);
+ static void (*old_free_hook)(void *, const void *);
+ static void *(*old_realloc_hook)(void *, size_t, const void *);
+ static AllocatedBlocks blocks;
+};
+
+
+#endif
// Test driver for text collection
#include <iostream>
+#include <cstdlib>
+#include "HeapProfiler.h"
using std::cout;
using std::endl;
int main()
{
- uchar *text = (uchar*) "acabab";
- TextCollection *csa = TextCollection::InitTextCollection(1);
- csa->InsertText(text);
- text = (uchar*) "abaca";
- csa->InsertText(text);
- text = (uchar*) "abacb";
- csa->InsertText(text);
-
- csa->MakeStatic();
-// FILE *pFile = fopen ( "mysave.txt" , "rb" );
-// csa->Load(pFile);
-
- text = csa->GetText(0);
- cout << "Text 0: \"" << text << "\"" << endl;
- delete [] text;
- text = csa->GetText(1);
- cout << "Text 1: \"" << text << "\"" << endl;
- delete [] text;
- text = csa->GetText(2);
- cout << "Text 2: \"" << text << "\"" << endl;
- delete [] text;
-
- text = csa->GetText(2, 2, 4);
- cout << "Substring of Text 3: \"" << text << "\"" << endl;
- delete [] text;
-
- printf("n:o contains: %u\n", csa->CountContains((uchar *)"ac"));
- printf("n:o suffix: %u\n", csa->CountSuffix((uchar *)"b"));
- printf("n:o equal: %u\n", csa->CountEqual((uchar *)"acabab"));
- printf("is equal: %u\n", csa->IsEqual((uchar *)"abacb"));
-
- TextCollection::document_result dr;
- dr = csa->Contains((uchar*)"ab");
- printDocumentResult(dr);
-
- TextCollection::full_result fr;
- fr = csa->FullContains((uchar *)"ab");
- printFullResult(fr);
-
-// FILE *pFile2 = fopen ( "mysave.txt" , "wb" );
-// csa->Save(pFile2);
-
- delete csa;
+ std::string kbd;
+ uchar * str = (uchar*) "";
+
+ TextCollection *csa = TextCollection::InitTextCollection(64);
+ for(int i = 0; i<1000000; i++){
+ csa->InsertText(str);
+ };
+ std::cerr << "Before MakeStatic() [press enter]\n";
+ std::cin >> kbd;
+ std::cerr << "heap usage: " << HeapProfiler::GetHeapConsumption()/(1024*1024) << " Mbytes" << std::endl;
+ csa->MakeStatic();
+ std::cerr << "After MakeStatic() [press enter]\n";
+ std::cin >> kbd;
+ std::cerr << "heap usage: " << HeapProfiler::GetHeapConsumption()/(1024*1024) << " Mbytes" << std::endl;
+ delete csa;
+ std::cerr << "After Delete [press enter]\n";
+ std::cerr << "heap usage: " << HeapProfiler::GetHeapConsumption()/(1024*1024) << " Mbytes" << std::endl;
+ std::cin >> kbd;
+ return 0;
}