summaryrefslogtreecommitdiff
path: root/absl/strings/cord.cc
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2020-07-30 13:58:50 -0700
committerGravatar Mark Barolak <mbar@google.com>2020-07-31 11:30:59 -0400
commit184cf2524101310a0ba315c743e82cf45fccccf8 (patch)
tree61f5cb2de5da31efd024ce2a49f2d304352b33ba /absl/strings/cord.cc
parent82302f1e05d6daed93bdd77e8951b529b0ebfcf6 (diff)
Export of internal Abseil changes
-- 587e6db882749fa7faa12815e614afab04d218b9 by Derek Mauro <dmauro@google.com>: Use attribute detection for other sanitizer related attributes PiperOrigin-RevId: 324077073 -- 3ee55e4935b4235516b1fcac3c55945e510f7afc by Evan Brown <ezb@google.com>: Simplify CordRepExternal allocation/deallocation. I think this can save some memory when `Releaser` is empty and when on platforms where alignof(CordRepExternal) < (default `::operator new` alignment). We no longer need the API requirement that alignof(Releaser) <= (default `::operator new` alignment). Also remove another static_assert from a TODO in cord_internal.h and fix some warnings about calling std::move on a forwarding reference. PiperOrigin-RevId: 324053720 -- 9fc78436565eb3b204d4aa425ee3773354392f45 by Derek Mauro <dmauro@google.com>: Use auto-detected sanitizer attributes for ASAN, MSAN, and TSAN builds PiperOrigin-RevId: 323831461 GitOrigin-RevId: 587e6db882749fa7faa12815e614afab04d218b9 Change-Id: Ie0e4a2846d7f66988a2d81a5e50721b62fdb3d6d
Diffstat (limited to 'absl/strings/cord.cc')
-rw-r--r--absl/strings/cord.cc74
1 files changed, 11 insertions, 63 deletions
diff --git a/absl/strings/cord.cc b/absl/strings/cord.cc
index 920dcc67..763dcc45 100644
--- a/absl/strings/cord.cc
+++ b/absl/strings/cord.cc
@@ -61,48 +61,6 @@ enum CordRepKind {
FLAT = 3,
};
-namespace {
-
-// Type used with std::allocator for allocating and deallocating
-// `CordRepExternal`. std::allocator is used because it opaquely handles the
-// different new / delete overloads available on a given platform.
-struct alignas(absl::cord_internal::ExternalRepAlignment()) ExternalAllocType {
- unsigned char value[absl::cord_internal::ExternalRepAlignment()];
-};
-
-// Returns the number of objects to pass in to std::allocator<ExternalAllocType>
-// allocate() and deallocate() to create enough room for `CordRepExternal` with
-// `releaser_size` bytes on the end.
-constexpr size_t GetExternalAllocNumObjects(size_t releaser_size) {
- // Be sure to round up since `releaser_size` could be smaller than
- // `sizeof(ExternalAllocType)`.
- return (sizeof(CordRepExternal) + releaser_size + sizeof(ExternalAllocType) -
- 1) /
- sizeof(ExternalAllocType);
-}
-
-// Allocates enough memory for `CordRepExternal` and a releaser with size
-// `releaser_size` bytes.
-void* AllocateExternal(size_t releaser_size) {
- return std::allocator<ExternalAllocType>().allocate(
- GetExternalAllocNumObjects(releaser_size));
-}
-
-// Deallocates the memory for a `CordRepExternal` assuming it was allocated with
-// a releaser of given size and alignment.
-void DeallocateExternal(CordRepExternal* p, size_t releaser_size) {
- std::allocator<ExternalAllocType>().deallocate(
- reinterpret_cast<ExternalAllocType*>(p),
- GetExternalAllocNumObjects(releaser_size));
-}
-
-// Returns a pointer to the type erased releaser for the given CordRepExternal.
-void* GetExternalReleaser(CordRepExternal* rep) {
- return rep + 1;
-}
-
-} // namespace
-
namespace cord_internal {
inline CordRepConcat* CordRep::concat() {
@@ -304,11 +262,7 @@ static void UnrefInternal(CordRep* rep) {
}
} else if (rep->tag == EXTERNAL) {
CordRepExternal* rep_external = rep->external();
- absl::string_view data(rep_external->base, rep->length);
- void* releaser = GetExternalReleaser(rep_external);
- size_t releaser_size = rep_external->releaser_invoker(releaser, data);
- rep_external->~CordRepExternal();
- DeallocateExternal(rep_external, releaser_size);
+ rep_external->releaser_invoker(rep_external);
rep = nullptr;
} else if (rep->tag == SUBSTRING) {
CordRepSubstring* rep_substring = rep->substring();
@@ -458,18 +412,12 @@ static CordRep* NewTree(const char* data,
namespace cord_internal {
-ExternalRepReleaserPair NewExternalWithUninitializedReleaser(
- absl::string_view data, ExternalReleaserInvoker invoker,
- size_t releaser_size) {
+void InitializeCordRepExternal(absl::string_view data, CordRepExternal* rep) {
assert(!data.empty());
-
- void* raw_rep = AllocateExternal(releaser_size);
- auto* rep = new (raw_rep) CordRepExternal();
rep->length = data.size();
rep->tag = EXTERNAL;
rep->base = data.data();
- rep->releaser_invoker = invoker;
- return {VerifyTree(rep), GetExternalReleaser(rep)};
+ VerifyTree(rep);
}
} // namespace cord_internal
@@ -721,12 +669,12 @@ Cord::Cord(T&& src) {
std::string data;
};
const absl::string_view original_data = src;
- CordRepExternal* rep =
- static_cast<CordRepExternal*>(absl::cord_internal::NewExternalRep(
- original_data, StringReleaser{std::move(src)}));
+ auto* rep = static_cast<
+ ::absl::cord_internal::CordRepExternalImpl<StringReleaser>*>(
+ absl::cord_internal::NewExternalRep(
+ original_data, StringReleaser{std::forward<T>(src)}));
// Moving src may have invalidated its data pointer, so adjust it.
- rep->base =
- static_cast<StringReleaser*>(GetExternalReleaser(rep))->data.data();
+ rep->base = rep->template get<0>().data.data();
contents_.set_tree(rep);
}
}
@@ -775,7 +723,7 @@ Cord& Cord::operator=(T&& src) {
if (src.size() <= kMaxBytesToCopy) {
*this = absl::string_view(src);
} else {
- *this = Cord(std::move(src));
+ *this = Cord(std::forward<T>(src));
}
return *this;
}
@@ -898,7 +846,7 @@ void Cord::Append(T&& src) {
if (src.size() <= kMaxBytesToCopy) {
Append(absl::string_view(src));
} else {
- Append(Cord(std::move(src)));
+ Append(Cord(std::forward<T>(src)));
}
}
@@ -938,7 +886,7 @@ inline void Cord::Prepend(T&& src) {
if (src.size() <= kMaxBytesToCopy) {
Prepend(absl::string_view(src));
} else {
- Prepend(Cord(std::move(src)));
+ Prepend(Cord(std::forward<T>(src)));
}
}