修改pods
This commit is contained in:
10
Pods/abseil/absl/strings/internal/charconv_bigint.h
generated
10
Pods/abseil/absl/strings/internal/charconv_bigint.h
generated
@@ -109,7 +109,17 @@ class BigUnsigned {
|
||||
size_ = (std::min)(size_ + word_shift, max_words);
|
||||
count %= 32;
|
||||
if (count == 0) {
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=warray-bounds
|
||||
// shows a lot of bogus -Warray-bounds warnings under GCC.
|
||||
// This is not the only one in Abseil.
|
||||
#if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(14, 0)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Warray-bounds"
|
||||
#endif
|
||||
std::copy_backward(words_, words_ + size_ - word_shift, words_ + size_);
|
||||
#if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(14, 0)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
} else {
|
||||
for (int i = (std::min)(size_, max_words - 1); i > word_shift; --i) {
|
||||
words_[i] = (words_[i - word_shift] << count) |
|
||||
|
||||
38
Pods/abseil/absl/strings/internal/cord_internal.h
generated
38
Pods/abseil/absl/strings/internal/cord_internal.h
generated
@@ -85,7 +85,7 @@ enum Constants {
|
||||
};
|
||||
|
||||
// Emits a fatal error "Unexpected node type: xyz" and aborts the program.
|
||||
ABSL_ATTRIBUTE_NORETURN void LogFatalNodeType(CordRep* rep);
|
||||
[[noreturn]] void LogFatalNodeType(CordRep* rep);
|
||||
|
||||
// Fast implementation of memmove for up to 15 bytes. This implementation is
|
||||
// safe for overlapping regions. If nullify_tail is true, the destination is
|
||||
@@ -259,7 +259,7 @@ struct CordRep {
|
||||
// on the specific layout of these fields. Notably: the non-trivial field
|
||||
// `refcount` being preceded by `length`, and being tailed by POD data
|
||||
// members only.
|
||||
// # LINT.IfChange
|
||||
// LINT.IfChange
|
||||
size_t length;
|
||||
RefcountAndFlags refcount;
|
||||
// If tag < FLAT, it represents CordRepKind and indicates the type of node.
|
||||
@@ -275,7 +275,7 @@ struct CordRep {
|
||||
// allocate room for these in the derived class, as not all compilers reuse
|
||||
// padding space from the base class (clang and gcc do, MSVC does not, etc)
|
||||
uint8_t storage[3];
|
||||
// # LINT.ThenChange(cord_rep_btree.h:copy_raw)
|
||||
// LINT.ThenChange(cord_rep_btree.h:copy_raw)
|
||||
|
||||
// Returns true if this instance's tag matches the requested type.
|
||||
constexpr bool IsSubstring() const { return tag == SUBSTRING; }
|
||||
@@ -352,18 +352,19 @@ struct CordRepExternal : public CordRep {
|
||||
static void Delete(CordRep* rep);
|
||||
};
|
||||
|
||||
struct Rank1 {};
|
||||
struct Rank0 : Rank1 {};
|
||||
// Use go/ranked-overloads for dispatching.
|
||||
struct Rank0 {};
|
||||
struct Rank1 : Rank0 {};
|
||||
|
||||
template <typename Releaser, typename = ::absl::base_internal::invoke_result_t<
|
||||
Releaser, absl::string_view>>
|
||||
void InvokeReleaser(Rank0, Releaser&& releaser, absl::string_view data) {
|
||||
void InvokeReleaser(Rank1, Releaser&& releaser, absl::string_view data) {
|
||||
::absl::base_internal::invoke(std::forward<Releaser>(releaser), data);
|
||||
}
|
||||
|
||||
template <typename Releaser,
|
||||
typename = ::absl::base_internal::invoke_result_t<Releaser>>
|
||||
void InvokeReleaser(Rank1, Releaser&& releaser, absl::string_view) {
|
||||
void InvokeReleaser(Rank0, Releaser&& releaser, absl::string_view) {
|
||||
::absl::base_internal::invoke(std::forward<Releaser>(releaser));
|
||||
}
|
||||
|
||||
@@ -381,7 +382,7 @@ struct CordRepExternalImpl
|
||||
}
|
||||
|
||||
~CordRepExternalImpl() {
|
||||
InvokeReleaser(Rank0{}, std::move(this->template get<0>()),
|
||||
InvokeReleaser(Rank1{}, std::move(this->template get<0>()),
|
||||
absl::string_view(base, length));
|
||||
}
|
||||
|
||||
@@ -398,7 +399,6 @@ inline CordRepSubstring* CordRepSubstring::Create(CordRep* child, size_t pos,
|
||||
assert(pos < child->length);
|
||||
assert(n <= child->length - pos);
|
||||
|
||||
// TODO(b/217376272): Harden internal logic.
|
||||
// Move to strategical places inside the Cord logic and make this an assert.
|
||||
if (ABSL_PREDICT_FALSE(!(child->IsExternal() || child->IsFlat()))) {
|
||||
LogFatalNodeType(child);
|
||||
@@ -520,6 +520,7 @@ class InlineData {
|
||||
|
||||
constexpr InlineData(const InlineData& rhs) noexcept;
|
||||
InlineData& operator=(const InlineData& rhs) noexcept;
|
||||
friend void swap(InlineData& lhs, InlineData& rhs) noexcept;
|
||||
|
||||
friend bool operator==(const InlineData& lhs, const InlineData& rhs) {
|
||||
#ifdef ABSL_INTERNAL_CORD_HAVE_SANITIZER
|
||||
@@ -770,6 +771,12 @@ class InlineData {
|
||||
char data[kMaxInline + 1];
|
||||
AsTree as_tree;
|
||||
};
|
||||
|
||||
// TODO(b/145829486): see swap(InlineData, InlineData) for more info.
|
||||
inline void SwapValue(Rep rhs, Rep& refrhs) {
|
||||
memcpy(&refrhs, this, sizeof(*this));
|
||||
memcpy(this, &rhs, sizeof(*this));
|
||||
}
|
||||
};
|
||||
|
||||
// Private implementation of `Compare()`
|
||||
@@ -884,6 +891,19 @@ inline void CordRep::Unref(CordRep* rep) {
|
||||
}
|
||||
}
|
||||
|
||||
inline void swap(InlineData& lhs, InlineData& rhs) noexcept {
|
||||
lhs.unpoison();
|
||||
rhs.unpoison();
|
||||
// TODO(b/145829486): `std::swap(lhs.rep_, rhs.rep_)` results in bad codegen
|
||||
// on clang, spilling the temporary swap value on the stack. Since `Rep` is
|
||||
// trivial, we can make clang DTRT by calling a hand-rolled `SwapValue` where
|
||||
// we pass `rhs` both by value (register allocated) and by reference. The IR
|
||||
// then folds and inlines correctly into an optimized swap without spill.
|
||||
lhs.rep_.SwapValue(rhs.rep_, rhs.rep_);
|
||||
rhs.poison();
|
||||
lhs.poison();
|
||||
}
|
||||
|
||||
} // namespace cord_internal
|
||||
|
||||
ABSL_NAMESPACE_END
|
||||
|
||||
@@ -684,14 +684,14 @@ inline CordRepBtree* CordRepBtree::CopyRaw(size_t new_length) const {
|
||||
// except `refcount` is trivially copyable, and the compiler does not
|
||||
// efficiently coalesce member-wise copy of these members.
|
||||
// See https://gcc.godbolt.org/z/qY8zsca6z
|
||||
// # LINT.IfChange(copy_raw)
|
||||
// LINT.IfChange(copy_raw)
|
||||
tree->length = new_length;
|
||||
uint8_t* dst = &tree->tag;
|
||||
const uint8_t* src = &tag;
|
||||
const ptrdiff_t offset = src - reinterpret_cast<const uint8_t*>(this);
|
||||
memcpy(dst, src, sizeof(CordRepBtree) - static_cast<size_t>(offset));
|
||||
return tree;
|
||||
// # LINT.ThenChange()
|
||||
// LINT.ThenChange()
|
||||
}
|
||||
|
||||
inline CordRepBtree* CordRepBtree::Copy() const {
|
||||
|
||||
32
Pods/abseil/absl/strings/internal/cordz_functions.cc
generated
32
Pods/abseil/absl/strings/internal/cordz_functions.cc
generated
@@ -40,13 +40,15 @@ std::atomic<int> g_cordz_mean_interval(50000);
|
||||
// Special negative 'not initialized' per thread value for cordz_next_sample.
|
||||
static constexpr int64_t kInitCordzNextSample = -1;
|
||||
|
||||
ABSL_CONST_INIT thread_local int64_t cordz_next_sample = kInitCordzNextSample;
|
||||
ABSL_CONST_INIT thread_local SamplingState cordz_next_sample = {
|
||||
kInitCordzNextSample, 1};
|
||||
|
||||
// kIntervalIfDisabled is the number of profile-eligible events need to occur
|
||||
// before the code will confirm that cordz is still disabled.
|
||||
constexpr int64_t kIntervalIfDisabled = 1 << 16;
|
||||
|
||||
ABSL_ATTRIBUTE_NOINLINE bool cordz_should_profile_slow() {
|
||||
ABSL_ATTRIBUTE_NOINLINE int64_t
|
||||
cordz_should_profile_slow(SamplingState& state) {
|
||||
|
||||
thread_local absl::profiling_internal::ExponentialBiased
|
||||
exponential_biased_generator;
|
||||
@@ -55,30 +57,34 @@ ABSL_ATTRIBUTE_NOINLINE bool cordz_should_profile_slow() {
|
||||
// Check if we disabled profiling. If so, set the next sample to a "large"
|
||||
// number to minimize the overhead of the should_profile codepath.
|
||||
if (mean_interval <= 0) {
|
||||
cordz_next_sample = kIntervalIfDisabled;
|
||||
return false;
|
||||
state = {kIntervalIfDisabled, kIntervalIfDisabled};
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check if we're always sampling.
|
||||
if (mean_interval == 1) {
|
||||
cordz_next_sample = 1;
|
||||
return true;
|
||||
state = {1, 1};
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (cordz_next_sample <= 0) {
|
||||
if (cordz_next_sample.next_sample <= 0) {
|
||||
// If first check on current thread, check cordz_should_profile()
|
||||
// again using the created (initial) stride in cordz_next_sample.
|
||||
const bool initialized = cordz_next_sample != kInitCordzNextSample;
|
||||
cordz_next_sample = exponential_biased_generator.GetStride(mean_interval);
|
||||
return initialized || cordz_should_profile();
|
||||
const bool initialized =
|
||||
cordz_next_sample.next_sample != kInitCordzNextSample;
|
||||
auto old_stride = state.sample_stride;
|
||||
auto stride = exponential_biased_generator.GetStride(mean_interval);
|
||||
state = {stride, stride};
|
||||
bool should_sample = initialized || cordz_should_profile() > 0;
|
||||
return should_sample ? old_stride : 0;
|
||||
}
|
||||
|
||||
--cordz_next_sample;
|
||||
return false;
|
||||
--state.next_sample;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cordz_set_next_sample_for_testing(int64_t next_sample) {
|
||||
cordz_next_sample = next_sample;
|
||||
cordz_next_sample = {next_sample, next_sample};
|
||||
}
|
||||
|
||||
#endif // ABSL_INTERNAL_CORDZ_ENABLED
|
||||
|
||||
32
Pods/abseil/absl/strings/internal/cordz_functions.h
generated
32
Pods/abseil/absl/strings/internal/cordz_functions.h
generated
@@ -41,23 +41,33 @@ void set_cordz_mean_interval(int32_t mean_interval);
|
||||
|
||||
#ifdef ABSL_INTERNAL_CORDZ_ENABLED
|
||||
|
||||
struct SamplingState {
|
||||
int64_t next_sample;
|
||||
int64_t sample_stride;
|
||||
};
|
||||
|
||||
// cordz_next_sample is the number of events until the next sample event. If
|
||||
// the value is 1 or less, the code will check on the next event if cordz is
|
||||
// enabled, and if so, will sample the Cord. cordz is only enabled when we can
|
||||
// use thread locals.
|
||||
ABSL_CONST_INIT extern thread_local int64_t cordz_next_sample;
|
||||
ABSL_CONST_INIT extern thread_local SamplingState cordz_next_sample;
|
||||
|
||||
// Determines if the next sample should be profiled. If it is, the value pointed
|
||||
// at by next_sample will be set with the interval until the next sample.
|
||||
bool cordz_should_profile_slow();
|
||||
// Determines if the next sample should be profiled.
|
||||
// Returns:
|
||||
// 0: Do not sample
|
||||
// >0: Sample with the stride of the last sampling period
|
||||
int64_t cordz_should_profile_slow(SamplingState& state);
|
||||
|
||||
// Returns true if the next cord should be sampled.
|
||||
inline bool cordz_should_profile() {
|
||||
if (ABSL_PREDICT_TRUE(cordz_next_sample > 1)) {
|
||||
cordz_next_sample--;
|
||||
return false;
|
||||
// Determines if the next sample should be profiled.
|
||||
// Returns:
|
||||
// 0: Do not sample
|
||||
// >0: Sample with the stride of the last sampling period
|
||||
inline int64_t cordz_should_profile() {
|
||||
if (ABSL_PREDICT_TRUE(cordz_next_sample.next_sample > 1)) {
|
||||
cordz_next_sample.next_sample--;
|
||||
return 0;
|
||||
}
|
||||
return cordz_should_profile_slow();
|
||||
return cordz_should_profile_slow(cordz_next_sample);
|
||||
}
|
||||
|
||||
// Sets the interval until the next sample (for testing only)
|
||||
@@ -65,7 +75,7 @@ void cordz_set_next_sample_for_testing(int64_t next_sample);
|
||||
|
||||
#else // ABSL_INTERNAL_CORDZ_ENABLED
|
||||
|
||||
inline bool cordz_should_profile() { return false; }
|
||||
inline int64_t cordz_should_profile() { return 0; }
|
||||
inline void cordz_set_next_sample_for_testing(int64_t) {}
|
||||
|
||||
#endif // ABSL_INTERNAL_CORDZ_ENABLED
|
||||
|
||||
48
Pods/abseil/absl/strings/internal/cordz_handle.cc
generated
48
Pods/abseil/absl/strings/internal/cordz_handle.cc
generated
@@ -16,6 +16,7 @@
|
||||
#include <atomic>
|
||||
|
||||
#include "absl/base/internal/raw_logging.h" // For ABSL_RAW_CHECK
|
||||
#include "absl/base/no_destructor.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
|
||||
namespace absl {
|
||||
@@ -43,33 +44,32 @@ struct Queue {
|
||||
}
|
||||
};
|
||||
|
||||
static Queue* GlobalQueue() {
|
||||
static Queue* global_queue = new Queue;
|
||||
return global_queue;
|
||||
static Queue& GlobalQueue() {
|
||||
static absl::NoDestructor<Queue> global_queue;
|
||||
return *global_queue;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CordzHandle::CordzHandle(bool is_snapshot) : is_snapshot_(is_snapshot) {
|
||||
Queue* global_queue = GlobalQueue();
|
||||
Queue& global_queue = GlobalQueue();
|
||||
if (is_snapshot) {
|
||||
MutexLock lock(&global_queue->mutex);
|
||||
CordzHandle* dq_tail =
|
||||
global_queue->dq_tail.load(std::memory_order_acquire);
|
||||
MutexLock lock(&global_queue.mutex);
|
||||
CordzHandle* dq_tail = global_queue.dq_tail.load(std::memory_order_acquire);
|
||||
if (dq_tail != nullptr) {
|
||||
dq_prev_ = dq_tail;
|
||||
dq_tail->dq_next_ = this;
|
||||
}
|
||||
global_queue->dq_tail.store(this, std::memory_order_release);
|
||||
global_queue.dq_tail.store(this, std::memory_order_release);
|
||||
}
|
||||
}
|
||||
|
||||
CordzHandle::~CordzHandle() {
|
||||
Queue* global_queue = GlobalQueue();
|
||||
Queue& global_queue = GlobalQueue();
|
||||
if (is_snapshot_) {
|
||||
std::vector<CordzHandle*> to_delete;
|
||||
{
|
||||
MutexLock lock(&global_queue->mutex);
|
||||
MutexLock lock(&global_queue.mutex);
|
||||
CordzHandle* next = dq_next_;
|
||||
if (dq_prev_ == nullptr) {
|
||||
// We were head of the queue, delete every CordzHandle until we reach
|
||||
@@ -85,7 +85,7 @@ CordzHandle::~CordzHandle() {
|
||||
if (next) {
|
||||
next->dq_prev_ = dq_prev_;
|
||||
} else {
|
||||
global_queue->dq_tail.store(dq_prev_, std::memory_order_release);
|
||||
global_queue.dq_tail.store(dq_prev_, std::memory_order_release);
|
||||
}
|
||||
}
|
||||
for (CordzHandle* handle : to_delete) {
|
||||
@@ -95,20 +95,20 @@ CordzHandle::~CordzHandle() {
|
||||
}
|
||||
|
||||
bool CordzHandle::SafeToDelete() const {
|
||||
return is_snapshot_ || GlobalQueue()->IsEmpty();
|
||||
return is_snapshot_ || GlobalQueue().IsEmpty();
|
||||
}
|
||||
|
||||
void CordzHandle::Delete(CordzHandle* handle) {
|
||||
assert(handle);
|
||||
if (handle) {
|
||||
Queue* const queue = GlobalQueue();
|
||||
Queue& queue = GlobalQueue();
|
||||
if (!handle->SafeToDelete()) {
|
||||
MutexLock lock(&queue->mutex);
|
||||
CordzHandle* dq_tail = queue->dq_tail.load(std::memory_order_acquire);
|
||||
MutexLock lock(&queue.mutex);
|
||||
CordzHandle* dq_tail = queue.dq_tail.load(std::memory_order_acquire);
|
||||
if (dq_tail != nullptr) {
|
||||
handle->dq_prev_ = dq_tail;
|
||||
dq_tail->dq_next_ = handle;
|
||||
queue->dq_tail.store(handle, std::memory_order_release);
|
||||
queue.dq_tail.store(handle, std::memory_order_release);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -118,9 +118,9 @@ void CordzHandle::Delete(CordzHandle* handle) {
|
||||
|
||||
std::vector<const CordzHandle*> CordzHandle::DiagnosticsGetDeleteQueue() {
|
||||
std::vector<const CordzHandle*> handles;
|
||||
Queue* global_queue = GlobalQueue();
|
||||
MutexLock lock(&global_queue->mutex);
|
||||
CordzHandle* dq_tail = global_queue->dq_tail.load(std::memory_order_acquire);
|
||||
Queue& global_queue = GlobalQueue();
|
||||
MutexLock lock(&global_queue.mutex);
|
||||
CordzHandle* dq_tail = global_queue.dq_tail.load(std::memory_order_acquire);
|
||||
for (const CordzHandle* p = dq_tail; p; p = p->dq_prev_) {
|
||||
handles.push_back(p);
|
||||
}
|
||||
@@ -133,9 +133,9 @@ bool CordzHandle::DiagnosticsHandleIsSafeToInspect(
|
||||
if (handle == nullptr) return true;
|
||||
if (handle->is_snapshot_) return false;
|
||||
bool snapshot_found = false;
|
||||
Queue* global_queue = GlobalQueue();
|
||||
MutexLock lock(&global_queue->mutex);
|
||||
for (const CordzHandle* p = global_queue->dq_tail; p; p = p->dq_prev_) {
|
||||
Queue& global_queue = GlobalQueue();
|
||||
MutexLock lock(&global_queue.mutex);
|
||||
for (const CordzHandle* p = global_queue.dq_tail; p; p = p->dq_prev_) {
|
||||
if (p == handle) return !snapshot_found;
|
||||
if (p == this) snapshot_found = true;
|
||||
}
|
||||
@@ -150,8 +150,8 @@ CordzHandle::DiagnosticsGetSafeToInspectDeletedHandles() {
|
||||
return handles;
|
||||
}
|
||||
|
||||
Queue* global_queue = GlobalQueue();
|
||||
MutexLock lock(&global_queue->mutex);
|
||||
Queue& global_queue = GlobalQueue();
|
||||
MutexLock lock(&global_queue.mutex);
|
||||
for (const CordzHandle* p = dq_next_; p != nullptr; p = p->dq_next_) {
|
||||
if (!p->is_snapshot()) {
|
||||
handles.push_back(p);
|
||||
|
||||
19
Pods/abseil/absl/strings/internal/cordz_info.cc
generated
19
Pods/abseil/absl/strings/internal/cordz_info.cc
generated
@@ -14,6 +14,8 @@
|
||||
|
||||
#include "absl/strings/internal/cordz_info.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/spinlock.h"
|
||||
#include "absl/container/inlined_vector.h"
|
||||
@@ -247,10 +249,12 @@ CordzInfo* CordzInfo::Next(const CordzSnapshot& snapshot) const {
|
||||
return next;
|
||||
}
|
||||
|
||||
void CordzInfo::TrackCord(InlineData& cord, MethodIdentifier method) {
|
||||
void CordzInfo::TrackCord(InlineData& cord, MethodIdentifier method,
|
||||
int64_t sampling_stride) {
|
||||
assert(cord.is_tree());
|
||||
assert(!cord.is_profiled());
|
||||
CordzInfo* cordz_info = new CordzInfo(cord.as_tree(), nullptr, method);
|
||||
CordzInfo* cordz_info =
|
||||
new CordzInfo(cord.as_tree(), nullptr, method, sampling_stride);
|
||||
cord.set_cordz_info(cordz_info);
|
||||
cordz_info->Track();
|
||||
}
|
||||
@@ -266,7 +270,8 @@ void CordzInfo::TrackCord(InlineData& cord, const InlineData& src,
|
||||
if (cordz_info != nullptr) cordz_info->Untrack();
|
||||
|
||||
// Start new cord sample
|
||||
cordz_info = new CordzInfo(cord.as_tree(), src.cordz_info(), method);
|
||||
cordz_info = new CordzInfo(cord.as_tree(), src.cordz_info(), method,
|
||||
src.cordz_info()->sampling_stride());
|
||||
cord.set_cordz_info(cordz_info);
|
||||
cordz_info->Track();
|
||||
}
|
||||
@@ -298,9 +303,8 @@ size_t CordzInfo::FillParentStack(const CordzInfo* src, void** stack) {
|
||||
return src->stack_depth_;
|
||||
}
|
||||
|
||||
CordzInfo::CordzInfo(CordRep* rep,
|
||||
const CordzInfo* src,
|
||||
MethodIdentifier method)
|
||||
CordzInfo::CordzInfo(CordRep* rep, const CordzInfo* src,
|
||||
MethodIdentifier method, int64_t sampling_stride)
|
||||
: rep_(rep),
|
||||
stack_depth_(
|
||||
static_cast<size_t>(absl::GetStackTrace(stack_,
|
||||
@@ -309,7 +313,8 @@ CordzInfo::CordzInfo(CordRep* rep,
|
||||
parent_stack_depth_(FillParentStack(src, parent_stack_)),
|
||||
method_(method),
|
||||
parent_method_(GetParentMethod(src)),
|
||||
create_time_(absl::Now()) {
|
||||
create_time_(absl::Now()),
|
||||
sampling_stride_(sampling_stride) {
|
||||
update_tracker_.LossyAdd(method);
|
||||
if (src) {
|
||||
// Copy parent counters.
|
||||
|
||||
13
Pods/abseil/absl/strings/internal/cordz_info.h
generated
13
Pods/abseil/absl/strings/internal/cordz_info.h
generated
@@ -60,7 +60,8 @@ class ABSL_LOCKABLE CordzInfo : public CordzHandle {
|
||||
// and/or deleted. `method` identifies the Cord public API method initiating
|
||||
// the cord to be sampled.
|
||||
// Requires `cord` to hold a tree, and `cord.cordz_info()` to be null.
|
||||
static void TrackCord(InlineData& cord, MethodIdentifier method);
|
||||
static void TrackCord(InlineData& cord, MethodIdentifier method,
|
||||
int64_t sampling_stride);
|
||||
|
||||
// Identical to TrackCord(), except that this function fills the
|
||||
// `parent_stack` and `parent_method` properties of the returned CordzInfo
|
||||
@@ -181,6 +182,8 @@ class ABSL_LOCKABLE CordzInfo : public CordzHandle {
|
||||
// or RemovePrefix.
|
||||
CordzStatistics GetCordzStatistics() const;
|
||||
|
||||
int64_t sampling_stride() const { return sampling_stride_; }
|
||||
|
||||
private:
|
||||
using SpinLock = absl::base_internal::SpinLock;
|
||||
using SpinLockHolder = ::absl::base_internal::SpinLockHolder;
|
||||
@@ -199,7 +202,7 @@ class ABSL_LOCKABLE CordzInfo : public CordzHandle {
|
||||
static constexpr size_t kMaxStackDepth = 64;
|
||||
|
||||
explicit CordzInfo(CordRep* rep, const CordzInfo* src,
|
||||
MethodIdentifier method);
|
||||
MethodIdentifier method, int64_t weight);
|
||||
~CordzInfo() override;
|
||||
|
||||
// Sets `rep_` without holding a lock.
|
||||
@@ -250,12 +253,14 @@ class ABSL_LOCKABLE CordzInfo : public CordzHandle {
|
||||
const MethodIdentifier parent_method_;
|
||||
CordzUpdateTracker update_tracker_;
|
||||
const absl::Time create_time_;
|
||||
const int64_t sampling_stride_;
|
||||
};
|
||||
|
||||
inline ABSL_ATTRIBUTE_ALWAYS_INLINE void CordzInfo::MaybeTrackCord(
|
||||
InlineData& cord, MethodIdentifier method) {
|
||||
if (ABSL_PREDICT_FALSE(cordz_should_profile())) {
|
||||
TrackCord(cord, method);
|
||||
auto stride = cordz_should_profile();
|
||||
if (ABSL_PREDICT_FALSE(stride > 0)) {
|
||||
TrackCord(cord, method, stride);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
7
Pods/abseil/absl/strings/internal/escaping.cc
generated
7
Pods/abseil/absl/strings/internal/escaping.cc
generated
@@ -14,6 +14,8 @@
|
||||
|
||||
#include "absl/strings/internal/escaping.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "absl/base/internal/endian.h"
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
|
||||
@@ -31,12 +33,14 @@ ABSL_CONST_INIT const char kBase64Chars[] =
|
||||
ABSL_CONST_INIT const char kWebSafeBase64Chars[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
||||
|
||||
|
||||
size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding) {
|
||||
// Base64 encodes three bytes of input at a time. If the input is not
|
||||
// divisible by three, we pad as appropriate.
|
||||
//
|
||||
// Base64 encodes each three bytes of input into four bytes of output.
|
||||
constexpr size_t kMaxSize = (std::numeric_limits<size_t>::max() - 1) / 4 * 3;
|
||||
ABSL_INTERNAL_CHECK(input_len <= kMaxSize,
|
||||
"CalculateBase64EscapedLenInternal() overflow");
|
||||
size_t len = (input_len / 3) * 4;
|
||||
|
||||
// Since all base 64 input is an integral number of octets, only the following
|
||||
@@ -66,7 +70,6 @@ size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding) {
|
||||
}
|
||||
}
|
||||
|
||||
assert(len >= input_len); // make sure we didn't overflow
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
// Copyright 2024 The Abseil Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_STRINGS_INTERNAL_HAS_ABSL_STRINGIFY_H_
|
||||
#define ABSL_STRINGS_INTERNAL_HAS_ABSL_STRINGIFY_H_
|
||||
|
||||
#include "absl/strings/has_absl_stringify.h"
|
||||
|
||||
#include "absl/base/config.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
|
||||
namespace strings_internal {
|
||||
|
||||
// This exists to fix a circular dependency problem with the GoogleTest release.
|
||||
// GoogleTest referenced this internal file and this internal trait. Since
|
||||
// simultaneous releases are not possible since once release must reference
|
||||
// another, we will temporarily add this back.
|
||||
// https://github.com/google/googletest/blob/v1.14.x/googletest/include/gtest/gtest-printers.h#L119
|
||||
//
|
||||
// This file can be deleted after the next Abseil and GoogleTest release.
|
||||
//
|
||||
// https://github.com/google/googletest/pull/4368#issuecomment-1717699895
|
||||
// https://github.com/google/googletest/pull/4368#issuecomment-1717699895
|
||||
using ::absl::HasAbslStringify;
|
||||
|
||||
} // namespace strings_internal
|
||||
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_STRINGS_INTERNAL_HAS_ABSL_STRINGIFY_H_
|
||||
@@ -31,16 +31,23 @@
|
||||
#ifndef ABSL_STRINGS_INTERNAL_STR_JOIN_INTERNAL_H_
|
||||
#define ABSL_STRINGS_INTERNAL_STR_JOIN_INTERNAL_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <initializer_list>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
#include "absl/strings/internal/ostringstream.h"
|
||||
#include "absl/strings/internal/resize_uninitialized.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
@@ -230,14 +237,19 @@ std::string JoinAlgorithm(Iterator start, Iterator end, absl::string_view s,
|
||||
if (start != end) {
|
||||
// Sums size
|
||||
auto&& start_value = *start;
|
||||
size_t result_size = start_value.size();
|
||||
// Use uint64_t to prevent size_t overflow. We assume it is not possible for
|
||||
// in memory strings to overflow a uint64_t.
|
||||
uint64_t result_size = start_value.size();
|
||||
for (Iterator it = start; ++it != end;) {
|
||||
result_size += s.size();
|
||||
result_size += (*it).size();
|
||||
}
|
||||
|
||||
if (result_size > 0) {
|
||||
STLStringResizeUninitialized(&result, result_size);
|
||||
constexpr uint64_t kMaxSize =
|
||||
uint64_t{(std::numeric_limits<size_t>::max)()};
|
||||
ABSL_INTERNAL_CHECK(result_size <= kMaxSize, "size_t overflow");
|
||||
STLStringResizeUninitialized(&result, static_cast<size_t>(result_size));
|
||||
|
||||
// Joins strings
|
||||
char* result_buf = &*result.begin();
|
||||
@@ -310,6 +322,15 @@ std::string JoinRange(const Range& range, absl::string_view separator) {
|
||||
return JoinRange(begin(range), end(range), separator);
|
||||
}
|
||||
|
||||
template <typename Tuple, std::size_t... I>
|
||||
std::string JoinTuple(const Tuple& value, absl::string_view separator,
|
||||
std::index_sequence<I...>) {
|
||||
return JoinRange(
|
||||
std::initializer_list<absl::string_view>{
|
||||
static_cast<const AlphaNum&>(std::get<I>(value)).Piece()...},
|
||||
separator);
|
||||
}
|
||||
|
||||
} // namespace strings_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#define ABSL_STRINGS_INTERNAL_STR_SPLIT_INTERNAL_H_
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <initializer_list>
|
||||
#include <iterator>
|
||||
#include <tuple>
|
||||
@@ -402,7 +403,10 @@ class Splitter {
|
||||
ar[index].size = it->size();
|
||||
++it;
|
||||
} while (++index != ar.size() && !it.at_end());
|
||||
v.insert(v.end(), ar.begin(), ar.begin() + index);
|
||||
// We static_cast index to a signed type to work around overzealous
|
||||
// compiler warnings about signedness.
|
||||
v.insert(v.end(), ar.begin(),
|
||||
ar.begin() + static_cast<ptrdiff_t>(index));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user