Reviewers: Mikhail Naganov (Chromium),

Description:
Fix memory leak from d8 shell.

We were not disposing the semaphores used in SourceGroup.

[email protected]

Signed-off-by: Thiago Farina <[email protected]>


Please review this at http://codereview.chromium.org/7754007/

SVN Base: git://github.com/v8/v8.git@trunk

Affected files:
  M src/d8.h
  M src/d8.cc
  M src/smart-pointer.h


Index: src/d8.cc
diff --git a/src/d8.cc b/src/d8.cc
index 5c604368920a35c5aa81feb6818219b59c697a43..6cb43a7a7d35989e44f2d4728ac3a9d81a75428d 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -1021,7 +1021,7 @@ i::Thread::Options SourceGroup::GetThreadOptions() {
 void SourceGroup::ExecuteInThread() {
   Isolate* isolate = Isolate::New();
   do {
-    if (next_semaphore_ != NULL) next_semaphore_->Wait();
+    if (!next_semaphore_.is_empty()) next_semaphore_->Wait();
     {
       Isolate::Scope iscope(isolate);
       Locker lock(isolate);
@@ -1033,7 +1033,7 @@ void SourceGroup::ExecuteInThread() {
       }
       context.Dispose();
     }
-    if (done_semaphore_ != NULL) done_semaphore_->Signal();
+    if (!done_semaphore_.is_empty()) done_semaphore_->Signal();
   } while (!Shell::options.last_run);
   isolate->Dispose();
 }
Index: src/d8.h
diff --git a/src/d8.h b/src/d8.h
index 28321f56dae720dd2e02d56881132966f53921c7..eb267fe19379cd59e8c2c82f032acbe1deaf574b 100644
--- a/src/d8.h
+++ b/src/d8.h
@@ -28,11 +28,11 @@
 #ifndef V8_D8_H_
 #define V8_D8_H_

-
 #ifndef V8_SHARED
-#include "v8.h"
 #include "allocation.h"
 #include "hashmap.h"
+#include "smart-pointer.h"
+#include "v8.h"
 #else
 #include "../include/v8.h"
 #endif  // V8_SHARED
@@ -158,8 +158,8 @@ class SourceGroup {
   static i::Thread::Options GetThreadOptions();
   void ExecuteInThread();

-  i::Semaphore* next_semaphore_;
-  i::Semaphore* done_semaphore_;
+  i::SmartPointer<i::Semaphore> next_semaphore_;
+  i::SmartPointer<i::Semaphore> done_semaphore_;
   i::Thread* thread_;
 #endif  // V8_SHARED

Index: src/smart-pointer.h
diff --git a/src/smart-pointer.h b/src/smart-pointer.h
index 0fa8224e71476ed81a3f04e6bcbd276be3d33ff5..a3e930d81a0c1c58c42a0621cd059deee2cfb549 100644
--- a/src/smart-pointer.h
+++ b/src/smart-pointer.h
@@ -37,35 +37,31 @@ namespace internal {
 template<typename T>
 class SmartPointer {
  public:
+  // Default constructor. Constructs an empty scoped pointer.
+  inline SmartPointer() : p_(NULL) {}

-  // Default constructor. Construct an empty scoped pointer.
-  inline SmartPointer() : p(NULL) {}
-
-
-  // Construct a scoped pointer from a plain one.
-  explicit inline SmartPointer(T* pointer) : p(pointer) {}
-
+  // Constructs a scoped pointer from a plain one.
+  explicit inline SmartPointer(T* ptr) : p_(ptr) {}

   // Copy constructor removes the pointer from the original to avoid double
   // freeing.
-  inline SmartPointer(const SmartPointer<T>& rhs) : p(rhs.p) {
-    const_cast<SmartPointer<T>&>(rhs).p = NULL;
+  inline SmartPointer(const SmartPointer<T>& rhs) : p_(rhs.p_) {
+    const_cast<SmartPointer<T>&>(rhs).p_ = NULL;
   }

-
// When the destructor of the scoped pointer is executed the plain pointer // is deleted using DeleteArray. This implies that you must allocate with
   // NewArray.
-  inline ~SmartPointer() { if (p) DeleteArray(p); }
+  inline ~SmartPointer() { if (p_) DeleteArray(p_); }

+  inline T* operator->() const { return p_; }

   // You can get the underlying pointer out with the * operator.
-  inline T* operator*() { return p; }
-
+  inline T* operator*() { return p_; }

   // You can use [n] to index as if it was a plain pointer
   inline T& operator[](size_t i) {
-    return p[i];
+    return p_[i];
   }

// We don't have implicit conversion to a T* since that hinders migration:
@@ -77,31 +73,26 @@ class SmartPointer {
   // deleted then call Detach().  Afterwards, the smart pointer is empty
   // (NULL).
   inline T* Detach() {
-    T* temp = p;
-    p = NULL;
+    T* temp = p_;
+    p_ = NULL;
     return temp;
   }

-
// Assignment requires an empty (NULL) SmartPointer as the receiver. Like
   // the copy constructor it removes the pointer in the original to avoid
   // double freeing.
   inline SmartPointer& operator=(const SmartPointer<T>& rhs) {
     ASSERT(is_empty());
-    T* tmp = rhs.p;  // swap to handle self-assignment
-    const_cast<SmartPointer<T>&>(rhs).p = NULL;
-    p = tmp;
+    T* tmp = rhs.p_;  // swap to handle self-assignment
+    const_cast<SmartPointer<T>&>(rhs).p_ = NULL;
+    p_ = tmp;
     return *this;
   }

-
-  inline bool is_empty() {
-    return p == NULL;
-  }
-
+  inline bool is_empty() { return p_ == NULL; }

  private:
-  T* p;
+  T* p_;
 };

 } }  // namespace v8::internal


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to