aboutsummaryrefslogtreecommitdiff
path: root/absl/strings/internal/cord_internal.h
diff options
context:
space:
mode:
Diffstat (limited to 'absl/strings/internal/cord_internal.h')
-rw-r--r--absl/strings/internal/cord_internal.h64
1 files changed, 19 insertions, 45 deletions
diff --git a/absl/strings/internal/cord_internal.h b/absl/strings/internal/cord_internal.h
index 20dd008c..8744540e 100644
--- a/absl/strings/internal/cord_internal.h
+++ b/absl/strings/internal/cord_internal.h
@@ -55,24 +55,15 @@ struct CordRepExternal;
struct CordRepFlat;
struct CordRepSubstring;
struct CordRepCrc;
-class CordRepRing;
class CordRepBtree;
class CordzInfo;
// Default feature enable states for cord ring buffers
-enum CordFeatureDefaults {
- kCordEnableRingBufferDefault = false,
- kCordShallowSubcordsDefault = false
-};
+enum CordFeatureDefaults { kCordShallowSubcordsDefault = false };
-extern std::atomic<bool> cord_ring_buffer_enabled;
extern std::atomic<bool> shallow_subcords_enabled;
-inline void enable_cord_ring_buffer(bool enable) {
- cord_ring_buffer_enabled.store(enable, std::memory_order_relaxed);
-}
-
inline void enable_shallow_subcords(bool enable) {
shallow_subcords_enabled.store(enable, std::memory_order_relaxed);
}
@@ -110,8 +101,16 @@ inline void SmallMemmove(char* dst, const char* src, size_t n) {
if (nullify_tail) {
memset(dst + 7, 0, 8);
}
+ // GCC 12 has a false-positive -Wstringop-overflow warning here.
+#if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(12, 0)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstringop-overflow"
+#endif
memcpy(dst, &buf1, 8);
memcpy(dst + n - 8, &buf2, 8);
+#if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(12, 0)
+#pragma GCC diagnostic pop
+#endif
} else if (n >= 4) {
uint32_t buf1;
uint32_t buf2;
@@ -158,18 +157,18 @@ class RefcountAndFlags {
// false. Always returns false when the immortal bit is set.
inline bool Decrement() {
int32_t refcount = count_.load(std::memory_order_acquire);
- assert((refcount & kRefcountMask) > 0 || refcount & kImmortalFlag);
+ assert(refcount > 0 || refcount & kImmortalFlag);
return refcount != kRefIncrement &&
- (count_.fetch_sub(kRefIncrement, std::memory_order_acq_rel) &
- kHighRefcountMask) != 0;
+ count_.fetch_sub(kRefIncrement, std::memory_order_acq_rel) !=
+ kRefIncrement;
}
// Same as Decrement but expect that refcount is greater than 1.
inline bool DecrementExpectHighRefcount() {
int32_t refcount =
count_.fetch_sub(kRefIncrement, std::memory_order_acq_rel);
- assert((refcount & kRefcountMask) > 0 || refcount & kImmortalFlag);
- return (refcount & kHighRefcountMask) != 0;
+ assert(refcount > 0 || refcount & kImmortalFlag);
+ return refcount != kRefIncrement;
}
// Returns the current reference count using acquire semantics.
@@ -185,10 +184,9 @@ class RefcountAndFlags {
// This call performs the test for a reference count of one, and
// performs the memory barrier needed for the owning thread
// to act on the object, knowing that it has exclusive access to the
- // object. Always returns false when the immortal bit is set.
+ // object. Always returns false when the immortal bit is set.
inline bool IsOne() {
- return (count_.load(std::memory_order_acquire) & kRefcountMask) ==
- kRefIncrement;
+ return count_.load(std::memory_order_acquire) == kRefIncrement;
}
bool IsImmortal() const {
@@ -196,32 +194,15 @@ class RefcountAndFlags {
}
private:
- // We reserve the bottom bits for flags.
+ // We reserve the bottom bit for flag.
// kImmortalBit indicates that this entity should never be collected; it is
// used for the StringConstant constructor to avoid collecting immutable
// constant cords.
- // kReservedFlag is reserved for future use.
enum Flags {
- kNumFlags = 2,
+ kNumFlags = 1,
kImmortalFlag = 0x1,
- kReservedFlag = 0x2,
kRefIncrement = (1 << kNumFlags),
-
- // Bitmask to use when checking refcount by equality. This masks out
- // all flags except kImmortalFlag, which is part of the refcount for
- // purposes of equality. (A refcount of 0 or 1 does not count as 0 or 1
- // if the immortal bit is set.)
- kRefcountMask = ~kReservedFlag,
-
- // Bitmask to use when checking if refcount is equal to 1 and not
- // immortal when decrementing the refcount. This masks out kRefIncrement and
- // all flags except kImmortalFlag. If the masked RefcountAndFlags is 0, we
- // assume the refcount is equal to 1, since we know it's not immortal and
- // not greater than 1. If the masked RefcountAndFlags is not 0, we can
- // assume the refcount is not equal to 1 since either a higher bit in the
- // refcount is set, or kImmortal is set.
- kHighRefcountMask = kRefcountMask & ~kRefIncrement,
};
std::atomic<int32_t> count_;
@@ -233,7 +214,7 @@ enum CordRepKind {
SUBSTRING = 1,
CRC = 2,
BTREE = 3,
- RING = 4,
+ UNUSED_4 = 4,
EXTERNAL = 5,
// We have different tags for different sized flat arrays,
@@ -252,12 +233,8 @@ enum CordRepKind {
// There are various locations where we want to check if some rep is a 'plain'
// data edge, i.e. an external or flat rep. By having FLAT == EXTERNAL + 1, we
// can perform this check in a single branch as 'tag >= EXTERNAL'
-// Likewise, we have some locations where we check for 'ring or external/flat',
-// so likewise align RING to EXTERNAL.
// Note that we can leave this optimization to the compiler. The compiler will
// DTRT when it sees a condition like `tag == EXTERNAL || tag >= FLAT`.
-static_assert(RING == BTREE + 1, "BTREE and RING not consecutive");
-static_assert(EXTERNAL == RING + 1, "BTREE and EXTERNAL not consecutive");
static_assert(FLAT == EXTERNAL + 1, "EXTERNAL and FLAT not consecutive");
struct CordRep {
@@ -301,15 +278,12 @@ struct CordRep {
// # LINT.ThenChange(cord_rep_btree.h:copy_raw)
// Returns true if this instance's tag matches the requested type.
- constexpr bool IsRing() const { return tag == RING; }
constexpr bool IsSubstring() const { return tag == SUBSTRING; }
constexpr bool IsCrc() const { return tag == CRC; }
constexpr bool IsExternal() const { return tag == EXTERNAL; }
constexpr bool IsFlat() const { return tag >= FLAT; }
constexpr bool IsBtree() const { return tag == BTREE; }
- inline CordRepRing* ring();
- inline const CordRepRing* ring() const;
inline CordRepSubstring* substring();
inline const CordRepSubstring* substring() const;
inline CordRepCrc* crc();