Skip to content

Commit 9c6a50f

Browse files
Abseil Teamrogeeff
authored andcommitted
Export of internal Abseil changes
-- 4ff721439234e91caf6f7b772e5f554e7dd423c8 by Benjamin Barenblat <[email protected]>: Remove endian-sensitivity from hash slow path Prior to this commit, the Abseil hash fast path was endian-agnostic, but the slow path assumed a little-endian platform. Change the slow path to be endian-correct, ensuring that values produced by the fast and slow paths are equal even on big-endian systems. PiperOrigin-RevId: 355424258 -- 7f4fe1aa4de46ad0a2ef19fa9c061fc12a7391ed by Abseil Team <[email protected]>: Directly store CordzInfo in the InlineData data contents of InlineRep This greatly reduces the cost of coping and moving cords. Especially the move constructor and move assignment are now back to lean loads and stores without needing any CordzInfo lookups for tracked cords. PiperOrigin-RevId: 355409161 -- 3ca4ca84ed6d98f1e383ffd8d12c28876e905bb3 by Abseil Team <[email protected]>: Add #include <unordered_map> PiperOrigin-RevId: 355386114 -- 30b0ffad0621971b3135148fcc9e183b0dd2a6bb by Abseil Team <[email protected]>: Optimize Cord copy constructor This change avoids double stores of the Cord copy constructor from the zero init of the InlineData / InlineRep contents followed by the assignment and inlines the copy constructor. PiperOrigin-RevId: 355287939 -- 0c043fa7b6e41ca7cefc5edc1e17ad46223e4e77 by CJ Johnson <[email protected]>: Now that the absl::Cleanup example returns absl::Status, since we decided on absl::FailedPreconditionError, the precondition should be a positive statement and then the check should be failure to adhere to that positive statement PiperOrigin-RevId: 355216923 -- 9ed922ca5d28fe8790ec6bc0837cf39fbcc92896 by Gennadiy Rozental <[email protected]>: Do not set mvsc linker flags for clang-cl (fixes abseil#874) Import of abseil#891 PiperOrigin-RevId: 355199380 GitOrigin-RevId: 4ff721439234e91caf6f7b772e5f554e7dd423c8 Change-Id: I3d9d2383549720d7a91f9108dfcd979ad6632fce
1 parent 58a9c6d commit 9c6a50f

File tree

10 files changed

+90
-28
lines changed

10 files changed

+90
-28
lines changed

absl/cleanup/cleanup.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
//
4242
// Data data;
4343
// while (ReadData(source_file, &data)) {
44-
// if (data.IsBad()) {
44+
// if (!data.IsGood()) {
4545
// absl::Status result = absl::FailedPreconditionError("Read bad data");
4646
// return result; // Both cleanups execute
4747
// }
@@ -87,7 +87,7 @@ class ABSL_MUST_USE_RESULT Cleanup {
8787

8888
public:
8989
Cleanup(Callback callback) // NOLINT
90-
: storage_(std::move(callback), /*engaged=*/true) {}
90+
: storage_(std::move(callback), /* is_callback_engaged = */ true) {}
9191

9292
Cleanup(Cleanup&& other) = default;
9393

absl/cleanup/internal/cleanup.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,30 +45,32 @@ class Storage {
4545
public:
4646
Storage() = delete;
4747

48-
Storage(Callback callback, bool engaged)
49-
: callback_(std::move(callback)), engaged_(engaged) {}
48+
Storage(Callback callback, bool is_callback_engaged)
49+
: callback_(std::move(callback)),
50+
is_callback_engaged_(is_callback_engaged) {}
5051

5152
Storage(Storage&& other)
5253
: callback_(std::move(other.callback_)),
53-
engaged_(absl::exchange(other.engaged_, false)) {}
54+
is_callback_engaged_(
55+
absl::exchange(other.is_callback_engaged_, false)) {}
5456

5557
Storage(const Storage& other) = delete;
5658

5759
Storage& operator=(Storage&& other) = delete;
5860

5961
Storage& operator=(const Storage& other) = delete;
6062

61-
bool IsCallbackEngaged() const { return engaged_; }
63+
bool IsCallbackEngaged() const { return is_callback_engaged_; }
6264

63-
void DisengageCallback() { engaged_ = false; }
65+
void DisengageCallback() { is_callback_engaged_ = false; }
6466

6567
void InvokeCallback() ABSL_NO_THREAD_SAFETY_ANALYSIS {
6668
std::move(callback_)();
6769
}
6870

6971
private:
7072
Callback callback_;
71-
bool engaged_;
73+
bool is_callback_engaged_;
7274
};
7375

7476
} // namespace cleanup_internal

absl/container/internal/unordered_map_constructor_test.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#define ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_CONSTRUCTOR_TEST_H_
1717

1818
#include <algorithm>
19+
#include <unordered_map>
1920
#include <vector>
2021

2122
#include "gmock/gmock.h"

absl/hash/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ cc_library(
3838
deps = [
3939
":city",
4040
":wyhash",
41+
"//absl/base:config",
4142
"//absl/base:core_headers",
4243
"//absl/base:endian",
4344
"//absl/container:fixed_array",

absl/hash/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ absl_cc_library(
2626
${ABSL_DEFAULT_COPTS}
2727
DEPS
2828
absl::city
29+
absl::config
2930
absl::core_headers
3031
absl::endian
3132
absl::fixed_array

absl/hash/internal/hash.h

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@
3838
#include <utility>
3939
#include <vector>
4040

41-
#include "absl/base/internal/endian.h"
41+
#include "absl/base/config.h"
42+
#include "absl/base/internal/unaligned_access.h"
4243
#include "absl/base/port.h"
4344
#include "absl/container/fixed_array.h"
4445
#include "absl/hash/internal/wyhash.h"
@@ -804,26 +805,54 @@ class ABSL_DLL HashState : public HashStateBase<HashState> {
804805
size_t len);
805806

806807
// Reads 9 to 16 bytes from p.
807-
// The first 8 bytes are in .first, the rest (zero padded) bytes are in
808-
// .second.
808+
// The least significant 8 bytes are in .first, the rest (zero padded) bytes
809+
// are in .second.
809810
static std::pair<uint64_t, uint64_t> Read9To16(const unsigned char* p,
810811
size_t len) {
811-
uint64_t high = little_endian::Load64(p + len - 8);
812-
return {little_endian::Load64(p), high >> (128 - len * 8)};
812+
uint64_t low_mem = absl::base_internal::UnalignedLoad64(p);
813+
uint64_t high_mem = absl::base_internal::UnalignedLoad64(p + len - 8);
814+
#ifdef ABSL_IS_LITTLE_ENDIAN
815+
uint64_t most_significant = high_mem;
816+
uint64_t least_significant = low_mem;
817+
#else
818+
uint64_t most_significant = low_mem;
819+
uint64_t least_significant = high_mem;
820+
#endif
821+
return {least_significant, most_significant >> (128 - len * 8)};
813822
}
814823

815824
// Reads 4 to 8 bytes from p. Zero pads to fill uint64_t.
816825
static uint64_t Read4To8(const unsigned char* p, size_t len) {
817-
return (static_cast<uint64_t>(little_endian::Load32(p + len - 4))
818-
<< (len - 4) * 8) |
819-
little_endian::Load32(p);
826+
uint32_t low_mem = absl::base_internal::UnalignedLoad32(p);
827+
uint32_t high_mem = absl::base_internal::UnalignedLoad32(p + len - 4);
828+
#ifdef ABSL_IS_LITTLE_ENDIAN
829+
uint32_t most_significant = high_mem;
830+
uint32_t least_significant = low_mem;
831+
#else
832+
uint32_t most_significant = low_mem;
833+
uint32_t least_significant = high_mem;
834+
#endif
835+
return (static_cast<uint64_t>(most_significant) << (len - 4) * 8) |
836+
least_significant;
820837
}
821838

822839
// Reads 1 to 3 bytes from p. Zero pads to fill uint32_t.
823840
static uint32_t Read1To3(const unsigned char* p, size_t len) {
824-
return static_cast<uint32_t>((p[0]) | //
825-
(p[len / 2] << (len / 2 * 8)) | //
826-
(p[len - 1] << ((len - 1) * 8)));
841+
unsigned char mem0 = p[0];
842+
unsigned char mem1 = p[len / 2];
843+
unsigned char mem2 = p[len - 1];
844+
#ifdef ABSL_IS_LITTLE_ENDIAN
845+
unsigned char significant2 = mem2;
846+
unsigned char significant1 = mem1;
847+
unsigned char significant0 = mem0;
848+
#else
849+
unsigned char significant2 = mem0;
850+
unsigned char significant1 = mem1;
851+
unsigned char significant0 = mem2;
852+
#endif
853+
return static_cast<uint32_t>(significant0 | //
854+
(significant1 << (len / 2 * 8)) | //
855+
(significant2 << ((len - 1) * 8)));
827856
}
828857

829858
ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t Mix(uint64_t state, uint64_t v) {

absl/strings/cord.cc

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,9 @@ void Cord::InlineRep::AssignSlow(const Cord::InlineRep& src) {
495495

496496
data_ = src.data_;
497497
if (is_tree()) {
498+
data_.set_profiled(false);
498499
CordRep::Ref(tree());
500+
clear_cordz_info();
499501
}
500502
}
501503

@@ -509,12 +511,6 @@ void Cord::InlineRep::ClearSlow() {
509511
// --------------------------------------------------------------------
510512
// Constructors and destructors
511513

512-
Cord::Cord(const Cord& src) : contents_(src.contents_) {
513-
if (CordRep* tree = contents_.tree()) {
514-
CordRep::Ref(tree);
515-
}
516-
}
517-
518514
Cord::Cord(absl::string_view src) {
519515
const size_t n = src.size();
520516
if (n <= InlineRep::kMaxInline) {

absl/strings/cord.h

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,23 @@ class Cord {
755755

756756
bool is_tree() const { return data_.is_tree(); }
757757

758+
// Returns true if the Cord is being profiled by cordz.
759+
bool is_profiled() const { return data_.is_tree() && data_.is_profiled(); }
760+
761+
// Returns the profiled CordzInfo, or nullptr if not sampled.
762+
absl::cord_internal::CordzInfo* cordz_info() const {
763+
return data_.cordz_info();
764+
}
765+
766+
// Sets the profiled CordzInfo. `cordz_info` must not be null.
767+
void set_cordz_info(cord_internal::CordzInfo* cordz_info) {
768+
assert(cordz_info != nullptr);
769+
data_.set_cordz_info(cordz_info);
770+
}
771+
772+
// Resets the current cordz_info to null / empty.
773+
void clear_cordz_info() { data_.clear_cordz_info(); }
774+
758775
private:
759776
friend class Cord;
760777

@@ -921,8 +938,12 @@ Cord MakeCordFromExternal(absl::string_view data, Releaser&& releaser) {
921938
constexpr Cord::InlineRep::InlineRep(cord_internal::InlineData data)
922939
: data_(data) {}
923940

924-
inline Cord::InlineRep::InlineRep(const Cord::InlineRep& src) {
925-
data_ = src.data_;
941+
inline Cord::InlineRep::InlineRep(const Cord::InlineRep& src)
942+
: data_(src.data_) {
943+
if (is_tree()) {
944+
data_.clear_cordz_info();
945+
absl::cord_internal::CordRep::Ref(as_tree());
946+
}
926947
}
927948

928949
inline Cord::InlineRep::InlineRep(Cord::InlineRep&& src) {
@@ -956,7 +977,6 @@ inline void Cord::InlineRep::Swap(Cord::InlineRep* rhs) {
956977
if (rhs == this) {
957978
return;
958979
}
959-
960980
std::swap(data_, rhs->data_);
961981
}
962982

@@ -1037,6 +1057,8 @@ inline Cord& Cord::operator=(const Cord& x) {
10371057
return *this;
10381058
}
10391059

1060+
inline Cord::Cord(const Cord& src) : contents_(src.contents_) {}
1061+
10401062
inline Cord::Cord(Cord&& src) noexcept : contents_(std::move(src.contents_)) {}
10411063

10421064
inline void Cord::swap(Cord& other) noexcept {

absl/strings/cord_test.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,10 @@ class CordTestPeer {
183183
}
184184

185185
static bool IsTree(const Cord& c) { return c.contents_.is_tree(); }
186+
187+
static cord_internal::CordzInfo* GetCordzInfo(const Cord& c) {
188+
return c.contents_.cordz_info();
189+
}
186190
};
187191

188192
ABSL_NAMESPACE_END

absl/strings/internal/cord_internal.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,12 @@ class InlineData {
387387
as_tree_.cordz_info = absl::big_endian::FromHost64(info);
388388
}
389389

390+
// Resets the current cordz_info to null / empty.
391+
void clear_cordz_info() {
392+
assert(is_tree());
393+
as_tree_.cordz_info = kNullCordzInfo;
394+
}
395+
390396
// Returns a read only pointer to the character data inside this instance.
391397
// Requires the current instance to hold inline data.
392398
const char* as_chars() const {

0 commit comments

Comments
 (0)