Revision: 8949
Author:   [email protected]
Date:     Wed Aug 17 01:48:54 2011
Log:      Fix memory leaks in ~Zone and ~Isolate

TEST=chromium valgrind bots

Review URL: http://codereview.chromium.org/7660016
http://code.google.com/p/v8/source/detail?r=8949

Modified:
 /branches/bleeding_edge/src/isolate.cc
 /branches/bleeding_edge/src/serialize.cc
 /branches/bleeding_edge/src/serialize.h
 /branches/bleeding_edge/src/zone.cc
 /branches/bleeding_edge/src/zone.h

=======================================
--- /branches/bleeding_edge/src/isolate.cc      Thu Aug  4 08:18:18 2011
+++ /branches/bleeding_edge/src/isolate.cc      Wed Aug 17 01:48:54 2011
@@ -1533,6 +1533,9 @@
 Isolate::~Isolate() {
   TRACE_ISOLATE(destructor);

+  // Has to be called while counters_ are still alive.
+  zone_.DeleteKeptSegment();
+
   delete unicode_cache_;
   unicode_cache_ = NULL;

@@ -1591,6 +1594,9 @@
   delete global_handles_;
   global_handles_ = NULL;

+  delete external_reference_table_;
+  external_reference_table_ = NULL;
+
 #ifdef ENABLE_DEBUGGER_SUPPORT
   delete debugger_;
   debugger_ = NULL;
=======================================
--- /branches/bleeding_edge/src/serialize.cc    Wed Jul 13 02:09:04 2011
+++ /branches/bleeding_edge/src/serialize.cc    Wed Aug 17 01:48:54 2011
@@ -62,57 +62,15 @@
 }


