aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkString.cpp
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2017-10-05 11:28:20 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-10-05 11:28:35 +0000
commit01f8e41c1368bfd60d3f011cb5aa9cc478799e63 (patch)
treea6188765164358d4eb742c6ef7c05ae1d57c653c /src/core/SkString.cpp
parent1ea81e766e1a12d5498c481ff8cc5225da0b4860 (diff)
Revert "Clean up SkString reference counting a bit."
This reverts commit a910c847e9d04e183e9e610902cbd363c8488196. Reason for revert: Compilation failure on Ubuntu14 bots ../../../../../work/skia/src/core/SkString.cpp:200:55: error: could not convert ‘{0, {0}, 0}’ from ‘<brace-enclosed initializer list>’ to ‘const SkString::Rec’ const SkString::Rec SkString::gEmptyRec = { 0, {0}, 0 }; Original change's description: > Clean up SkString reference counting a bit. > > BUG=skia:7107 > > Change-Id: I47072bf31b902c79dbb850179ff6d35940de3e63 > Reviewed-on: https://skia-review.googlesource.com/54720 > Reviewed-by: Ben Wagner <bungeman@google.com> > Commit-Queue: Ben Wagner <bungeman@google.com> TBR=mtklein@google.com,bungeman@google.com,reed@google.com Change-Id: I6ec327511e8e1c1fd7e4c1bd5839c0547d4ab609 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: skia:7107 Reviewed-on: https://skia-review.googlesource.com/55640 Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src/core/SkString.cpp')
-rw-r--r--src/core/SkString.cpp70
1 files changed, 39 insertions, 31 deletions
diff --git a/src/core/SkString.cpp b/src/core/SkString.cpp
index 23ef8f19f4..d0e3c12cbe 100644
--- a/src/core/SkString.cpp
+++ b/src/core/SkString.cpp
@@ -220,7 +220,7 @@ static size_t check_add32(size_t base, size_t extra) {
return extra;
}
-sk_sp<SkString::Rec> SkString::Rec::Make(const char text[], size_t len) {
+SkString::Rec* SkString::AllocRec(const char text[], size_t len) {
Rec* rec;
if (0 == len) {
@@ -237,29 +237,15 @@ sk_sp<SkString::Rec> SkString::Rec::Make(const char text[], size_t len) {
}
rec->data()[len] = 0;
}
- return sk_sp<SkString::Rec>(rec);
+ return rec;
}
-void SkString::Rec::ref() const {
- if (this == &SkString::gEmptyRec) {
- return;
- }
- // No barrier required.
- (void)this->fRefCnt.fetch_add(+1, std::memory_order_relaxed);
-}
-
-void SkString::Rec::unref() const {
- if (this == &SkString::gEmptyRec) {
- return;
- }
- SkASSERT(this->fRefCnt.load(std::memory_order_relaxed) > 0);
- if (1 == this->fRefCnt.fetch_add(-1, std::memory_order_acq_rel)) {
- sk_free(const_cast<SkString::Rec*>(this));
+SkString::Rec* SkString::RefRec(Rec* src) {
+ if (src != &gEmptyRec) {
+ // No barrier required.
+ (void)src->fRefCnt.fetch_add(+1, std::memory_order_relaxed);
}
-}
-
-bool SkString::Rec::unique() const {
- return fRefCnt.load(std::memory_order_acquire) == 1;
+ return src;
}
#ifdef SK_DEBUG
@@ -269,7 +255,7 @@ void SkString::validate() const {
SkASSERT(0 == gEmptyRec.fRefCnt.load(std::memory_order_relaxed));
SkASSERT(0 == gEmptyRec.data()[0]);
- if (fRec.get() != &gEmptyRec) {
+ if (fRec != &gEmptyRec) {
SkASSERT(fRec->fLength > 0);
SkASSERT(fRec->fRefCnt.load(std::memory_order_relaxed) > 0);
SkASSERT(0 == fRec->data()[fRec->fLength]);
@@ -283,34 +269,41 @@ SkString::SkString() : fRec(const_cast<Rec*>(&gEmptyRec)) {
}
SkString::SkString(size_t len) {
- fRec = Rec::Make(nullptr, len);
+ fRec = AllocRec(nullptr, len);
}
SkString::SkString(const char text[]) {
size_t len = text ? strlen(text) : 0;
- fRec = Rec::Make(text, len);
+ fRec = AllocRec(text, len);
}
SkString::SkString(const char text[], size_t len) {
- fRec = Rec::Make(text, len);
+ fRec = AllocRec(text, len);
}
SkString::SkString(const SkString& src) {
src.validate();
- fRec = src.fRec;
+ fRec = RefRec(src.fRec);
}
SkString::SkString(SkString&& src) {
src.validate();
- fRec = std::move(src.fRec);
- src.fRec.reset(const_cast<Rec*>(&gEmptyRec));
+ fRec = src.fRec;
+ src.fRec = const_cast<Rec*>(&gEmptyRec);
}
SkString::~SkString() {
this->validate();
+
+ if (fRec->fLength) {
+ SkASSERT(fRec->fRefCnt.load(std::memory_order_relaxed) > 0);
+ if (1 == fRec->fRefCnt.fetch_add(-1, std::memory_order_acq_rel)) {
+ sk_free(fRec);
+ }
+ }
}
bool SkString::equals(const SkString& src) const {
@@ -357,7 +350,15 @@ SkString& SkString::operator=(const char text[]) {
void SkString::reset() {
this->validate();
- fRec.reset(const_cast<Rec*>(&gEmptyRec));
+
+ if (fRec->fLength) {
+ SkASSERT(fRec->fRefCnt.load(std::memory_order_relaxed) > 0);
+ if (1 == fRec->fRefCnt.fetch_add(-1, std::memory_order_acq_rel)) {
+ sk_free(fRec);
+ }
+ }
+
+ fRec = const_cast<Rec*>(&gEmptyRec);
}
char* SkString::writable_str() {
@@ -365,7 +366,14 @@ char* SkString::writable_str() {
if (fRec->fLength) {
if (!fRec->unique()) {
- fRec = Rec::Make(fRec->data(), fRec->fLength);
+ Rec* rec = AllocRec(fRec->data(), fRec->fLength);
+ if (1 == fRec->fRefCnt.fetch_add(-1, std::memory_order_acq_rel)) {
+ // In this case after our check of fRecCnt > 1, we suddenly
+ // did become the only owner, so now we have two copies of the
+ // data (fRec and rec), so we need to delete one of them.
+ sk_free(fRec);
+ }
+ fRec = rec;
}
}
return fRec->data();
@@ -625,7 +633,7 @@ void SkString::swap(SkString& other) {
this->validate();
other.validate();
- SkTSwap(fRec, other.fRec);
+ SkTSwap<Rec*>(fRec, other.fRec);
}
///////////////////////////////////////////////////////////////////////////////