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