Use sized deallocation for RE2's DFA.

Change-Id: I2433c8b172a4802e3e09eefa0afef34654e86dc8
Reviewed-on: https://code-review.googlesource.com/23630
Reviewed-by: Paul Wankadia <junyer@google.com>
diff --git a/re2/dfa.cc b/re2/dfa.cc
index 50d1ad0..c1c8460 100644
--- a/re2/dfa.cc
+++ b/re2/dfa.cc
@@ -771,7 +771,7 @@
   mem_budget_ -= mem + kStateCacheOverhead;
 
   // Allocate new state along with room for next_ and inst_.
-  char* space = new char[mem];
+  char* space = std::allocator<char>().allocate(mem);
   State* s = new (space) State;
   (void) new (s->next_) std::atomic<State*>[nnext];
   // Work around a unfortunate bug in older versions of libstdc++.
@@ -798,7 +798,12 @@
     StateSet::iterator tmp = begin;
     ++begin;
     // Deallocate the blob of memory that we allocated in DFA::CachedState().
-    delete[] reinterpret_cast<const char*>(*tmp);
+    // We recompute mem in order to benefit from sized delete where possible.
+    int ninst = (*tmp)->ninst_;
+    int nnext = prog_->bytemap_range() + 1;  // + 1 for kByteEndText slot
+    int mem = sizeof(State) + nnext*sizeof(std::atomic<State*>) +
+              ninst*sizeof(int);
+    std::allocator<char>().deallocate(reinterpret_cast<char*>(*tmp), mem);
   }
   state_cache_.clear();
 }