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
|
#ifndef LLVM_CLANG_REWRITE_CORE_REWRITEROPE_H
|
||||||
#define 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/ADT/StringRef.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
@ -34,11 +35,10 @@ namespace clang {
|
||||||
unsigned RefCount;
|
unsigned RefCount;
|
||||||
char Data[1]; // Variable sized.
|
char Data[1]; // Variable sized.
|
||||||
|
|
||||||
void addRef() {
|
void Retain() { ++RefCount; }
|
||||||
++RefCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dropRef() {
|
void Release() {
|
||||||
|
assert(RefCount > 0 && "Reference count is already zero.");
|
||||||
if (--RefCount == 0)
|
if (--RefCount == 0)
|
||||||
delete [] (char*)this;
|
delete [] (char*)this;
|
||||||
}
|
}
|
||||||
|
@ -57,39 +57,15 @@ namespace clang {
|
||||||
/// that both refer to the same underlying RopeRefCountString (just with
|
/// that both refer to the same underlying RopeRefCountString (just with
|
||||||
/// different offsets) which is a nice constant time operation.
|
/// different offsets) which is a nice constant time operation.
|
||||||
struct RopePiece {
|
struct RopePiece {
|
||||||
RopeRefCountString *StrData;
|
llvm::IntrusiveRefCntPtr<RopeRefCountString> StrData;
|
||||||
unsigned StartOffs;
|
unsigned StartOffs;
|
||||||
unsigned EndOffs;
|
unsigned EndOffs;
|
||||||
|
|
||||||
RopePiece() : StrData(nullptr), StartOffs(0), EndOffs(0) {}
|
RopePiece() : StrData(nullptr), StartOffs(0), EndOffs(0) {}
|
||||||
|
|
||||||
RopePiece(RopeRefCountString *Str, unsigned Start, unsigned End)
|
RopePiece(llvm::IntrusiveRefCntPtr<RopeRefCountString> Str, unsigned Start,
|
||||||
: StrData(Str), StartOffs(Start), EndOffs(End) {
|
unsigned End)
|
||||||
if (StrData)
|
: StrData(std::move(Str)), StartOffs(Start), EndOffs(End) {}
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char &operator[](unsigned Offset) const {
|
const char &operator[](unsigned Offset) const {
|
||||||
return StrData->Data[Offset+StartOffs];
|
return StrData->Data[Offset+StartOffs];
|
||||||
|
@ -191,7 +167,7 @@ class RewriteRope {
|
||||||
|
|
||||||
/// We allocate space for string data out of a buffer of size AllocChunkSize.
|
/// We allocate space for string data out of a buffer of size AllocChunkSize.
|
||||||
/// This keeps track of how much space is left.
|
/// This keeps track of how much space is left.
|
||||||
RopeRefCountString *AllocBuffer;
|
llvm::IntrusiveRefCntPtr<RopeRefCountString> AllocBuffer;
|
||||||
unsigned AllocOffs;
|
unsigned AllocOffs;
|
||||||
enum { AllocChunkSize = 4080 };
|
enum { AllocChunkSize = 4080 };
|
||||||
|
|
||||||
|
@ -201,12 +177,6 @@ public:
|
||||||
: Chunks(RHS.Chunks), AllocBuffer(nullptr), AllocOffs(AllocChunkSize) {
|
: 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 iterator;
|
||||||
typedef RopePieceBTree::iterator const_iterator;
|
typedef RopePieceBTree::iterator const_iterator;
|
||||||
iterator begin() const { return Chunks.begin(); }
|
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
|
// 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.
|
// Make a new chunk and share it with later allocations.
|
||||||
|
|
||||||
if (AllocBuffer)
|
|
||||||
AllocBuffer->dropRef();
|
|
||||||
|
|
||||||
unsigned AllocSize = offsetof(RopeRefCountString, Data) + AllocChunkSize;
|
unsigned AllocSize = offsetof(RopeRefCountString, Data) + AllocChunkSize;
|
||||||
AllocBuffer = reinterpret_cast<RopeRefCountString *>(new char[AllocSize]);
|
RopeRefCountString *Res =
|
||||||
AllocBuffer->RefCount = 0;
|
reinterpret_cast<RopeRefCountString *>(new char[AllocSize]);
|
||||||
memcpy(AllocBuffer->Data, Start, Len);
|
Res->RefCount = 0;
|
||||||
|
memcpy(Res->Data, Start, Len);
|
||||||
|
AllocBuffer = Res;
|
||||||
AllocOffs = Len;
|
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);
|
return RopePiece(AllocBuffer, 0, Len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue