forked from OSchip/llvm-project
Use intrusive refcounted pointers to manage RopeRefCountString lifetime.
std::shared_ptr<char []> would be even nicer, but shared_ptr doesn't work with arrays :( No functionality change. llvm-svn: 217798
This commit is contained in:
parent
f090bda1d5
commit
fdacdb26af
|
@ -14,6 +14,7 @@
|
|||
#ifndef LLVM_CLANG_REWRITE_CORE_REWRITEROPE_H
|
||||
#define LLVM_CLANG_REWRITE_CORE_REWRITEROPE_H
|
||||
|
||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <cassert>
|
||||
|
@ -34,11 +35,10 @@ namespace clang {
|
|||
unsigned RefCount;
|
||||
char Data[1]; // Variable sized.
|
||||
|
||||
void addRef() {
|
||||
++RefCount;
|
||||
}
|
||||
void Retain() { ++RefCount; }
|
||||
|
||||
void dropRef() {
|
||||
void Release() {
|
||||
assert(RefCount > 0 && "Reference count is already zero.");
|
||||
if (--RefCount == 0)
|
||||
delete [] (char*)this;
|
||||
}
|
||||
|
@ -57,39 +57,15 @@ namespace clang {
|
|||
/// that both refer to the same underlying RopeRefCountString (just with
|
||||
/// different offsets) which is a nice constant time operation.
|
||||
struct RopePiece {
|
||||
RopeRefCountString *StrData;
|
||||
llvm::IntrusiveRefCntPtr<RopeRefCountString> StrData;
|
||||
unsigned StartOffs;
|
||||
unsigned EndOffs;
|
||||
|
||||
RopePiece() : StrData(nullptr), StartOffs(0), EndOffs(0) {}
|
||||
|
||||
RopePiece(RopeRefCountString *Str, unsigned Start, unsigned End)
|
||||
: StrData(Str), StartOffs(Start), EndOffs(End) {
|
||||
if (StrData)
|
||||
StrData->addRef();
|
||||
}
|
||||
RopePiece(const RopePiece &RP)
|
||||
: StrData(RP.StrData), StartOffs(RP.StartOffs), EndOffs(RP.EndOffs) {
|
||||
if (StrData)
|
||||
StrData->addRef();
|
||||
}
|
||||
|
||||
~RopePiece() {
|
||||
if (StrData)
|
||||
StrData->dropRef();
|
||||
}
|
||||
|
||||
void operator=(const RopePiece &RHS) {
|
||||
if (StrData != RHS.StrData) {
|
||||
if (StrData)
|
||||
StrData->dropRef();
|
||||
StrData = RHS.StrData;
|
||||
if (StrData)
|
||||
StrData->addRef();
|
||||
}
|
||||
StartOffs = RHS.StartOffs;
|
||||
EndOffs = RHS.EndOffs;
|
||||
}
|
||||
RopePiece(llvm::IntrusiveRefCntPtr<RopeRefCountString> Str, unsigned Start,
|
||||
unsigned End)
|
||||
: StrData(std::move(Str)), StartOffs(Start), EndOffs(End) {}
|
||||
|
||||
const char &operator[](unsigned Offset) const {
|
||||
return StrData->Data[Offset+StartOffs];
|
||||
|
@ -191,7 +167,7 @@ class RewriteRope {
|
|||
|
||||
/// We allocate space for string data out of a buffer of size AllocChunkSize.
|
||||
/// This keeps track of how much space is left.
|
||||
RopeRefCountString *AllocBuffer;
|
||||
llvm::IntrusiveRefCntPtr<RopeRefCountString> AllocBuffer;
|
||||
unsigned AllocOffs;
|
||||
enum { AllocChunkSize = 4080 };
|
||||
|
||||
|
@ -201,12 +177,6 @@ public:
|
|||
: Chunks(RHS.Chunks), AllocBuffer(nullptr), AllocOffs(AllocChunkSize) {
|
||||
}
|
||||
|
||||
~RewriteRope() {
|
||||
// If we had an allocation buffer, drop our reference to it.
|
||||
if (AllocBuffer)
|
||||
AllocBuffer->dropRef();
|
||||
}
|
||||
|
||||
typedef RopePieceBTree::iterator iterator;
|
||||
typedef RopePieceBTree::iterator const_iterator;
|
||||
iterator begin() const { return Chunks.begin(); }
|
||||
|
|
|
@ -788,18 +788,14 @@ RopePiece RewriteRope::MakeRopeString(const char *Start, const char *End) {
|
|||
// 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.
|
||||
|
||||
if (AllocBuffer)
|
||||
AllocBuffer->dropRef();
|
||||
|
||||
unsigned AllocSize = offsetof(RopeRefCountString, Data) + AllocChunkSize;
|
||||
AllocBuffer = reinterpret_cast<RopeRefCountString *>(new char[AllocSize]);
|
||||
AllocBuffer->RefCount = 0;
|
||||
memcpy(AllocBuffer->Data, Start, Len);
|
||||
RopeRefCountString *Res =
|
||||
reinterpret_cast<RopeRefCountString *>(new char[AllocSize]);
|
||||
Res->RefCount = 0;
|
||||
memcpy(Res->Data, Start, Len);
|
||||
AllocBuffer = Res;
|
||||
AllocOffs = Len;
|
||||
|
||||
// Start out the new allocation with a refcount of 1, since we have an
|
||||
// internal reference to it.
|
||||
AllocBuffer->addRef();
|
||||
return RopePiece(AllocBuffer, 0, Len);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue