about summary refs log tree commit diff homepage
path: root/lib/Core/Memory.cpp
diff options
context:
space:
mode:
authorCristian Cadar <cristic@cs.stanford.edu>2012-01-18 18:58:10 +0000
committerCristian Cadar <cristic@cs.stanford.edu>2012-01-18 18:58:10 +0000
commitd32d0df34ab754d4d3b27b287092e536f03a231c (patch)
tree7d76e832672acd1ba11e2b3696b751d3baeee68a /lib/Core/Memory.cpp
parent5344817c3de946e0636f6f671749c464dc4c02f2 (diff)
downloadklee-d32d0df34ab754d4d3b27b287092e536f03a231c.tar.gz
Nice patch by Gang Hu, Heming Cui and Junfeng Yang fixing a memory
leak in KLEE.

From Gang Hu: "The memory leak is caused by two reasons.  First, the
MemoryObject objects are not freed, until the MemoryManager is
destroyed.  Second, when KLEE allocates a non-fixed MemoryObject
object, KLEE also allocates a block of memory which is the same as the
object's size. This block of memory is never freed.  So, this patch
generally does reference counting on the MemoryObject objects, and
frees them as soon as the reference count drops to zero."

Many thanks to Paul Marinescu as well, who tested this patch
thoroughly on the Coreutils benchmarks.  On 1h runs, the memory
consumption typically goes down by 1-5%, but some applications which
see more significant gains.



git-svn-id: https://llvm.org/svn/llvm-project/klee/trunk@148402 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Core/Memory.cpp')
-rw-r--r--lib/Core/Memory.cpp17
1 files changed, 17 insertions, 0 deletions
diff --git a/lib/Core/Memory.cpp b/lib/Core/Memory.cpp
index d54264a3..7b3655f8 100644
--- a/lib/Core/Memory.cpp
+++ b/lib/Core/Memory.cpp
@@ -17,6 +17,7 @@
 #include "klee/util/BitArray.h"
 
 #include "ObjectHolder.h"
+#include "MemoryManager.h"
 
 #include <llvm/Function.h>
 #include <llvm/Instruction.h>
@@ -63,6 +64,8 @@ ObjectHolder &ObjectHolder::operator=(const ObjectHolder &b) {
 int MemoryObject::counter = 0;
 
 MemoryObject::~MemoryObject() {
+  if (parent)
+    parent->markFreed(this);
 }
 
 void MemoryObject::getAllocInfo(std::string &result) const {
@@ -100,6 +103,7 @@ ObjectState::ObjectState(const MemoryObject *mo)
     updates(0, 0),
     size(mo->size),
     readOnly(false) {
+  mo->refCount++;
   if (!UseConstantArrays) {
     // FIXME: Leaked.
     static unsigned id = 0;
@@ -120,6 +124,7 @@ ObjectState::ObjectState(const MemoryObject *mo, const Array *array)
     updates(array, 0),
     size(mo->size),
     readOnly(false) {
+  mo->refCount++;
   makeSymbolic();
 }
 
@@ -135,6 +140,8 @@ ObjectState::ObjectState(const ObjectState &os)
     size(os.size),
     readOnly(false) {
   assert(!os.readOnly && "no need to copy read only object?");
+  if (object)
+    object->refCount++;
 
   if (os.knownSymbolics) {
     knownSymbolics = new ref<Expr>[size];
@@ -150,6 +157,16 @@ ObjectState::~ObjectState() {
   if (flushMask) delete flushMask;
   if (knownSymbolics) delete[] knownSymbolics;
   delete[] concreteStore;
+
+  if (object)
+  {
+    assert(object->refCount > 0);
+    object->refCount--;
+    if (object->refCount == 0)
+    {
+      delete object;
+    }
+  }
 }
 
 /***/