[PATCH] Make RewriteBuffer write in chunks

Alp Toker alp at nuanti.com
Wed Nov 6 23:08:30 PST 2013


Rewrite was previously allocating potentially huge std::strings with
each call and filling it one character at a time.

This has become a hot path for Refactoring, Modernize, FixIt, Format,
and particularly ARCMT/ObjCMT which call it multiple times on the full
source tree -- so copying out contiguous chunks while avoiding large
allocations is a good idea.

This commit preserves the existing interface of RewriteRope and pokes
into it directly for access to the byte vectors.

Resolves a FIXME back from r101521. No change in behaviour.

-- 
http://www.nuanti.com
the browser experts

-------------- next part --------------
diff --git a/include/clang/Rewrite/Core/RewriteRope.h b/include/clang/Rewrite/Core/RewriteRope.h
index a5192ef..5bcdac2 100644
--- a/include/clang/Rewrite/Core/RewriteRope.h
+++ b/include/clang/Rewrite/Core/RewriteRope.h
@@ -108,7 +108,7 @@ namespace clang {
   /// over bytes that are in a RopePieceBTree.  This first iterates over bytes
   /// in a RopePiece, then iterates over RopePiece's in a RopePieceBTreeLeaf,
   /// then iterates over RopePieceBTreeLeaf's in a RopePieceBTree.
-  class RopePieceBTreeIterator :
+  struct RopePieceBTreeIterator :
       public std::iterator<std::forward_iterator_tag, const char, ptrdiff_t> {
     /// CurNode - The current B+Tree node that we are inspecting.
     const void /*RopePieceBTreeLeaf*/ *CurNode;
@@ -117,7 +117,6 @@ namespace clang {
     const RopePiece *CurPiece;
     /// CurChar - The current byte in the RopePiece we are pointing to.
     unsigned CurChar;
-  public:
     // begin iterator.
     RopePieceBTreeIterator(const void /*RopePieceBTreeNode*/ *N);
     // end iterator
@@ -144,7 +143,6 @@ namespace clang {
     inline RopePieceBTreeIterator operator++(int) { // Postincrement
       RopePieceBTreeIterator tmp = *this; ++*this; return tmp;
     }
-  private:
     void MoveToNextPiece();
   };
 
diff --git a/lib/Rewrite/Core/Rewriter.cpp b/lib/Rewrite/Core/Rewriter.cpp
index afb1080..6a41e79 100644
--- a/lib/Rewrite/Core/Rewriter.cpp
+++ b/lib/Rewrite/Core/Rewriter.cpp
@@ -26,8 +26,12 @@
 using namespace clang;
 
 raw_ostream &RewriteBuffer::write(raw_ostream &os) const {
-  // FIXME: eliminate the copy by writing out each chunk at a time
-  os << std::string(begin(), end());
+  for (RopePieceBTreeIterator I = begin(), E = end(); I != E;
+       I.MoveToNextPiece()) {
+    const char *piece = &(*I.CurPiece)[I.CurChar];
+    size_t size = I.CurPiece->size();
+    os.write(piece, size);
+  }
   return os;
 }
 


More information about the cfe-commits mailing list