about summary refs log tree commit diff
path: root/src/rt/memory_region.cpp
diff options
context:
space:
mode:
authorEric Holk <eholk@mozilla.com>2011-07-18 12:02:26 -0700
committerBrian Anderson <banderson@mozilla.com>2011-07-21 11:51:22 -0700
commit3ae4dcd41e72d197e3882835253745f79588b04a (patch)
tree38b0fa41afe156057c8913f779fda2e4ca0b08ac /src/rt/memory_region.cpp
parenta44fb04d57400f70ad58c1e35fc9dd9a7c43de07 (diff)
downloadrust-3ae4dcd41e72d197e3882835253745f79588b04a.tar.gz
rust-3ae4dcd41e72d197e3882835253745f79588b04a.zip
Lots of work on memory tracking and channels.
We're trying to get closer to doing correct move semantics for channel
operations. This involves a lot of cleanup (such as removing the
unused sched parameter from rust_vec constructor) and making
circular_buffer kernel_owned.

Added tagging for memory allocations. This means we give a string tag
to everything we allocate. If we leak something and TRACK_ALLOCATIONS
is enabled, then it's much easier now to tell exactly what is leaking.
Diffstat (limited to 'src/rt/memory_region.cpp')
-rw-r--r--src/rt/memory_region.cpp94
1 files changed, 39 insertions, 55 deletions
diff --git a/src/rt/memory_region.cpp b/src/rt/memory_region.cpp
index 0d10146a52b..603ec12e796 100644
--- a/src/rt/memory_region.cpp
+++ b/src/rt/memory_region.cpp
@@ -4,7 +4,13 @@
 // NB: please do not commit code with this uncommented. It's
 // hugely expensive and should only be used as a last resort.
 //
-// #define TRACK_ALLOCATIONS
+#define TRACK_ALLOCATIONS
+
+#define MAGIC 0xbadc0ffe
+
+memory_region::alloc_header *memory_region::get_header(void *mem) {
+    return (alloc_header *)((char *)mem - sizeof(alloc_header));
+}
 
 memory_region::memory_region(rust_srv *srv, bool synchronized) :
     _srv(srv), _parent(NULL), _live_allocations(0),
@@ -19,37 +25,37 @@ memory_region::memory_region(memory_region *parent) :
 }
 
 void memory_region::add_alloc() {
-    //_live_allocations++;
-    sync::increment(_live_allocations);
+    _live_allocations++;
+    //sync::increment(_live_allocations);
 }
 
 void memory_region::dec_alloc() {
-    //_live_allocations--;
-    sync::decrement(_live_allocations);
+    _live_allocations--;
+    //sync::decrement(_live_allocations);
 }
 
 void memory_region::free(void *mem) {
     // printf("free: ptr 0x%" PRIxPTR" region=%p\n", (uintptr_t) mem, this);
     if (!mem) { return; }
     if (_synchronized) { _lock.lock(); }
+    alloc_header *alloc = get_header(mem);
+    assert(alloc->magic == MAGIC);
 #ifdef TRACK_ALLOCATIONS
-    int index = ((int  *)mem)[-1];
-    if (_allocation_list[index] != (uint8_t *)mem - sizeof(int)) {
+    if (_allocation_list[alloc->index] != alloc) {
         printf("free: ptr 0x%" PRIxPTR " is not in allocation_list\n",
                (uintptr_t) mem);
         _srv->fatal("not in allocation_list", __FILE__, __LINE__, "");
     }
     else {
         // printf("freed index %d\n", index);
-        _allocation_list[index] = NULL;
+        _allocation_list[alloc->index] = NULL;
     }
-    mem = (void*)((uint8_t*)mem - sizeof(int));
 #endif
     if (_live_allocations < 1) {
         _srv->fatal("live_allocs < 1", __FILE__, __LINE__, "");
     }
     dec_alloc();
-    _srv->free(mem);
+    _srv->free(alloc);
     if (_synchronized) { _lock.unlock(); }
 }
 
@@ -59,77 +65,55 @@ memory_region::realloc(void *mem, size_t size) {
     if (!mem) {
         add_alloc();
     }
+    size += sizeof(alloc_header);
+    alloc_header *alloc = get_header(mem);
+    assert(alloc->magic == MAGIC);
+    alloc_header *newMem = (alloc_header *)_srv->realloc(alloc, size);
 #ifdef TRACK_ALLOCATIONS
-    size += sizeof(int);
-    mem = (void*)((uint8_t*)mem - sizeof(int));
-    int index = *(int  *)mem;
-#endif
-    void *newMem = _srv->realloc(mem, size);
-#ifdef TRACK_ALLOCATIONS
-    if (_allocation_list[index] != mem) {
+    if (_allocation_list[newMem->index] != alloc) {
         printf("at index %d, found %p, expected %p\n",
-               index, _allocation_list[index], mem);
+               alloc->index, _allocation_list[alloc->index], alloc);
         printf("realloc: ptr 0x%" PRIxPTR " is not in allocation_list\n",
             (uintptr_t) mem);
         _srv->fatal("not in allocation_list", __FILE__, __LINE__, "");
     }
     else {
-        _allocation_list[index] = newMem;
-        (*(int*)newMem) = index;
+        _allocation_list[newMem->index] = newMem;
         // printf("realloc: stored %p at index %d, replacing %p\n",
         //        newMem, index, mem);
     }
 #endif
     if (_synchronized) { _lock.unlock(); }
-#ifdef TRACK_ALLOCATIONS
-    newMem = (void *)((uint8_t*)newMem + sizeof(int));
-#endif
-    return newMem;
+    return newMem->data;
 }
 
 void *
-memory_region::malloc(size_t size) {
+memory_region::malloc(size_t size, const char *tag, bool zero) {
     if (_synchronized) { _lock.lock(); }
     add_alloc();
+    size_t old_size = size;
+    size += sizeof(alloc_header);
+    alloc_header *mem = (alloc_header *)_srv->malloc(size);
+    mem->magic = MAGIC;
+    mem->tag = tag;
 #ifdef TRACK_ALLOCATIONS
-    size += sizeof(int);
-#endif
-    void *mem = _srv->malloc(size);
-#ifdef TRACK_ALLOCATIONS
-    int index = _allocation_list.append(mem);
-    int *p = (int *)mem;
-    *p = index;
+    mem->index = _allocation_list.append(mem);
     // printf("malloc: stored %p at index %d\n", mem, index);
 #endif
     // printf("malloc: ptr 0x%" PRIxPTR " region=%p\n",
     //        (uintptr_t) mem, this);
+
+    if(zero) {
+        memset(mem->data, 0, old_size);
+    }
+
     if (_synchronized) { _lock.unlock(); }
-#ifdef TRACK_ALLOCATIONS
-    mem = (void*)((uint8_t*)mem + sizeof(int));
-#endif
-    return mem;
+    return mem->data;
 }
 
 void *
-memory_region::calloc(size_t size) {
-    if (_synchronized) { _lock.lock(); }
-    add_alloc();
-#ifdef TRACK_ALLOCATIONS
-    size += sizeof(int);
-#endif
-    void *mem = _srv->malloc(size);
-    memset(mem, 0, size);
-#ifdef TRACK_ALLOCATIONS
-    int index = _allocation_list.append(mem);
-    int *p = (int *)mem;
-    *p = index;
-    // printf("calloc: stored %p at index %d\n", mem, index);
-#endif
-    if (_synchronized) { _lock.unlock(); }
-#ifdef TRACK_ALLOCATIONS
-    mem = (void*)((uint8_t*)mem + sizeof(int));
-#endif
-    return mem;
+memory_region::calloc(size_t size, const char *tag) {
+    return malloc(size, tag, true);
 }
 
 memory_region::~memory_region() {