Index: src/zone.cc |
diff --git a/src/zone.cc b/src/zone.cc |
index 82a2efa94ea90e8cf0d30cc611e61dc9bc97523e..2a0a0e284610a03abe195bb42384ca8f35561dce 100644 |
--- a/src/zone.cc |
+++ b/src/zone.cc |
@@ -78,31 +78,82 @@ Zone::Zone(Isolate* isolate) |
Zone::~Zone() { |
+ DeleteAll(); |
+ DeleteKeptSegment(); |
+ |
+ ASSERT(segment_bytes_allocated_ == 0); |
+} |
+ |
+ |
+void Zone::DeleteAll() { |
#ifdef DEBUG |
// Constant byte value used for zapping dead memory in debug mode. |
static const unsigned char kZapDeadByte = 0xcd; |
#endif |
- // Traverse the chained list of segments, zapping |
- // (in debug mode) and freeing every segment |
- Segment* current = segment_head_; |
- while (current != NULL) { |
+ // Find a segment with a suitable size to keep around. |
+ Segment* keep = segment_head_; |
+ while (keep != NULL && keep->size() > kMaximumKeptSegmentSize) { |
+ keep = keep->next(); |
+ } |
+ |
+ // Traverse the chained list of segments, zapping (in debug mode) |
+ // and freeing every segment except the one we wish to keep. |
+ for (Segment* current = segment_head_; current != NULL; ) { |
Segment* next = current->next(); |
- int size = current->size(); |
+ if (current == keep) { |
+ // Unlink the segment we wish to keep from the list. |
+ current->clear_next(); |
+ } else { |
+ int size = current->size(); |
#ifdef DEBUG |
- // Zap the entire current segment (including the header). |
- memset(current, kZapDeadByte, size); |
+ // Zap the entire current segment (including the header). |
+ memset(current, kZapDeadByte, size); |
#endif |
- DeleteSegment(current, size); |
+ DeleteSegment(current, size); |
+ } |
current = next; |
} |
- // We must clear the position and limit to force |
- // a new segment to be allocated on demand. |
- position_ = limit_ = 0; |
+ // If we have found a segment we want to keep, we must recompute the |
+ // variables 'position' and 'limit' to prepare for future allocate |
+ // attempts. Otherwise, we must clear the position and limit to |
+ // force a new segment to be allocated on demand. |
+ if (keep != NULL) { |
+ Address start = keep->start(); |
+ position_ = RoundUp(start, kAlignment); |
+ limit_ = keep->end(); |
+#ifdef DEBUG |
+ // Zap the contents of the kept segment (but not the header). |
+ memset(start, kZapDeadByte, keep->capacity()); |
+#endif |
+ } else { |
+ position_ = limit_ = 0; |
+ } |
+ |
+ // Update the head segment to be the kept segment (if any). |
+ segment_head_ = keep; |
+} |
+ |
+ |
+void Zone::DeleteKeptSegment() { |
+#ifdef DEBUG |
+ // Constant byte value used for zapping dead memory in debug mode. |
+ static const unsigned char kZapDeadByte = 0xcd; |
+#endif |
+ |
+ ASSERT(segment_head_ == NULL || segment_head_->next() == NULL); |
+ if (segment_head_ != NULL) { |
+ int size = segment_head_->size(); |
+#ifdef DEBUG |
+ // Zap the entire kept segment (including the header). |
+ memset(segment_head_, kZapDeadByte, size); |
+#endif |
+ DeleteSegment(segment_head_, size); |
+ segment_head_ = NULL; |
+ } |
- // Update the head segment. |
- segment_head_ = NULL; |
+ ASSERT(segment_bytes_allocated_ == 0); |
} |