-// ExternalReferenceTable is a helper class that defines the relationship
-// between external references and their encodings. It is used to build
-// hashmaps in ExternalReferenceEncoder and ExternalReferenceDecoder.
-class ExternalReferenceTable {
- public:
-  static ExternalReferenceTable* instance(Isolate* isolate) {
-    ExternalReferenceTable* external_reference_table =
-        isolate->external_reference_table();
-    if (external_reference_table == NULL) {
-      external_reference_table = new ExternalReferenceTable(isolate);
-      isolate->set_external_reference_table(external_reference_table);
-    }
-    return external_reference_table;
-  }
-
-  int size() const { return refs_.length(); }
-
-  Address address(int i) { return refs_[i].address; }
-
-  uint32_t code(int i) { return refs_[i].code; }
-
-  const char* name(int i) { return refs_[i].name; }
-
-  int max_id(int code) { return max_id_[code]; }
-
- private:
-  explicit ExternalReferenceTable(Isolate* isolate) : refs_(64) {
-      PopulateTable(isolate);
-  }
-  ~ExternalReferenceTable() { }
-
-  struct ExternalReferenceEntry {
-    Address address;
-    uint32_t code;
-    const char* name;
-  };
-
-  void PopulateTable(Isolate* isolate);
-
-  // For a few types of references, we can get their address from their id.
-  void AddFromId(TypeCode type,
-                 uint16_t id,
-                 const char* name,
-                 Isolate* isolate);
-
-  // For other types of references, the caller will figure out the address.
-  void Add(Address address, TypeCode type, uint16_t id, const char* name);
-
-  List<ExternalReferenceEntry> refs_;
-  int max_id_[kTypeCodeCount];
-};
+ExternalReferenceTable* ExternalReferenceTable::instance(Isolate* isolate) {
+  ExternalReferenceTable* external_reference_table =
+      isolate->external_reference_table();
+  if (external_reference_table == NULL) {
+    external_reference_table = new ExternalReferenceTable(isolate);
+    isolate->set_external_reference_table(external_reference_table);
+  }
+  return external_reference_table;
+}


 void ExternalReferenceTable::AddFromId(TypeCode type,
=======================================
--- /branches/bleeding_edge/src/serialize.h     Thu Aug 11 09:29:28 2011
+++ /branches/bleeding_edge/src/serialize.h     Wed Aug 17 01:48:54 2011
@@ -60,6 +60,52 @@
 const int kDebugIdShift = kDebugRegisterBits;


+// ExternalReferenceTable is a helper class that defines the relationship
+// between external references and their encodings. It is used to build
+// hashmaps in ExternalReferenceEncoder and ExternalReferenceDecoder.
+class ExternalReferenceTable {
+ public:
+  static ExternalReferenceTable* instance(Isolate* isolate);
+
+  ~ExternalReferenceTable() { }
+
+  int size() const { return refs_.length(); }
+
+  Address address(int i) { return refs_[i].address; }
+
+  uint32_t code(int i) { return refs_[i].code; }
+
+  const char* name(int i) { return refs_[i].name; }
+
+  int max_id(int code) { return max_id_[code]; }
+
+ private:
+  explicit ExternalReferenceTable(Isolate* isolate) : refs_(64) {
+      PopulateTable(isolate);
+  }
+
+  struct ExternalReferenceEntry {
+    Address address;
+    uint32_t code;
+    const char* name;
+  };
+
+  void PopulateTable(Isolate* isolate);
+
+  // For a few types of references, we can get their address from their id.
+  void AddFromId(TypeCode type,
+                 uint16_t id,
+                 const char* name,
+                 Isolate* isolate);
+
+  // For other types of references, the caller will figure out the address.
+  void Add(Address address, TypeCode type, uint16_t id, const char* name);
+
+  List<ExternalReferenceEntry> refs_;
+  int max_id_[kTypeCodeCount];
+};
+
+
 class ExternalReferenceEncoder {
  public:
   ExternalReferenceEncoder();
=======================================
--- /branches/bleeding_edge/src/zone.cc Fri Mar 18 13:35:07 2011
+++ /branches/bleeding_edge/src/zone.cc Wed Aug 17 01:48:54 2011
@@ -32,24 +32,6 @@

 namespace v8 {
 namespace internal {
-
-
-Zone::Zone()
-    : zone_excess_limit_(256 * MB),
-      segment_bytes_allocated_(0),
-      position_(0),
-      limit_(0),
-      scope_nesting_(0),
-      segment_head_(NULL) {
-}
-unsigned Zone::allocation_size_ = 0;
-
-
-ZoneScope::~ZoneScope() {
-  ASSERT_EQ(Isolate::Current(), isolate_);
-  if (ShouldDeleteOnExit()) isolate_->zone()->DeleteAll();
-  isolate_->zone()->scope_nesting_--;
-}


 // Segments represent chunks of memory: They have starting address
@@ -60,6 +42,11 @@

 class Segment {
  public:
+  void Initialize(Segment* next, int size) {
+    next_ = next;
+    size_ = size;
+  }
+
   Segment* next() const { return next_; }
   void clear_next() { next_ = NULL; }

@@ -77,9 +64,24 @@

   Segment* next_;
   int size_;
-
-  friend class Zone;
 };
+
+
+Zone::Zone()
+    : zone_excess_limit_(256 * MB),
+      segment_bytes_allocated_(0),
+      position_(0),
+      limit_(0),
+      scope_nesting_(0),
+      segment_head_(NULL) {
+}
+unsigned Zone::allocation_size_ = 0;
+
+ZoneScope::~ZoneScope() {
+  ASSERT_EQ(Isolate::Current(), isolate_);
+  if (ShouldDeleteOnExit()) isolate_->zone()->DeleteAll();
+  isolate_->zone()->scope_nesting_--;
+}


 // Creates a new segment, sets it size, and pushes it to the front
@@ -88,8 +90,7 @@
   Segment* result = reinterpret_cast<Segment*>(Malloced::New(size));
   adjust_segment_bytes_allocated(size);
   if (result != NULL) {
-    result->next_ = segment_head_;
-    result->size_ = size;
+    result->Initialize(segment_head_, size);
     segment_head_ = result;
   }
   return result;
@@ -153,6 +154,14 @@
   // Update the head segment to be the kept segment (if any).
   segment_head_ = keep;
 }
+
+
+void Zone::DeleteKeptSegment() {
+  if (segment_head_ != NULL) {
+    DeleteSegment(segment_head_, segment_head_->size());
+    segment_head_ = NULL;
+  }
+}


 Address Zone::NewExpand(int size) {
=======================================
--- /branches/bleeding_edge/src/zone.h  Fri Jul 15 09:57:35 2011
+++ /branches/bleeding_edge/src/zone.h  Wed Aug 17 01:48:54 2011
@@ -65,9 +65,13 @@
   template <typename T>
   inline T* NewArray(int length);

-  // Delete all objects and free all memory allocated in the Zone.
+ // Deletes all objects and free all memory allocated in the Zone. Keeps one + // small (size <= kMaximumKeptSegmentSize) segment around if it finds one.
   void DeleteAll();

+  // Deletes the last small segment kept around by DeleteAll().
+  void DeleteKeptSegment();
+
   // Returns true if more memory has been allocated in zones than
   // the limit allows.
   inline bool excess_allocation();

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

Reply via email to