[parser] Fix memory accounting of explicitly cleared zones

Bug: chromium:889086
Change-Id: Ie5a6a9e27260545469ea62d35b9571c0524f0f92
Reviewed-on: https://chromium-review.googlesource.com/1245427
Reviewed-by: Marja Hölttä <marja@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56235}
diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc
index 9713d0f..8353716 100644
--- a/src/parsing/parser.cc
+++ b/src/parsing/parser.cc
@@ -36,7 +36,7 @@
 class PreParserZoneScope {
  public:
   explicit PreParserZoneScope(PreParser* preparser) : preparser_(preparser) {}
-  ~PreParserZoneScope() { preparser_->zone()->DeleteAll(); }
+  ~PreParserZoneScope() { preparser_->zone()->ReleaseMemory(); }
 
  private:
   PreParser* preparser_;
diff --git a/src/zone/zone.cc b/src/zone/zone.cc
index 295d781..a851f67 100644
--- a/src/zone/zone.cc
+++ b/src/zone/zone.cc
@@ -43,7 +43,6 @@
 
 Zone::~Zone() {
   allocator_->ZoneDestruction(this);
-
   DeleteAll();
 
   DCHECK_EQ(segment_bytes_allocated_, 0);
@@ -77,6 +76,12 @@
   return reinterpret_cast<void*>(result);
 }
 
+void Zone::ReleaseMemory() {
+  allocator_->ZoneDestruction(this);
+  DeleteAll();
+  allocator_->ZoneCreation(this);
+}
+
 void Zone::DeleteAll() {
   // Traverse the chained list of segments and return them all to the allocator.
   for (Segment* current = segment_head_; current;) {
diff --git a/src/zone/zone.h b/src/zone/zone.h
index 2d916b9..12e4973 100644
--- a/src/zone/zone.h
+++ b/src/zone/zone.h
@@ -57,8 +57,9 @@
   // Seals the zone to prevent any further allocation.
   void Seal() { sealed_ = true; }
 
-  // Deletes all objects and free all memory allocated in the Zone.
-  void DeleteAll();
+  // Allows the zone to be safely reused. Releases the memory and fires zone
+  // destruction and creation events for the accounting allocator.
+  void ReleaseMemory();
 
   // Returns true if more memory has been allocated in zones than
   // the limit allows.
@@ -73,6 +74,9 @@
   AccountingAllocator* allocator() const { return allocator_; }
 
  private:
+  // Deletes all objects and free all memory allocated in the Zone.
+  void DeleteAll();
+
   // All pointers returned from New() are 8-byte aligned.
   static const size_t kAlignmentInBytes = 8;