From 3eb670721ff170ac9fcf8b8b3218984db3cc8078 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 8 Nov 2007 18:32:01 +0000 Subject: [PATCH] improve MakeRopeString to avoid doing a malloc for every 2-character string that gets inserted. This speeds up the rewriter another 10%. llvm-svn: 43896 --- clang/include/clang/Rewrite/RewriteRope.h | 42 +++++++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/Rewrite/RewriteRope.h b/clang/include/clang/Rewrite/RewriteRope.h index 3d5b0237811a..59e05bee3d0a 100644 --- a/clang/include/clang/Rewrite/RewriteRope.h +++ b/clang/include/clang/Rewrite/RewriteRope.h @@ -130,8 +130,14 @@ public: class RewriteRope { std::vector 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 iterator; @@ -257,12 +263,34 @@ public: private: RopePiece MakeRopeString(const char *Start, const char *End) { - unsigned Size = End-Start+sizeof(RopeRefCountString)-1; - RopeRefCountString *Res = - reinterpret_cast(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(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(new char[AllocSize]); + AllocBuffer->RefCount = 0; + memcpy(AllocBuffer->Data, Start, Len); + AllocOffs = Len; + return RopePiece(AllocBuffer, 0, Len); } unsigned getChunkIdx(iterator Loc) const {