[cfe-commits] r43896 - /cfe/trunk/include/clang/Rewrite/RewriteRope.h

Chris Lattner sabre at nondot.org
Thu Nov 8 10:32:01 PST 2007


Author: lattner
Date: Thu Nov  8 12:32:01 2007
New Revision: 43896

URL: http://llvm.org/viewvc/llvm-project?rev=43896&view=rev
Log:
improve MakeRopeString to avoid doing a malloc for every 2-character string 
that gets inserted.  This speeds up the rewriter another 10%.


Modified:
    cfe/trunk/include/clang/Rewrite/RewriteRope.h

Modified: cfe/trunk/include/clang/Rewrite/RewriteRope.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Rewrite/RewriteRope.h?rev=43896&r1=43895&r2=43896&view=diff

==============================================================================
--- cfe/trunk/include/clang/Rewrite/RewriteRope.h (original)
+++ cfe/trunk/include/clang/Rewrite/RewriteRope.h Thu Nov  8 12:32:01 2007
@@ -130,8 +130,14 @@
 class RewriteRope {
   std::vector<RopePiece*> Chunks;
   unsigned CurSize;
+  
+  /// We allocate space for string data out of a buffer of size AllocChunkSize.
+  /// This keeps track of how much space is left.
+  RopeRefCountString *AllocBuffer;
+  unsigned AllocOffs;
+  enum { AllocChunkSize = 4080 };
 public:
-  RewriteRope() : CurSize(0) {}
+  RewriteRope() : CurSize(0), AllocBuffer(0), AllocOffs(AllocChunkSize) {}
   ~RewriteRope() { clear(); }
   
   typedef RewriteRopeIterator<char, RopePiece*> iterator;
@@ -257,12 +263,34 @@
 
 private:
   RopePiece MakeRopeString(const char *Start, const char *End) {
-    unsigned Size = End-Start+sizeof(RopeRefCountString)-1;
-    RopeRefCountString *Res = 
-      reinterpret_cast<RopeRefCountString *>(new char[Size]);
-    Res->RefCount = 0;
-    memcpy(Res->Data, Start, End-Start);
-    return RopePiece(Res, 0, End-Start);
+    unsigned Len = End-Start;
+    
+    // If we have space for this string in the current alloc buffer, use it.
+    if (AllocOffs+Len <= AllocChunkSize) {
+      memcpy(AllocBuffer->Data+AllocOffs, Start, Len);
+      AllocOffs += Len;
+      return RopePiece(AllocBuffer, AllocOffs-Len, AllocOffs);
+    }
+
+    // If we don't have enough room because this specific allocation is huge,
+    // just allocate a new rope piece for it alone.
+    if (Len > AllocChunkSize) {
+      unsigned Size = End-Start+sizeof(RopeRefCountString)-1;
+      RopeRefCountString *Res = 
+        reinterpret_cast<RopeRefCountString *>(new char[Size]);
+      Res->RefCount = 0;
+      memcpy(Res->Data, Start, End-Start);
+      return RopePiece(Res, 0, End-Start);
+    }
+    
+    // Otherwise, this was a small request but we just don't have space for it
+    // Make a new chunk and share it with later allocations.
+    unsigned AllocSize = sizeof(RopeRefCountString)-1+AllocChunkSize;
+    AllocBuffer = reinterpret_cast<RopeRefCountString *>(new char[AllocSize]);
+    AllocBuffer->RefCount = 0;
+    memcpy(AllocBuffer->Data, Start, Len);
+    AllocOffs = Len;
+    return RopePiece(AllocBuffer, 0, Len);
   }
   
   unsigned getChunkIdx(iterator Loc) const {





More information about the cfe-commits mailing list