Move data pointer for move operator=
The original implementation just moved each element over to
the destination Array. It maybe that it was discovered that
moving the pointer didn't pay off. I don't know if this was
tested or not.
Move the pointer from that to this if possible. Otherwise,
move the elements one-by-one.
Change-Id: I8c1dae1a79e46bb230c8eb84be723e0c05ba7459
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/605718
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
diff --git a/include/private/SkTArray.h b/include/private/SkTArray.h
index 9af1e2f..0e935a2 100644
--- a/include/private/SkTArray.h
+++ b/include/private/SkTArray.h
@@ -59,15 +59,14 @@
SkTArray(SkTArray&& that) {
if (that.fOwnMemory) {
- fData = that.fData;
- fSize = that.fSize;
- fCapacity = that.fCapacity;
- fOwnMemory = true;
+ fData = std::exchange(that.fData, nullptr);
+ fSize = std::exchange(that.fSize, 0);
- that.fData = nullptr;
- that.fSize = 0;
+ // exchange does not work for bit fields.
+ fCapacity = that.fCapacity;
that.fCapacity = 0;
- that.fOwnMemory = true;
+
+ fOwnMemory = true;
} else {
this->init(that.fSize);
that.move(fData);
@@ -103,10 +102,25 @@
SkTArray& operator=(SkTArray&& that) {
if (this != &that) {
this->clear();
- this->checkRealloc(that.size(), kExactFit);
- fSize = that.fSize;
- that.move(fData);
- that.fSize = 0;
+ if (that.fOwnMemory) {
+ // The storage is on the heap, so move the data pointer.
+ if (fOwnMemory) {
+ sk_free(fData);
+ }
+
+ fData = std::exchange(that.fData, nullptr);
+
+ // Can't use exchange with bitfields.
+ fCapacity = that.fCapacity;
+ that.fCapacity = 0;
+
+ fOwnMemory = true;
+ } else {
+ // The data is stored inline in that, so move it element-by-element.
+ this->checkRealloc(that.size(), kExactFit);
+ that.move(fData);
+ }
+ fSize = std::exchange(that.fSize, 0);
}
return *this;
}