diff --git a/DEPS b/DEPS index 32bf0f6922..cec6124daa 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', 'webrtc_git': 'https://webrtc.googlesource.com', - 'chromium_revision': 'ffaf1e2ba66b521c4afe3af865a3f044ae1bff00', + 'chromium_revision': 'ef538e3112d34f22bf36c50f71ec9c3108bda689', 'boringssl_git': 'https://boringssl.googlesource.com', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client @@ -27,7 +27,7 @@ vars = { # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'eca23c365a07863178be2918fb2c97b23fa97381', + 'catapult_revision': 'fdacd1639e2adc4631fc1d57f68e4d3715cef5ba', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -35,7 +35,7 @@ vars = { # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. - 'freetype_revision': '0589f6e6ee6e9bfe0c7139374fc8812e849e7bf7', + 'freetype_revision': '8f1ed54877ffab4fc2cf2be329446c748a885842', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling HarfBuzz # and whatever else without interference from each other. @@ -43,15 +43,15 @@ vars = { # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Chromium third_party # and whatever else without interference from each other. - 'chromium_third_party_revision': 'fb3dc2a0aa643c64ee5ee4c3ba13ed40443b68b7', + 'chromium_third_party_revision': 'cbc2a20101b62439635a362571b6ea68d542054c', } deps = { # TODO(kjellander): Move this to be Android-only once the libevent dependency # in base/third_party/libevent is solved. 'src/base': - Var('chromium_git') + '/chromium/src/base' + '@' + '27430762358b568f216d88d8af9dd83c1bddcd79', + Var('chromium_git') + '/chromium/src/base' + '@' + '02a6c4cdd034f8d80847508e82e1391f01033017', 'src/build': - Var('chromium_git') + '/chromium/src/build' + '@' + '459adce3ebfbc114c2d637ebd44c886eac58d441', + Var('chromium_git') + '/chromium/src/build' + '@' + '3c4d6b6d24da4fda0c55f2cff4dd9f542fbfdd43', 'src/buildtools': Var('chromium_git') + '/chromium/buildtools.git' + '@' + '6f4dae280c6a542acacd8db281decc5c0b2a9823', # Gradle 4.3-rc4. Used for testing Android Studio project generation for WebRTC. @@ -61,11 +61,11 @@ deps = { 'condition': 'checkout_android', }, 'src/ios': { - 'url': Var('chromium_git') + '/chromium/src/ios' + '@' + '71b35d6ee6df3985bb870990daa8851f60ce4d2e', + 'url': Var('chromium_git') + '/chromium/src/ios' + '@' + '0c6d3816a06717b42104f4d59f5b525c95e8ac97', 'condition': 'checkout_ios', }, 'src/testing': - Var('chromium_git') + '/chromium/src/testing' + '@' + 'f624b1f4b7e728d3816e5fcf7f51f98e6f7e7f54', + Var('chromium_git') + '/chromium/src/testing' + '@' + 'e0597e0b5d0d6d2b146bf1738347ca6bcb6613cd', # This entry is used for chromium third_party rolling into webrtc third_party only. 'src/third_party_chromium': { 'url': Var('chromium_git') + '/chromium/src/third_party' + '@' + Var('chromium_third_party_revision'), @@ -94,7 +94,7 @@ deps = { 'src/third_party/colorama/src': Var('chromium_git') + '/external/colorama.git' + '@' + '799604a1041e9b3bc5d2789ecbd7e8db2e18e6b8', 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'e05f18d47735f3bc3f5808d0ce38a452b82d95e8', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'e09b6845cf720ac429578b209267cb6dd1c901da', 'src/third_party/errorprone/lib': { 'url': Var('chromium_git') + '/chromium/third_party/errorprone.git' + '@' + '980d49e839aa4984015efed34b0134d4b2c9b6d7', 'condition': 'checkout_android', @@ -113,7 +113,7 @@ deps = { 'src/third_party/gtest-parallel': Var('chromium_git') + '/external/github.com/google/gtest-parallel' + '@' + 'cb3514a0858be0f66281d892e2242d1073fd75fe', 'src/third_party/googletest/src': - Var('chromium_git') + '/external/github.com/google/googletest.git' + '@' + '145d05750b15324899473340c8dd5af50d125d33', + Var('chromium_git') + '/external/github.com/google/googletest.git' + '@' + '9077ec7efe5b652468ab051e93c67589d5cb8f85', 'src/third_party/icu': { 'url': Var('chromium_git') + '/chromium/deps/icu.git' + '@' + 'f61e46dbee9d539a32551493e3bcc1dea92f83ec', }, @@ -185,7 +185,7 @@ deps = { 'src/third_party/yasm/source/patched-yasm': Var('chromium_git') + '/chromium/deps/yasm/patched-yasm.git' + '@' + 'b98114e18d8b9b84586b10d24353ab8616d4c5fc', 'src/tools': - Var('chromium_git') + '/chromium/src/tools' + '@' + '76e5757c8fdee7192701a19b6a807a5d9b5c8fc4', + Var('chromium_git') + '/chromium/src/tools' + '@' + 'c7862334ce4a9647355f622299799ef0554daf6f', 'src/tools/gyp': Var('chromium_git') + '/external/gyp.git' + '@' + 'd61a9397e668fa9843c4aa7da9e79460fe590bfb', 'src/tools/swarming_client': diff --git a/third_party/abseil-cpp/README.chromium b/third_party/abseil-cpp/README.chromium index 92298aca30..ed72e40a25 100644 --- a/third_party/abseil-cpp/README.chromium +++ b/third_party/abseil-cpp/README.chromium @@ -4,7 +4,7 @@ URL: https://github.com/abseil/abseil-cpp License: Apache 2.0 License File: LICENSE Version: 0 -Revision: 014f02a3eca93ef88163c3b408c86998ecf6572c +Revision: 92020a042c0cd46979db9f6f0cb32783dc07765e Security Critical: yes Description: diff --git a/third_party/abseil-cpp/WORKSPACE b/third_party/abseil-cpp/WORKSPACE index 064459306d..9c95065087 100644 --- a/third_party/abseil-cpp/WORKSPACE +++ b/third_party/abseil-cpp/WORKSPACE @@ -13,20 +13,20 @@ http_archive( # GoogleTest/GoogleMock framework. Used by most unit-tests. http_archive( name = "com_google_googletest", - urls = ["https://github.com/google/googletest/archive/master.zip"], - strip_prefix = "googletest-master", + urls = ["https://github.com/google/googletest/archive/4e4df226fc197c0dda6e37f5c8c3845ca1e73a49.zip"], + strip_prefix = "googletest-4e4df226fc197c0dda6e37f5c8c3845ca1e73a49", ) # Google benchmark. http_archive( name = "com_github_google_benchmark", - urls = ["https://github.com/google/benchmark/archive/master.zip"], - strip_prefix = "benchmark-master", + urls = ["https://github.com/google/benchmark/archive/16703ff83c1ae6d53e5155df3bb3ab0bc96083be.zip"], + strip_prefix = "benchmark-16703ff83c1ae6d53e5155df3bb3ab0bc96083be", ) # RE2 regular-expression framework. Used by some unit-tests. http_archive( name = "com_googlesource_code_re2", - urls = ["https://github.com/google/re2/archive/master.zip"], - strip_prefix = "re2-master", + urls = ["https://github.com/google/re2/archive/6cf8ccd82dbaab2668e9b13596c68183c9ecd13f.zip"], + strip_prefix = "re2-6cf8ccd82dbaab2668e9b13596c68183c9ecd13f", ) diff --git a/third_party/abseil-cpp/absl/algorithm/BUILD.bazel b/third_party/abseil-cpp/absl/algorithm/BUILD.bazel index 3b24ce1202..d04dc71206 100644 --- a/third_party/abseil-cpp/absl/algorithm/BUILD.bazel +++ b/third_party/abseil-cpp/absl/algorithm/BUILD.bazel @@ -49,7 +49,7 @@ cc_test( deps = [ ":algorithm", "//absl/base:core_headers", - "@com_github_google_benchmark//:benchmark", + "@com_github_google_benchmark//:benchmark_main", ], ) diff --git a/third_party/abseil-cpp/absl/algorithm/equal_benchmark.cc b/third_party/abseil-cpp/absl/algorithm/equal_benchmark.cc index 9af36ce79f..19c0780ccd 100644 --- a/third_party/abseil-cpp/absl/algorithm/equal_benchmark.cc +++ b/third_party/abseil-cpp/absl/algorithm/equal_benchmark.cc @@ -124,5 +124,3 @@ BENCHMARK_TEMPLATE(BM_absl_equal_self_benchmark, EightBits) ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); } // namespace - -BENCHMARK_MAIN(); diff --git a/third_party/abseil-cpp/absl/base/BUILD.bazel b/third_party/abseil-cpp/absl/base/BUILD.bazel index 3d3c7aea57..1e93d97ebd 100644 --- a/third_party/abseil-cpp/absl/base/BUILD.bazel +++ b/third_party/abseil-cpp/absl/base/BUILD.bazel @@ -371,6 +371,11 @@ cc_test( size = "small", srcs = ["internal/sysinfo_test.cc"], copts = ABSL_TEST_COPTS, + tags = [ + "no_test_android_arm", + "no_test_android_arm64", + "no_test_android_x86", + ], deps = [ ":base", "//absl/synchronization", @@ -416,6 +421,6 @@ cc_test( deps = [ ":base", "//absl/synchronization", - "@com_github_google_benchmark//:benchmark", + "@com_github_google_benchmark//:benchmark_main", ], ) diff --git a/third_party/abseil-cpp/absl/base/exception_safety_testing_test.cc b/third_party/abseil-cpp/absl/base/exception_safety_testing_test.cc index a8b82b73da..97c8d6f831 100644 --- a/third_party/abseil-cpp/absl/base/exception_safety_testing_test.cc +++ b/third_party/abseil-cpp/absl/base/exception_safety_testing_test.cc @@ -168,8 +168,58 @@ TEST(ThrowingValueTest, ThrowingCompoundAssignmentOps) { TEST(ThrowingValueTest, ThrowingStreamOps) { ThrowingValue<> bomb; - TestOp([&]() { std::cin >> bomb; }); - TestOp([&]() { std::cout << bomb; }); + TestOp([&]() { + std::istringstream stream; + stream >> bomb; + }); + TestOp([&]() { + std::stringstream stream; + stream << bomb; + }); +} + +// Tests the operator<< of ThrowingValue by forcing ConstructorTracker to emit +// a nonfatal failure that contains the std::string representation of the Thrower +TEST(ThrowingValueTest, StreamOpsOutput) { + using ::testing::TypeSpec; + exceptions_internal::ConstructorTracker ct(exceptions_internal::countdown); + + // Test default spec list (kEverythingThrows) + EXPECT_NONFATAL_FAILURE( + { + using Thrower = ThrowingValue; + auto thrower = Thrower(123); + thrower.~Thrower(); + }, + "ThrowingValue<>(123)"); + + // Test with one item in spec list (kNoThrowCopy) + EXPECT_NONFATAL_FAILURE( + { + using Thrower = ThrowingValue; + auto thrower = Thrower(234); + thrower.~Thrower(); + }, + "ThrowingValue(234)"); + + // Test with multiple items in spec list (kNoThrowMove, kNoThrowNew) + EXPECT_NONFATAL_FAILURE( + { + using Thrower = + ThrowingValue; + auto thrower = Thrower(345); + thrower.~Thrower(); + }, + "ThrowingValue(345)"); + + // Test with all items in spec list (kNoThrowCopy, kNoThrowMove, kNoThrowNew) + EXPECT_NONFATAL_FAILURE( + { + using Thrower = ThrowingValue(-1)>; + auto thrower = Thrower(456); + thrower.~Thrower(); + }, + "ThrowingValue(456)"); } template @@ -653,20 +703,20 @@ struct BasicGuaranteeWithExtraInvariants : public NonNegative { }; constexpr int BasicGuaranteeWithExtraInvariants::kExceptionSentinel; -TEST(ExceptionCheckTest, BasicGuaranteeWithInvariants) { +TEST(ExceptionCheckTest, BasicGuaranteeWithExtraInvariants) { auto tester_with_val = tester.WithInitialValue(BasicGuaranteeWithExtraInvariants{}); EXPECT_TRUE(tester_with_val.Test()); EXPECT_TRUE( tester_with_val - .WithInvariants([](BasicGuaranteeWithExtraInvariants* w) { - if (w->i == BasicGuaranteeWithExtraInvariants::kExceptionSentinel) { + .WithInvariants([](BasicGuaranteeWithExtraInvariants* o) { + if (o->i == BasicGuaranteeWithExtraInvariants::kExceptionSentinel) { return testing::AssertionSuccess(); } return testing::AssertionFailure() << "i should be " << BasicGuaranteeWithExtraInvariants::kExceptionSentinel - << ", but is " << w->i; + << ", but is " << o->i; }) .Test()); } @@ -846,29 +896,28 @@ TEST(ConstructorTrackerTest, NotDestroyedAfter) { new (&storage) Tracked; }, "not destroyed"); - - // Manual destruction of the Tracked instance is not required because - // ~ConstructorTracker() handles that automatically when a leak is found } TEST(ConstructorTrackerTest, DestroyedTwice) { + exceptions_internal::ConstructorTracker ct(exceptions_internal::countdown); EXPECT_NONFATAL_FAILURE( { Tracked t; t.~Tracked(); }, - "destroyed improperly"); + "re-destroyed"); } TEST(ConstructorTrackerTest, ConstructedTwice) { + exceptions_internal::ConstructorTracker ct(exceptions_internal::countdown); absl::aligned_storage_t storage; EXPECT_NONFATAL_FAILURE( { new (&storage) Tracked; new (&storage) Tracked; + reinterpret_cast(&storage)->~Tracked(); }, "re-constructed"); - reinterpret_cast(&storage)->~Tracked(); } TEST(ThrowingValueTraitsTest, RelationalOperators) { diff --git a/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.cc b/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.cc index d3e94074b8..f1d081f7e5 100644 --- a/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.cc +++ b/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.cc @@ -21,16 +21,14 @@ namespace testing { exceptions_internal::NoThrowTag nothrow_ctor; -bool nothrow_guarantee(const void*) { - return ::testing::AssertionFailure() - << "Exception thrown violating NoThrow Guarantee"; -} exceptions_internal::StrongGuaranteeTagType strong_guarantee; namespace exceptions_internal { int countdown = -1; +ConstructorTracker* ConstructorTracker::current_tracker_instance_ = nullptr; + void MaybeThrow(absl::string_view msg, bool throw_bad_alloc) { if (countdown-- == 0) { if (throw_bad_alloc) throw TestBadAllocException(msg); @@ -43,6 +41,31 @@ testing::AssertionResult FailureMessage(const TestException& e, return testing::AssertionFailure() << "Exception thrown from " << e.what(); } +std::string GetSpecString(TypeSpec spec) { + std::string out; + absl::string_view sep; + const auto append = [&](absl::string_view s) { + absl::StrAppend(&out, sep, s); + sep = " | "; + }; + if (static_cast(TypeSpec::kNoThrowCopy & spec)) { + append("kNoThrowCopy"); + } + if (static_cast(TypeSpec::kNoThrowMove & spec)) { + append("kNoThrowMove"); + } + if (static_cast(TypeSpec::kNoThrowNew & spec)) { + append("kNoThrowNew"); + } + return out; +} + +std::string GetSpecString(AllocSpec spec) { + return static_cast(AllocSpec::kNoThrowAllocate & spec) + ? "kNoThrowAllocate" + : ""; +} + } // namespace exceptions_internal } // namespace testing diff --git a/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.h b/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.h index c3ff34c50a..8c2f5093fc 100644 --- a/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.h +++ b/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.h @@ -62,6 +62,9 @@ constexpr AllocSpec operator&(AllocSpec a, AllocSpec b) { namespace exceptions_internal { +std::string GetSpecString(TypeSpec); +std::string GetSpecString(AllocSpec); + struct NoThrowTag {}; struct StrongGuaranteeTagType {}; @@ -101,36 +104,9 @@ void MaybeThrow(absl::string_view msg, bool throw_bad_alloc = false); testing::AssertionResult FailureMessage(const TestException& e, int countdown) noexcept; -class ConstructorTracker; - -class TrackedObject { - public: - TrackedObject(const TrackedObject&) = delete; - TrackedObject(TrackedObject&&) = delete; - - protected: - explicit TrackedObject(const char* child_ctor) { - if (!GetInstanceMap().emplace(this, child_ctor).second) { - ADD_FAILURE() << "Object at address " << static_cast(this) - << " re-constructed in ctor " << child_ctor; - } - } - - ~TrackedObject() noexcept { - if (GetInstanceMap().erase(this) == 0) { - ADD_FAILURE() << "Object at address " << static_cast(this) - << " destroyed improperly"; - } - } - - private: - using InstanceMap = std::unordered_map; - static InstanceMap& GetInstanceMap() { - static auto* instance_map = new InstanceMap(); - return *instance_map; - } - - friend class ConstructorTracker; +struct TrackedAddress { + bool is_alive; + std::string description; }; // Inspects the constructions and destructions of anything inheriting from @@ -138,33 +114,86 @@ class TrackedObject { // ConstructorTracker will destroy everything left over in its destructor. class ConstructorTracker { public: - explicit ConstructorTracker(int c) - : init_count_(c), init_instances_(TrackedObject::GetInstanceMap()) {} + explicit ConstructorTracker(int count) : countdown_(count) { + assert(current_tracker_instance_ == nullptr); + current_tracker_instance_ = this; + } + ~ConstructorTracker() { - auto& cur_instances = TrackedObject::GetInstanceMap(); - for (auto it = cur_instances.begin(); it != cur_instances.end();) { - if (init_instances_.count(it->first) == 0) { - ADD_FAILURE() << "Object at address " << static_cast(it->first) - << " constructed from " << it->second - << " where the exception countdown was set to " - << init_count_ << " was not destroyed"; - // Erasing an item inside an unordered_map invalidates the existing - // iterator. A new one is returned for iteration to continue. - it = cur_instances.erase(it); - } else { - ++it; + assert(current_tracker_instance_ == this); + current_tracker_instance_ = nullptr; + + for (auto& it : address_map_) { + void* address = it.first; + TrackedAddress& tracked_address = it.second; + if (tracked_address.is_alive) { + ADD_FAILURE() << "Object at address " << address + << " with countdown of " << countdown_ + << " was not destroyed [" << tracked_address.description + << "]"; } } } + static void ObjectConstructed(void* address, std::string description) { + if (!CurrentlyTracking()) return; + + TrackedAddress& tracked_address = + current_tracker_instance_->address_map_[address]; + if (tracked_address.is_alive) { + ADD_FAILURE() << "Object at address " << address << " with countdown of " + << current_tracker_instance_->countdown_ + << " was re-constructed. Previously: [" + << tracked_address.description << "] Now: [" << description + << "]"; + } + tracked_address = {true, std::move(description)}; + } + + static void ObjectDestructed(void* address) { + if (!CurrentlyTracking()) return; + + auto it = current_tracker_instance_->address_map_.find(address); + // Not tracked. Ignore. + if (it == current_tracker_instance_->address_map_.end()) return; + + TrackedAddress& tracked_address = it->second; + if (!tracked_address.is_alive) { + ADD_FAILURE() << "Object at address " << address << " with countdown of " + << current_tracker_instance_->countdown_ + << " was re-destroyed or created prior to construction " + << "tracking [" << tracked_address.description << "]"; + } + tracked_address.is_alive = false; + } + private: - int init_count_; - TrackedObject::InstanceMap init_instances_; + static bool CurrentlyTracking() { + return current_tracker_instance_ != nullptr; + } + + std::unordered_map address_map_; + int countdown_; + + static ConstructorTracker* current_tracker_instance_; +}; + +class TrackedObject { + public: + TrackedObject(const TrackedObject&) = delete; + TrackedObject(TrackedObject&&) = delete; + + protected: + explicit TrackedObject(std::string description) { + ConstructorTracker::ObjectConstructed(this, std::move(description)); + } + + ~TrackedObject() noexcept { ConstructorTracker::ObjectDestructed(this); } }; template absl::optional TestSingleInvariantAtCountdownImpl( - const Factory& factory, Operation operation, int count, + const Factory& factory, const Operation& operation, int count, const Invariant& invariant) { auto t_ptr = factory(); absl::optional current_res; @@ -229,7 +258,6 @@ inline absl::optional TestAllInvariantsAtCountdown( extern exceptions_internal::NoThrowTag nothrow_ctor; -bool nothrow_guarantee(const void*); extern exceptions_internal::StrongGuaranteeTagType strong_guarantee; // A test class which is convertible to bool. The conversion can be @@ -283,17 +311,18 @@ class ThrowingValue : private exceptions_internal::TrackedObject { return static_cast(Spec & spec); } + static constexpr int kDefaultValue = 0; static constexpr int kBadValue = 938550620; public: - ThrowingValue() : TrackedObject(ABSL_PRETTY_FUNCTION) { + ThrowingValue() : TrackedObject(GetInstanceString(kDefaultValue)) { exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); - dummy_ = 0; + dummy_ = kDefaultValue; } ThrowingValue(const ThrowingValue& other) noexcept( IsSpecified(TypeSpec::kNoThrowCopy)) - : TrackedObject(ABSL_PRETTY_FUNCTION) { + : TrackedObject(GetInstanceString(other.dummy_)) { if (!IsSpecified(TypeSpec::kNoThrowCopy)) { exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); } @@ -302,20 +331,20 @@ class ThrowingValue : private exceptions_internal::TrackedObject { ThrowingValue(ThrowingValue&& other) noexcept( IsSpecified(TypeSpec::kNoThrowMove)) - : TrackedObject(ABSL_PRETTY_FUNCTION) { + : TrackedObject(GetInstanceString(other.dummy_)) { if (!IsSpecified(TypeSpec::kNoThrowMove)) { exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); } dummy_ = other.dummy_; } - explicit ThrowingValue(int i) : TrackedObject(ABSL_PRETTY_FUNCTION) { + explicit ThrowingValue(int i) : TrackedObject(GetInstanceString(i)) { exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); dummy_ = i; } ThrowingValue(int i, exceptions_internal::NoThrowTag) noexcept - : TrackedObject(ABSL_PRETTY_FUNCTION), dummy_(i) {} + : TrackedObject(GetInstanceString(i)), dummy_(i) {} // absl expects nothrow destructors ~ThrowingValue() noexcept = default; @@ -548,9 +577,9 @@ class ThrowingValue : private exceptions_internal::TrackedObject { void operator&() const = delete; // NOLINT(runtime/operator) // Stream operators - friend std::ostream& operator<<(std::ostream& os, const ThrowingValue&) { + friend std::ostream& operator<<(std::ostream& os, const ThrowingValue& tv) { exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); - return os; + return os << GetInstanceString(tv.dummy_); } friend std::istream& operator>>(std::istream& is, const ThrowingValue&) { @@ -606,6 +635,12 @@ class ThrowingValue : private exceptions_internal::TrackedObject { const int& Get() const noexcept { return dummy_; } private: + static std::string GetInstanceString(int dummy) { + return absl::StrCat("ThrowingValue<", + exceptions_internal::GetSpecString(Spec), ">(", dummy, + ")"); + } + int dummy_; }; // While not having to do with exceptions, explicitly delete comma operator, to @@ -658,26 +693,30 @@ class ThrowingAllocator : private exceptions_internal::TrackedObject { using propagate_on_container_swap = std::true_type; using is_always_equal = std::false_type; - ThrowingAllocator() : TrackedObject(ABSL_PRETTY_FUNCTION) { + ThrowingAllocator() : TrackedObject(GetInstanceString(next_id_)) { exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); dummy_ = std::make_shared(next_id_++); } template ThrowingAllocator(const ThrowingAllocator& other) noexcept // NOLINT - : TrackedObject(ABSL_PRETTY_FUNCTION), dummy_(other.State()) {} + : TrackedObject(GetInstanceString(*other.State())), + dummy_(other.State()) {} // According to C++11 standard [17.6.3.5], Table 28, the move/copy ctors of // allocator shall not exit via an exception, thus they are marked noexcept. ThrowingAllocator(const ThrowingAllocator& other) noexcept - : TrackedObject(ABSL_PRETTY_FUNCTION), dummy_(other.State()) {} + : TrackedObject(GetInstanceString(*other.State())), + dummy_(other.State()) {} template ThrowingAllocator(ThrowingAllocator&& other) noexcept // NOLINT - : TrackedObject(ABSL_PRETTY_FUNCTION), dummy_(std::move(other.State())) {} + : TrackedObject(GetInstanceString(*other.State())), + dummy_(std::move(other.State())) {} ThrowingAllocator(ThrowingAllocator&& other) noexcept - : TrackedObject(ABSL_PRETTY_FUNCTION), dummy_(std::move(other.State())) {} + : TrackedObject(GetInstanceString(*other.State())), + dummy_(std::move(other.State())) {} ~ThrowingAllocator() noexcept = default; @@ -758,6 +797,12 @@ class ThrowingAllocator : private exceptions_internal::TrackedObject { friend class ThrowingAllocator; private: + static std::string GetInstanceString(int dummy) { + return absl::StrCat("ThrowingAllocator<", + exceptions_internal::GetSpecString(Spec), ">(", dummy, + ")"); + } + const std::shared_ptr& State() const { return dummy_; } std::shared_ptr& State() { return dummy_; } @@ -801,6 +846,29 @@ void TestThrowingCtor(Args&&... args) { } } +// Tests the nothrow guarantee of the provided nullary operation. If the an +// exception is thrown, the result will be AssertionFailure(). Otherwise, it +// will be AssertionSuccess(). +template +testing::AssertionResult TestNothrowOp(const Operation& operation) { + struct Cleanup { + Cleanup() { exceptions_internal::SetCountdown(); } + ~Cleanup() { exceptions_internal::UnsetCountdown(); } + } c; + try { + operation(); + return testing::AssertionSuccess(); + } catch (exceptions_internal::TestException) { + return testing::AssertionFailure() + << "TestException thrown during call to operation() when nothrow " + "guarantee was expected."; + } catch (...) { + return testing::AssertionFailure() + << "Unknown exception thrown during call to operation() when " + "nothrow guarantee was expected."; + } +} + namespace exceptions_internal { // Dummy struct for ExceptionSafetyTester<> partial state. diff --git a/third_party/abseil-cpp/absl/base/internal/exception_testing.h b/third_party/abseil-cpp/absl/base/internal/exception_testing.h index 07d7e8ee1b..fd89a3f626 100644 --- a/third_party/abseil-cpp/absl/base/internal/exception_testing.h +++ b/third_party/abseil-cpp/absl/base/internal/exception_testing.h @@ -28,8 +28,12 @@ #define ABSL_BASE_INTERNAL_EXPECT_FAIL(expr, exception_t, text) \ EXPECT_THROW(expr, exception_t) +#elif defined(__ANDROID__) +// Android asserts do not log anywhere that gtest can currently inspect. +// So we expect exit, but cannot match the message. +#define ABSL_BASE_INTERNAL_EXPECT_FAIL(expr, exception_t, text) \ + EXPECT_DEATH(expr, ".*") #else - #define ABSL_BASE_INTERNAL_EXPECT_FAIL(expr, exception_t, text) \ EXPECT_DEATH(expr, text) diff --git a/third_party/abseil-cpp/absl/base/internal/hide_ptr.h b/third_party/abseil-cpp/absl/base/internal/hide_ptr.h index 2c2e11f679..45cf438912 100644 --- a/third_party/abseil-cpp/absl/base/internal/hide_ptr.h +++ b/third_party/abseil-cpp/absl/base/internal/hide_ptr.h @@ -23,9 +23,7 @@ namespace base_internal { // Arbitrary value with high bits set. Xor'ing with it is unlikely // to map one valid pointer to another valid pointer. constexpr uintptr_t HideMask() { - static_assert(sizeof(uintptr_t) == 4 || sizeof(uintptr_t) == 8, - "uintptr_t must be 32 or 64 bits"); - return sizeof(uintptr_t) == 8 ? 0xF03A5F7BF03A5F7BULL : 0xF03A5F7BUL; + return (uintptr_t{0xF03A5F7BU} << (sizeof(uintptr_t) - 4) * 8) | 0xF03A5F7BU; } // Hide a pointer from the leak checker. For internal use only. diff --git a/third_party/abseil-cpp/absl/base/internal/spinlock.cc b/third_party/abseil-cpp/absl/base/internal/spinlock.cc index 28a2059f32..1b97efbccc 100644 --- a/third_party/abseil-cpp/absl/base/internal/spinlock.cc +++ b/third_party/abseil-cpp/absl/base/internal/spinlock.cc @@ -18,10 +18,12 @@ #include #include +#include "absl/base/attributes.h" #include "absl/base/internal/atomic_hook.h" #include "absl/base/internal/cycleclock.h" #include "absl/base/internal/spinlock_wait.h" #include "absl/base/internal/sysinfo.h" /* For NumCPUs() */ +#include "absl/base/call_once.h" // Description of lock-word: // 31..00: [............................3][2][1][0] @@ -54,30 +56,10 @@ namespace absl { namespace base_internal { -static int adaptive_spin_count = 0; - -namespace { -struct SpinLock_InitHelper { - SpinLock_InitHelper() { - // On multi-cpu machines, spin for longer before yielding - // the processor or sleeping. Reduces idle time significantly. - if (base_internal::NumCPUs() > 1) { - adaptive_spin_count = 1000; - } - } -}; - -// Hook into global constructor execution: -// We do not do adaptive spinning before that, -// but nothing lock-intensive should be going on at that time. -static SpinLock_InitHelper init_helper; - ABSL_CONST_INIT static base_internal::AtomicHook submit_profile_data; -} // namespace - void RegisterSpinLockProfiler(void (*fn)(const void *contendedlock, int64_t wait_cycles)) { submit_profile_data.Store(fn); @@ -120,6 +102,14 @@ void SpinLock::InitLinkerInitializedAndCooperative() { // from the lock is returned from the method. uint32_t SpinLock::SpinLoop(int64_t initial_wait_timestamp, uint32_t *wait_cycles) { + // We are already in the slow path of SpinLock, initialize the + // adaptive_spin_count here. + ABSL_CONST_INIT static absl::once_flag init_adaptive_spin_count; + ABSL_CONST_INIT static int adaptive_spin_count = 0; + base_internal::LowLevelCallOnce(&init_adaptive_spin_count, []() { + adaptive_spin_count = base_internal::NumCPUs() > 1 ? 1000 : 1; + }); + int c = adaptive_spin_count; uint32_t lock_value; do { diff --git a/third_party/abseil-cpp/absl/base/internal/thread_identity_benchmark.cc b/third_party/abseil-cpp/absl/base/internal/thread_identity_benchmark.cc index fe22e4cff1..242522b441 100644 --- a/third_party/abseil-cpp/absl/base/internal/thread_identity_benchmark.cc +++ b/third_party/abseil-cpp/absl/base/internal/thread_identity_benchmark.cc @@ -36,5 +36,3 @@ void BM_UnsafeCurrentThreadIdentity(benchmark::State& state) { BENCHMARK(BM_UnsafeCurrentThreadIdentity); } // namespace - -BENCHMARK_MAIN(); diff --git a/third_party/abseil-cpp/absl/base/optimization.h b/third_party/abseil-cpp/absl/base/optimization.h index aaaffa495a..2fddfc800c 100644 --- a/third_party/abseil-cpp/absl/base/optimization.h +++ b/third_party/abseil-cpp/absl/base/optimization.h @@ -158,8 +158,8 @@ #define ABSL_PREDICT_FALSE(x) (__builtin_expect(x, 0)) #define ABSL_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) #else -#define ABSL_PREDICT_FALSE(x) x -#define ABSL_PREDICT_TRUE(x) x +#define ABSL_PREDICT_FALSE(x) (x) +#define ABSL_PREDICT_TRUE(x) (x) #endif #endif // ABSL_BASE_OPTIMIZATION_H_ diff --git a/third_party/abseil-cpp/absl/container/BUILD.bazel b/third_party/abseil-cpp/absl/container/BUILD.bazel index 303410834b..119d5c88de 100644 --- a/third_party/abseil-cpp/absl/container/BUILD.bazel +++ b/third_party/abseil-cpp/absl/container/BUILD.bazel @@ -69,7 +69,7 @@ cc_test( tags = ["benchmark"], deps = [ ":fixed_array", - "@com_github_google_benchmark//:benchmark", + "@com_github_google_benchmark//:benchmark_main", ], ) @@ -126,7 +126,7 @@ cc_test( ":inlined_vector", "//absl/base", "//absl/strings", - "@com_github_google_benchmark//:benchmark", + "@com_github_google_benchmark//:benchmark_main", ], ) diff --git a/third_party/abseil-cpp/absl/container/fixed_array_benchmark.cc b/third_party/abseil-cpp/absl/container/fixed_array_benchmark.cc index 2d39898d8a..b4f0cf2aeb 100644 --- a/third_party/abseil-cpp/absl/container/fixed_array_benchmark.cc +++ b/third_party/abseil-cpp/absl/container/fixed_array_benchmark.cc @@ -64,5 +64,3 @@ BENCHMARK_TEMPLATE(BM_FixedArray, std::string, 256)->Range(0, 1 << 16); BENCHMARK_TEMPLATE(BM_FixedArray, std::string, 65536)->Range(0, 1 << 16); } // namespace - -BENCHMARK_MAIN(); diff --git a/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc b/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc index c6bc5cd96d..5977bc934f 100644 --- a/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc +++ b/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc @@ -372,5 +372,3 @@ void BM_StdVectorEmpty(benchmark::State& state) { BENCHMARK(BM_StdVectorEmpty); } // namespace - -BENCHMARK_MAIN(); diff --git a/third_party/abseil-cpp/absl/memory/memory.h b/third_party/abseil-cpp/absl/memory/memory.h index 055d88e001..cd818cff4f 100644 --- a/third_party/abseil-cpp/absl/memory/memory.h +++ b/third_party/abseil-cpp/absl/memory/memory.h @@ -179,9 +179,9 @@ typename memory_internal::MakeUniqueResult::invalid make_unique( // useful within templates that need to handle a complement of raw pointers, // `std::nullptr_t`, and smart pointers. template -auto RawPtr(T&& ptr) -> decltype(&*ptr) { +auto RawPtr(T&& ptr) -> decltype(std::addressof(*ptr)) { // ptr is a forwarding reference to support Ts with non-const operators. - return (ptr != nullptr) ? &*ptr : nullptr; + return (ptr != nullptr) ? std::addressof(*ptr) : nullptr; } inline std::nullptr_t RawPtr(std::nullptr_t) { return nullptr; } diff --git a/third_party/abseil-cpp/absl/numeric/BUILD.bazel b/third_party/abseil-cpp/absl/numeric/BUILD.bazel index 0791145d0f..f49571ebb3 100644 --- a/third_party/abseil-cpp/absl/numeric/BUILD.bazel +++ b/third_party/abseil-cpp/absl/numeric/BUILD.bazel @@ -53,3 +53,15 @@ cc_test( "@com_google_googletest//:gtest_main", ], ) + +cc_test( + name = "int128_benchmark", + srcs = ["int128_benchmark.cc"], + copts = ABSL_TEST_COPTS, + tags = ["benchmark"], + deps = [ + ":int128", + "//absl/base:config", + "@com_github_google_benchmark//:benchmark_main", + ], +) diff --git a/third_party/abseil-cpp/absl/numeric/int128_benchmark.cc b/third_party/abseil-cpp/absl/numeric/int128_benchmark.cc new file mode 100644 index 0000000000..1cb7d0ed87 --- /dev/null +++ b/third_party/abseil-cpp/absl/numeric/int128_benchmark.cc @@ -0,0 +1,221 @@ +// Copyright 2017 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 +// +// http://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. + +#include "absl/numeric/int128.h" + +#include +#include +#include +#include + +#include "benchmark/benchmark.h" +#include "absl/base/config.h" + +namespace { + +constexpr size_t kSampleSize = 1000000; + +std::mt19937 MakeRandomEngine() { + std::random_device r; + std::seed_seq seed({r(), r(), r(), r(), r(), r(), r(), r()}); + return std::mt19937(seed); +} + +std::vector> +GetRandomClass128SampleUniformDivisor() { + std::vector> values; + std::mt19937 random = MakeRandomEngine(); + std::uniform_int_distribution uniform_uint64; + values.reserve(kSampleSize); + for (size_t i = 0; i < kSampleSize; ++i) { + absl::uint128 a = + absl::MakeUint128(uniform_uint64(random), uniform_uint64(random)); + absl::uint128 b = + absl::MakeUint128(uniform_uint64(random), uniform_uint64(random)); + values.emplace_back(std::max(a, b), + std::max(absl::uint128(2), std::min(a, b))); + } + return values; +} + +void BM_DivideClass128UniformDivisor(benchmark::State& state) { + auto values = GetRandomClass128SampleUniformDivisor(); + while (state.KeepRunningBatch(values.size())) { + for (const auto& pair : values) { + benchmark::DoNotOptimize(pair.first / pair.second); + } + } +} +BENCHMARK(BM_DivideClass128UniformDivisor); + +std::vector> +GetRandomClass128SampleSmallDivisor() { + std::vector> values; + std::mt19937 random = MakeRandomEngine(); + std::uniform_int_distribution uniform_uint64; + values.reserve(kSampleSize); + for (size_t i = 0; i < kSampleSize; ++i) { + absl::uint128 a = + absl::MakeUint128(uniform_uint64(random), uniform_uint64(random)); + uint64_t b = std::max(uint64_t{2}, uniform_uint64(random)); + values.emplace_back(std::max(a, absl::uint128(b)), b); + } + return values; +} + +void BM_DivideClass128SmallDivisor(benchmark::State& state) { + auto values = GetRandomClass128SampleSmallDivisor(); + while (state.KeepRunningBatch(values.size())) { + for (const auto& pair : values) { + benchmark::DoNotOptimize(pair.first / pair.second); + } + } +} +BENCHMARK(BM_DivideClass128SmallDivisor); + +std::vector> GetRandomClass128Sample() { + std::vector> values; + std::mt19937 random = MakeRandomEngine(); + std::uniform_int_distribution uniform_uint64; + values.reserve(kSampleSize); + for (size_t i = 0; i < kSampleSize; ++i) { + values.emplace_back( + absl::MakeUint128(uniform_uint64(random), uniform_uint64(random)), + absl::MakeUint128(uniform_uint64(random), uniform_uint64(random))); + } + return values; +} + +void BM_MultiplyClass128(benchmark::State& state) { + auto values = GetRandomClass128Sample(); + while (state.KeepRunningBatch(values.size())) { + for (const auto& pair : values) { + benchmark::DoNotOptimize(pair.first * pair.second); + } + } +} +BENCHMARK(BM_MultiplyClass128); + +void BM_AddClass128(benchmark::State& state) { + auto values = GetRandomClass128Sample(); + while (state.KeepRunningBatch(values.size())) { + for (const auto& pair : values) { + benchmark::DoNotOptimize(pair.first + pair.second); + } + } +} +BENCHMARK(BM_AddClass128); + +#ifdef ABSL_HAVE_INTRINSIC_INT128 + +// Some implementations of do not support __int128 when it is +// available, so we make our own uniform_int_distribution-like type. +class UniformIntDistribution128 { + public: + // NOLINTNEXTLINE: mimicking std::uniform_int_distribution API + unsigned __int128 operator()(std::mt19937& generator) { + return (static_cast(dist64_(generator)) << 64) | + dist64_(generator); + } + + private: + std::uniform_int_distribution dist64_; +}; + +std::vector> +GetRandomIntrinsic128SampleUniformDivisor() { + std::vector> values; + std::mt19937 random = MakeRandomEngine(); + UniformIntDistribution128 uniform_uint128; + values.reserve(kSampleSize); + for (size_t i = 0; i < kSampleSize; ++i) { + unsigned __int128 a = uniform_uint128(random); + unsigned __int128 b = uniform_uint128(random); + values.emplace_back( + std::max(a, b), + std::max(static_cast(2), std::min(a, b))); + } + return values; +} + +void BM_DivideIntrinsic128UniformDivisor(benchmark::State& state) { + auto values = GetRandomIntrinsic128SampleUniformDivisor(); + while (state.KeepRunningBatch(values.size())) { + for (const auto& pair : values) { + benchmark::DoNotOptimize(pair.first / pair.second); + } + } +} +BENCHMARK(BM_DivideIntrinsic128UniformDivisor); + +std::vector> +GetRandomIntrinsic128SampleSmallDivisor() { + std::vector> values; + std::mt19937 random = MakeRandomEngine(); + UniformIntDistribution128 uniform_uint128; + std::uniform_int_distribution uniform_uint64; + values.reserve(kSampleSize); + for (size_t i = 0; i < kSampleSize; ++i) { + unsigned __int128 a = uniform_uint128(random); + uint64_t b = std::max(uint64_t{2}, uniform_uint64(random)); + values.emplace_back(std::max(a, static_cast(b)), b); + } + return values; +} + +void BM_DivideIntrinsic128SmallDivisor(benchmark::State& state) { + auto values = GetRandomIntrinsic128SampleSmallDivisor(); + while (state.KeepRunningBatch(values.size())) { + for (const auto& pair : values) { + benchmark::DoNotOptimize(pair.first / pair.second); + } + } +} +BENCHMARK(BM_DivideIntrinsic128SmallDivisor); + +std::vector> + GetRandomIntrinsic128Sample() { + std::vector> values; + std::mt19937 random = MakeRandomEngine(); + UniformIntDistribution128 uniform_uint128; + values.reserve(kSampleSize); + for (size_t i = 0; i < kSampleSize; ++i) { + values.emplace_back(uniform_uint128(random), uniform_uint128(random)); + } + return values; +} + +void BM_MultiplyIntrinsic128(benchmark::State& state) { + auto values = GetRandomIntrinsic128Sample(); + while (state.KeepRunningBatch(values.size())) { + for (const auto& pair : values) { + benchmark::DoNotOptimize(pair.first * pair.second); + } + } +} +BENCHMARK(BM_MultiplyIntrinsic128); + +void BM_AddIntrinsic128(benchmark::State& state) { + auto values = GetRandomIntrinsic128Sample(); + while (state.KeepRunningBatch(values.size())) { + for (const auto& pair : values) { + benchmark::DoNotOptimize(pair.first + pair.second); + } + } +} +BENCHMARK(BM_AddIntrinsic128); + +#endif // ABSL_HAVE_INTRINSIC_INT128 + +} // namespace diff --git a/third_party/abseil-cpp/absl/strings/BUILD.bazel b/third_party/abseil-cpp/absl/strings/BUILD.bazel index 28cf2d2eba..f06bdc0d01 100644 --- a/third_party/abseil-cpp/absl/strings/BUILD.bazel +++ b/third_party/abseil-cpp/absl/strings/BUILD.bazel @@ -111,7 +111,7 @@ cc_test( size = "small", srcs = [ "escaping_test.cc", - "internal/escaping_test_common.inc", + "internal/escaping_test_common.h", ], copts = ABSL_TEST_COPTS, visibility = ["//visibility:private"], @@ -123,11 +123,32 @@ cc_test( ], ) +cc_test( + name = "escaping_benchmark", + srcs = [ + "escaping_benchmark.cc", + "internal/escaping_test_common.h", + ], + copts = ABSL_TEST_COPTS, + tags = ["benchmark"], + visibility = ["//visibility:private"], + deps = [ + ":strings", + "//absl/base", + "@com_github_google_benchmark//:benchmark_main", + ], +) + cc_test( name = "ascii_test", size = "small", srcs = ["ascii_test.cc"], copts = ABSL_TEST_COPTS, + tags = [ + "no_test_android_arm", + "no_test_android_arm64", + "no_test_android_x86", + ], visibility = ["//visibility:private"], deps = [ ":strings", @@ -136,6 +157,22 @@ cc_test( ], ) +cc_test( + name = "memutil_benchmark", + srcs = [ + "internal/memutil.h", + "internal/memutil_benchmark.cc", + ], + copts = ABSL_TEST_COPTS, + tags = ["benchmark"], + visibility = ["//visibility:private"], + deps = [ + ":strings", + "//absl/base:core_headers", + "@com_github_google_benchmark//:benchmark_main", + ], +) + cc_test( name = "memutil_test", size = "small", @@ -178,7 +215,7 @@ cc_test( ":strings", "//absl/base", "//absl/base:core_headers", - "@com_github_google_benchmark//:benchmark", + "@com_github_google_benchmark//:benchmark_main", ], ) @@ -219,7 +256,7 @@ cc_test( deps = [ ":strings", "//absl/base", - "@com_github_google_benchmark//:benchmark", + "@com_github_google_benchmark//:benchmark_main", ], ) @@ -257,7 +294,7 @@ cc_test( deps = [ ":strings", "//absl/base", - "@com_github_google_benchmark//:benchmark", + "@com_github_google_benchmark//:benchmark_main", ], ) @@ -273,6 +310,18 @@ cc_test( ], ) +cc_test( + name = "ostringstream_benchmark", + srcs = ["internal/ostringstream_benchmark.cc"], + copts = ABSL_TEST_COPTS, + tags = ["benchmark"], + visibility = ["//visibility:private"], + deps = [ + ":internal", + "@com_github_google_benchmark//:benchmark_main", + ], +) + cc_test( name = "resize_uninitialized_test", size = "small", @@ -312,7 +361,7 @@ cc_test( deps = [ ":strings", "//absl/memory", - "@com_github_google_benchmark//:benchmark", + "@com_github_google_benchmark//:benchmark_main", ], ) @@ -337,7 +386,7 @@ cc_test( visibility = ["//visibility:private"], deps = [ ":strings", - "@com_github_google_benchmark//:benchmark", + "@com_github_google_benchmark//:benchmark_main", ], ) @@ -345,11 +394,14 @@ cc_test( name = "numbers_test", size = "small", srcs = [ - "internal/numbers_test_common.inc", + "internal/numbers_test_common.h", "numbers_test.cc", ], copts = ABSL_TEST_COPTS, tags = [ + "no_test_android_arm", + "no_test_android_arm64", + "no_test_android_x86", "no_test_loonix", ], visibility = ["//visibility:private"], @@ -377,8 +429,24 @@ cc_test( name = "char_map_test", srcs = ["internal/char_map_test.cc"], copts = ABSL_TEST_COPTS, + tags = [ + "no_test_android_arm", + "no_test_android_arm64", + "no_test_android_x86", + ], deps = [ ":internal", "@com_google_googletest//:gtest_main", ], ) + +cc_test( + name = "char_map_benchmark", + srcs = ["internal/char_map_benchmark.cc"], + copts = ABSL_TEST_COPTS, + tags = ["benchmark"], + deps = [ + ":internal", + "@com_github_google_benchmark//:benchmark_main", + ], +) diff --git a/third_party/abseil-cpp/absl/strings/ascii_test.cc b/third_party/abseil-cpp/absl/strings/ascii_test.cc index 97f36013bd..9903b0496b 100644 --- a/third_party/abseil-cpp/absl/strings/ascii_test.cc +++ b/third_party/abseil-cpp/absl/strings/ascii_test.cc @@ -130,9 +130,11 @@ TEST(AsciiIsFoo, All) { // Checks that absl::ascii_isfoo returns the same value as isfoo in the C // locale. TEST(AsciiIsFoo, SameAsIsFoo) { +#ifndef __ANDROID__ // temporarily change locale to C. It should already be C, but just for safety - std::string old_locale = setlocale(LC_CTYPE, nullptr); - ASSERT_TRUE(setlocale(LC_CTYPE, "C")); + const char* old_locale = setlocale(LC_CTYPE, "C"); + ASSERT_TRUE(old_locale != nullptr); +#endif for (int i = 0; i < 256; i++) { EXPECT_EQ(isalpha(i) != 0, absl::ascii_isalpha(i)) << i; @@ -150,14 +152,18 @@ TEST(AsciiIsFoo, SameAsIsFoo) { EXPECT_EQ(isascii(i) != 0, absl::ascii_isascii(i)) << i; } +#ifndef __ANDROID__ // restore the old locale. - ASSERT_TRUE(setlocale(LC_CTYPE, old_locale.c_str())); + ASSERT_TRUE(setlocale(LC_CTYPE, old_locale)); +#endif } TEST(AsciiToFoo, All) { +#ifndef __ANDROID__ // temporarily change locale to C. It should already be C, but just for safety - std::string old_locale = setlocale(LC_CTYPE, nullptr); - ASSERT_TRUE(setlocale(LC_CTYPE, "C")); + const char* old_locale = setlocale(LC_CTYPE, "C"); + ASSERT_TRUE(old_locale != nullptr); +#endif for (int i = 0; i < 256; i++) { if (absl::ascii_islower(i)) @@ -180,9 +186,10 @@ TEST(AsciiToFoo, All) { EXPECT_EQ(absl::ascii_tolower(i), absl::ascii_tolower(sc)) << i; EXPECT_EQ(absl::ascii_toupper(i), absl::ascii_toupper(sc)) << i; } - +#ifndef __ANDROID__ // restore the old locale. - ASSERT_TRUE(setlocale(LC_CTYPE, old_locale.c_str())); + ASSERT_TRUE(setlocale(LC_CTYPE, old_locale)); +#endif } TEST(AsciiStrTo, Lower) { diff --git a/third_party/abseil-cpp/absl/strings/escaping_benchmark.cc b/third_party/abseil-cpp/absl/strings/escaping_benchmark.cc new file mode 100644 index 0000000000..0f791f4e87 --- /dev/null +++ b/third_party/abseil-cpp/absl/strings/escaping_benchmark.cc @@ -0,0 +1,94 @@ +// Copyright 2018 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 +// +// http://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. + +#include "absl/strings/escaping.h" + +#include +#include +#include + +#include "benchmark/benchmark.h" +#include "absl/base/internal/raw_logging.h" +#include "absl/strings/internal/escaping_test_common.h" + +namespace { + +void BM_CUnescapeHexString(benchmark::State& state) { + std::string src; + for (int i = 0; i < 50; i++) { + src += "\\x55"; + } + std::string dest; + for (auto _ : state) { + absl::CUnescape(src, &dest); + } +} +BENCHMARK(BM_CUnescapeHexString); + +void BM_WebSafeBase64Escape_string(benchmark::State& state) { + std::string raw; + for (int i = 0; i < 10; ++i) { + for (const auto& test_set : absl::strings_internal::base64_strings()) { + raw += std::string(test_set.plaintext); + } + } + + // The actual benchmark loop is tiny... + std::string escaped; + for (auto _ : state) { + absl::WebSafeBase64Escape(raw, &escaped); + } + + // We want to be sure the compiler doesn't throw away the loop above, + // and the easiest way to ensure that is to round-trip the results and verify + // them. + std::string round_trip; + absl::WebSafeBase64Unescape(escaped, &round_trip); + ABSL_RAW_CHECK(round_trip == raw, ""); +} +BENCHMARK(BM_WebSafeBase64Escape_string); + +// Used for the CEscape benchmarks +const char kStringValueNoEscape[] = "1234567890"; +const char kStringValueSomeEscaped[] = "123\n56789\xA1"; +const char kStringValueMostEscaped[] = "\xA1\xA2\ny\xA4\xA5\xA6z\b\r"; + +void CEscapeBenchmarkHelper(benchmark::State& state, const char* string_value, + int max_len) { + std::string src; + while (src.size() < max_len) { + absl::StrAppend(&src, string_value); + } + + for (auto _ : state) { + absl::CEscape(src); + } +} + +void BM_CEscape_NoEscape(benchmark::State& state) { + CEscapeBenchmarkHelper(state, kStringValueNoEscape, state.range(0)); +} +BENCHMARK(BM_CEscape_NoEscape)->Range(1, 1 << 14); + +void BM_CEscape_SomeEscaped(benchmark::State& state) { + CEscapeBenchmarkHelper(state, kStringValueSomeEscaped, state.range(0)); +} +BENCHMARK(BM_CEscape_SomeEscaped)->Range(1, 1 << 14); + +void BM_CEscape_MostEscaped(benchmark::State& state) { + CEscapeBenchmarkHelper(state, kStringValueMostEscaped, state.range(0)); +} +BENCHMARK(BM_CEscape_MostEscaped)->Range(1, 1 << 14); + +} // namespace diff --git a/third_party/abseil-cpp/absl/strings/escaping_test.cc b/third_party/abseil-cpp/absl/strings/escaping_test.cc index 982989b8b4..3f65ec107f 100644 --- a/third_party/abseil-cpp/absl/strings/escaping_test.cc +++ b/third_party/abseil-cpp/absl/strings/escaping_test.cc @@ -25,7 +25,7 @@ #include "absl/container/fixed_array.h" #include "absl/strings/str_cat.h" -#include "absl/strings/internal/escaping_test_common.inc" +#include "absl/strings/internal/escaping_test_common.h" namespace { @@ -575,7 +575,7 @@ TEST(Base64, EscapeAndUnescape) { } // Now try the long strings, this tests the streaming - for (const auto& tc : base64_strings) { + for (const auto& tc : absl::strings_internal::base64_strings()) { std::string buffer; absl::WebSafeBase64Escape(tc.plaintext, &buffer); EXPECT_EQ(tc.cyphertext, buffer); diff --git a/third_party/abseil-cpp/absl/strings/internal/char_map_benchmark.cc b/third_party/abseil-cpp/absl/strings/internal/char_map_benchmark.cc new file mode 100644 index 0000000000..c45f3157c2 --- /dev/null +++ b/third_party/abseil-cpp/absl/strings/internal/char_map_benchmark.cc @@ -0,0 +1,61 @@ +// Copyright 2017 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 +// +// http://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. + +#include "absl/strings/internal/char_map.h" + +#include + +#include "benchmark/benchmark.h" + +namespace { + +absl::strings_internal::Charmap MakeBenchmarkMap() { + absl::strings_internal::Charmap m; + uint32_t x[] = {0x0, 0x1, 0x2, 0x3, 0xf, 0xe, 0xd, 0xc}; + for (uint32_t& t : x) t *= static_cast(0x11111111UL); + for (uint32_t i = 0; i < 256; ++i) { + if ((x[i / 32] >> (i % 32)) & 1) + m = m | absl::strings_internal::Charmap::Char(i); + } + return m; +} + +// Micro-benchmark for Charmap::contains. +void BM_Contains(benchmark::State& state) { + // Loop-body replicated 10 times to increase time per iteration. + // Argument continuously changed to avoid generating common subexpressions. + const absl::strings_internal::Charmap benchmark_map = MakeBenchmarkMap(); + unsigned char c = 0; + int ops = 0; + for (auto _ : state) { + ops += benchmark_map.contains(c++); + ops += benchmark_map.contains(c++); + ops += benchmark_map.contains(c++); + ops += benchmark_map.contains(c++); + ops += benchmark_map.contains(c++); + ops += benchmark_map.contains(c++); + ops += benchmark_map.contains(c++); + ops += benchmark_map.contains(c++); + ops += benchmark_map.contains(c++); + ops += benchmark_map.contains(c++); + } + benchmark::DoNotOptimize(ops); +} +BENCHMARK(BM_Contains); + +// We don't bother benchmarking Charmap::IsZero or Charmap::IntersectsWith; +// their running time is data-dependent and it is not worth characterizing +// "typical" data. + +} // namespace diff --git a/third_party/abseil-cpp/absl/strings/internal/escaping_test_common.h b/third_party/abseil-cpp/absl/strings/internal/escaping_test_common.h new file mode 100644 index 0000000000..cc41f4312c --- /dev/null +++ b/third_party/abseil-cpp/absl/strings/internal/escaping_test_common.h @@ -0,0 +1,131 @@ +// Copyright 2017 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 +// +// http://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. +// +// This test contains common things needed by both escaping_test.cc and +// escaping_benchmark.cc. + +#ifndef ABSL_STRINGS_INTERNAL_ESCAPING_TEST_COMMON_H_ +#define ABSL_STRINGS_INTERNAL_ESCAPING_TEST_COMMON_H_ + +#include +#include "absl/strings/string_view.h" + +namespace absl { +namespace strings_internal { + +struct base64_testcase { + absl::string_view plaintext; + absl::string_view cyphertext; +}; + +inline const std::array& base64_strings() { + static const std::array testcase{{ + // Some google quotes + // Cyphertext created with "uuencode (GNU sharutils) 4.6.3" + // (Note that we're testing the websafe encoding, though, so if + // you add messages, be sure to run "tr -- '+/' '-_'" on the output) + { "I was always good at math and science, and I never realized " + "that was unusual or somehow undesirable. So one of the things " + "I care a lot about is helping to remove that stigma, " + "to show girls that you can be feminine, you can like the things " + "that girls like, but you can also be really good at technology. " + "You can be really good at building things." + " - Marissa Meyer, Newsweek, 2010-12-22" "\n", + + "SSB3YXMgYWx3YXlzIGdvb2QgYXQgbWF0aCBhbmQgc2NpZW5jZSwgYW5kIEkg" + "bmV2ZXIgcmVhbGl6ZWQgdGhhdCB3YXMgdW51c3VhbCBvciBzb21laG93IHVu" + "ZGVzaXJhYmxlLiBTbyBvbmUgb2YgdGhlIHRoaW5ncyBJIGNhcmUgYSBsb3Qg" + "YWJvdXQgaXMgaGVscGluZyB0byByZW1vdmUgdGhhdCBzdGlnbWEsIHRvIHNo" + "b3cgZ2lybHMgdGhhdCB5b3UgY2FuIGJlIGZlbWluaW5lLCB5b3UgY2FuIGxp" + "a2UgdGhlIHRoaW5ncyB0aGF0IGdpcmxzIGxpa2UsIGJ1dCB5b3UgY2FuIGFs" + "c28gYmUgcmVhbGx5IGdvb2QgYXQgdGVjaG5vbG9neS4gWW91IGNhbiBiZSBy" + "ZWFsbHkgZ29vZCBhdCBidWlsZGluZyB0aGluZ3MuIC0gTWFyaXNzYSBNZXll" + "ciwgTmV3c3dlZWssIDIwMTAtMTItMjIK" }, + + { "Typical first year for a new cluster: " + "~0.5 overheating " + "~1 PDU failure " + "~1 rack-move " + "~1 network rewiring " + "~20 rack failures " + "~5 racks go wonky " + "~8 network maintenances " + "~12 router reloads " + "~3 router failures " + "~dozens of minor 30-second blips for dns " + "~1000 individual machine failures " + "~thousands of hard drive failures " + "slow disks, bad memory, misconfigured machines, flaky machines, etc." + " - Jeff Dean, The Joys of Real Hardware" "\n", + + "VHlwaWNhbCBmaXJzdCB5ZWFyIGZvciBhIG5ldyBjbHVzdGVyOiB-MC41IG92" + "ZXJoZWF0aW5nIH4xIFBEVSBmYWlsdXJlIH4xIHJhY2stbW92ZSB-MSBuZXR3" + "b3JrIHJld2lyaW5nIH4yMCByYWNrIGZhaWx1cmVzIH41IHJhY2tzIGdvIHdv" + "bmt5IH44IG5ldHdvcmsgbWFpbnRlbmFuY2VzIH4xMiByb3V0ZXIgcmVsb2Fk" + "cyB-MyByb3V0ZXIgZmFpbHVyZXMgfmRvemVucyBvZiBtaW5vciAzMC1zZWNv" + "bmQgYmxpcHMgZm9yIGRucyB-MTAwMCBpbmRpdmlkdWFsIG1hY2hpbmUgZmFp" + "bHVyZXMgfnRob3VzYW5kcyBvZiBoYXJkIGRyaXZlIGZhaWx1cmVzIHNsb3cg" + "ZGlza3MsIGJhZCBtZW1vcnksIG1pc2NvbmZpZ3VyZWQgbWFjaGluZXMsIGZs" + "YWt5IG1hY2hpbmVzLCBldGMuIC0gSmVmZiBEZWFuLCBUaGUgSm95cyBvZiBS" + "ZWFsIEhhcmR3YXJlCg" }, + + { "I'm the head of the webspam team at Google. " + "That means that if you type your name into Google and get porn back, " + "it's my fault. Unless you're a porn star, in which case porn is a " + "completely reasonable response." + " - Matt Cutts, Google Plus" "\n", + + "SSdtIHRoZSBoZWFkIG9mIHRoZSB3ZWJzcGFtIHRlYW0gYXQgR29vZ2xlLiAg" + "VGhhdCBtZWFucyB0aGF0IGlmIHlvdSB0eXBlIHlvdXIgbmFtZSBpbnRvIEdv" + "b2dsZSBhbmQgZ2V0IHBvcm4gYmFjaywgaXQncyBteSBmYXVsdC4gVW5sZXNz" + "IHlvdSdyZSBhIHBvcm4gc3RhciwgaW4gd2hpY2ggY2FzZSBwb3JuIGlzIGEg" + "Y29tcGxldGVseSByZWFzb25hYmxlIHJlc3BvbnNlLiAtIE1hdHQgQ3V0dHMs" + "IEdvb2dsZSBQbHVzCg" }, + + { "It will still be a long time before machines approach human " + "intelligence. " + "But luckily, machines don't actually have to be intelligent; " + "they just have to fake it. Access to a wealth of information, " + "combined with a rudimentary decision-making capacity, " + "can often be almost as useful. Of course, the results are better yet " + "when coupled with intelligence. A reference librarian with access to " + "a good search engine is a formidable tool." + " - Craig Silverstein, Siemens Pictures of the Future, Spring 2004" + "\n", + + "SXQgd2lsbCBzdGlsbCBiZSBhIGxvbmcgdGltZSBiZWZvcmUgbWFjaGluZXMg" + "YXBwcm9hY2ggaHVtYW4gaW50ZWxsaWdlbmNlLiBCdXQgbHVja2lseSwgbWFj" + "aGluZXMgZG9uJ3QgYWN0dWFsbHkgaGF2ZSB0byBiZSBpbnRlbGxpZ2VudDsg" + "dGhleSBqdXN0IGhhdmUgdG8gZmFrZSBpdC4gQWNjZXNzIHRvIGEgd2VhbHRo" + "IG9mIGluZm9ybWF0aW9uLCBjb21iaW5lZCB3aXRoIGEgcnVkaW1lbnRhcnkg" + "ZGVjaXNpb24tbWFraW5nIGNhcGFjaXR5LCBjYW4gb2Z0ZW4gYmUgYWxtb3N0" + "IGFzIHVzZWZ1bC4gT2YgY291cnNlLCB0aGUgcmVzdWx0cyBhcmUgYmV0dGVy" + "IHlldCB3aGVuIGNvdXBsZWQgd2l0aCBpbnRlbGxpZ2VuY2UuIEEgcmVmZXJl" + "bmNlIGxpYnJhcmlhbiB3aXRoIGFjY2VzcyB0byBhIGdvb2Qgc2VhcmNoIGVu" + "Z2luZSBpcyBhIGZvcm1pZGFibGUgdG9vbC4gLSBDcmFpZyBTaWx2ZXJzdGVp" + "biwgU2llbWVucyBQaWN0dXJlcyBvZiB0aGUgRnV0dXJlLCBTcHJpbmcgMjAw" + "NAo" }, + + // Degenerate edge case + { "", + "" }, + }}; + + return testcase; +} + +} // namespace strings_internal +} // namespace absl + +#endif // ABSL_STRINGS_INTERNAL_ESCAPING_TEST_COMMON_H_ diff --git a/third_party/abseil-cpp/absl/strings/internal/memutil_benchmark.cc b/third_party/abseil-cpp/absl/strings/internal/memutil_benchmark.cc new file mode 100644 index 0000000000..77915adb95 --- /dev/null +++ b/third_party/abseil-cpp/absl/strings/internal/memutil_benchmark.cc @@ -0,0 +1,323 @@ +// Copyright 2018 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 +// +// http://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. + +#include "absl/strings/internal/memutil.h" + +#include +#include + +#include "benchmark/benchmark.h" +#include "absl/strings/ascii.h" + +// We fill the haystack with aaaaaaaaaaaaaaaaaa...aaaab. +// That gives us: +// - an easy search: 'b' +// - a medium search: 'ab'. That means every letter is a possible match. +// - a pathological search: 'aaaaaa.......aaaaab' (half as many a's as haytack) +// We benchmark case-sensitive and case-insensitive versions of +// three memmem implementations: +// - memmem() from memutil.h +// - search() from STL +// - memmatch(), a custom implementation using memchr and memcmp. +// Here are sample results: +// +// Run on (12 X 3800 MHz CPU s) +// CPU Caches: +// L1 Data 32K (x6) +// L1 Instruction 32K (x6) +// L2 Unified 256K (x6) +// L3 Unified 15360K (x1) +// ---------------------------------------------------------------- +// Benchmark Time CPU Iterations +// ---------------------------------------------------------------- +// BM_Memmem 3583 ns 3582 ns 196469 2.59966GB/s +// BM_MemmemMedium 13743 ns 13742 ns 50901 693.986MB/s +// BM_MemmemPathological 13695030 ns 13693977 ns 51 713.133kB/s +// BM_Memcasemem 3299 ns 3299 ns 212942 2.82309GB/s +// BM_MemcasememMedium 16407 ns 16406 ns 42170 581.309MB/s +// BM_MemcasememPathological 17267745 ns 17266030 ns 41 565.598kB/s +// BM_Search 1610 ns 1609 ns 431321 5.78672GB/s +// BM_SearchMedium 11111 ns 11110 ns 63001 858.414MB/s +// BM_SearchPathological 12117390 ns 12116397 ns 58 805.984kB/s +// BM_Searchcase 3081 ns 3081 ns 229949 3.02313GB/s +// BM_SearchcaseMedium 16003 ns 16001 ns 44170 595.998MB/s +// BM_SearchcasePathological 15823413 ns 15821909 ns 44 617.222kB/s +// BM_Memmatch 197 ns 197 ns 3584225 47.2951GB/s +// BM_MemmatchMedium 52333 ns 52329 ns 13280 182.244MB/s +// BM_MemmatchPathological 659799 ns 659727 ns 1058 14.4556MB/s +// BM_Memcasematch 5460 ns 5460 ns 127606 1.70586GB/s +// BM_MemcasematchMedium 32861 ns 32857 ns 21258 290.248MB/s +// BM_MemcasematchPathological 15154243 ns 15153089 ns 46 644.464kB/s +// BM_MemmemStartup 5 ns 5 ns 150821500 +// BM_SearchStartup 5 ns 5 ns 150644203 +// BM_MemmatchStartup 7 ns 7 ns 97068802 +// +// Conclusions: +// +// The following recommendations are based on the sample results above. However, +// we have found that the performance of STL search can vary significantly +// depending on compiler and standard library implementation. We recommend you +// run the benchmarks for yourself on relevant platforms. +// +// If you need case-insensitive, STL search is slightly better than memmem for +// all cases. +// +// Case-sensitive is more subtle: +// Custom memmatch is _very_ fast at scanning, so if you have very few possible +// matches in your haystack, that's the way to go. Performance drops +// significantly with more matches. +// +// STL search is slightly faster than memmem in the medium and pathological +// benchmarks. However, the performance of memmem is currently more dependable +// across platforms and build configurations. + +namespace { + +constexpr int kHaystackSize = 10000; +constexpr int64_t kHaystackSize64 = kHaystackSize; +const char* MakeHaystack() { + char* haystack = new char[kHaystackSize]; + for (int i = 0; i < kHaystackSize - 1; ++i) haystack[i] = 'a'; + haystack[kHaystackSize - 1] = 'b'; + return haystack; +} +const char* const kHaystack = MakeHaystack(); + +void BM_Memmem(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize( + absl::strings_internal::memmem(kHaystack, kHaystackSize, "b", 1)); + } + state.SetBytesProcessed(kHaystackSize64 * state.iterations()); +} +BENCHMARK(BM_Memmem); + +void BM_MemmemMedium(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize( + absl::strings_internal::memmem(kHaystack, kHaystackSize, "ab", 2)); + } + state.SetBytesProcessed(kHaystackSize64 * state.iterations()); +} +BENCHMARK(BM_MemmemMedium); + +void BM_MemmemPathological(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize(absl::strings_internal::memmem( + kHaystack, kHaystackSize, kHaystack + kHaystackSize / 2, + kHaystackSize - kHaystackSize / 2)); + } + state.SetBytesProcessed(kHaystackSize64 * state.iterations()); +} +BENCHMARK(BM_MemmemPathological); + +void BM_Memcasemem(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize( + absl::strings_internal::memcasemem(kHaystack, kHaystackSize, "b", 1)); + } + state.SetBytesProcessed(kHaystackSize64 * state.iterations()); +} +BENCHMARK(BM_Memcasemem); + +void BM_MemcasememMedium(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize( + absl::strings_internal::memcasemem(kHaystack, kHaystackSize, "ab", 2)); + } + state.SetBytesProcessed(kHaystackSize64 * state.iterations()); +} +BENCHMARK(BM_MemcasememMedium); + +void BM_MemcasememPathological(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize(absl::strings_internal::memcasemem( + kHaystack, kHaystackSize, kHaystack + kHaystackSize / 2, + kHaystackSize - kHaystackSize / 2)); + } + state.SetBytesProcessed(kHaystackSize64 * state.iterations()); +} +BENCHMARK(BM_MemcasememPathological); + +bool case_eq(const char a, const char b) { + return absl::ascii_tolower(a) == absl::ascii_tolower(b); +} + +void BM_Search(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize, + kHaystack + kHaystackSize - 1, + kHaystack + kHaystackSize)); + } + state.SetBytesProcessed(kHaystackSize64 * state.iterations()); +} +BENCHMARK(BM_Search); + +void BM_SearchMedium(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize, + kHaystack + kHaystackSize - 2, + kHaystack + kHaystackSize)); + } + state.SetBytesProcessed(kHaystackSize64 * state.iterations()); +} +BENCHMARK(BM_SearchMedium); + +void BM_SearchPathological(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize, + kHaystack + kHaystackSize / 2, + kHaystack + kHaystackSize)); + } + state.SetBytesProcessed(kHaystackSize64 * state.iterations()); +} +BENCHMARK(BM_SearchPathological); + +void BM_Searchcase(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize, + kHaystack + kHaystackSize - 1, + kHaystack + kHaystackSize, case_eq)); + } + state.SetBytesProcessed(kHaystackSize64 * state.iterations()); +} +BENCHMARK(BM_Searchcase); + +void BM_SearchcaseMedium(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize, + kHaystack + kHaystackSize - 2, + kHaystack + kHaystackSize, case_eq)); + } + state.SetBytesProcessed(kHaystackSize64 * state.iterations()); +} +BENCHMARK(BM_SearchcaseMedium); + +void BM_SearchcasePathological(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize(std::search(kHaystack, kHaystack + kHaystackSize, + kHaystack + kHaystackSize / 2, + kHaystack + kHaystackSize, case_eq)); + } + state.SetBytesProcessed(kHaystackSize64 * state.iterations()); +} +BENCHMARK(BM_SearchcasePathological); + +char* memcasechr(const char* s, int c, size_t slen) { + c = absl::ascii_tolower(c); + for (; slen; ++s, --slen) { + if (absl::ascii_tolower(*s) == c) return const_cast(s); + } + return nullptr; +} + +const char* memcasematch(const char* phaystack, size_t haylen, + const char* pneedle, size_t neelen) { + if (0 == neelen) { + return phaystack; // even if haylen is 0 + } + if (haylen < neelen) return nullptr; + + const char* match; + const char* hayend = phaystack + haylen - neelen + 1; + while ((match = static_cast( + memcasechr(phaystack, pneedle[0], hayend - phaystack)))) { + if (absl::strings_internal::memcasecmp(match, pneedle, neelen) == 0) + return match; + else + phaystack = match + 1; + } + return nullptr; +} + +void BM_Memmatch(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize( + absl::strings_internal::memmatch(kHaystack, kHaystackSize, "b", 1)); + } + state.SetBytesProcessed(kHaystackSize64 * state.iterations()); +} +BENCHMARK(BM_Memmatch); + +void BM_MemmatchMedium(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize( + absl::strings_internal::memmatch(kHaystack, kHaystackSize, "ab", 2)); + } + state.SetBytesProcessed(kHaystackSize64 * state.iterations()); +} +BENCHMARK(BM_MemmatchMedium); + +void BM_MemmatchPathological(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize(absl::strings_internal::memmatch( + kHaystack, kHaystackSize, kHaystack + kHaystackSize / 2, + kHaystackSize - kHaystackSize / 2)); + } + state.SetBytesProcessed(kHaystackSize64 * state.iterations()); +} +BENCHMARK(BM_MemmatchPathological); + +void BM_Memcasematch(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize(memcasematch(kHaystack, kHaystackSize, "b", 1)); + } + state.SetBytesProcessed(kHaystackSize64 * state.iterations()); +} +BENCHMARK(BM_Memcasematch); + +void BM_MemcasematchMedium(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize(memcasematch(kHaystack, kHaystackSize, "ab", 2)); + } + state.SetBytesProcessed(kHaystackSize64 * state.iterations()); +} +BENCHMARK(BM_MemcasematchMedium); + +void BM_MemcasematchPathological(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize(memcasematch(kHaystack, kHaystackSize, + kHaystack + kHaystackSize / 2, + kHaystackSize - kHaystackSize / 2)); + } + state.SetBytesProcessed(kHaystackSize64 * state.iterations()); +} +BENCHMARK(BM_MemcasematchPathological); + +void BM_MemmemStartup(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize(absl::strings_internal::memmem( + kHaystack + kHaystackSize - 10, 10, kHaystack + kHaystackSize - 1, 1)); + } +} +BENCHMARK(BM_MemmemStartup); + +void BM_SearchStartup(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize( + std::search(kHaystack + kHaystackSize - 10, kHaystack + kHaystackSize, + kHaystack + kHaystackSize - 1, kHaystack + kHaystackSize)); + } +} +BENCHMARK(BM_SearchStartup); + +void BM_MemmatchStartup(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize(absl::strings_internal::memmatch( + kHaystack + kHaystackSize - 10, 10, kHaystack + kHaystackSize - 1, 1)); + } +} +BENCHMARK(BM_MemmatchStartup); + +} // namespace diff --git a/third_party/abseil-cpp/absl/strings/internal/numbers_test_common.h b/third_party/abseil-cpp/absl/strings/internal/numbers_test_common.h new file mode 100644 index 0000000000..20e3af5114 --- /dev/null +++ b/third_party/abseil-cpp/absl/strings/internal/numbers_test_common.h @@ -0,0 +1,178 @@ +// Copyright 2017 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 +// +// http://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. +// +// This file contains common things needed by numbers_test.cc, +// numbers_legacy_test.cc and numbers_benchmark.cc. + +#ifndef ABSL_STRINGS_INTERNAL_NUMBERS_TEST_COMMON_H_ +#define ABSL_STRINGS_INTERNAL_NUMBERS_TEST_COMMON_H_ + +#include +#include +#include +#include + +namespace absl { +namespace strings_internal { + +template +inline bool Itoa(IntType value, int base, std::string* destination) { + destination->clear(); + if (base <= 1 || base > 36) { + return false; + } + + if (value == 0) { + destination->push_back('0'); + return true; + } + + bool negative = value < 0; + while (value != 0) { + const IntType next_value = value / base; + // Can't use std::abs here because of problems when IntType is unsigned. + int remainder = value > next_value * base ? value - next_value * base + : next_value * base - value; + char c = remainder < 10 ? '0' + remainder : 'A' + remainder - 10; + destination->insert(0, 1, c); + value = next_value; + } + + if (negative) { + destination->insert(0, 1, '-'); + } + return true; +} + +struct uint32_test_case { + const char* str; + bool expect_ok; + int base; // base to pass to the conversion function + uint32_t expected; +}; + +inline const std::array& strtouint32_test_cases() { + static const std::array test_cases{{ + {"0xffffffff", true, 16, std::numeric_limits::max()}, + {"0x34234324", true, 16, 0x34234324}, + {"34234324", true, 16, 0x34234324}, + {"0", true, 16, 0}, + {" \t\n 0xffffffff", true, 16, std::numeric_limits::max()}, + {" \f\v 46", true, 10, 46}, // must accept weird whitespace + {" \t\n 72717222", true, 8, 072717222}, + {" \t\n 072717222", true, 8, 072717222}, + {" \t\n 072717228", false, 8, 07271722}, + {"0", true, 0, 0}, + + // Base-10 version. + {"34234324", true, 0, 34234324}, + {"4294967295", true, 0, std::numeric_limits::max()}, + {"34234324 \n\t", true, 10, 34234324}, + + // Unusual base + {"0", true, 3, 0}, + {"2", true, 3, 2}, + {"11", true, 3, 4}, + + // Invalid uints. + {"", false, 0, 0}, + {" ", false, 0, 0}, + {"abc", false, 0, 0}, // would be valid hex, but prefix is missing + {"34234324a", false, 0, 34234324}, + {"34234.3", false, 0, 34234}, + {"-1", false, 0, 0}, + {" -123", false, 0, 0}, + {" \t\n -123", false, 0, 0}, + + // Out of bounds. + {"4294967296", false, 0, std::numeric_limits::max()}, + {"0x100000000", false, 0, std::numeric_limits::max()}, + {nullptr, false, 0, 0}, + }}; + return test_cases; +} + +struct uint64_test_case { + const char* str; + bool expect_ok; + int base; + uint64_t expected; +}; + +inline const std::array& strtouint64_test_cases() { + static const std::array test_cases{{ + {"0x3423432448783446", true, 16, int64_t{0x3423432448783446}}, + {"3423432448783446", true, 16, int64_t{0x3423432448783446}}, + + {"0", true, 16, 0}, + {"000", true, 0, 0}, + {"0", true, 0, 0}, + {" \t\n 0xffffffffffffffff", true, 16, + std::numeric_limits::max()}, + + {"012345670123456701234", true, 8, int64_t{012345670123456701234}}, + {"12345670123456701234", true, 8, int64_t{012345670123456701234}}, + + {"12845670123456701234", false, 8, 0}, + + // Base-10 version. + {"34234324487834466", true, 0, int64_t{34234324487834466}}, + + {" \t\n 18446744073709551615", true, 0, + std::numeric_limits::max()}, + + {"34234324487834466 \n\t ", true, 0, int64_t{34234324487834466}}, + + {" \f\v 46", true, 10, 46}, // must accept weird whitespace + + // Unusual base + {"0", true, 3, 0}, + {"2", true, 3, 2}, + {"11", true, 3, 4}, + + {"0", true, 0, 0}, + + // Invalid uints. + {"", false, 0, 0}, + {" ", false, 0, 0}, + {"abc", false, 0, 0}, + {"34234324487834466a", false, 0, 0}, + {"34234487834466.3", false, 0, 0}, + {"-1", false, 0, 0}, + {" -123", false, 0, 0}, + {" \t\n -123", false, 0, 0}, + + // Out of bounds. + {"18446744073709551616", false, 10, 0}, + {"18446744073709551616", false, 0, 0}, + {"0x10000000000000000", false, 16, std::numeric_limits::max()}, + {"0X10000000000000000", false, 16, + std::numeric_limits::max()}, // 0X versus 0x. + {"0x10000000000000000", false, 0, std::numeric_limits::max()}, + {"0X10000000000000000", false, 0, + std::numeric_limits::max()}, // 0X versus 0x. + + {"0x1234", true, 16, 0x1234}, + + // Base-10 std::string version. + {"1234", true, 0, 1234}, + {nullptr, false, 0, 0}, + }}; + return test_cases; +} + +} // namespace strings_internal +} // namespace absl + +#endif // ABSL_STRINGS_INTERNAL_NUMBERS_TEST_COMMON_H_ diff --git a/third_party/abseil-cpp/absl/strings/internal/ostringstream_benchmark.cc b/third_party/abseil-cpp/absl/strings/internal/ostringstream_benchmark.cc new file mode 100644 index 0000000000..c93f96909d --- /dev/null +++ b/third_party/abseil-cpp/absl/strings/internal/ostringstream_benchmark.cc @@ -0,0 +1,106 @@ +// Copyright 2018 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 +// +// http://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. + +#include "absl/strings/internal/ostringstream.h" + +#include +#include + +#include "benchmark/benchmark.h" + +namespace { + +enum StringType { + kNone, + kStdString, +}; + +// Benchmarks for std::ostringstream. +template +void BM_StdStream(benchmark::State& state) { + const int num_writes = state.range(0); + const int bytes_per_write = state.range(1); + const std::string payload(bytes_per_write, 'x'); + for (auto _ : state) { + std::ostringstream strm; + benchmark::DoNotOptimize(strm); + for (int i = 0; i != num_writes; ++i) { + strm << payload; + } + switch (kOutput) { + case kNone: { + break; + } + case kStdString: { + std::string s = strm.str(); + benchmark::DoNotOptimize(s); + break; + } + } + } +} + +// Create the stream, optionally write to it, then destroy it. +BENCHMARK_TEMPLATE(BM_StdStream, kNone) + ->ArgPair(0, 0) + ->ArgPair(1, 16) // 16 bytes is small enough for SSO + ->ArgPair(1, 256) // 256 bytes requires heap allocation + ->ArgPair(1024, 256); +// Create the stream, write to it, get std::string out, then destroy. +BENCHMARK_TEMPLATE(BM_StdStream, kStdString) + ->ArgPair(1, 16) // 16 bytes is small enough for SSO + ->ArgPair(1, 256) // 256 bytes requires heap allocation + ->ArgPair(1024, 256); + +// Benchmarks for OStringStream. +template +void BM_CustomStream(benchmark::State& state) { + const int num_writes = state.range(0); + const int bytes_per_write = state.range(1); + const std::string payload(bytes_per_write, 'x'); + for (auto _ : state) { + std::string out; + absl::strings_internal::OStringStream strm(&out); + benchmark::DoNotOptimize(strm); + for (int i = 0; i != num_writes; ++i) { + strm << payload; + } + switch (kOutput) { + case kNone: { + break; + } + case kStdString: { + std::string s = out; + benchmark::DoNotOptimize(s); + break; + } + } + } +} + +// Create the stream, optionally write to it, then destroy it. +BENCHMARK_TEMPLATE(BM_CustomStream, kNone) + ->ArgPair(0, 0) + ->ArgPair(1, 16) // 16 bytes is small enough for SSO + ->ArgPair(1, 256) // 256 bytes requires heap allocation + ->ArgPair(1024, 256); +// Create the stream, write to it, get std::string out, then destroy. +// It's not useful in practice to extract std::string from OStringStream; we +// measure it for completeness. +BENCHMARK_TEMPLATE(BM_CustomStream, kStdString) + ->ArgPair(1, 16) // 16 bytes is small enough for SSO + ->ArgPair(1, 256) // 256 bytes requires heap allocation + ->ArgPair(1024, 256); + +} // namespace diff --git a/third_party/abseil-cpp/absl/strings/numbers.h b/third_party/abseil-cpp/absl/strings/numbers.h index 75925e61f2..cf3c597266 100644 --- a/third_party/abseil-cpp/absl/strings/numbers.h +++ b/third_party/abseil-cpp/absl/strings/numbers.h @@ -52,12 +52,16 @@ ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view s, int_type* out); // // Converts the given std::string (optionally followed or preceded by ASCII // whitespace) into a float, which may be rounded on overflow or underflow. +// See http://en.cppreference.com/w/c/std::string/byte/strtof for details about the +// allowed formats for `str`. ABSL_MUST_USE_RESULT bool SimpleAtof(absl::string_view str, float* value); // SimpleAtod() // // Converts the given std::string (optionally followed or preceded by ASCII // whitespace) into a double, which may be rounded on overflow or underflow. +// See http://en.cppreference.com/w/c/std::string/byte/strtof for details about the +// allowed formats for `str`. ABSL_MUST_USE_RESULT bool SimpleAtod(absl::string_view str, double* value); // SimpleAtob() diff --git a/third_party/abseil-cpp/absl/strings/numbers_test.cc b/third_party/abseil-cpp/absl/strings/numbers_test.cc index 5bb39ca9b5..24e7138cfa 100644 --- a/third_party/abseil-cpp/absl/strings/numbers_test.cc +++ b/third_party/abseil-cpp/absl/strings/numbers_test.cc @@ -38,7 +38,7 @@ #include "absl/base/internal/raw_logging.h" #include "absl/strings/str_cat.h" -#include "absl/strings/internal/numbers_test_common.inc" +#include "absl/strings/internal/numbers_test_common.h" namespace { @@ -48,6 +48,9 @@ using absl::numbers_internal::safe_strto64_base; using absl::numbers_internal::safe_strtou32_base; using absl::numbers_internal::safe_strtou64_base; using absl::numbers_internal::SixDigitsToBuffer; +using absl::strings_internal::Itoa; +using absl::strings_internal::strtouint32_test_cases; +using absl::strings_internal::strtouint64_test_cases; using absl::SimpleAtoi; using testing::Eq; using testing::MatchesRegex; @@ -119,7 +122,7 @@ TEST(ToString, PerfectDtoa) { {1e-300, 1e-200, 1e-100, 0.1, 1.0, 10.0, 1e100, 1e300}) { double d = multiplier * i; std::string s = PerfectDtoa(d); - EXPECT_EQ(d, strtod(s.c_str(), nullptr)); + EXPECT_DOUBLE_EQ(d, strtod(s.c_str(), nullptr)); } } } @@ -654,8 +657,8 @@ TEST(stringtest, safe_strtou64_random) { } TEST(stringtest, safe_strtou32_base) { - for (int i = 0; strtouint32_test_cases[i].str != nullptr; ++i) { - const auto& e = strtouint32_test_cases[i]; + for (int i = 0; strtouint32_test_cases()[i].str != nullptr; ++i) { + const auto& e = strtouint32_test_cases()[i]; uint32_t value; EXPECT_EQ(e.expect_ok, safe_strtou32_base(e.str, &value, e.base)) << "str=\"" << e.str << "\" base=" << e.base; @@ -667,8 +670,8 @@ TEST(stringtest, safe_strtou32_base) { } TEST(stringtest, safe_strtou32_base_length_delimited) { - for (int i = 0; strtouint32_test_cases[i].str != nullptr; ++i) { - const auto& e = strtouint32_test_cases[i]; + for (int i = 0; strtouint32_test_cases()[i].str != nullptr; ++i) { + const auto& e = strtouint32_test_cases()[i]; std::string tmp(e.str); tmp.append("12"); // Adds garbage at the end. @@ -685,8 +688,8 @@ TEST(stringtest, safe_strtou32_base_length_delimited) { } TEST(stringtest, safe_strtou64_base) { - for (int i = 0; strtouint64_test_cases[i].str != nullptr; ++i) { - const auto& e = strtouint64_test_cases[i]; + for (int i = 0; strtouint64_test_cases()[i].str != nullptr; ++i) { + const auto& e = strtouint64_test_cases()[i]; uint64_t value; EXPECT_EQ(e.expect_ok, safe_strtou64_base(e.str, &value, e.base)) << "str=\"" << e.str << "\" base=" << e.base; @@ -697,8 +700,8 @@ TEST(stringtest, safe_strtou64_base) { } TEST(stringtest, safe_strtou64_base_length_delimited) { - for (int i = 0; strtouint64_test_cases[i].str != nullptr; ++i) { - const auto& e = strtouint64_test_cases[i]; + for (int i = 0; strtouint64_test_cases()[i].str != nullptr; ++i) { + const auto& e = strtouint64_test_cases()[i]; std::string tmp(e.str); tmp.append("12"); // Adds garbage at the end. diff --git a/third_party/abseil-cpp/absl/strings/str_cat_benchmark.cc b/third_party/abseil-cpp/absl/strings/str_cat_benchmark.cc index 1791410c6e..b6df9e309c 100644 --- a/third_party/abseil-cpp/absl/strings/str_cat_benchmark.cc +++ b/third_party/abseil-cpp/absl/strings/str_cat_benchmark.cc @@ -138,5 +138,3 @@ void BM_DoubleToString_By_SixDigits(benchmark::State& state) { BENCHMARK(BM_DoubleToString_By_SixDigits); } // namespace - -BENCHMARK_MAIN(); diff --git a/third_party/abseil-cpp/absl/strings/str_cat_test.cc b/third_party/abseil-cpp/absl/strings/str_cat_test.cc index c86a5952fa..e9d6769063 100644 --- a/third_party/abseil-cpp/absl/strings/str_cat_test.cc +++ b/third_party/abseil-cpp/absl/strings/str_cat_test.cc @@ -22,6 +22,15 @@ #include "gtest/gtest.h" #include "absl/strings/substitute.h" +#ifdef __ANDROID__ +// Android assert messages only go to system log, so death tests cannot inspect +// the message for matching. +#define ABSL_EXPECT_DEBUG_DEATH(statement, regex) \ + EXPECT_DEBUG_DEATH(statement, ".*") +#else +#define ABSL_EXPECT_DEBUG_DEATH EXPECT_DEBUG_DEATH +#endif + namespace { // Test absl::StrCat of ints and longs of various sizes and signdedness. @@ -396,8 +405,9 @@ TEST(StrAppend, Death) { std::string s = "self"; // on linux it's "assertion", on mac it's "Assertion", // on chromiumos it's "Assertion ... failed". - EXPECT_DEBUG_DEATH(absl::StrAppend(&s, s.c_str() + 1), "ssertion.*failed"); - EXPECT_DEBUG_DEATH(absl::StrAppend(&s, s), "ssertion.*failed"); + ABSL_EXPECT_DEBUG_DEATH(absl::StrAppend(&s, s.c_str() + 1), + "ssertion.*failed"); + ABSL_EXPECT_DEBUG_DEATH(absl::StrAppend(&s, s), "ssertion.*failed"); } #endif // GTEST_HAS_DEATH_TEST diff --git a/third_party/abseil-cpp/absl/strings/str_join_benchmark.cc b/third_party/abseil-cpp/absl/strings/str_join_benchmark.cc index 79cad5e393..7fb0e4973c 100644 --- a/third_party/abseil-cpp/absl/strings/str_join_benchmark.cc +++ b/third_party/abseil-cpp/absl/strings/str_join_benchmark.cc @@ -94,5 +94,3 @@ BENCHMARK(BM_JoinStreamable) ->ArgPair(256, 256); } // namespace - -BENCHMARK_MAIN(); diff --git a/third_party/abseil-cpp/absl/strings/str_replace_benchmark.cc b/third_party/abseil-cpp/absl/strings/str_replace_benchmark.cc index 9dd72eb6e7..e608de8d19 100644 --- a/third_party/abseil-cpp/absl/strings/str_replace_benchmark.cc +++ b/third_party/abseil-cpp/absl/strings/str_replace_benchmark.cc @@ -120,5 +120,3 @@ void BM_StrReplaceAll(benchmark::State& state) { BENCHMARK(BM_StrReplaceAll); } // namespace - -BENCHMARK_MAIN(); diff --git a/third_party/abseil-cpp/absl/strings/str_split_benchmark.cc b/third_party/abseil-cpp/absl/strings/str_split_benchmark.cc index c35787b7ef..326ff744eb 100644 --- a/third_party/abseil-cpp/absl/strings/str_split_benchmark.cc +++ b/third_party/abseil-cpp/absl/strings/str_split_benchmark.cc @@ -154,5 +154,3 @@ BENCHMARK_TEMPLATE(BM_SplitStringWithOneCharNoVector, OneCharLiteral); BENCHMARK_TEMPLATE(BM_SplitStringWithOneCharNoVector, OneCharStringLiteral); } // namespace - -BENCHMARK_MAIN(); diff --git a/third_party/abseil-cpp/absl/strings/string_view_benchmark.cc b/third_party/abseil-cpp/absl/strings/string_view_benchmark.cc index c66f0fbd54..fb46db18b3 100644 --- a/third_party/abseil-cpp/absl/strings/string_view_benchmark.cc +++ b/third_party/abseil-cpp/absl/strings/string_view_benchmark.cc @@ -327,5 +327,3 @@ void BM_AppendToStringNative(benchmark::State& state) { BENCHMARK(BM_AppendToStringNative)->Range(1 << 3, 1 << 12); } // namespace - -BENCHMARK_MAIN(); diff --git a/third_party/abseil-cpp/absl/strings/string_view_test.cc b/third_party/abseil-cpp/absl/strings/string_view_test.cc index 4162102489..b19d07c7fd 100644 --- a/third_party/abseil-cpp/absl/strings/string_view_test.cc +++ b/third_party/abseil-cpp/absl/strings/string_view_test.cc @@ -29,6 +29,15 @@ #include "absl/base/config.h" #include "absl/base/dynamic_annotations.h" +#ifdef __ANDROID__ +// Android assert messages only go to system log, so death tests cannot inspect +// the message for matching. +#define ABSL_EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + EXPECT_DEATH_IF_SUPPORTED(statement, ".*") +#else +#define ABSL_EXPECT_DEATH_IF_SUPPORTED EXPECT_DEATH_IF_SUPPORTED +#endif + namespace { // A minimal allocator that uses malloc(). @@ -1068,7 +1077,8 @@ TEST(HugeStringView, TwoPointTwoGB) { #if !defined(NDEBUG) && !defined(ABSL_HAVE_STD_STRING_VIEW) TEST(NonNegativeLenTest, NonNegativeLen) { - EXPECT_DEATH_IF_SUPPORTED(absl::string_view("xyz", -1), "len <= kMaxSize"); + ABSL_EXPECT_DEATH_IF_SUPPORTED(absl::string_view("xyz", -1), + "len <= kMaxSize"); } TEST(LenExceedsMaxSizeTest, LenExceedsMaxSize) { @@ -1078,8 +1088,8 @@ TEST(LenExceedsMaxSizeTest, LenExceedsMaxSize) { absl::string_view ok_view("", max_size); // Adding one to the max should trigger an assertion. - EXPECT_DEATH_IF_SUPPORTED(absl::string_view("", max_size + 1), - "len <= kMaxSize"); + ABSL_EXPECT_DEATH_IF_SUPPORTED(absl::string_view("", max_size + 1), + "len <= kMaxSize"); } #endif // !defined(NDEBUG) && !defined(ABSL_HAVE_STD_STRING_VIEW) diff --git a/third_party/abseil-cpp/absl/strings/substitute.h b/third_party/abseil-cpp/absl/strings/substitute.h index 5747d384d3..c4b25ba709 100644 --- a/third_party/abseil-cpp/absl/strings/substitute.h +++ b/third_party/abseil-cpp/absl/strings/substitute.h @@ -99,7 +99,10 @@ class Arg { // Explicitly overload `const char*` so the compiler doesn't cast to `bool`. Arg(const char* value) // NOLINT(runtime/explicit) : piece_(absl::NullSafeStringView(value)) {} - Arg(const std::string& value) // NOLINT(runtime/explicit) + template + Arg( // NOLINT + const std::basic_string, Allocator>& + value) noexcept : piece_(value) {} Arg(absl::string_view value) // NOLINT(runtime/explicit) : piece_(value) {} diff --git a/third_party/abseil-cpp/absl/synchronization/BUILD.bazel b/third_party/abseil-cpp/absl/synchronization/BUILD.bazel index 67ce7ff9bb..123536ea4d 100644 --- a/third_party/abseil-cpp/absl/synchronization/BUILD.bazel +++ b/third_party/abseil-cpp/absl/synchronization/BUILD.bazel @@ -130,7 +130,7 @@ cc_test( deps = [ ":graphcycles_internal", "//absl/base", - "@com_github_google_benchmark//:benchmark", + "@com_github_google_benchmark//:benchmark_main", ], ) @@ -150,6 +150,9 @@ cc_test( srcs = ["mutex_test.cc"], copts = ABSL_TEST_COPTS, tags = [ + "no_test_android_arm", + "no_test_android_arm64", + "no_test_android_x86", "no_test_loonix", # Too slow. ], deps = [ @@ -173,7 +176,7 @@ cc_test( ":synchronization", ":thread_pool", "//absl/base", - "@com_github_google_benchmark//:benchmark", + "@com_github_google_benchmark//:benchmark_main", ], ) diff --git a/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.h b/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.h index 53474b7b0b..2e6686a4c0 100644 --- a/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.h +++ b/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.h @@ -133,4 +133,5 @@ class GraphCycles { } // namespace synchronization_internal } // namespace absl + #endif diff --git a/third_party/abseil-cpp/absl/synchronization/internal/graphcycles_benchmark.cc b/third_party/abseil-cpp/absl/synchronization/internal/graphcycles_benchmark.cc index b4a1debe75..a239c25c3a 100644 --- a/third_party/abseil-cpp/absl/synchronization/internal/graphcycles_benchmark.cc +++ b/third_party/abseil-cpp/absl/synchronization/internal/graphcycles_benchmark.cc @@ -42,5 +42,3 @@ void BM_StressTest(benchmark::State& state) { BENCHMARK(BM_StressTest)->Range(2048, 1048576); } // namespace - -BENCHMARK_MAIN(); diff --git a/third_party/abseil-cpp/absl/synchronization/mutex_benchmark.cc b/third_party/abseil-cpp/absl/synchronization/mutex_benchmark.cc index d91071b71b..30a523556c 100644 --- a/third_party/abseil-cpp/absl/synchronization/mutex_benchmark.cc +++ b/third_party/abseil-cpp/absl/synchronization/mutex_benchmark.cc @@ -92,5 +92,3 @@ BENCHMARK(BM_ContendedMutex)->Threads(1); BENCHMARK(BM_ContendedMutex)->ThreadPerCpu(); } // namespace - -BENCHMARK_MAIN(); diff --git a/third_party/abseil-cpp/absl/time/BUILD.bazel b/third_party/abseil-cpp/absl/time/BUILD.bazel index 7126f1410f..fe55fe1f9b 100644 --- a/third_party/abseil-cpp/absl/time/BUILD.bazel +++ b/third_party/abseil-cpp/absl/time/BUILD.bazel @@ -81,10 +81,6 @@ cc_test( ], copts = ABSL_TEST_COPTS, tags = [ - "no_test_android_arm", - "no_test_android_arm64", - "no_test_android_x86", - "no_test_ios_x86_64", "no_test_loonix", ], deps = [ @@ -97,3 +93,23 @@ cc_test( "@com_google_googletest//:gtest_main", ], ) + +cc_test( + name = "time_benchmark", + srcs = [ + "clock_benchmark.cc", + "duration_benchmark.cc", + "format_benchmark.cc", + "time_benchmark.cc", + ], + copts = ABSL_TEST_COPTS, + tags = [ + "benchmark", + ], + deps = [ + ":test_util", + ":time", + "//absl/base", + "@com_github_google_benchmark//:benchmark_main", + ], +) diff --git a/third_party/abseil-cpp/absl/time/clock_benchmark.cc b/third_party/abseil-cpp/absl/time/clock_benchmark.cc new file mode 100644 index 0000000000..3d3cd9d5c4 --- /dev/null +++ b/third_party/abseil-cpp/absl/time/clock_benchmark.cc @@ -0,0 +1,72 @@ +// Copyright 2018 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 +// +// http://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. + +#include "absl/time/clock.h" + +#if !defined(_WIN32) +#include +#endif // _WIN32 +#include + +#include "absl/base/internal/cycleclock.h" +#include "benchmark/benchmark.h" + +namespace { + +void BM_Clock_Now_AbslTime(benchmark::State& state) { + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::Now()); + } +} +BENCHMARK(BM_Clock_Now_AbslTime); + +void BM_Clock_Now_GetCurrentTimeNanos(benchmark::State& state) { + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::GetCurrentTimeNanos()); + } +} +BENCHMARK(BM_Clock_Now_GetCurrentTimeNanos); + +void BM_Clock_Now_AbslTime_ToUnixNanos(benchmark::State& state) { + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::ToUnixNanos(absl::Now())); + } +} +BENCHMARK(BM_Clock_Now_AbslTime_ToUnixNanos); + +void BM_Clock_Now_CycleClock(benchmark::State& state) { + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::base_internal::CycleClock::Now()); + } +} +BENCHMARK(BM_Clock_Now_CycleClock); + +#if !defined(_WIN32) +static void BM_Clock_Now_gettimeofday(benchmark::State& state) { + struct timeval tv; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(gettimeofday(&tv, nullptr)); + } +} +BENCHMARK(BM_Clock_Now_gettimeofday); + +static void BM_Clock_Now_clock_gettime(benchmark::State& state) { + struct timespec ts; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(clock_gettime(CLOCK_REALTIME, &ts)); + } +} +BENCHMARK(BM_Clock_Now_clock_gettime); +#endif // _WIN32 + +} // namespace diff --git a/third_party/abseil-cpp/absl/time/duration_benchmark.cc b/third_party/abseil-cpp/absl/time/duration_benchmark.cc new file mode 100644 index 0000000000..54f89a1f00 --- /dev/null +++ b/third_party/abseil-cpp/absl/time/duration_benchmark.cc @@ -0,0 +1,361 @@ +// Copyright 2018 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 +// +// http://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. + +#include +#include +#include +#include +#include + +#include "absl/time/time.h" +#include "benchmark/benchmark.h" + +namespace { + +// +// Factory functions +// + +void BM_Duration_Factory_Nanoseconds(benchmark::State& state) { + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::Nanoseconds(1)); + } +} +BENCHMARK(BM_Duration_Factory_Nanoseconds); + +void BM_Duration_Factory_Microseconds(benchmark::State& state) { + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::Microseconds(1)); + } +} +BENCHMARK(BM_Duration_Factory_Microseconds); + +void BM_Duration_Factory_Milliseconds(benchmark::State& state) { + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::Milliseconds(1)); + } +} +BENCHMARK(BM_Duration_Factory_Milliseconds); + +void BM_Duration_Factory_Seconds(benchmark::State& state) { + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::Seconds(1)); + } +} +BENCHMARK(BM_Duration_Factory_Seconds); + +void BM_Duration_Factory_Minutes(benchmark::State& state) { + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::Minutes(1)); + } +} +BENCHMARK(BM_Duration_Factory_Minutes); + +void BM_Duration_Factory_Hours(benchmark::State& state) { + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::Hours(1)); + } +} +BENCHMARK(BM_Duration_Factory_Hours); + +// +// Arithmetic +// + +void BM_Duration_Addition(benchmark::State& state) { + absl::Duration d = absl::Nanoseconds(1); + absl::Duration step = absl::Milliseconds(1); + while (state.KeepRunning()) { + benchmark::DoNotOptimize(d += step); + } +} +BENCHMARK(BM_Duration_Addition); + +void BM_Duration_Subtraction(benchmark::State& state) { + absl::Duration d = absl::Seconds(std::numeric_limits::max()); + absl::Duration step = absl::Milliseconds(1); + while (state.KeepRunning()) { + benchmark::DoNotOptimize(d -= step); + } +} +BENCHMARK(BM_Duration_Subtraction); + +void BM_Duration_Multiplication_Fixed(benchmark::State& state) { + absl::Duration d = absl::Milliseconds(1); + absl::Duration s; + int i = 0; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(s += d * (i + 1)); + ++i; + } +} +BENCHMARK(BM_Duration_Multiplication_Fixed); + +void BM_Duration_Multiplication_Double(benchmark::State& state) { + absl::Duration d = absl::Milliseconds(1); + absl::Duration s; + int i = 0; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(s += d * (i + 1.0)); + ++i; + } +} +BENCHMARK(BM_Duration_Multiplication_Double); + +void BM_Duration_Division_Fixed(benchmark::State& state) { + absl::Duration d = absl::Seconds(1); + int i = 0; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(d /= i + 1); + ++i; + } +} +BENCHMARK(BM_Duration_Division_Fixed); + +void BM_Duration_Division_Double(benchmark::State& state) { + absl::Duration d = absl::Seconds(1); + int i = 0; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(d /= i + 1.0); + ++i; + } +} +BENCHMARK(BM_Duration_Division_Double); + +void BM_Duration_FDivDuration_Nanoseconds(benchmark::State& state) { + double d = 1; + int i = 0; + while (state.KeepRunning()) { + benchmark::DoNotOptimize( + d += absl::FDivDuration(absl::Milliseconds(i), absl::Nanoseconds(1))); + ++i; + } +} +BENCHMARK(BM_Duration_FDivDuration_Nanoseconds); + +void BM_Duration_IDivDuration_Nanoseconds(benchmark::State& state) { + int64_t a = 1; + absl::Duration ignore; + int i = 0; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(a += + absl::IDivDuration(absl::Nanoseconds(i), + absl::Nanoseconds(1), &ignore)); + ++i; + } +} +BENCHMARK(BM_Duration_IDivDuration_Nanoseconds); + +void BM_Duration_IDivDuration_Microseconds(benchmark::State& state) { + int64_t a = 1; + absl::Duration ignore; + int i = 0; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(a += absl::IDivDuration(absl::Microseconds(i), + absl::Microseconds(1), + &ignore)); + ++i; + } +} +BENCHMARK(BM_Duration_IDivDuration_Microseconds); + +void BM_Duration_IDivDuration_Milliseconds(benchmark::State& state) { + int64_t a = 1; + absl::Duration ignore; + int i = 0; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(a += absl::IDivDuration(absl::Milliseconds(i), + absl::Milliseconds(1), + &ignore)); + ++i; + } +} +BENCHMARK(BM_Duration_IDivDuration_Milliseconds); + +void BM_Duration_IDivDuration_Seconds(benchmark::State& state) { + int64_t a = 1; + absl::Duration ignore; + int i = 0; + while (state.KeepRunning()) { + benchmark::DoNotOptimize( + a += absl::IDivDuration(absl::Seconds(i), absl::Seconds(1), &ignore)); + ++i; + } +} +BENCHMARK(BM_Duration_IDivDuration_Seconds); + +void BM_Duration_IDivDuration_Minutes(benchmark::State& state) { + int64_t a = 1; + absl::Duration ignore; + int i = 0; + while (state.KeepRunning()) { + benchmark::DoNotOptimize( + a += absl::IDivDuration(absl::Minutes(i), absl::Minutes(1), &ignore)); + ++i; + } +} +BENCHMARK(BM_Duration_IDivDuration_Minutes); + +void BM_Duration_IDivDuration_Hours(benchmark::State& state) { + int64_t a = 1; + absl::Duration ignore; + int i = 0; + while (state.KeepRunning()) { + benchmark::DoNotOptimize( + a += absl::IDivDuration(absl::Hours(i), absl::Hours(1), &ignore)); + ++i; + } +} +BENCHMARK(BM_Duration_IDivDuration_Hours); + +void BM_Duration_ToInt64Nanoseconds(benchmark::State& state) { + absl::Duration d = absl::Seconds(100000); + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::ToInt64Nanoseconds(d)); + } +} +BENCHMARK(BM_Duration_ToInt64Nanoseconds); + +void BM_Duration_ToInt64Microseconds(benchmark::State& state) { + absl::Duration d = absl::Seconds(100000); + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::ToInt64Microseconds(d)); + } +} +BENCHMARK(BM_Duration_ToInt64Microseconds); + +void BM_Duration_ToInt64Milliseconds(benchmark::State& state) { + absl::Duration d = absl::Seconds(100000); + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::ToInt64Milliseconds(d)); + } +} +BENCHMARK(BM_Duration_ToInt64Milliseconds); + +void BM_Duration_ToInt64Seconds(benchmark::State& state) { + absl::Duration d = absl::Seconds(100000); + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::ToInt64Seconds(d)); + } +} +BENCHMARK(BM_Duration_ToInt64Seconds); + +void BM_Duration_ToInt64Minutes(benchmark::State& state) { + absl::Duration d = absl::Seconds(100000); + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::ToInt64Minutes(d)); + } +} +BENCHMARK(BM_Duration_ToInt64Minutes); + +void BM_Duration_ToInt64Hours(benchmark::State& state) { + absl::Duration d = absl::Seconds(100000); + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::ToInt64Hours(d)); + } +} +BENCHMARK(BM_Duration_ToInt64Hours); + +// +// To/FromTimespec +// + +void BM_Duration_ToTimespec_AbslTime(benchmark::State& state) { + absl::Duration d = absl::Seconds(1); + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::ToTimespec(d)); + } +} +BENCHMARK(BM_Duration_ToTimespec_AbslTime); + +ABSL_ATTRIBUTE_NOINLINE timespec DoubleToTimespec(double seconds) { + timespec ts; + ts.tv_sec = seconds; + ts.tv_nsec = (seconds - ts.tv_sec) * (1000 * 1000 * 1000); + return ts; +} + +void BM_Duration_ToTimespec_Double(benchmark::State& state) { + while (state.KeepRunning()) { + benchmark::DoNotOptimize(DoubleToTimespec(1.0)); + } +} +BENCHMARK(BM_Duration_ToTimespec_Double); + +void BM_Duration_FromTimespec_AbslTime(benchmark::State& state) { + timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = 0; + while (state.KeepRunning()) { + if (++ts.tv_nsec == 1000 * 1000 * 1000) { + ++ts.tv_sec; + ts.tv_nsec = 0; + } + benchmark::DoNotOptimize(absl::DurationFromTimespec(ts)); + } +} +BENCHMARK(BM_Duration_FromTimespec_AbslTime); + +ABSL_ATTRIBUTE_NOINLINE double TimespecToDouble(timespec ts) { + return ts.tv_sec + (ts.tv_nsec / (1000 * 1000 * 1000)); +} + +void BM_Duration_FromTimespec_Double(benchmark::State& state) { + timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = 0; + while (state.KeepRunning()) { + if (++ts.tv_nsec == 1000 * 1000 * 1000) { + ++ts.tv_sec; + ts.tv_nsec = 0; + } + benchmark::DoNotOptimize(TimespecToDouble(ts)); + } +} +BENCHMARK(BM_Duration_FromTimespec_Double); + +// +// String conversions +// + +const char* const kDurations[] = { + "0", // 0 + "123ns", // 1 + "1h2m3s", // 2 + "-2h3m4.005006007s", // 3 + "2562047788015215h30m7.99999999975s", // 4 +}; +const int kNumDurations = sizeof(kDurations) / sizeof(kDurations[0]); + +void BM_Duration_FormatDuration(benchmark::State& state) { + const std::string s = kDurations[state.range(0)]; + state.SetLabel(s); + absl::Duration d; + absl::ParseDuration(kDurations[state.range(0)], &d); + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::FormatDuration(d)); + } +} +BENCHMARK(BM_Duration_FormatDuration)->DenseRange(0, kNumDurations - 1); + +void BM_Duration_ParseDuration(benchmark::State& state) { + const std::string s = kDurations[state.range(0)]; + state.SetLabel(s); + absl::Duration d; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::ParseDuration(s, &d)); + } +} +BENCHMARK(BM_Duration_ParseDuration)->DenseRange(0, kNumDurations - 1); + +} // namespace diff --git a/third_party/abseil-cpp/absl/time/duration_test.cc b/third_party/abseil-cpp/absl/time/duration_test.cc index 7918e16770..704684edb3 100644 --- a/third_party/abseil-cpp/absl/time/duration_test.cc +++ b/third_party/abseil-cpp/absl/time/duration_test.cc @@ -330,18 +330,10 @@ TEST(Duration, ToChrono) { EXPECT_EQ(hours::max(), absl::ToChronoHours(inf)); } -// Used for testing the factory overloads. -template -struct ImplicitlyConvertible { - T n_; - explicit ImplicitlyConvertible(T n) : n_(n) {} - // Marking this conversion operator with 'explicit' will cause the test to - // fail (as desired). - operator T() { return n_; } -}; - TEST(Duration, FactoryOverloads) { + enum E { kOne = 1 }; #define TEST_FACTORY_OVERLOADS(NAME) \ + EXPECT_EQ(1, NAME(kOne) / NAME(kOne)); \ EXPECT_EQ(1, NAME(static_cast(1)) / NAME(1)); \ EXPECT_EQ(1, NAME(static_cast(1)) / NAME(1)); \ EXPECT_EQ(1, NAME(static_cast(1)) / NAME(1)); \ @@ -350,14 +342,6 @@ TEST(Duration, FactoryOverloads) { EXPECT_EQ(1, NAME(static_cast(1)) / NAME(1)); \ EXPECT_EQ(1, NAME(static_cast(1)) / NAME(1)); \ EXPECT_EQ(1, NAME(static_cast(1)) / NAME(1)); \ - EXPECT_EQ(1, NAME(ImplicitlyConvertible(1)) / NAME(1)); \ - EXPECT_EQ(1, NAME(ImplicitlyConvertible(1)) / NAME(1)); \ - EXPECT_EQ(1, NAME(ImplicitlyConvertible(1)) / NAME(1)); \ - EXPECT_EQ(1, NAME(ImplicitlyConvertible(1)) / NAME(1)); \ - EXPECT_EQ(1, NAME(ImplicitlyConvertible(1)) / NAME(1)); \ - EXPECT_EQ(1, NAME(ImplicitlyConvertible(1)) / NAME(1)); \ - EXPECT_EQ(1, NAME(ImplicitlyConvertible(1)) / NAME(1)); \ - EXPECT_EQ(1, NAME(ImplicitlyConvertible(1)) / NAME(1)); \ EXPECT_EQ(NAME(1) / 2, NAME(static_cast(0.5))); \ EXPECT_EQ(NAME(1) / 2, NAME(static_cast(0.5))); \ EXPECT_EQ(1.5, absl::FDivDuration(NAME(static_cast(1.5)), NAME(1))); \ diff --git a/third_party/abseil-cpp/absl/time/format_benchmark.cc b/third_party/abseil-cpp/absl/time/format_benchmark.cc new file mode 100644 index 0000000000..ee53d71c68 --- /dev/null +++ b/third_party/abseil-cpp/absl/time/format_benchmark.cc @@ -0,0 +1,63 @@ +// Copyright 2018 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 +// +// http://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. + +#include +#include + +#include "absl/time/internal/test_util.h" +#include "absl/time/time.h" +#include "benchmark/benchmark.h" + +namespace { + +namespace { +const char* const kFormats[] = { + absl::RFC1123_full, // 0 + absl::RFC1123_no_wday, // 1 + absl::RFC3339_full, // 2 + absl::RFC3339_sec, // 3 + "%Y-%m-%dT%H:%M:%S", // 4 + "%Y-%m-%d", // 5 +}; +const int kNumFormats = sizeof(kFormats) / sizeof(kFormats[0]); +} // namespace + +void BM_Format_FormatTime(benchmark::State& state) { + const std::string fmt = kFormats[state.range(0)]; + state.SetLabel(fmt); + const absl::TimeZone lax = + absl::time_internal::LoadTimeZone("America/Los_Angeles"); + const absl::Time t = + absl::FromDateTime(1977, 6, 28, 9, 8, 7, lax) + absl::Nanoseconds(1); + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::FormatTime(fmt, t, lax).length()); + } +} +BENCHMARK(BM_Format_FormatTime)->DenseRange(0, kNumFormats - 1); + +void BM_Format_ParseTime(benchmark::State& state) { + const std::string fmt = kFormats[state.range(0)]; + state.SetLabel(fmt); + const absl::TimeZone lax = + absl::time_internal::LoadTimeZone("America/Los_Angeles"); + absl::Time t = + absl::FromDateTime(1977, 6, 28, 9, 8, 7, lax) + absl::Nanoseconds(1); + const std::string when = absl::FormatTime(fmt, t, lax); + std::string err; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::ParseTime(fmt, when, lax, &t, &err)); + } +} +BENCHMARK(BM_Format_ParseTime)->DenseRange(0, kNumFormats - 1); + +} // namespace diff --git a/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.bazel b/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.bazel index 468470b4fb..9f1ba21cf7 100644 --- a/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.bazel +++ b/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.bazel @@ -81,6 +81,11 @@ cc_test( size = "small", srcs = ["src/time_zone_format_test.cc"], data = [":zoneinfo"], + tags = [ + "no_test_android_arm", + "no_test_android_arm64", + "no_test_android_x86", + ], deps = [ ":civil_time", ":time_zone", @@ -93,6 +98,11 @@ cc_test( size = "small", srcs = ["src/time_zone_lookup_test.cc"], data = [":zoneinfo"], + tags = [ + "no_test_android_arm", + "no_test_android_arm64", + "no_test_android_x86", + ], deps = [ ":civil_time", ":time_zone", @@ -102,6 +112,24 @@ cc_test( ### benchmarks +cc_test( + name = "cctz_benchmark", + srcs = [ + "src/cctz_benchmark.cc", + "src/time_zone_if.h", + "src/time_zone_impl.h", + "src/time_zone_info.h", + "src/tzfile.h", + ], + linkstatic = 1, + tags = ["benchmark"], + deps = [ + ":civil_time", + ":time_zone", + "@com_github_google_benchmark//:benchmark_main", + ], +) + ### examples ### binaries diff --git a/third_party/abseil-cpp/absl/time/internal/cctz/src/cctz_benchmark.cc b/third_party/abseil-cpp/absl/time/internal/cctz/src/cctz_benchmark.cc new file mode 100644 index 0000000000..f13cb4ee6b --- /dev/null +++ b/third_party/abseil-cpp/absl/time/internal/cctz/src/cctz_benchmark.cc @@ -0,0 +1,982 @@ +// Copyright 2016 Google Inc. All Rights Reserved. +// +// 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 +// +// http://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. + +#include +#include +#include +#include +#include +#include +#include + +#include "benchmark/benchmark.h" +#include "absl/time/internal/cctz/include/cctz/civil_time.h" +#include "absl/time/internal/cctz/include/cctz/time_zone.h" +#include "time_zone_impl.h" + +namespace { + +namespace cctz = absl::time_internal::cctz; + +void BM_Difference_Days(benchmark::State& state) { + const cctz::civil_day c(2014, 8, 22); + const cctz::civil_day epoch(1970, 1, 1); + while (state.KeepRunning()) { + benchmark::DoNotOptimize(c - epoch); + } +} +BENCHMARK(BM_Difference_Days); + +void BM_Step_Days(benchmark::State& state) { + const cctz::civil_day kStart(2014, 8, 22); + cctz::civil_day c = kStart; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(++c); + } +} +BENCHMARK(BM_Step_Days); + +const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez"; +const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez"; + +const char RFC1123_full[] = "%a, %d %b %Y %H:%M:%S %z"; +const char RFC1123_no_wday[] = "%d %b %Y %H:%M:%S %z"; + +// A list of known time-zone names. +// TODO: Refactor with src/time_zone_lookup_test.cc. +const char* const kTimeZoneNames[] = { + "Africa/Abidjan", + "Africa/Accra", + "Africa/Addis_Ababa", + "Africa/Algiers", + "Africa/Asmara", + "Africa/Asmera", + "Africa/Bamako", + "Africa/Bangui", + "Africa/Banjul", + "Africa/Bissau", + "Africa/Blantyre", + "Africa/Brazzaville", + "Africa/Bujumbura", + "Africa/Cairo", + "Africa/Casablanca", + "Africa/Ceuta", + "Africa/Conakry", + "Africa/Dakar", + "Africa/Dar_es_Salaam", + "Africa/Djibouti", + "Africa/Douala", + "Africa/El_Aaiun", + "Africa/Freetown", + "Africa/Gaborone", + "Africa/Harare", + "Africa/Johannesburg", + "Africa/Juba", + "Africa/Kampala", + "Africa/Khartoum", + "Africa/Kigali", + "Africa/Kinshasa", + "Africa/Lagos", + "Africa/Libreville", + "Africa/Lome", + "Africa/Luanda", + "Africa/Lubumbashi", + "Africa/Lusaka", + "Africa/Malabo", + "Africa/Maputo", + "Africa/Maseru", + "Africa/Mbabane", + "Africa/Mogadishu", + "Africa/Monrovia", + "Africa/Nairobi", + "Africa/Ndjamena", + "Africa/Niamey", + "Africa/Nouakchott", + "Africa/Ouagadougou", + "Africa/Porto-Novo", + "Africa/Sao_Tome", + "Africa/Timbuktu", + "Africa/Tripoli", + "Africa/Tunis", + "Africa/Windhoek", + "America/Adak", + "America/Anchorage", + "America/Anguilla", + "America/Antigua", + "America/Araguaina", + "America/Argentina/Buenos_Aires", + "America/Argentina/Catamarca", + "America/Argentina/ComodRivadavia", + "America/Argentina/Cordoba", + "America/Argentina/Jujuy", + "America/Argentina/La_Rioja", + "America/Argentina/Mendoza", + "America/Argentina/Rio_Gallegos", + "America/Argentina/Salta", + "America/Argentina/San_Juan", + "America/Argentina/San_Luis", + "America/Argentina/Tucuman", + "America/Argentina/Ushuaia", + "America/Aruba", + "America/Asuncion", + "America/Atikokan", + "America/Atka", + "America/Bahia", + "America/Bahia_Banderas", + "America/Barbados", + "America/Belem", + "America/Belize", + "America/Blanc-Sablon", + "America/Boa_Vista", + "America/Bogota", + "America/Boise", + "America/Buenos_Aires", + "America/Cambridge_Bay", + "America/Campo_Grande", + "America/Cancun", + "America/Caracas", + "America/Catamarca", + "America/Cayenne", + "America/Cayman", + "America/Chicago", + "America/Chihuahua", + "America/Coral_Harbour", + "America/Cordoba", + "America/Costa_Rica", + "America/Creston", + "America/Cuiaba", + "America/Curacao", + "America/Danmarkshavn", + "America/Dawson", + "America/Dawson_Creek", + "America/Denver", + "America/Detroit", + "America/Dominica", + "America/Edmonton", + "America/Eirunepe", + "America/El_Salvador", + "America/Ensenada", + "America/Fort_Nelson", + "America/Fort_Wayne", + "America/Fortaleza", + "America/Glace_Bay", + "America/Godthab", + "America/Goose_Bay", + "America/Grand_Turk", + "America/Grenada", + "America/Guadeloupe", + "America/Guatemala", + "America/Guayaquil", + "America/Guyana", + "America/Halifax", + "America/Havana", + "America/Hermosillo", + "America/Indiana/Indianapolis", + "America/Indiana/Knox", + "America/Indiana/Marengo", + "America/Indiana/Petersburg", + "America/Indiana/Tell_City", + "America/Indiana/Vevay", + "America/Indiana/Vincennes", + "America/Indiana/Winamac", + "America/Indianapolis", + "America/Inuvik", + "America/Iqaluit", + "America/Jamaica", + "America/Jujuy", + "America/Juneau", + "America/Kentucky/Louisville", + "America/Kentucky/Monticello", + "America/Knox_IN", + "America/Kralendijk", + "America/La_Paz", + "America/Lima", + "America/Los_Angeles", + "America/Louisville", + "America/Lower_Princes", + "America/Maceio", + "America/Managua", + "America/Manaus", + "America/Marigot", + "America/Martinique", + "America/Matamoros", + "America/Mazatlan", + "America/Mendoza", + "America/Menominee", + "America/Merida", + "America/Metlakatla", + "America/Mexico_City", + "America/Miquelon", + "America/Moncton", + "America/Monterrey", + "America/Montevideo", + "America/Montreal", + "America/Montserrat", + "America/Nassau", + "America/New_York", + "America/Nipigon", + "America/Nome", + "America/Noronha", + "America/North_Dakota/Beulah", + "America/North_Dakota/Center", + "America/North_Dakota/New_Salem", + "America/Ojinaga", + "America/Panama", + "America/Pangnirtung", + "America/Paramaribo", + "America/Phoenix", + "America/Port-au-Prince", + "America/Port_of_Spain", + "America/Porto_Acre", + "America/Porto_Velho", + "America/Puerto_Rico", + "America/Punta_Arenas", + "America/Rainy_River", + "America/Rankin_Inlet", + "America/Recife", + "America/Regina", + "America/Resolute", + "America/Rio_Branco", + "America/Rosario", + "America/Santa_Isabel", + "America/Santarem", + "America/Santiago", + "America/Santo_Domingo", + "America/Sao_Paulo", + "America/Scoresbysund", + "America/Shiprock", + "America/Sitka", + "America/St_Barthelemy", + "America/St_Johns", + "America/St_Kitts", + "America/St_Lucia", + "America/St_Thomas", + "America/St_Vincent", + "America/Swift_Current", + "America/Tegucigalpa", + "America/Thule", + "America/Thunder_Bay", + "America/Tijuana", + "America/Toronto", + "America/Tortola", + "America/Vancouver", + "America/Virgin", + "America/Whitehorse", + "America/Winnipeg", + "America/Yakutat", + "America/Yellowknife", + "Antarctica/Casey", + "Antarctica/Davis", + "Antarctica/DumontDUrville", + "Antarctica/Macquarie", + "Antarctica/Mawson", + "Antarctica/McMurdo", + "Antarctica/Palmer", + "Antarctica/Rothera", + "Antarctica/South_Pole", + "Antarctica/Syowa", + "Antarctica/Troll", + "Antarctica/Vostok", + "Arctic/Longyearbyen", + "Asia/Aden", + "Asia/Almaty", + "Asia/Amman", + "Asia/Anadyr", + "Asia/Aqtau", + "Asia/Aqtobe", + "Asia/Ashgabat", + "Asia/Ashkhabad", + "Asia/Atyrau", + "Asia/Baghdad", + "Asia/Bahrain", + "Asia/Baku", + "Asia/Bangkok", + "Asia/Barnaul", + "Asia/Beirut", + "Asia/Bishkek", + "Asia/Brunei", + "Asia/Calcutta", + "Asia/Chita", + "Asia/Choibalsan", + "Asia/Chongqing", + "Asia/Chungking", + "Asia/Colombo", + "Asia/Dacca", + "Asia/Damascus", + "Asia/Dhaka", + "Asia/Dili", + "Asia/Dubai", + "Asia/Dushanbe", + "Asia/Famagusta", + "Asia/Gaza", + "Asia/Harbin", + "Asia/Hebron", + "Asia/Ho_Chi_Minh", + "Asia/Hong_Kong", + "Asia/Hovd", + "Asia/Irkutsk", + "Asia/Istanbul", + "Asia/Jakarta", + "Asia/Jayapura", + "Asia/Jerusalem", + "Asia/Kabul", + "Asia/Kamchatka", + "Asia/Karachi", + "Asia/Kashgar", + "Asia/Kathmandu", + "Asia/Katmandu", + "Asia/Khandyga", + "Asia/Kolkata", + "Asia/Krasnoyarsk", + "Asia/Kuala_Lumpur", + "Asia/Kuching", + "Asia/Kuwait", + "Asia/Macao", + "Asia/Macau", + "Asia/Magadan", + "Asia/Makassar", + "Asia/Manila", + "Asia/Muscat", + "Asia/Nicosia", + "Asia/Novokuznetsk", + "Asia/Novosibirsk", + "Asia/Omsk", + "Asia/Oral", + "Asia/Phnom_Penh", + "Asia/Pontianak", + "Asia/Pyongyang", + "Asia/Qatar", + "Asia/Qyzylorda", + "Asia/Rangoon", + "Asia/Riyadh", + "Asia/Saigon", + "Asia/Sakhalin", + "Asia/Samarkand", + "Asia/Seoul", + "Asia/Shanghai", + "Asia/Singapore", + "Asia/Srednekolymsk", + "Asia/Taipei", + "Asia/Tashkent", + "Asia/Tbilisi", + "Asia/Tehran", + "Asia/Tel_Aviv", + "Asia/Thimbu", + "Asia/Thimphu", + "Asia/Tokyo", + "Asia/Tomsk", + "Asia/Ujung_Pandang", + "Asia/Ulaanbaatar", + "Asia/Ulan_Bator", + "Asia/Urumqi", + "Asia/Ust-Nera", + "Asia/Vientiane", + "Asia/Vladivostok", + "Asia/Yakutsk", + "Asia/Yangon", + "Asia/Yekaterinburg", + "Asia/Yerevan", + "Atlantic/Azores", + "Atlantic/Bermuda", + "Atlantic/Canary", + "Atlantic/Cape_Verde", + "Atlantic/Faeroe", + "Atlantic/Faroe", + "Atlantic/Jan_Mayen", + "Atlantic/Madeira", + "Atlantic/Reykjavik", + "Atlantic/South_Georgia", + "Atlantic/St_Helena", + "Atlantic/Stanley", + "Australia/ACT", + "Australia/Adelaide", + "Australia/Brisbane", + "Australia/Broken_Hill", + "Australia/Canberra", + "Australia/Currie", + "Australia/Darwin", + "Australia/Eucla", + "Australia/Hobart", + "Australia/LHI", + "Australia/Lindeman", + "Australia/Lord_Howe", + "Australia/Melbourne", + "Australia/NSW", + "Australia/North", + "Australia/Perth", + "Australia/Queensland", + "Australia/South", + "Australia/Sydney", + "Australia/Tasmania", + "Australia/Victoria", + "Australia/West", + "Australia/Yancowinna", + "Brazil/Acre", + "Brazil/DeNoronha", + "Brazil/East", + "Brazil/West", + "CET", + "CST6CDT", + "Canada/Atlantic", + "Canada/Central", + "Canada/Eastern", + "Canada/Mountain", + "Canada/Newfoundland", + "Canada/Pacific", + "Canada/Saskatchewan", + "Canada/Yukon", + "Chile/Continental", + "Chile/EasterIsland", + "Cuba", + "EET", + "EST", + "EST5EDT", + "Egypt", + "Eire", + "Etc/GMT", + "Etc/GMT+0", + "Etc/GMT+1", + "Etc/GMT+10", + "Etc/GMT+11", + "Etc/GMT+12", + "Etc/GMT+2", + "Etc/GMT+3", + "Etc/GMT+4", + "Etc/GMT+5", + "Etc/GMT+6", + "Etc/GMT+7", + "Etc/GMT+8", + "Etc/GMT+9", + "Etc/GMT-0", + "Etc/GMT-1", + "Etc/GMT-10", + "Etc/GMT-11", + "Etc/GMT-12", + "Etc/GMT-13", + "Etc/GMT-14", + "Etc/GMT-2", + "Etc/GMT-3", + "Etc/GMT-4", + "Etc/GMT-5", + "Etc/GMT-6", + "Etc/GMT-7", + "Etc/GMT-8", + "Etc/GMT-9", + "Etc/GMT0", + "Etc/Greenwich", + "Etc/UCT", + "Etc/UTC", + "Etc/Universal", + "Etc/Zulu", + "Europe/Amsterdam", + "Europe/Andorra", + "Europe/Astrakhan", + "Europe/Athens", + "Europe/Belfast", + "Europe/Belgrade", + "Europe/Berlin", + "Europe/Bratislava", + "Europe/Brussels", + "Europe/Bucharest", + "Europe/Budapest", + "Europe/Busingen", + "Europe/Chisinau", + "Europe/Copenhagen", + "Europe/Dublin", + "Europe/Gibraltar", + "Europe/Guernsey", + "Europe/Helsinki", + "Europe/Isle_of_Man", + "Europe/Istanbul", + "Europe/Jersey", + "Europe/Kaliningrad", + "Europe/Kiev", + "Europe/Kirov", + "Europe/Lisbon", + "Europe/Ljubljana", + "Europe/London", + "Europe/Luxembourg", + "Europe/Madrid", + "Europe/Malta", + "Europe/Mariehamn", + "Europe/Minsk", + "Europe/Monaco", + "Europe/Moscow", + "Europe/Nicosia", + "Europe/Oslo", + "Europe/Paris", + "Europe/Podgorica", + "Europe/Prague", + "Europe/Riga", + "Europe/Rome", + "Europe/Samara", + "Europe/San_Marino", + "Europe/Sarajevo", + "Europe/Saratov", + "Europe/Simferopol", + "Europe/Skopje", + "Europe/Sofia", + "Europe/Stockholm", + "Europe/Tallinn", + "Europe/Tirane", + "Europe/Tiraspol", + "Europe/Ulyanovsk", + "Europe/Uzhgorod", + "Europe/Vaduz", + "Europe/Vatican", + "Europe/Vienna", + "Europe/Vilnius", + "Europe/Volgograd", + "Europe/Warsaw", + "Europe/Zagreb", + "Europe/Zaporozhye", + "Europe/Zurich", + "GB", + "GB-Eire", + "GMT", + "GMT+0", + "GMT-0", + "GMT0", + "Greenwich", + "HST", + "Hongkong", + "Iceland", + "Indian/Antananarivo", + "Indian/Chagos", + "Indian/Christmas", + "Indian/Cocos", + "Indian/Comoro", + "Indian/Kerguelen", + "Indian/Mahe", + "Indian/Maldives", + "Indian/Mauritius", + "Indian/Mayotte", + "Indian/Reunion", + "Iran", + "Israel", + "Jamaica", + "Japan", + "Kwajalein", + "Libya", + "MET", + "MST", + "MST7MDT", + "Mexico/BajaNorte", + "Mexico/BajaSur", + "Mexico/General", + "NZ", + "NZ-CHAT", + "Navajo", + "PRC", + "PST8PDT", + "Pacific/Apia", + "Pacific/Auckland", + "Pacific/Bougainville", + "Pacific/Chatham", + "Pacific/Chuuk", + "Pacific/Easter", + "Pacific/Efate", + "Pacific/Enderbury", + "Pacific/Fakaofo", + "Pacific/Fiji", + "Pacific/Funafuti", + "Pacific/Galapagos", + "Pacific/Gambier", + "Pacific/Guadalcanal", + "Pacific/Guam", + "Pacific/Honolulu", + "Pacific/Johnston", + "Pacific/Kiritimati", + "Pacific/Kosrae", + "Pacific/Kwajalein", + "Pacific/Majuro", + "Pacific/Marquesas", + "Pacific/Midway", + "Pacific/Nauru", + "Pacific/Niue", + "Pacific/Norfolk", + "Pacific/Noumea", + "Pacific/Pago_Pago", + "Pacific/Palau", + "Pacific/Pitcairn", + "Pacific/Pohnpei", + "Pacific/Ponape", + "Pacific/Port_Moresby", + "Pacific/Rarotonga", + "Pacific/Saipan", + "Pacific/Samoa", + "Pacific/Tahiti", + "Pacific/Tarawa", + "Pacific/Tongatapu", + "Pacific/Truk", + "Pacific/Wake", + "Pacific/Wallis", + "Pacific/Yap", + "Poland", + "Portugal", + "ROC", + "ROK", + "Singapore", + "Turkey", + "UCT", + "US/Alaska", + "US/Aleutian", + "US/Arizona", + "US/Central", + "US/East-Indiana", + "US/Eastern", + "US/Hawaii", + "US/Indiana-Starke", + "US/Michigan", + "US/Mountain", + "US/Pacific", + "US/Samoa", + "UTC", + "Universal", + "W-SU", + "WET", + "Zulu", + nullptr +}; + +std::vector AllTimeZoneNames() { + std::vector names; + for (const char* const* namep = kTimeZoneNames; *namep != nullptr; ++namep) { + names.push_back(std::string("file:") + *namep); + } + assert(!names.empty()); + + std::mt19937 urbg(42); // a UniformRandomBitGenerator with fixed seed + std::shuffle(names.begin(), names.end(), urbg); + return names; +} + +cctz::time_zone TestTimeZone() { + cctz::time_zone tz; + cctz::load_time_zone("America/Los_Angeles", &tz); + return tz; +} + +void BM_Zone_LoadUTCTimeZoneFirst(benchmark::State& state) { + cctz::time_zone tz; + cctz::load_time_zone("UTC", &tz); // in case we're first + cctz::time_zone::Impl::ClearTimeZoneMapTestOnly(); + while (state.KeepRunning()) { + benchmark::DoNotOptimize(cctz::load_time_zone("UTC", &tz)); + } +} +BENCHMARK(BM_Zone_LoadUTCTimeZoneFirst); + +void BM_Zone_LoadUTCTimeZoneLast(benchmark::State& state) { + cctz::time_zone tz; + for (const auto& name : AllTimeZoneNames()) { + cctz::load_time_zone(name, &tz); // prime cache + } + while (state.KeepRunning()) { + benchmark::DoNotOptimize(cctz::load_time_zone("UTC", &tz)); + } +} +BENCHMARK(BM_Zone_LoadUTCTimeZoneLast); + +void BM_Zone_LoadTimeZoneFirst(benchmark::State& state) { + cctz::time_zone tz = cctz::utc_time_zone(); // in case we're first + const std::string name = "file:America/Los_Angeles"; + while (state.KeepRunning()) { + state.PauseTiming(); + cctz::time_zone::Impl::ClearTimeZoneMapTestOnly(); + state.ResumeTiming(); + benchmark::DoNotOptimize(cctz::load_time_zone(name, &tz)); + } +} +BENCHMARK(BM_Zone_LoadTimeZoneFirst); + +void BM_Zone_LoadTimeZoneCached(benchmark::State& state) { + cctz::time_zone tz = cctz::utc_time_zone(); // in case we're first + cctz::time_zone::Impl::ClearTimeZoneMapTestOnly(); + const std::string name = "file:America/Los_Angeles"; + cctz::load_time_zone(name, &tz); // prime cache + while (state.KeepRunning()) { + benchmark::DoNotOptimize(cctz::load_time_zone(name, &tz)); + } +} +BENCHMARK(BM_Zone_LoadTimeZoneCached); + +void BM_Zone_LoadLocalTimeZoneCached(benchmark::State& state) { + cctz::utc_time_zone(); // in case we're first + cctz::time_zone::Impl::ClearTimeZoneMapTestOnly(); + cctz::local_time_zone(); // prime cache + while (state.KeepRunning()) { + benchmark::DoNotOptimize(cctz::local_time_zone()); + } +} +BENCHMARK(BM_Zone_LoadLocalTimeZoneCached); + +void BM_Zone_LoadAllTimeZonesFirst(benchmark::State& state) { + cctz::time_zone tz; + const std::vector names = AllTimeZoneNames(); + for (auto index = names.size(); state.KeepRunning(); ++index) { + if (index == names.size()) { + index = 0; + } + if (index == 0) { + state.PauseTiming(); + cctz::time_zone::Impl::ClearTimeZoneMapTestOnly(); + state.ResumeTiming(); + } + benchmark::DoNotOptimize(cctz::load_time_zone(names[index], &tz)); + } +} +BENCHMARK(BM_Zone_LoadAllTimeZonesFirst); + +void BM_Zone_LoadAllTimeZonesCached(benchmark::State& state) { + cctz::time_zone tz; + const std::vector names = AllTimeZoneNames(); + for (const auto& name : names) { + cctz::load_time_zone(name, &tz); // prime cache + } + for (auto index = names.size(); state.KeepRunning(); ++index) { + if (index == names.size()) { + index = 0; + } + benchmark::DoNotOptimize(cctz::load_time_zone(names[index], &tz)); + } +} +BENCHMARK(BM_Zone_LoadAllTimeZonesCached); + +void BM_Zone_TimeZoneImplGetImplicit(benchmark::State& state) { + cctz::time_zone tz; // implicit UTC + cctz::time_zone::Impl::get(tz); + while (state.KeepRunning()) { + cctz::time_zone::Impl::get(tz); + } +} +BENCHMARK(BM_Zone_TimeZoneImplGetImplicit); + +void BM_Zone_TimeZoneImplGetExplicit(benchmark::State& state) { + cctz::time_zone tz = cctz::utc_time_zone(); // explicit UTC + cctz::time_zone::Impl::get(tz); + while (state.KeepRunning()) { + cctz::time_zone::Impl::get(tz); + } +} +BENCHMARK(BM_Zone_TimeZoneImplGetExplicit); + +void BM_Zone_UTCTimeZone(benchmark::State& state) { + cctz::time_zone tz; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(cctz::utc_time_zone()); + } +} +BENCHMARK(BM_Zone_UTCTimeZone); + +// In each "ToDateTime" benchmark we switch between two instants +// separated by at least one transition in order to defeat any +// internal caching of previous results (e.g., see local_time_hint_). +// +// The "UTC" variants use UTC instead of the Google/local time zone. + +void BM_Time_ToDateTime_CCTZ(benchmark::State& state) { + const cctz::time_zone tz = TestTimeZone(); + std::chrono::system_clock::time_point tp = + std::chrono::system_clock::from_time_t(1384569027); + std::chrono::system_clock::time_point tp2 = + std::chrono::system_clock::from_time_t(1418962578); + while (state.KeepRunning()) { + std::swap(tp, tp2); + tp += std::chrono::seconds(1); + benchmark::DoNotOptimize(cctz::convert(tp, tz)); + } +} +BENCHMARK(BM_Time_ToDateTime_CCTZ); + +void BM_Time_ToDateTime_Libc(benchmark::State& state) { + // No timezone support, so just use localtime. + time_t t = 1384569027; + time_t t2 = 1418962578; + struct tm tm; + while (state.KeepRunning()) { + std::swap(t, t2); + t += 1; +#if defined(_WIN32) || defined(_WIN64) + benchmark::DoNotOptimize(localtime_s(&tm, &t)); +#else + benchmark::DoNotOptimize(localtime_r(&t, &tm)); +#endif + } +} +BENCHMARK(BM_Time_ToDateTime_Libc); + +void BM_Time_ToDateTimeUTC_CCTZ(benchmark::State& state) { + const cctz::time_zone tz = cctz::utc_time_zone(); + std::chrono::system_clock::time_point tp = + std::chrono::system_clock::from_time_t(1384569027); + while (state.KeepRunning()) { + tp += std::chrono::seconds(1); + benchmark::DoNotOptimize(cctz::convert(tp, tz)); + } +} +BENCHMARK(BM_Time_ToDateTimeUTC_CCTZ); + +void BM_Time_ToDateTimeUTC_Libc(benchmark::State& state) { + time_t t = 1384569027; + struct tm tm; + while (state.KeepRunning()) { + t += 1; +#if defined(_WIN32) || defined(_WIN64) + benchmark::DoNotOptimize(gmtime_s(&tm, &t)); +#else + benchmark::DoNotOptimize(gmtime_r(&t, &tm)); +#endif + } +} +BENCHMARK(BM_Time_ToDateTimeUTC_Libc); + +// In each "FromDateTime" benchmark we switch between two YMDhms +// values separated by at least one transition in order to defeat any +// internal caching of previous results (e.g., see time_local_hint_). +// +// The "UTC" variants use UTC instead of the Google/local time zone. +// The "Day0" variants require normalization of the day of month. + +void BM_Time_FromDateTime_CCTZ(benchmark::State& state) { + const cctz::time_zone tz = TestTimeZone(); + int i = 0; + while (state.KeepRunning()) { + if ((i++ & 1) == 0) { + benchmark::DoNotOptimize( + cctz::convert(cctz::civil_second(2014, 12, 18, 20, 16, 18), tz)); + } else { + benchmark::DoNotOptimize( + cctz::convert(cctz::civil_second(2013, 11, 15, 18, 30, 27), tz)); + } + } +} +BENCHMARK(BM_Time_FromDateTime_CCTZ); + +void BM_Time_FromDateTime_Libc(benchmark::State& state) { + // No timezone support, so just use localtime. + int i = 0; + while (state.KeepRunning()) { + struct tm tm; + if ((i++ & 1) == 0) { + tm.tm_year = 2014 - 1900; + tm.tm_mon = 12 - 1; + tm.tm_mday = 18; + tm.tm_hour = 20; + tm.tm_min = 16; + tm.tm_sec = 18; + } else { + tm.tm_year = 2013 - 1900; + tm.tm_mon = 11 - 1; + tm.tm_mday = 15; + tm.tm_hour = 18; + tm.tm_min = 30; + tm.tm_sec = 27; + } + tm.tm_isdst = -1; + benchmark::DoNotOptimize(mktime(&tm)); + } +} +BENCHMARK(BM_Time_FromDateTime_Libc); + +void BM_Time_FromDateTimeUTC_CCTZ(benchmark::State& state) { + const cctz::time_zone tz = cctz::utc_time_zone(); + while (state.KeepRunning()) { + benchmark::DoNotOptimize( + cctz::convert(cctz::civil_second(2014, 12, 18, 20, 16, 18), tz)); + } +} +BENCHMARK(BM_Time_FromDateTimeUTC_CCTZ); + +// There is no BM_Time_FromDateTimeUTC_Libc. + +void BM_Time_FromDateTimeDay0_CCTZ(benchmark::State& state) { + const cctz::time_zone tz = TestTimeZone(); + int i = 0; + while (state.KeepRunning()) { + if ((i++ & 1) == 0) { + benchmark::DoNotOptimize( + cctz::convert(cctz::civil_second(2014, 12, 0, 20, 16, 18), tz)); + } else { + benchmark::DoNotOptimize( + cctz::convert(cctz::civil_second(2013, 11, 0, 18, 30, 27), tz)); + } + } +} +BENCHMARK(BM_Time_FromDateTimeDay0_CCTZ); + +void BM_Time_FromDateTimeDay0_Libc(benchmark::State& state) { + // No timezone support, so just use localtime. + int i = 0; + while (state.KeepRunning()) { + struct tm tm; + if ((i++ & 1) == 0) { + tm.tm_year = 2014 - 1900; + tm.tm_mon = 12 - 1; + tm.tm_mday = 0; + tm.tm_hour = 20; + tm.tm_min = 16; + tm.tm_sec = 18; + } else { + tm.tm_year = 2013 - 1900; + tm.tm_mon = 11 - 1; + tm.tm_mday = 0; + tm.tm_hour = 18; + tm.tm_min = 30; + tm.tm_sec = 27; + } + tm.tm_isdst = -1; + benchmark::DoNotOptimize(mktime(&tm)); + } +} +BENCHMARK(BM_Time_FromDateTimeDay0_Libc); + +const char* const kFormats[] = { + RFC1123_full, // 0 + RFC1123_no_wday, // 1 + RFC3339_full, // 2 + RFC3339_sec, // 3 + "%Y-%m-%dT%H:%M:%S", // 4 + "%Y-%m-%d", // 5 +}; +const int kNumFormats = sizeof(kFormats) / sizeof(kFormats[0]); + +void BM_Format_FormatTime(benchmark::State& state) { + const std::string fmt = kFormats[state.range(0)]; + state.SetLabel(fmt); + const cctz::time_zone tz = TestTimeZone(); + const std::chrono::system_clock::time_point tp = + cctz::convert(cctz::civil_second(1977, 6, 28, 9, 8, 7), tz) + + std::chrono::microseconds(1); + while (state.KeepRunning()) { + benchmark::DoNotOptimize(cctz::format(fmt, tp, tz)); + } +} +BENCHMARK(BM_Format_FormatTime)->DenseRange(0, kNumFormats - 1); + +void BM_Format_ParseTime(benchmark::State& state) { + const std::string fmt = kFormats[state.range(0)]; + state.SetLabel(fmt); + const cctz::time_zone tz = TestTimeZone(); + std::chrono::system_clock::time_point tp = + cctz::convert(cctz::civil_second(1977, 6, 28, 9, 8, 7), tz) + + std::chrono::microseconds(1); + const std::string when = cctz::format(fmt, tp, tz); + while (state.KeepRunning()) { + benchmark::DoNotOptimize(cctz::parse(fmt, when, tz, &tp)); + } +} +BENCHMARK(BM_Format_ParseTime)->DenseRange(0, kNumFormats - 1); + +} // namespace diff --git a/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format_test.cc b/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format_test.cc index 6cea0360dd..7d5b02ad3a 100644 --- a/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format_test.cc +++ b/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format_test.cc @@ -463,8 +463,12 @@ TEST(Format, ExtendedSecondOffset) { EXPECT_TRUE(load_time_zone("Europe/Moscow", &tz)); tp = convert(civil_second(1919, 6, 30, 23, 59, 59), utc); +#if defined(__ANDROID__) && __ANDROID_API__ < 25 + // Only Android 'N'.1 and beyond have this tz2016g transition. +#else TestFormatSpecifier(tp, tz, "%E*z", "+04:31:19"); TestFormatSpecifier(tp, tz, "%Ez", "+04:31"); +#endif tp += seconds(1); TestFormatSpecifier(tp, tz, "%E*z", "+04:00:00"); } diff --git a/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc b/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc index f97eab0227..06b172a803 100644 --- a/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc +++ b/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc @@ -693,7 +693,14 @@ TEST(TimeZones, LoadZonesConcurrently) { // Allow a small number of failures to account for skew between // the contents of kTimeZoneNames and the zoneinfo data source. +#if defined(__ANDROID__) + // Cater to the possibility of using an even older zoneinfo data + // source when running on Android, where it is difficult to override + // the bionic tzdata provided by the test environment. + const std::size_t max_failures = 20; +#else const std::size_t max_failures = 3; +#endif std::set failures; for (const auto& thread_failure : thread_failures) { failures.insert(thread_failure.begin(), thread_failure.end()); @@ -839,7 +846,7 @@ TEST(TimeZoneImpl, LocalTimeInFixed) { const time_zone tz = fixed_time_zone(offset); const auto tp = system_clock::from_time_t(0); ExpectTime(tp, tz, 1969, 12, 31, 15, 26, 13, offset.count(), false, - "UTC-083347"); + "-083347"); EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz)))); } @@ -1098,6 +1105,9 @@ TEST(TimeZoneEdgeCase, PacificApia) { TEST(TimeZoneEdgeCase, AfricaCairo) { const time_zone tz = LoadZone("Africa/Cairo"); +#if defined(__ANDROID__) && __ANDROID_API__ < 21 + // Only Android 'L' and beyond have this tz2014c transition. +#else // An interesting case of midnight not existing. // // 1400191199 == Thu, 15 May 2014 23:59:59 +0200 (EET) @@ -1106,11 +1116,15 @@ TEST(TimeZoneEdgeCase, AfricaCairo) { ExpectTime(tp, tz, 2014, 5, 15, 23, 59, 59, 2 * 3600, false, "EET"); tp += seconds(1); ExpectTime(tp, tz, 2014, 5, 16, 1, 0, 0, 3 * 3600, true, "EEST"); +#endif } TEST(TimeZoneEdgeCase, AfricaMonrovia) { const time_zone tz = LoadZone("Africa/Monrovia"); +#if defined(__ANDROID__) && __ANDROID_API__ < 26 + // Only Android 'O' and beyond have this tz2017b transition. +#else // Strange offset change -00:44:30 -> +00:00:00 (non-DST) // // 63593069 == Thu, 6 Jan 1972 23:59:59 -0044 (MMT) @@ -1119,6 +1133,7 @@ TEST(TimeZoneEdgeCase, AfricaMonrovia) { ExpectTime(tp, tz, 1972, 1, 6, 23, 59, 59, -44.5 * 60, false, "MMT"); tp += seconds(1); ExpectTime(tp, tz, 1972, 1, 7, 0, 44, 30, 0 * 60, false, "GMT"); +#endif } TEST(TimeZoneEdgeCase, AmericaJamaica) { diff --git a/third_party/abseil-cpp/absl/time/time.h b/third_party/abseil-cpp/absl/time/time.h index c50d69a568..99c12bbd87 100644 --- a/third_party/abseil-cpp/absl/time/time.h +++ b/third_party/abseil-cpp/absl/time/time.h @@ -82,8 +82,15 @@ constexpr Duration MakeDuration(int64_t hi, uint32_t lo); constexpr Duration MakeDuration(int64_t hi, int64_t lo); constexpr int64_t kTicksPerNanosecond = 4; constexpr int64_t kTicksPerSecond = 1000 * 1000 * 1000 * kTicksPerNanosecond; +template +constexpr Duration FromInt64(int64_t v, std::ratio<1, N>); +constexpr Duration FromInt64(int64_t v, std::ratio<60>); +constexpr Duration FromInt64(int64_t v, std::ratio<3600>); template -using IsFloatingPoint = +using EnableIfIntegral = typename std::enable_if< + std::is_integral::value || std::is_enum::value, int>::type; +template +using EnableIfFloat = typename std::enable_if::value, int>::type; } // namespace time_internal @@ -178,15 +185,15 @@ inline Duration operator-(Duration lhs, Duration rhs) { return lhs -= rhs; } // Multiplicative Operators template -inline Duration operator*(Duration lhs, T rhs) { +Duration operator*(Duration lhs, T rhs) { return lhs *= rhs; } template -inline Duration operator*(T lhs, Duration rhs) { +Duration operator*(T lhs, Duration rhs) { return rhs *= lhs; } template -inline Duration operator/(Duration lhs, T rhs) { +Duration operator/(Duration lhs, T rhs) { return lhs /= rhs; } inline int64_t operator/(Duration lhs, Duration rhs) { @@ -322,27 +329,27 @@ constexpr Duration Hours(int64_t n); // Example: // auto a = absl::Seconds(1.5); // OK // auto b = absl::Milliseconds(1500); // BETTER -template = 0> +template = 0> Duration Nanoseconds(T n) { return n * Nanoseconds(1); } -template = 0> +template = 0> Duration Microseconds(T n) { return n * Microseconds(1); } -template = 0> +template = 0> Duration Milliseconds(T n) { return n * Milliseconds(1); } -template = 0> +template = 0> Duration Seconds(T n) { return n * Seconds(1); } -template = 0> +template = 0> Duration Minutes(T n) { return n * Minutes(1); } -template = 0> +template = 0> Duration Hours(T n) { return n * Hours(1); } @@ -1154,10 +1161,16 @@ constexpr Duration FromInt64(int64_t v, std::ratio<1, N>) { v / N, v % N * kTicksPerNanosecond * 1000 * 1000 * 1000 / N); } constexpr Duration FromInt64(int64_t v, std::ratio<60>) { - return Minutes(v); + return (v <= std::numeric_limits::max() / 60 && + v >= std::numeric_limits::min() / 60) + ? MakeDuration(v * 60) + : v > 0 ? InfiniteDuration() : -InfiniteDuration(); } constexpr Duration FromInt64(int64_t v, std::ratio<3600>) { - return Hours(v); + return (v <= std::numeric_limits::max() / 3600 && + v >= std::numeric_limits::min() / 3600) + ? MakeDuration(v * 3600) + : v > 0 ? InfiniteDuration() : -InfiniteDuration(); } // IsValidRep64(0) is true if the expression `int64_t{std::declval()}` is @@ -1220,6 +1233,24 @@ T ToChronoDuration(Duration d) { } } // namespace time_internal +constexpr Duration Nanoseconds(int64_t n) { + return time_internal::FromInt64(n, std::nano{}); +} +constexpr Duration Microseconds(int64_t n) { + return time_internal::FromInt64(n, std::micro{}); +} +constexpr Duration Milliseconds(int64_t n) { + return time_internal::FromInt64(n, std::milli{}); +} +constexpr Duration Seconds(int64_t n) { + return time_internal::FromInt64(n, std::ratio<1>{}); +} +constexpr Duration Minutes(int64_t n) { + return time_internal::FromInt64(n, std::ratio<60>{}); +} +constexpr Duration Hours(int64_t n) { + return time_internal::FromInt64(n, std::ratio<3600>{}); +} constexpr bool operator<(Duration lhs, Duration rhs) { return time_internal::GetRepHi(lhs) != time_internal::GetRepHi(rhs) @@ -1261,39 +1292,6 @@ constexpr Duration operator-(Duration d) { time_internal::GetRepLo(d)); } -constexpr Duration Nanoseconds(int64_t n) { - return time_internal::MakeNormalizedDuration( - n / (1000 * 1000 * 1000), - n % (1000 * 1000 * 1000) * time_internal::kTicksPerNanosecond); -} - -constexpr Duration Microseconds(int64_t n) { - return time_internal::MakeNormalizedDuration( - n / (1000 * 1000), - n % (1000 * 1000) * (1000 * time_internal::kTicksPerNanosecond)); -} - -constexpr Duration Milliseconds(int64_t n) { - return time_internal::MakeNormalizedDuration( - n / 1000, n % 1000 * (1000 * 1000 * time_internal::kTicksPerNanosecond)); -} - -constexpr Duration Seconds(int64_t n) { return time_internal::MakeDuration(n); } - -constexpr Duration Minutes(int64_t n) { - return (n <= std::numeric_limits::max() / 60 && - n >= std::numeric_limits::min() / 60) - ? time_internal::MakeDuration(n * 60) - : n > 0 ? InfiniteDuration() : -InfiniteDuration(); -} - -constexpr Duration Hours(int64_t n) { - return (n <= std::numeric_limits::max() / 3600 && - n >= std::numeric_limits::min() / 3600) - ? time_internal::MakeDuration(n * 3600) - : n > 0 ? InfiniteDuration() : -InfiniteDuration(); -} - constexpr Duration InfiniteDuration() { return time_internal::MakeDuration(std::numeric_limits::max(), ~0U); } diff --git a/third_party/abseil-cpp/absl/time/time_benchmark.cc b/third_party/abseil-cpp/absl/time/time_benchmark.cc new file mode 100644 index 0000000000..e1009946cd --- /dev/null +++ b/third_party/abseil-cpp/absl/time/time_benchmark.cc @@ -0,0 +1,316 @@ +// Copyright 2018 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 +// +// http://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. + +#include "absl/time/time.h" + +#if !defined(_WIN32) +#include +#endif // _WIN32 +#include +#include +#include +#include +#include +#include +#include + +#include "absl/time/clock.h" +#include "absl/time/internal/test_util.h" +#include "benchmark/benchmark.h" + +namespace { + +// +// Addition/Subtraction of a duration +// + +void BM_Time_Arithmetic(benchmark::State& state) { + const absl::Duration nano = absl::Nanoseconds(1); + const absl::Duration sec = absl::Seconds(1); + absl::Time t = absl::UnixEpoch(); + while (state.KeepRunning()) { + benchmark::DoNotOptimize(t += nano); + benchmark::DoNotOptimize(t -= sec); + } +} +BENCHMARK(BM_Time_Arithmetic); + +// +// Time difference +// + +void BM_Time_Difference(benchmark::State& state) { + absl::Time start = absl::Now(); + absl::Time end = start + absl::Nanoseconds(1); + absl::Duration diff; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(diff += end - start); + } +} +BENCHMARK(BM_Time_Difference); + +// +// ToDateTime +// +// In each "ToDateTime" benchmark we switch between two instants +// separated by at least one transition in order to defeat any +// internal caching of previous results (e.g., see local_time_hint_). +// +// The "UTC" variants use UTC instead of the Google/local time zone. +// + +void BM_Time_ToDateTime_Absl(benchmark::State& state) { + const absl::TimeZone tz = + absl::time_internal::LoadTimeZone("America/Los_Angeles"); + absl::Time t = absl::FromUnixSeconds(1384569027); + absl::Time t2 = absl::FromUnixSeconds(1418962578); + while (state.KeepRunning()) { + std::swap(t, t2); + t += absl::Seconds(1); + benchmark::DoNotOptimize(t.In(tz)); + } +} +BENCHMARK(BM_Time_ToDateTime_Absl); + +void BM_Time_ToDateTime_Libc(benchmark::State& state) { + // No timezone support, so just use localtime. + time_t t = 1384569027; + time_t t2 = 1418962578; + while (state.KeepRunning()) { + std::swap(t, t2); + t += 1; + struct tm tm; +#if !defined(_WIN32) + benchmark::DoNotOptimize(localtime_r(&t, &tm)); +#else // _WIN32 + benchmark::DoNotOptimize(localtime_s(&tm, &t)); +#endif // _WIN32 + } +} +BENCHMARK(BM_Time_ToDateTime_Libc); + +void BM_Time_ToDateTimeUTC_Absl(benchmark::State& state) { + const absl::TimeZone tz = absl::UTCTimeZone(); + absl::Time t = absl::FromUnixSeconds(1384569027); + while (state.KeepRunning()) { + t += absl::Seconds(1); + benchmark::DoNotOptimize(t.In(tz)); + } +} +BENCHMARK(BM_Time_ToDateTimeUTC_Absl); + +void BM_Time_ToDateTimeUTC_Libc(benchmark::State& state) { + time_t t = 1384569027; + while (state.KeepRunning()) { + t += 1; + struct tm tm; +#if !defined(_WIN32) + benchmark::DoNotOptimize(gmtime_r(&t, &tm)); +#else // _WIN32 + benchmark::DoNotOptimize(gmtime_s(&tm, &t)); +#endif // _WIN32 + } +} +BENCHMARK(BM_Time_ToDateTimeUTC_Libc); + +// +// FromUnixMicros +// + +void BM_Time_FromUnixMicros(benchmark::State& state) { + int i = 0; + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::FromUnixMicros(i)); + ++i; + } +} +BENCHMARK(BM_Time_FromUnixMicros); + +void BM_Time_ToUnixNanos(benchmark::State& state) { + const absl::Time t = absl::UnixEpoch() + absl::Seconds(123); + while (state.KeepRunning()) { + benchmark::DoNotOptimize(ToUnixNanos(t)); + } +} +BENCHMARK(BM_Time_ToUnixNanos); + +void BM_Time_ToUnixMicros(benchmark::State& state) { + const absl::Time t = absl::UnixEpoch() + absl::Seconds(123); + while (state.KeepRunning()) { + benchmark::DoNotOptimize(ToUnixMicros(t)); + } +} +BENCHMARK(BM_Time_ToUnixMicros); + +void BM_Time_ToUnixMillis(benchmark::State& state) { + const absl::Time t = absl::UnixEpoch() + absl::Seconds(123); + while (state.KeepRunning()) { + benchmark::DoNotOptimize(ToUnixMillis(t)); + } +} +BENCHMARK(BM_Time_ToUnixMillis); + +void BM_Time_ToUnixSeconds(benchmark::State& state) { + const absl::Time t = absl::UnixEpoch() + absl::Seconds(123); + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::ToUnixSeconds(t)); + } +} +BENCHMARK(BM_Time_ToUnixSeconds); + +// +// FromDateTime +// +// In each "FromDateTime" benchmark we switch between two YMDhms +// values separated by at least one transition in order to defeat any +// internal caching of previous results (e.g., see time_local_hint_). +// +// The "UTC" variants use UTC instead of the Google/local time zone. +// The "Day0" variants require normalization of the day of month. +// + +void BM_Time_FromDateTime_Absl(benchmark::State& state) { + const absl::TimeZone tz = + absl::time_internal::LoadTimeZone("America/Los_Angeles"); + int i = 0; + while (state.KeepRunning()) { + if ((i & 1) == 0) { + absl::FromDateTime(2014, 12, 18, 20, 16, 18, tz); + } else { + absl::FromDateTime(2013, 11, 15, 18, 30, 27, tz); + } + ++i; + } +} +BENCHMARK(BM_Time_FromDateTime_Absl); + +void BM_Time_FromDateTime_Libc(benchmark::State& state) { + // No timezone support, so just use localtime. + int i = 0; + while (state.KeepRunning()) { + struct tm tm; + if ((i & 1) == 0) { + tm.tm_year = 2014 - 1900; + tm.tm_mon = 12 - 1; + tm.tm_mday = 18; + tm.tm_hour = 20; + tm.tm_min = 16; + tm.tm_sec = 18; + } else { + tm.tm_year = 2013 - 1900; + tm.tm_mon = 11 - 1; + tm.tm_mday = 15; + tm.tm_hour = 18; + tm.tm_min = 30; + tm.tm_sec = 27; + } + tm.tm_isdst = -1; + mktime(&tm); + ++i; + } +} +BENCHMARK(BM_Time_FromDateTime_Libc); + +void BM_Time_FromDateTimeUTC_Absl(benchmark::State& state) { + const absl::TimeZone tz = absl::UTCTimeZone(); + while (state.KeepRunning()) { + FromDateTime(2014, 12, 18, 20, 16, 18, tz); + } +} +BENCHMARK(BM_Time_FromDateTimeUTC_Absl); + +void BM_Time_FromDateTimeDay0_Absl(benchmark::State& state) { + const absl::TimeZone tz = + absl::time_internal::LoadTimeZone("America/Los_Angeles"); + int i = 0; + while (state.KeepRunning()) { + if ((i & 1) == 0) { + absl::FromDateTime(2014, 12, 0, 20, 16, 18, tz); + } else { + absl::FromDateTime(2013, 11, 0, 18, 30, 27, tz); + } + ++i; + } +} +BENCHMARK(BM_Time_FromDateTimeDay0_Absl); + +void BM_Time_FromDateTimeDay0_Libc(benchmark::State& state) { + // No timezone support, so just use localtime. + int i = 0; + while (state.KeepRunning()) { + struct tm tm; + if ((i & 1) == 0) { + tm.tm_year = 2014 - 1900; + tm.tm_mon = 12 - 1; + tm.tm_mday = 0; + tm.tm_hour = 20; + tm.tm_min = 16; + tm.tm_sec = 18; + } else { + tm.tm_year = 2013 - 1900; + tm.tm_mon = 11 - 1; + tm.tm_mday = 0; + tm.tm_hour = 18; + tm.tm_min = 30; + tm.tm_sec = 27; + } + tm.tm_isdst = -1; + mktime(&tm); + ++i; + } +} +BENCHMARK(BM_Time_FromDateTimeDay0_Libc); + +// +// To/FromTimespec +// + +void BM_Time_ToTimespec(benchmark::State& state) { + absl::Time now = absl::Now(); + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::ToTimespec(now)); + } +} +BENCHMARK(BM_Time_ToTimespec); + +void BM_Time_FromTimespec(benchmark::State& state) { + timespec ts = absl::ToTimespec(absl::Now()); + while (state.KeepRunning()) { + if (++ts.tv_nsec == 1000 * 1000 * 1000) { + ++ts.tv_sec; + ts.tv_nsec = 0; + } + benchmark::DoNotOptimize(absl::TimeFromTimespec(ts)); + } +} +BENCHMARK(BM_Time_FromTimespec); + +// +// Comparison with InfiniteFuture/Past +// + +void BM_Time_InfiniteFuture(benchmark::State& state) { + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::InfiniteFuture()); + } +} +BENCHMARK(BM_Time_InfiniteFuture); + +void BM_Time_InfinitePast(benchmark::State& state) { + while (state.KeepRunning()) { + benchmark::DoNotOptimize(absl::InfinitePast()); + } +} +BENCHMARK(BM_Time_InfinitePast); + +} // namespace diff --git a/third_party/abseil-cpp/absl/types/BUILD.bazel b/third_party/abseil-cpp/absl/types/BUILD.bazel index f8d53c263b..1fc4c098e9 100644 --- a/third_party/abseil-cpp/absl/types/BUILD.bazel +++ b/third_party/abseil-cpp/absl/types/BUILD.bazel @@ -28,7 +28,7 @@ licenses(["notice"]) # Apache 2.0 cc_library( name = "any", hdrs = ["any.h"], - copts = ABSL_DEFAULT_COPTS + ABSL_EXCEPTIONS_FLAG, + copts = ABSL_DEFAULT_COPTS, deps = [ ":bad_any_cast", "//absl/base:config", @@ -40,9 +40,19 @@ cc_library( cc_library( name = "bad_any_cast", - srcs = ["bad_any_cast.cc"], hdrs = ["bad_any_cast.h"], + copts = ABSL_DEFAULT_COPTS, + deps = [":bad_any_cast_impl"], +) + +cc_library( + name = "bad_any_cast_impl", + srcs = [ + "bad_any_cast.cc", + "bad_any_cast.h", + ], copts = ABSL_EXCEPTIONS_FLAG + ABSL_DEFAULT_COPTS, + visibility = ["//visibility:private"], deps = [ "//absl/base", "//absl/base:config", @@ -193,6 +203,19 @@ cc_test( ], ) +cc_test( + name = "optional_exception_safety_test", + srcs = [ + "optional_exception_safety_test.cc", + ], + copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, + deps = [ + ":optional", + "//absl/base:exception_safety_testing", + "@com_google_googletest//:gtest_main", + ], +) + cc_library( name = "variant", srcs = ["internal/variant.h"], diff --git a/third_party/abseil-cpp/absl/types/BUILD.gn b/third_party/abseil-cpp/absl/types/BUILD.gn index bdde0f6844..b05a14aa61 100644 --- a/third_party/abseil-cpp/absl/types/BUILD.gn +++ b/third_party/abseil-cpp/absl/types/BUILD.gn @@ -35,6 +35,21 @@ source_set("any") { } source_set("bad_any_cast") { + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ + "//build/config/compiler:no_chromium_code", + "//third_party/abseil-cpp:absl_default_cflags_cc", + ] + public_configs = [ "//third_party/abseil-cpp:absl_include_config" ] + public = [ + "bad_any_cast.h", + ] + deps = [ + ":bad_any_cast_impl", + ] +} + +source_set("bad_any_cast_impl") { configs -= [ "//build/config/compiler:chromium_code" ] configs += [ "//build/config/compiler:no_chromium_code", @@ -51,6 +66,8 @@ source_set("bad_any_cast") { "../base", "../base:config", ] + visibility = [] + visibility += [ ":*" ] } source_set("span") { diff --git a/third_party/abseil-cpp/absl/types/CMakeLists.txt b/third_party/abseil-cpp/absl/types/CMakeLists.txt index fbd8374031..2f2e3a7780 100644 --- a/third_party/abseil-cpp/absl/types/CMakeLists.txt +++ b/third_party/abseil-cpp/absl/types/CMakeLists.txt @@ -209,3 +209,20 @@ absl_test( ) +# test optional_exception_safety_test +set(OPTIONAL_EXCEPTION_SAFETY_TEST_SRC "optional_exception_safety_test.cc") +set(OPTIONAL_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES + absl::optional + absl_base_internal_exception_safety_testing +) + +absl_test( + TARGET + optional_exception_safety_test + SOURCES + ${OPTIONAL_EXCEPTION_SAFETY_TEST_SRC} + PUBLIC_LIBRARIES + ${OPTIONAL_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES} + PRIVATE_COMPILE_FLAGS + ${ABSL_EXCEPTIONS_FLAG} +) diff --git a/third_party/abseil-cpp/absl/types/optional_exception_safety_test.cc b/third_party/abseil-cpp/absl/types/optional_exception_safety_test.cc new file mode 100644 index 0000000000..d2ef04b8d1 --- /dev/null +++ b/third_party/abseil-cpp/absl/types/optional_exception_safety_test.cc @@ -0,0 +1,282 @@ +// Copyright 2017 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 +// +// http://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. + +#include "absl/types/optional.h" + +#include "gtest/gtest.h" +#include "absl/base/internal/exception_safety_testing.h" + +namespace absl { + +namespace { + +using ::testing::AssertionFailure; +using ::testing::AssertionResult; +using ::testing::AssertionSuccess; +using ::testing::MakeExceptionSafetyTester; + +using Thrower = testing::ThrowingValue; +using Optional = absl::optional; + +using MoveThrower = testing::ThrowingValue; +using MoveOptional = absl::optional; + +constexpr int kInitialInteger = 5; +constexpr int kUpdatedInteger = 10; + +template +bool ValueThrowsBadOptionalAccess(const OptionalT& optional) try { + return (static_cast(optional.value()), false); +} catch (absl::bad_optional_access) { + return true; +} + +template +AssertionResult CheckInvariants(OptionalT* optional_ptr) { + // Check the current state post-throw for validity + auto& optional = *optional_ptr; + + if (optional.has_value() && ValueThrowsBadOptionalAccess(optional)) { + return AssertionFailure() + << "Optional with value should not throw bad_optional_access when " + "accessing the value."; + } + if (!optional.has_value() && !ValueThrowsBadOptionalAccess(optional)) { + return AssertionFailure() + << "Optional without a value should throw bad_optional_access when " + "accessing the value."; + } + + // Reset to a known state + optional.reset(); + + // Confirm that the known post-reset state is valid + if (optional.has_value()) { + return AssertionFailure() + << "Optional should not contain a value after being reset."; + } + if (!ValueThrowsBadOptionalAccess(optional)) { + return AssertionFailure() << "Optional should throw bad_optional_access " + "when accessing the value after being reset."; + } + + return AssertionSuccess(); +} + +template +AssertionResult CheckDisengaged(OptionalT* optional_ptr) { + auto& optional = *optional_ptr; + + if (optional.has_value()) { + return AssertionFailure() + << "Expected optional to not contain a value but a value was found."; + } + + return AssertionSuccess(); +} + +template +AssertionResult CheckEngaged(OptionalT* optional_ptr) { + auto& optional = *optional_ptr; + + if (!optional.has_value()) { + return AssertionFailure() + << "Expected optional to contain a value but no value was found."; + } + + return AssertionSuccess(); +} + +TEST(OptionalExceptionSafety, ThrowingConstructors) { + auto thrower_nonempty = Optional(Thrower(kInitialInteger)); + testing::TestThrowingCtor(thrower_nonempty); + + auto integer_nonempty = absl::optional(kInitialInteger); + testing::TestThrowingCtor(integer_nonempty); + testing::TestThrowingCtor(std::move(integer_nonempty)); // NOLINT + + testing::TestThrowingCtor(kInitialInteger); + using ThrowerVec = std::vector>; + testing::TestThrowingCtor>( + absl::in_place, + std::initializer_list{Thrower(), Thrower(), Thrower()}, + testing::ThrowingAllocator()); +} + +TEST(OptionalExceptionSafety, NothrowConstructors) { + // This constructor is marked noexcept. If it throws, the program will + // terminate. + testing::TestThrowingCtor(MoveOptional(kUpdatedInteger)); +} + +TEST(OptionalExceptionSafety, Emplace) { + // Test the basic guarantee plus test the result of optional::has_value() + // is false in all cases + auto disengaged_test = MakeExceptionSafetyTester().WithInvariants( + CheckInvariants, CheckDisengaged); + auto disengaged_test_empty = disengaged_test.WithInitialValue(Optional()); + auto disengaged_test_nonempty = + disengaged_test.WithInitialValue(Optional(kInitialInteger)); + + auto emplace_thrower_directly = [](Optional* optional_ptr) { + optional_ptr->emplace(kUpdatedInteger); + }; + EXPECT_TRUE(disengaged_test_empty.Test(emplace_thrower_directly)); + EXPECT_TRUE(disengaged_test_nonempty.Test(emplace_thrower_directly)); + + auto emplace_thrower_copy = [](Optional* optional_ptr) { + auto thrower = Thrower(kUpdatedInteger, testing::nothrow_ctor); + optional_ptr->emplace(thrower); + }; + EXPECT_TRUE(disengaged_test_empty.Test(emplace_thrower_copy)); + EXPECT_TRUE(disengaged_test_nonempty.Test(emplace_thrower_copy)); +} + +TEST(OptionalExceptionSafety, EverythingThrowsSwap) { + // Test the basic guarantee plus test the result of optional::has_value() + // remains the same + auto test = + MakeExceptionSafetyTester().WithInvariants(CheckInvariants); + auto disengaged_test_empty = test.WithInitialValue(Optional()) + .WithInvariants(CheckDisengaged); + auto engaged_test_nonempty = test.WithInitialValue(Optional(kInitialInteger)) + .WithInvariants(CheckEngaged); + + auto swap_empty = [](Optional* optional_ptr) { + auto empty = Optional(); + optional_ptr->swap(empty); + }; + EXPECT_TRUE(engaged_test_nonempty.Test(swap_empty)); + + auto swap_nonempty = [](Optional* optional_ptr) { + auto nonempty = + Optional(absl::in_place, kUpdatedInteger, testing::nothrow_ctor); + optional_ptr->swap(nonempty); + }; + EXPECT_TRUE(disengaged_test_empty.Test(swap_nonempty)); + EXPECT_TRUE(engaged_test_nonempty.Test(swap_nonempty)); +} + +TEST(OptionalExceptionSafety, NoThrowMoveSwap) { + // Tests the nothrow guarantee for optional of T with non-throwing move + { + auto empty = MoveOptional(); + auto nonempty = MoveOptional(kInitialInteger); + EXPECT_TRUE(testing::TestNothrowOp([&]() { nonempty.swap(empty); })); + } + { + auto nonempty = MoveOptional(kUpdatedInteger); + auto empty = MoveOptional(); + EXPECT_TRUE(testing::TestNothrowOp([&]() { empty.swap(nonempty); })); + } + { + auto nonempty_from = MoveOptional(kUpdatedInteger); + auto nonempty_to = MoveOptional(kInitialInteger); + EXPECT_TRUE( + testing::TestNothrowOp([&]() { nonempty_to.swap(nonempty_from); })); + } +} + +TEST(OptionalExceptionSafety, CopyAssign) { + // Test the basic guarantee plus test the result of optional::has_value() + // remains the same + auto test = + MakeExceptionSafetyTester().WithInvariants(CheckInvariants); + auto disengaged_test_empty = test.WithInitialValue(Optional()) + .WithInvariants(CheckDisengaged); + auto engaged_test_nonempty = test.WithInitialValue(Optional(kInitialInteger)) + .WithInvariants(CheckEngaged); + + auto copyassign_nonempty = [](Optional* optional_ptr) { + auto nonempty = + Optional(absl::in_place, kUpdatedInteger, testing::nothrow_ctor); + *optional_ptr = nonempty; + }; + EXPECT_TRUE(disengaged_test_empty.Test(copyassign_nonempty)); + EXPECT_TRUE(engaged_test_nonempty.Test(copyassign_nonempty)); + + auto copyassign_thrower = [](Optional* optional_ptr) { + auto thrower = Thrower(kUpdatedInteger, testing::nothrow_ctor); + *optional_ptr = thrower; + }; + EXPECT_TRUE(disengaged_test_empty.Test(copyassign_thrower)); + EXPECT_TRUE(engaged_test_nonempty.Test(copyassign_thrower)); +} + +TEST(OptionalExceptionSafety, MoveAssign) { + // Test the basic guarantee plus test the result of optional::has_value() + // remains the same + auto test = + MakeExceptionSafetyTester().WithInvariants(CheckInvariants); + auto disengaged_test_empty = test.WithInitialValue(Optional()) + .WithInvariants(CheckDisengaged); + auto engaged_test_nonempty = test.WithInitialValue(Optional(kInitialInteger)) + .WithInvariants(CheckEngaged); + + auto moveassign_empty = [](Optional* optional_ptr) { + auto empty = Optional(); + *optional_ptr = std::move(empty); + }; + EXPECT_TRUE(engaged_test_nonempty.Test(moveassign_empty)); + + auto moveassign_nonempty = [](Optional* optional_ptr) { + auto nonempty = + Optional(absl::in_place, kUpdatedInteger, testing::nothrow_ctor); + *optional_ptr = std::move(nonempty); + }; + EXPECT_TRUE(disengaged_test_empty.Test(moveassign_nonempty)); + EXPECT_TRUE(engaged_test_nonempty.Test(moveassign_nonempty)); + + auto moveassign_thrower = [](Optional* optional_ptr) { + auto thrower = Thrower(kUpdatedInteger, testing::nothrow_ctor); + *optional_ptr = std::move(thrower); + }; + EXPECT_TRUE(disengaged_test_empty.Test(moveassign_thrower)); + EXPECT_TRUE(engaged_test_nonempty.Test(moveassign_thrower)); +} + +TEST(OptionalExceptionSafety, NothrowMoveAssign) { + // Tests the nothrow guarantee for optional of T with non-throwing move + { + auto empty = MoveOptional(); + auto nonempty = MoveOptional(kInitialInteger); + EXPECT_TRUE(testing::TestNothrowOp([&]() { nonempty = std::move(empty); })); + } + { + auto nonempty = MoveOptional(kInitialInteger); + auto empty = MoveOptional(); + EXPECT_TRUE(testing::TestNothrowOp([&]() { empty = std::move(nonempty); })); + } + { + auto nonempty_from = MoveOptional(kUpdatedInteger); + auto nonempty_to = MoveOptional(kInitialInteger); + EXPECT_TRUE(testing::TestNothrowOp( + [&]() { nonempty_to = std::move(nonempty_from); })); + } + { + auto thrower = MoveThrower(kUpdatedInteger); + auto empty = MoveOptional(); + EXPECT_TRUE(testing::TestNothrowOp([&]() { empty = std::move(thrower); })); + } + { + auto thrower = MoveThrower(kUpdatedInteger); + auto nonempty = MoveOptional(kInitialInteger); + EXPECT_TRUE( + testing::TestNothrowOp([&]() { nonempty = std::move(thrower); })); + } +} + +} // namespace + +} // namespace absl diff --git a/third_party/abseil-cpp/absl/types/span.h b/third_party/abseil-cpp/absl/types/span.h index f781353c23..76be819ecc 100644 --- a/third_party/abseil-cpp/absl/types/span.h +++ b/third_party/abseil-cpp/absl/types/span.h @@ -279,7 +279,7 @@ class Span { using size_type = size_t; using difference_type = ptrdiff_t; - static const size_type npos = ~size_type{0}; + static const size_type npos = ~(size_type(0)); constexpr Span() noexcept : Span(nullptr, 0) {} constexpr Span(pointer array, size_type length) noexcept diff --git a/third_party/abseil-cpp/absl/types/variant_exception_safety_test.cc b/third_party/abseil-cpp/absl/types/variant_exception_safety_test.cc index 377e4afac5..27c0b96ca6 100644 --- a/third_party/abseil-cpp/absl/types/variant_exception_safety_test.cc +++ b/third_party/abseil-cpp/absl/types/variant_exception_safety_test.cc @@ -27,8 +27,8 @@ namespace absl { namespace { using ::testing::MakeExceptionSafetyTester; -using ::testing::nothrow_guarantee; using ::testing::strong_guarantee; +using ::testing::TestNothrowOp; using ::testing::TestThrowingCtor; using Thrower = testing::ThrowingValue<>; @@ -120,7 +120,11 @@ testing::AssertionResult CheckInvariants(ThrowingVariant* v) { return AssertionSuccess(); } -Thrower ExpectedThrower() { return Thrower(42); } +template +Thrower ExpectedThrower(Args&&... args) { + return Thrower(42, args...); +} + ThrowerVec ExpectedThrowerVec() { return {Thrower(100), Thrower(200)}; } ThrowingVariant ValuelessByException() { ThrowingVariant v; @@ -193,18 +197,14 @@ TEST(VariantExceptionSafetyTest, CopyAssign) { { // - neither *this nor rhs holds a value const ThrowingVariant rhs = ValuelessByException(); - EXPECT_TRUE(MakeExceptionSafetyTester() - .WithInitialValue(ValuelessByException()) - .WithInvariants(nothrow_guarantee) - .Test([&rhs](ThrowingVariant* lhs) { *lhs = rhs; })); + ThrowingVariant lhs = ValuelessByException(); + EXPECT_TRUE(TestNothrowOp([&]() { lhs = rhs; })); } { // - *this holds a value but rhs does not const ThrowingVariant rhs = ValuelessByException(); - EXPECT_TRUE(MakeExceptionSafetyTester() - .WithInitialValue(WithThrower()) - .WithInvariants(nothrow_guarantee) - .Test([&rhs](ThrowingVariant* lhs) { *lhs = rhs; })); + ThrowingVariant lhs = WithThrower(); + EXPECT_TRUE(TestNothrowOp([&]() { lhs = rhs; })); } // - index() == j { @@ -237,10 +237,8 @@ TEST(VariantExceptionSafetyTest, CopyAssign) { // should not throw because emplace() invokes Tj's copy ctor // which should not throw. const ThrowingVariant rhs(CopyNothrow{}); - EXPECT_TRUE(MakeExceptionSafetyTester() - .WithInitialValue(WithThrower()) - .WithInvariants(nothrow_guarantee) - .Test([&rhs](ThrowingVariant* lhs) { *lhs = rhs; })); + ThrowingVariant lhs = WithThrower(); + EXPECT_TRUE(TestNothrowOp([&]() { lhs = rhs; })); } { // is_nothrow_copy_constructible == false && @@ -281,23 +279,14 @@ TEST(VariantExceptionSafetyTest, MoveAssign) { { // - neither *this nor rhs holds a value ThrowingVariant rhs = ValuelessByException(); - - EXPECT_TRUE(MakeExceptionSafetyTester() - .WithInitialValue(ValuelessByException()) - .WithInvariants(nothrow_guarantee) - .Test([rhs](ThrowingVariant* lhs) mutable { - *lhs = std::move(rhs); - })); + ThrowingVariant lhs = ValuelessByException(); + EXPECT_TRUE(TestNothrowOp([&]() { lhs = std::move(rhs); })); } { // - *this holds a value but rhs does not ThrowingVariant rhs = ValuelessByException(); - EXPECT_TRUE(MakeExceptionSafetyTester() - .WithInitialValue(WithThrower()) - .WithInvariants(nothrow_guarantee) - .Test([rhs](ThrowingVariant* lhs) mutable { - *lhs = std::move(rhs); - })); + ThrowingVariant lhs = WithThrower(); + EXPECT_TRUE(TestNothrowOp([&]() { lhs = std::move(rhs); })); } { // - index() == j @@ -310,13 +299,14 @@ TEST(VariantExceptionSafetyTest, MoveAssign) { // Since Thrower's move assignment has basic guarantee, so should variant's. auto tester = MakeExceptionSafetyTester() .WithInitialValue(WithThrower()) - .WithOperation([rhs](ThrowingVariant* lhs) mutable { - *lhs = std::move(rhs); + .WithOperation([&](ThrowingVariant* lhs) { + auto copy = rhs; + *lhs = std::move(copy); }); EXPECT_TRUE(tester .WithInvariants( CheckInvariants, - [j](ThrowingVariant* lhs) { return lhs->index() == j; }) + [&](ThrowingVariant* lhs) { return lhs->index() == j; }) .Test()); EXPECT_FALSE(tester.WithInvariants(strong_guarantee).Test()); } @@ -332,8 +322,9 @@ TEST(VariantExceptionSafetyTest, MoveAssign) { [](ThrowingVariant* lhs) { return lhs->valueless_by_exception(); }) - .Test([rhs](ThrowingVariant* lhs) mutable { - *lhs = std::move(rhs); + .Test([&](ThrowingVariant* lhs) { + auto copy = rhs; + *lhs = std::move(copy); })); } } @@ -365,8 +356,9 @@ TEST(VariantExceptionSafetyTest, ValueAssign) { // move assign auto move_tester = MakeExceptionSafetyTester() .WithInitialValue(WithThrower()) - .WithOperation([rhs](ThrowingVariant* lhs) mutable { - *lhs = std::move(rhs); + .WithOperation([&](ThrowingVariant* lhs) { + auto copy = rhs; + *lhs = std::move(copy); }); EXPECT_TRUE(move_tester .WithInvariants(CheckInvariants, @@ -388,19 +380,13 @@ TEST(VariantExceptionSafetyTest, ValueAssign) { // invokes the copy/move constructor and it should not throw. { const CopyNothrow rhs; - EXPECT_TRUE(MakeExceptionSafetyTester() - .WithInitialValue(WithThrower()) - .WithInvariants(nothrow_guarantee) - .Test([&rhs](ThrowingVariant* lhs) { *lhs = rhs; })); + ThrowingVariant lhs = WithThrower(); + EXPECT_TRUE(TestNothrowOp([&]() { lhs = rhs; })); } { MoveNothrow rhs; - EXPECT_TRUE(MakeExceptionSafetyTester() - .WithInitialValue(WithThrower()) - .WithInvariants(nothrow_guarantee) - .Test([rhs](ThrowingVariant* lhs) mutable { - *lhs = std::move(rhs); - })); + ThrowingVariant lhs = WithThrower(); + EXPECT_TRUE(TestNothrowOp([&]() { lhs = std::move(rhs); })); } // if is_nothrow_constructible_v == false && // is_nothrow_move_constructible == false @@ -423,8 +409,8 @@ TEST(VariantExceptionSafetyTest, ValueAssign) { // move auto move_tester = MakeExceptionSafetyTester() .WithInitialValue(WithCopyNoThrow()) - .WithOperation([rhs](ThrowingVariant* lhs) mutable { - *lhs = std::move(rhs); + .WithOperation([](ThrowingVariant* lhs) { + *lhs = ExpectedThrower(testing::nothrow_ctor); }); EXPECT_TRUE(move_tester .WithInvariants(CheckInvariants, @@ -477,21 +463,20 @@ TEST(VariantExceptionSafetyTest, Swap) { // if both are valueless_by_exception(), no effect { ThrowingVariant rhs = ValuelessByException(); - EXPECT_TRUE( - MakeExceptionSafetyTester() - .WithInitialValue(ValuelessByException()) - .WithInvariants(nothrow_guarantee) - .Test([rhs](ThrowingVariant* lhs) mutable { lhs->swap(rhs); })); + ThrowingVariant lhs = ValuelessByException(); + EXPECT_TRUE(TestNothrowOp([&]() { lhs.swap(rhs); })); } // if index() == rhs.index(), calls swap(get(*this), get(rhs)) // where i is index(). { ThrowingVariant rhs = ExpectedThrower(); - EXPECT_TRUE( - MakeExceptionSafetyTester() - .WithInitialValue(WithThrower()) - .WithInvariants(CheckInvariants) - .Test([rhs](ThrowingVariant* lhs) mutable { lhs->swap(rhs); })); + EXPECT_TRUE(MakeExceptionSafetyTester() + .WithInitialValue(WithThrower()) + .WithInvariants(CheckInvariants) + .Test([&](ThrowingVariant* lhs) { + auto copy = rhs; + lhs->swap(copy); + })); } // Otherwise, exchanges the value of rhs and *this. The exception safety // involves variant in moved-from state which is not specified in the @@ -499,19 +484,23 @@ TEST(VariantExceptionSafetyTest, Swap) { // overall strong guarantee. So, we are only checking basic guarantee here. { ThrowingVariant rhs = ExpectedThrower(); - EXPECT_TRUE( - MakeExceptionSafetyTester() - .WithInitialValue(WithCopyNoThrow()) - .WithInvariants(CheckInvariants) - .Test([rhs](ThrowingVariant* lhs) mutable { lhs->swap(rhs); })); + EXPECT_TRUE(MakeExceptionSafetyTester() + .WithInitialValue(WithCopyNoThrow()) + .WithInvariants(CheckInvariants) + .Test([&](ThrowingVariant* lhs) { + auto copy = rhs; + lhs->swap(copy); + })); } { ThrowingVariant rhs = ExpectedThrower(); - EXPECT_TRUE( - MakeExceptionSafetyTester() - .WithInitialValue(WithCopyNoThrow()) - .WithInvariants(CheckInvariants) - .Test([rhs](ThrowingVariant* lhs) mutable { rhs.swap(*lhs); })); + EXPECT_TRUE(MakeExceptionSafetyTester() + .WithInitialValue(WithCopyNoThrow()) + .WithInvariants(CheckInvariants) + .Test([&](ThrowingVariant* lhs) { + auto copy = rhs; + copy.swap(*lhs); + })); } } diff --git a/third_party/closure_compiler/compiled_resources2.gyp b/third_party/closure_compiler/compiled_resources2.gyp index 1b6b8c04a4..7eddef4bd4 100644 --- a/third_party/closure_compiler/compiled_resources2.gyp +++ b/third_party/closure_compiler/compiled_resources2.gyp @@ -14,14 +14,6 @@ 'target_name': 'compiled_resources2', 'type': 'none', 'dependencies': [ - '<(DEPTH)/chrome/browser/resources/chromeos/braille_ime/compiled_resources2.gyp:*', - '<(DEPTH)/chrome/browser/resources/chromeos/compiled_resources2.gyp:*', - '<(DEPTH)/chrome/browser/resources/chromeos/login/compiled_resources2.gyp:*', - '<(DEPTH)/chrome/browser/resources/chromeos/multidevice_setup/compiled_resources2.gyp:*', - '<(DEPTH)/chrome/browser/resources/chromeos/network_ui/compiled_resources2.gyp:*', - '<(DEPTH)/chrome/browser/resources/chromeos/select_to_speak/compiled_resources2.gyp:*', - '<(DEPTH)/chrome/browser/resources/chromeos/switch_access/compiled_resources2.gyp:*', - '<(DEPTH)/chrome/browser/resources/chromeos/sys_internals/compiled_resources2.gyp:*', '<(DEPTH)/ui/webui/resources/cr_components/compiled_resources2.gyp:*', '<(DEPTH)/ui/webui/resources/cr_elements/compiled_resources2.gyp:*', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:*', diff --git a/third_party/closure_compiler/externs/automation.js b/third_party/closure_compiler/externs/automation.js index 98d97541c9..281a94fc4e 100644 --- a/third_party/closure_compiler/externs/automation.js +++ b/third_party/closure_compiler/externs/automation.js @@ -265,7 +265,6 @@ chrome.automation.StateType = { EXPANDED: 'expanded', FOCUSABLE: 'focusable', FOCUSED: 'focused', - HAS_POPUP: 'hasPopup', HORIZONTAL: 'horizontal', HOVERED: 'hovered', IGNORED: 'ignored', diff --git a/third_party/closure_compiler/externs/file_manager_private.js b/third_party/closure_compiler/externs/file_manager_private.js index ad527c3ebc..fb3103e405 100644 --- a/third_party/closure_compiler/externs/file_manager_private.js +++ b/third_party/closure_compiler/externs/file_manager_private.js @@ -250,7 +250,12 @@ chrome.fileManagerPrivate.FileTask; * starred: (boolean|undefined), * externalFileUrl: (string|undefined), * alternateUrl: (string|undefined), - * shareUrl: (string|undefined) + * shareUrl: (string|undefined), + * canCopy: (boolean|undefined), + * canDelete: (boolean|undefined), + * canRename: (boolean|undefined), + * canAddChildren: (boolean|undefined), + * canShare: (boolean|undefined) * }} */ chrome.fileManagerPrivate.EntryProperties; diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium index 3228297dd4..eea790ba85 100644 --- a/third_party/freetype/README.chromium +++ b/third_party/freetype/README.chromium @@ -1,7 +1,7 @@ Name: FreeType URL: http://www.freetype.org/ -Version: VER-2-9-1-36 -Revision: 0589f6e6ee6e9bfe0c7139374fc8812e849e7bf7 +Version: VER-2-9-1-56 +Revision: 8f1ed54877ffab4fc2cf2be329446c748a885842 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent JPEG Group) licenses" License File: src/docs/FTL.TXT diff --git a/third_party/freetype/include/freetype-custom-config/ftoption.h b/third_party/freetype/include/freetype-custom-config/ftoption.h index da0a6ba340..34af6ed9ee 100644 --- a/third_party/freetype/include/freetype-custom-config/ftoption.h +++ b/third_party/freetype/include/freetype-custom-config/ftoption.h @@ -1,19 +1,19 @@ -/***************************************************************************/ -/* */ -/* ftoption.h */ -/* */ -/* User-selectable configuration macros (specification only). */ -/* */ -/* Copyright 1996-2018 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ +/**************************************************************************** + * + * ftoption.h + * + * User-selectable configuration macros (specification only). + * + * Copyright 1996-2018 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ #ifndef FTOPTION_H_ @@ -25,45 +25,45 @@ FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* USER-SELECTABLE CONFIGURATION MACROS */ - /* */ - /* This file contains the default configuration macro definitions for */ - /* a standard build of the FreeType library. There are three ways to */ - /* use this file to build project-specific versions of the library: */ - /* */ - /* - You can modify this file by hand, but this is not recommended in */ - /* cases where you would like to build several versions of the */ - /* library from a single source directory. */ - /* */ - /* - You can put a copy of this file in your build directory, more */ - /* precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD' */ - /* is the name of a directory that is included _before_ the FreeType */ - /* include path during compilation. */ - /* */ - /* The default FreeType Makefiles and Jamfiles use the build */ - /* directory `builds/' by default, but you can easily change */ - /* that for your own projects. */ - /* */ - /* - Copy the file to `$BUILD/ft2build.h' and modify it */ - /* slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to */ - /* locate this file during the build. For example, */ - /* */ - /* #define FT_CONFIG_OPTIONS_H */ - /* #include */ - /* */ - /* will use `$BUILD/myftoptions.h' instead of this file for macro */ - /* definitions. */ - /* */ - /* Note also that you can similarly pre-define the macro */ - /* FT_CONFIG_MODULES_H used to locate the file listing of the modules */ - /* that are statically linked to the library at compile time. By */ - /* default, this file is . */ - /* */ - /* We highly recommend using the third method whenever possible. */ - /* */ - /*************************************************************************/ + /************************************************************************** + * + * USER-SELECTABLE CONFIGURATION MACROS + * + * This file contains the default configuration macro definitions for + * a standard build of the FreeType library. There are three ways to + * use this file to build project-specific versions of the library: + * + * - You can modify this file by hand, but this is not recommended in + * cases where you would like to build several versions of the + * library from a single source directory. + * + * - You can put a copy of this file in your build directory, more + * precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD' + * is the name of a directory that is included _before_ the FreeType + * include path during compilation. + * + * The default FreeType Makefiles and Jamfiles use the build + * directory `builds/' by default, but you can easily change + * that for your own projects. + * + * - Copy the file to `$BUILD/ft2build.h' and modify it + * slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to + * locate this file during the build. For example, + * + * #define FT_CONFIG_OPTIONS_H + * #include + * + * will use `$BUILD/myftoptions.h' instead of this file for macro + * definitions. + * + * Note also that you can similarly pre-define the macro + * FT_CONFIG_MODULES_H used to locate the file listing of the modules + * that are statically linked to the library at compile time. By + * default, this file is . + * + * We highly recommend using the third method whenever possible. + * + */ /*************************************************************************/ @@ -108,383 +108,384 @@ FT_BEGIN_HEADER #define FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES - /*************************************************************************/ - /* */ - /* Uncomment the line below if you want to activate LCD rendering */ - /* technology similar to ClearType in this build of the library. This */ - /* technology triples the resolution in the direction color subpixels. */ - /* To mitigate color fringes inherent to this technology, you also need */ - /* to explicitly set up LCD filtering. */ - /* */ - /* Note that this feature is covered by several Microsoft patents */ - /* and should not be activated in any default build of the library. */ - /* When this macro is not defined, FreeType offers alternative LCD */ - /* rendering technology that produces excellent output without LCD */ - /* filtering. */ - /* */ + /************************************************************************** + * + * Uncomment the line below if you want to activate LCD rendering + * technology similar to ClearType in this build of the library. This + * technology triples the resolution in the direction color subpixels. + * To mitigate color fringes inherent to this technology, you also need + * to explicitly set up LCD filtering. + * + * Note that this feature is covered by several Microsoft patents + * and should not be activated in any default build of the library. + * When this macro is not defined, FreeType offers alternative LCD + * rendering technology that produces excellent output without LCD + * filtering. + */ #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING - /*************************************************************************/ - /* */ - /* Many compilers provide a non-ANSI 64-bit data type that can be used */ - /* by FreeType to speed up some computations. However, this will create */ - /* some problems when compiling the library in strict ANSI mode. */ - /* */ - /* For this reason, the use of 64-bit integers is normally disabled when */ - /* the __STDC__ macro is defined. You can however disable this by */ - /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here. */ - /* */ - /* For most compilers, this will only create compilation warnings when */ - /* building the library. */ - /* */ - /* ObNote: The compiler-specific 64-bit integers are detected in the */ - /* file `ftconfig.h' either statically or through the */ - /* `configure' script on supported platforms. */ - /* */ + /************************************************************************** + * + * Many compilers provide a non-ANSI 64-bit data type that can be used + * by FreeType to speed up some computations. However, this will create + * some problems when compiling the library in strict ANSI mode. + * + * For this reason, the use of 64-bit integers is normally disabled when + * the __STDC__ macro is defined. You can however disable this by + * defining the macro FT_CONFIG_OPTION_FORCE_INT64 here. + * + * For most compilers, this will only create compilation warnings when + * building the library. + * + * ObNote: The compiler-specific 64-bit integers are detected in the + * file `ftconfig.h' either statically or through the + * `configure' script on supported platforms. + */ #undef FT_CONFIG_OPTION_FORCE_INT64 - /*************************************************************************/ - /* */ - /* If this macro is defined, do not try to use an assembler version of */ - /* performance-critical functions (e.g. FT_MulFix). You should only do */ - /* that to verify that the assembler function works properly, or to */ - /* execute benchmark tests of the various implementations. */ + /************************************************************************** + * + * If this macro is defined, do not try to use an assembler version of + * performance-critical functions (e.g. FT_MulFix). You should only do + * that to verify that the assembler function works properly, or to + * execute benchmark tests of the various implementations. + */ /* #define FT_CONFIG_OPTION_NO_ASSEMBLER */ - /*************************************************************************/ - /* */ - /* If this macro is defined, try to use an inlined assembler version of */ - /* the `FT_MulFix' function, which is a `hotspot' when loading and */ - /* hinting glyphs, and which should be executed as fast as possible. */ - /* */ - /* Note that if your compiler or CPU is not supported, this will default */ - /* to the standard and portable implementation found in `ftcalc.c'. */ - /* */ + /************************************************************************** + * + * If this macro is defined, try to use an inlined assembler version of + * the `FT_MulFix' function, which is a `hotspot' when loading and + * hinting glyphs, and which should be executed as fast as possible. + * + * Note that if your compiler or CPU is not supported, this will default + * to the standard and portable implementation found in `ftcalc.c'. + */ #define FT_CONFIG_OPTION_INLINE_MULFIX - /*************************************************************************/ - /* */ - /* LZW-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `compress' program. This is mostly used to parse many of the PCF */ - /* files that come with various X11 distributions. The implementation */ - /* uses NetBSD's `zopen' to partially uncompress the file on the fly */ - /* (see src/lzw/ftgzip.c). */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ + /************************************************************************** + * + * LZW-compressed file support. + * + * FreeType now handles font files that have been compressed with the + * `compress' program. This is mostly used to parse many of the PCF + * files that come with various X11 distributions. The implementation + * uses NetBSD's `zopen' to partially uncompress the file on the fly + * (see src/lzw/ftgzip.c). + * + * Define this macro if you want to enable this `feature'. + */ #define FT_CONFIG_OPTION_USE_LZW - /*************************************************************************/ - /* */ - /* Gzip-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `gzip' program. This is mostly used to parse many of the PCF files */ - /* that come with XFree86. The implementation uses `zlib' to */ - /* partially uncompress the file on the fly (see src/gzip/ftgzip.c). */ - /* */ - /* Define this macro if you want to enable this `feature'. See also */ - /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ - /* */ + /************************************************************************** + * + * Gzip-compressed file support. + * + * FreeType now handles font files that have been compressed with the + * `gzip' program. This is mostly used to parse many of the PCF files + * that come with XFree86. The implementation uses `zlib' to + * partially uncompress the file on the fly (see src/gzip/ftgzip.c). + * + * Define this macro if you want to enable this `feature'. See also + * the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. + */ #define FT_CONFIG_OPTION_USE_ZLIB - /*************************************************************************/ - /* */ - /* ZLib library selection */ - /* */ - /* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */ - /* It allows FreeType's `ftgzip' component to link to the system's */ - /* installation of the ZLib library. This is useful on systems like */ - /* Unix or VMS where it generally is already available. */ - /* */ - /* If you let it undefined, the component will use its own copy */ - /* of the zlib sources instead. These have been modified to be */ - /* included directly within the component and *not* export external */ - /* function names. This allows you to link any program with FreeType */ - /* _and_ ZLib without linking conflicts. */ - /* */ - /* Do not #undef this macro here since the build system might define */ - /* it for certain configurations only. */ - /* */ - /* If you use a build system like cmake or the `configure' script, */ - /* options set by those programs have precendence, overwriting the */ - /* value here with the configured one. */ - /* */ + /************************************************************************** + * + * ZLib library selection + * + * This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. + * It allows FreeType's `ftgzip' component to link to the system's + * installation of the ZLib library. This is useful on systems like + * Unix or VMS where it generally is already available. + * + * If you let it undefined, the component will use its own copy + * of the zlib sources instead. These have been modified to be + * included directly within the component and *not* export external + * function names. This allows you to link any program with FreeType + * _and_ ZLib without linking conflicts. + * + * Do not #undef this macro here since the build system might define + * it for certain configurations only. + * + * If you use a build system like cmake or the `configure' script, + * options set by those programs have precendence, overwriting the + * value here with the configured one. + */ /* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ - /*************************************************************************/ - /* */ - /* Bzip2-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `bzip2' program. This is mostly used to parse many of the PCF */ - /* files that come with XFree86. The implementation uses `libbz2' to */ - /* partially uncompress the file on the fly (see src/bzip2/ftbzip2.c). */ - /* Contrary to gzip, bzip2 currently is not included and need to use */ - /* the system available bzip2 implementation. */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ - /* If you use a build system like cmake or the `configure' script, */ - /* options set by those programs have precendence, overwriting the */ - /* value here with the configured one. */ - /* */ + /************************************************************************** + * + * Bzip2-compressed file support. + * + * FreeType now handles font files that have been compressed with the + * `bzip2' program. This is mostly used to parse many of the PCF + * files that come with XFree86. The implementation uses `libbz2' to + * partially uncompress the file on the fly (see src/bzip2/ftbzip2.c). + * Contrary to gzip, bzip2 currently is not included and need to use + * the system available bzip2 implementation. + * + * Define this macro if you want to enable this `feature'. + * + * If you use a build system like cmake or the `configure' script, + * options set by those programs have precendence, overwriting the + * value here with the configured one. + */ /* #define FT_CONFIG_OPTION_USE_BZIP2 */ - /*************************************************************************/ - /* */ - /* Define to disable the use of file stream functions and types, FILE, */ - /* fopen() etc. Enables the use of smaller system libraries on embedded */ - /* systems that have multiple system libraries, some with or without */ - /* file stream support, in the cases where file stream support is not */ - /* necessary such as memory loading of font files. */ - /* */ + /************************************************************************** + * + * Define to disable the use of file stream functions and types, FILE, + * fopen() etc. Enables the use of smaller system libraries on embedded + * systems that have multiple system libraries, some with or without + * file stream support, in the cases where file stream support is not + * necessary such as memory loading of font files. + */ /* #define FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */ - /*************************************************************************/ - /* */ - /* PNG bitmap support. */ - /* */ - /* FreeType now handles loading color bitmap glyphs in the PNG format. */ - /* This requires help from the external libpng library. Uncompressed */ - /* color bitmaps do not need any external libraries and will be */ - /* supported regardless of this configuration. */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ - /* If you use a build system like cmake or the `configure' script, */ - /* options set by those programs have precendence, overwriting the */ - /* value here with the configured one. */ - /* */ + /************************************************************************** + * + * PNG bitmap support. + * + * FreeType now handles loading color bitmap glyphs in the PNG format. + * This requires help from the external libpng library. Uncompressed + * color bitmaps do not need any external libraries and will be + * supported regardless of this configuration. + * + * Define this macro if you want to enable this `feature'. + * + * If you use a build system like cmake or the `configure' script, + * options set by those programs have precendence, overwriting the + * value here with the configured one. + */ #define FT_CONFIG_OPTION_USE_PNG - /*************************************************************************/ - /* */ - /* HarfBuzz support. */ - /* */ - /* FreeType uses the HarfBuzz library to improve auto-hinting of */ - /* OpenType fonts. If available, many glyphs not directly addressable */ - /* by a font's character map will be hinted also. */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ - /* If you use a build system like cmake or the `configure' script, */ - /* options set by those programs have precendence, overwriting the */ - /* value here with the configured one. */ - /* */ + /************************************************************************** + * + * HarfBuzz support. + * + * FreeType uses the HarfBuzz library to improve auto-hinting of + * OpenType fonts. If available, many glyphs not directly addressable + * by a font's character map will be hinted also. + * + * Define this macro if you want to enable this `feature'. + * + * If you use a build system like cmake or the `configure' script, + * options set by those programs have precendence, overwriting the + * value here with the configured one. + */ #if !defined(WITHOUT_HARFBUZZ) #define FT_CONFIG_OPTION_USE_HARFBUZZ #endif - /*************************************************************************/ - /* */ - /* Glyph Postscript Names handling */ - /* */ - /* By default, FreeType 2 is compiled with the `psnames' module. This */ - /* module is in charge of converting a glyph name string into a */ - /* Unicode value, or return a Macintosh standard glyph name for the */ - /* use with the TrueType `post' table. */ - /* */ - /* Undefine this macro if you do not want `psnames' compiled in your */ - /* build of FreeType. This has the following effects: */ - /* */ - /* - The TrueType driver will provide its own set of glyph names, */ - /* if you build it to support postscript names in the TrueType */ - /* `post' table, but will not synthesize a missing Unicode charmap. */ - /* */ - /* - The Type 1 driver will not be able to synthesize a Unicode */ - /* charmap out of the glyphs found in the fonts. */ - /* */ - /* You would normally undefine this configuration macro when building */ - /* a version of FreeType that doesn't contain a Type 1 or CFF driver. */ - /* */ + /************************************************************************** + * + * Glyph Postscript Names handling + * + * By default, FreeType 2 is compiled with the `psnames' module. This + * module is in charge of converting a glyph name string into a + * Unicode value, or return a Macintosh standard glyph name for the + * use with the TrueType `post' table. + * + * Undefine this macro if you do not want `psnames' compiled in your + * build of FreeType. This has the following effects: + * + * - The TrueType driver will provide its own set of glyph names, + * if you build it to support postscript names in the TrueType + * `post' table, but will not synthesize a missing Unicode charmap. + * + * - The Type 1 driver will not be able to synthesize a Unicode + * charmap out of the glyphs found in the fonts. + * + * You would normally undefine this configuration macro when building + * a version of FreeType that doesn't contain a Type 1 or CFF driver. + */ #define FT_CONFIG_OPTION_POSTSCRIPT_NAMES - /*************************************************************************/ - /* */ - /* Postscript Names to Unicode Values support */ - /* */ - /* By default, FreeType 2 is built with the `PSNames' module compiled */ - /* in. Among other things, the module is used to convert a glyph name */ - /* into a Unicode value. This is especially useful in order to */ - /* synthesize on the fly a Unicode charmap from the CFF/Type 1 driver */ - /* through a big table named the `Adobe Glyph List' (AGL). */ - /* */ - /* Undefine this macro if you do not want the Adobe Glyph List */ - /* compiled in your `PSNames' module. The Type 1 driver will not be */ - /* able to synthesize a Unicode charmap out of the glyphs found in the */ - /* fonts. */ - /* */ + /************************************************************************** + * + * Postscript Names to Unicode Values support + * + * By default, FreeType 2 is built with the `PSNames' module compiled + * in. Among other things, the module is used to convert a glyph name + * into a Unicode value. This is especially useful in order to + * synthesize on the fly a Unicode charmap from the CFF/Type 1 driver + * through a big table named the `Adobe Glyph List' (AGL). + * + * Undefine this macro if you do not want the Adobe Glyph List + * compiled in your `PSNames' module. The Type 1 driver will not be + * able to synthesize a Unicode charmap out of the glyphs found in the + * fonts. + */ #define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - /*************************************************************************/ - /* */ - /* Support for Mac fonts */ - /* */ - /* Define this macro if you want support for outline fonts in Mac */ - /* format (mac dfont, mac resource, macbinary containing a mac */ - /* resource) on non-Mac platforms. */ - /* */ - /* Note that the `FOND' resource isn't checked. */ - /* */ + /************************************************************************** + * + * Support for Mac fonts + * + * Define this macro if you want support for outline fonts in Mac + * format (mac dfont, mac resource, macbinary containing a mac + * resource) on non-Mac platforms. + * + * Note that the `FOND' resource isn't checked. + */ /* #define FT_CONFIG_OPTION_MAC_FONTS */ - /*************************************************************************/ - /* */ - /* Guessing methods to access embedded resource forks */ - /* */ - /* Enable extra Mac fonts support on non-Mac platforms (e.g. */ - /* GNU/Linux). */ - /* */ - /* Resource forks which include fonts data are stored sometimes in */ - /* locations which users or developers don't expected. In some cases, */ - /* resource forks start with some offset from the head of a file. In */ - /* other cases, the actual resource fork is stored in file different */ - /* from what the user specifies. If this option is activated, */ - /* FreeType tries to guess whether such offsets or different file */ - /* names must be used. */ - /* */ - /* Note that normal, direct access of resource forks is controlled via */ - /* the FT_CONFIG_OPTION_MAC_FONTS option. */ - /* */ + /************************************************************************** + * + * Guessing methods to access embedded resource forks + * + * Enable extra Mac fonts support on non-Mac platforms (e.g. + * GNU/Linux). + * + * Resource forks which include fonts data are stored sometimes in + * locations which users or developers don't expected. In some cases, + * resource forks start with some offset from the head of a file. In + * other cases, the actual resource fork is stored in file different + * from what the user specifies. If this option is activated, + * FreeType tries to guess whether such offsets or different file + * names must be used. + * + * Note that normal, direct access of resource forks is controlled via + * the FT_CONFIG_OPTION_MAC_FONTS option. + */ #ifdef FT_CONFIG_OPTION_MAC_FONTS #define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK #endif - /*************************************************************************/ - /* */ - /* Allow the use of FT_Incremental_Interface to load typefaces that */ - /* contain no glyph data, but supply it via a callback function. */ - /* This is required by clients supporting document formats which */ - /* supply font data incrementally as the document is parsed, such */ - /* as the Ghostscript interpreter for the PostScript language. */ - /* */ + /************************************************************************** + * + * Allow the use of FT_Incremental_Interface to load typefaces that + * contain no glyph data, but supply it via a callback function. + * This is required by clients supporting document formats which + * supply font data incrementally as the document is parsed, such + * as the Ghostscript interpreter for the PostScript language. + */ #define FT_CONFIG_OPTION_INCREMENTAL - /*************************************************************************/ - /* */ - /* The size in bytes of the render pool used by the scan-line converter */ - /* to do all of its work. */ - /* */ + /************************************************************************** + * + * The size in bytes of the render pool used by the scan-line converter + * to do all of its work. + */ #define FT_RENDER_POOL_SIZE 16384L - /*************************************************************************/ - /* */ - /* FT_MAX_MODULES */ - /* */ - /* The maximum number of modules that can be registered in a single */ - /* FreeType library object. 32 is the default. */ - /* */ + /************************************************************************** + * + * FT_MAX_MODULES + * + * The maximum number of modules that can be registered in a single + * FreeType library object. 32 is the default. + */ #define FT_MAX_MODULES 32 - /*************************************************************************/ - /* */ - /* Debug level */ - /* */ - /* FreeType can be compiled in debug or trace mode. In debug mode, */ - /* errors are reported through the `ftdebug' component. In trace */ - /* mode, additional messages are sent to the standard output during */ - /* execution. */ - /* */ - /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */ - /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */ - /* */ - /* Don't define any of these macros to compile in `release' mode! */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ + /************************************************************************** + * + * Debug level + * + * FreeType can be compiled in debug or trace mode. In debug mode, + * errors are reported through the `ftdebug' component. In trace + * mode, additional messages are sent to the standard output during + * execution. + * + * Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. + * Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. + * + * Don't define any of these macros to compile in `release' mode! + * + * Do not #undef these macros here since the build system might define + * them for certain configurations only. + */ /* #define FT_DEBUG_LEVEL_ERROR */ /* #define FT_DEBUG_LEVEL_TRACE */ - /*************************************************************************/ - /* */ - /* Autofitter debugging */ - /* */ - /* If FT_DEBUG_AUTOFIT is defined, FreeType provides some means to */ - /* control the autofitter behaviour for debugging purposes with global */ - /* boolean variables (consequently, you should *never* enable this */ - /* while compiling in `release' mode): */ - /* */ - /* _af_debug_disable_horz_hints */ - /* _af_debug_disable_vert_hints */ - /* _af_debug_disable_blue_hints */ - /* */ - /* Additionally, the following functions provide dumps of various */ - /* internal autofit structures to stdout (using `printf'): */ - /* */ - /* af_glyph_hints_dump_points */ - /* af_glyph_hints_dump_segments */ - /* af_glyph_hints_dump_edges */ - /* af_glyph_hints_get_num_segments */ - /* af_glyph_hints_get_segment_offset */ - /* */ - /* As an argument, they use another global variable: */ - /* */ - /* _af_debug_hints */ - /* */ - /* Please have a look at the `ftgrid' demo program to see how those */ - /* variables and macros should be used. */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ + /************************************************************************** + * + * Autofitter debugging + * + * If FT_DEBUG_AUTOFIT is defined, FreeType provides some means to + * control the autofitter behaviour for debugging purposes with global + * boolean variables (consequently, you should *never* enable this + * while compiling in `release' mode): + * + * _af_debug_disable_horz_hints + * _af_debug_disable_vert_hints + * _af_debug_disable_blue_hints + * + * Additionally, the following functions provide dumps of various + * internal autofit structures to stdout (using `printf'): + * + * af_glyph_hints_dump_points + * af_glyph_hints_dump_segments + * af_glyph_hints_dump_edges + * af_glyph_hints_get_num_segments + * af_glyph_hints_get_segment_offset + * + * As an argument, they use another global variable: + * + * _af_debug_hints + * + * Please have a look at the `ftgrid' demo program to see how those + * variables and macros should be used. + * + * Do not #undef these macros here since the build system might define + * them for certain configurations only. + */ /* #define FT_DEBUG_AUTOFIT */ - /*************************************************************************/ - /* */ - /* Memory Debugging */ - /* */ - /* FreeType now comes with an integrated memory debugger that is */ - /* capable of detecting simple errors like memory leaks or double */ - /* deletes. To compile it within your build of the library, you */ - /* should define FT_DEBUG_MEMORY here. */ - /* */ - /* Note that the memory debugger is only activated at runtime when */ - /* when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also! */ - /* */ - /* Do not #undef this macro here since the build system might define */ - /* it for certain configurations only. */ - /* */ + /************************************************************************** + * + * Memory Debugging + * + * FreeType now comes with an integrated memory debugger that is + * capable of detecting simple errors like memory leaks or double + * deletes. To compile it within your build of the library, you + * should define FT_DEBUG_MEMORY here. + * + * Note that the memory debugger is only activated at runtime when + * when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also! + * + * Do not #undef this macro here since the build system might define + * it for certain configurations only. + */ /* #define FT_DEBUG_MEMORY */ - /*************************************************************************/ - /* */ - /* Module errors */ - /* */ - /* If this macro is set (which is _not_ the default), the higher byte */ - /* of an error code gives the module in which the error has occurred, */ - /* while the lower byte is the real error code. */ - /* */ - /* Setting this macro makes sense for debugging purposes only, since */ - /* it would break source compatibility of certain programs that use */ - /* FreeType 2. */ - /* */ - /* More details can be found in the files ftmoderr.h and fterrors.h. */ - /* */ + /************************************************************************** + * + * Module errors + * + * If this macro is set (which is _not_ the default), the higher byte + * of an error code gives the module in which the error has occurred, + * while the lower byte is the real error code. + * + * Setting this macro makes sense for debugging purposes only, since + * it would break source compatibility of certain programs that use + * FreeType 2. + * + * More details can be found in the files ftmoderr.h and fterrors.h. + */ #undef FT_CONFIG_OPTION_USE_MODULE_ERRORS @@ -526,59 +527,60 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */ - /* embedded bitmaps in all formats using the SFNT module (namely */ - /* TrueType & OpenType). */ - /* */ + /************************************************************************** + * + * Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support + * embedded bitmaps in all formats using the SFNT module (namely + * TrueType & OpenType). + */ #define TT_CONFIG_OPTION_EMBEDDED_BITMAPS - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_COLOR_LAYERS if you want to support coloured */ - /* outlines (from the COLR/CPAL tables) in all formats using the SFNT */ - /* module (namely TrueType & OpenType). */ - /* */ + /************************************************************************** + * + * Define TT_CONFIG_OPTION_COLOR_LAYERS if you want to support coloured + * outlines (from the COLR/CPAL tables) in all formats using the SFNT + * module (namely TrueType & OpenType). + */ #define TT_CONFIG_OPTION_COLOR_LAYERS - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */ - /* load and enumerate the glyph Postscript names in a TrueType or */ - /* OpenType file. */ - /* */ - /* Note that when you do not compile the `PSNames' module by undefining */ - /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */ - /* contain additional code used to read the PS Names table from a font. */ - /* */ - /* (By default, the module uses `PSNames' to extract glyph names.) */ - /* */ + /************************************************************************** + * + * Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to + * load and enumerate the glyph Postscript names in a TrueType or + * OpenType file. + * + * Note that when you do not compile the `PSNames' module by undefining + * the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will + * contain additional code used to read the PS Names table from a font. + * + * (By default, the module uses `PSNames' to extract glyph names.) + */ #define TT_CONFIG_OPTION_POSTSCRIPT_NAMES - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */ - /* access the internal name table in a SFNT-based format like TrueType */ - /* or OpenType. The name table contains various strings used to */ - /* describe the font, like family name, copyright, version, etc. It */ - /* does not contain any glyph name though. */ - /* */ - /* Accessing SFNT names is done through the functions declared in */ - /* `ftsnames.h'. */ - /* */ + /************************************************************************** + * + * Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to + * access the internal name table in a SFNT-based format like TrueType + * or OpenType. The name table contains various strings used to + * describe the font, like family name, copyright, version, etc. It + * does not contain any glyph name though. + * + * Accessing SFNT names is done through the functions declared in + * `ftsnames.h'. + */ #define TT_CONFIG_OPTION_SFNT_NAMES - /*************************************************************************/ - /* */ - /* TrueType CMap support */ - /* */ - /* Here you can fine-tune which TrueType CMap table format shall be */ - /* supported. */ + /************************************************************************** + * + * TrueType CMap support + * + * Here you can fine-tune which TrueType CMap table format shall be + * supported. + */ #define TT_CONFIG_CMAP_FORMAT_0 #define TT_CONFIG_CMAP_FORMAT_2 #define TT_CONFIG_CMAP_FORMAT_4 @@ -598,131 +600,131 @@ FT_BEGIN_HEADER /*************************************************************************/ /*************************************************************************/ - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */ - /* a bytecode interpreter in the TrueType driver. */ - /* */ - /* By undefining this, you will only compile the code necessary to load */ - /* TrueType glyphs without hinting. */ - /* */ - /* Do not #undef this macro here, since the build system might */ - /* define it for certain configurations only. */ - /* */ + /************************************************************************** + * + * Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile + * a bytecode interpreter in the TrueType driver. + * + * By undefining this, you will only compile the code necessary to load + * TrueType glyphs without hinting. + * + * Do not #undef this macro here, since the build system might + * define it for certain configurations only. + */ #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */ - /* subpixel hinting support into the TrueType driver. This modifies the */ - /* TrueType hinting mechanism when anything but FT_RENDER_MODE_MONO is */ - /* requested. */ - /* */ - /* In particular, it modifies the bytecode interpreter to interpret (or */ - /* not) instructions in a certain way so that all TrueType fonts look */ - /* like they do in a Windows ClearType (DirectWrite) environment. See */ - /* [1] for a technical overview on what this means. See `ttinterp.h' */ - /* for more details on the LEAN option. */ - /* */ - /* There are three possible values. */ - /* */ - /* Value 1: */ - /* This value is associated with the `Infinality' moniker, */ - /* contributed by an individual nicknamed Infinality with the goal of */ - /* making TrueType fonts render better than on Windows. A high */ - /* amount of configurability and flexibility, down to rules for */ - /* single glyphs in fonts, but also very slow. Its experimental and */ - /* slow nature and the original developer losing interest meant that */ - /* this option was never enabled in default builds. */ - /* */ - /* The corresponding interpreter version is v38. */ - /* */ - /* Value 2: */ - /* The new default mode for the TrueType driver. The Infinality code */ - /* base was stripped to the bare minimum and all configurability */ - /* removed in the name of speed and simplicity. The configurability */ - /* was mainly aimed at legacy fonts like Arial, Times New Roman, or */ - /* Courier. Legacy fonts are fonts that modify vertical stems to */ - /* achieve clean black-and-white bitmaps. The new mode focuses on */ - /* applying a minimal set of rules to all fonts indiscriminately so */ - /* that modern and web fonts render well while legacy fonts render */ - /* okay. */ - /* */ - /* The corresponding interpreter version is v40. */ - /* */ - /* Value 3: */ - /* Compile both, making both v38 and v40 available (the latter is the */ - /* default). */ - /* */ - /* By undefining these, you get rendering behavior like on Windows */ - /* without ClearType, i.e., Windows XP without ClearType enabled and */ - /* Win9x (interpreter version v35). Or not, depending on how much */ - /* hinting blood and testing tears the font designer put into a given */ - /* font. If you define one or both subpixel hinting options, you can */ - /* switch between between v35 and the ones you define (using */ - /* `FT_Property_Set'). */ - /* */ - /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ - /* defined. */ - /* */ - /* [1] https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ - /* */ + /************************************************************************** + * + * Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile + * subpixel hinting support into the TrueType driver. This modifies the + * TrueType hinting mechanism when anything but FT_RENDER_MODE_MONO is + * requested. + * + * In particular, it modifies the bytecode interpreter to interpret (or + * not) instructions in a certain way so that all TrueType fonts look + * like they do in a Windows ClearType (DirectWrite) environment. See + * [1] for a technical overview on what this means. See `ttinterp.h' + * for more details on the LEAN option. + * + * There are three possible values. + * + * Value 1: + * This value is associated with the `Infinality' moniker, + * contributed by an individual nicknamed Infinality with the goal of + * making TrueType fonts render better than on Windows. A high + * amount of configurability and flexibility, down to rules for + * single glyphs in fonts, but also very slow. Its experimental and + * slow nature and the original developer losing interest meant that + * this option was never enabled in default builds. + * + * The corresponding interpreter version is v38. + * + * Value 2: + * The new default mode for the TrueType driver. The Infinality code + * base was stripped to the bare minimum and all configurability + * removed in the name of speed and simplicity. The configurability + * was mainly aimed at legacy fonts like Arial, Times New Roman, or + * Courier. Legacy fonts are fonts that modify vertical stems to + * achieve clean black-and-white bitmaps. The new mode focuses on + * applying a minimal set of rules to all fonts indiscriminately so + * that modern and web fonts render well while legacy fonts render + * okay. + * + * The corresponding interpreter version is v40. + * + * Value 3: + * Compile both, making both v38 and v40 available (the latter is the + * default). + * + * By undefining these, you get rendering behavior like on Windows + * without ClearType, i.e., Windows XP without ClearType enabled and + * Win9x (interpreter version v35). Or not, depending on how much + * hinting blood and testing tears the font designer put into a given + * font. If you define one or both subpixel hinting options, you can + * switch between between v35 and the ones you define (using + * `FT_Property_Set'). + * + * This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be + * defined. + * + * [1] https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx + */ /* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 1 */ #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 2 /* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING ( 1 | 2 ) */ - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the */ - /* TrueType glyph loader to use Apple's definition of how to handle */ - /* component offsets in composite glyphs. */ - /* */ - /* Apple and MS disagree on the default behavior of component offsets */ - /* in composites. Apple says that they should be scaled by the scaling */ - /* factors in the transformation matrix (roughly, it's more complex) */ - /* while MS says they should not. OpenType defines two bits in the */ - /* composite flags array which can be used to disambiguate, but old */ - /* fonts will not have them. */ - /* */ - /* https://www.microsoft.com/typography/otspec/glyf.htm */ - /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html */ - /* */ + /************************************************************************** + * + * Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the + * TrueType glyph loader to use Apple's definition of how to handle + * component offsets in composite glyphs. + * + * Apple and MS disagree on the default behavior of component offsets + * in composites. Apple says that they should be scaled by the scaling + * factors in the transformation matrix (roughly, it's more complex) + * while MS says they should not. OpenType defines two bits in the + * composite flags array which can be used to disambiguate, but old + * fonts will not have them. + * + * https://www.microsoft.com/typography/otspec/glyf.htm + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html + */ #undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include */ - /* support for Apple's distortable font technology (fvar, gvar, cvar, */ - /* and avar tables). This has many similarities to Type 1 Multiple */ - /* Masters support. */ - /* */ + /************************************************************************** + * + * Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include + * support for Apple's distortable font technology (fvar, gvar, cvar, + * and avar tables). This has many similarities to Type 1 Multiple + * Masters support. + */ #define TT_CONFIG_OPTION_GX_VAR_SUPPORT - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_BDF if you want to include support for */ - /* an embedded `BDF ' table within SFNT-based bitmap formats. */ - /* */ + /************************************************************************** + * + * Define TT_CONFIG_OPTION_BDF if you want to include support for + * an embedded `BDF ' table within SFNT-based bitmap formats. + */ /* #define TT_CONFIG_OPTION_BDF */ - /*************************************************************************/ - /* */ - /* Option TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES controls the maximum */ - /* number of bytecode instructions executed for a single run of the */ - /* bytecode interpreter, needed to prevent infinite loops. You don't */ - /* want to change this except for very special situations (e.g., making */ - /* a library fuzzer spend less time to handle broken fonts). */ - /* */ - /* It is not expected that this value is ever modified by a configuring */ - /* script; instead, it gets surrounded with #ifndef ... #endif so that */ - /* the value can be set as a preprocessor option on the compiler's */ - /* command line. */ - /* */ + /************************************************************************** + * + * Option TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES controls the maximum + * number of bytecode instructions executed for a single run of the + * bytecode interpreter, needed to prevent infinite loops. You don't + * want to change this except for very special situations (e.g., making + * a library fuzzer spend less time to handle broken fonts). + * + * It is not expected that this value is ever modified by a configuring + * script; instead, it gets surrounded with #ifndef ... #endif so that + * the value can be set as a preprocessor option on the compiler's + * command line. + */ #ifndef TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES #define TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES 1000000L #endif @@ -737,59 +739,59 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* T1_MAX_DICT_DEPTH is the maximum depth of nest dictionaries and */ - /* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */ - /* required. */ - /* */ + /************************************************************************** + * + * T1_MAX_DICT_DEPTH is the maximum depth of nest dictionaries and + * arrays in the Type 1 stream (see t1load.c). A minimum of 4 is + * required. + */ #define T1_MAX_DICT_DEPTH 5 - /*************************************************************************/ - /* */ - /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ - /* calls during glyph loading. */ - /* */ + /************************************************************************** + * + * T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine + * calls during glyph loading. + */ #define T1_MAX_SUBRS_CALLS 16 - /*************************************************************************/ - /* */ - /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ - /* minimum of 16 is required. */ - /* */ - /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */ - /* */ + /************************************************************************** + * + * T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A + * minimum of 16 is required. + * + * The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. + */ #define T1_MAX_CHARSTRINGS_OPERANDS 512 - /*************************************************************************/ - /* */ - /* Define this configuration macro if you want to prevent the */ - /* compilation of `t1afm', which is in charge of reading Type 1 AFM */ - /* files into an existing face. Note that if set, the T1 driver will be */ - /* unable to produce kerning distances. */ - /* */ + /************************************************************************** + * + * Define this configuration macro if you want to prevent the + * compilation of `t1afm', which is in charge of reading Type 1 AFM + * files into an existing face. Note that if set, the T1 driver will be + * unable to produce kerning distances. + */ #undef T1_CONFIG_OPTION_NO_AFM - /*************************************************************************/ - /* */ - /* Define this configuration macro if you want to prevent the */ - /* compilation of the Multiple Masters font support in the Type 1 */ - /* driver. */ - /* */ + /************************************************************************** + * + * Define this configuration macro if you want to prevent the + * compilation of the Multiple Masters font support in the Type 1 + * driver. + */ #undef T1_CONFIG_OPTION_NO_MM_SUPPORT - /*************************************************************************/ - /* */ - /* T1_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe Type 1 */ - /* engine gets compiled into FreeType. If defined, it is possible to */ - /* switch between the two engines using the `hinting-engine' property of */ - /* the type1 driver module. */ - /* */ + /************************************************************************** + * + * T1_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe Type 1 + * engine gets compiled into FreeType. If defined, it is possible to + * switch between the two engines using the `hinting-engine' property of + * the type1 driver module. + */ /* #define T1_CONFIG_OPTION_OLD_ENGINE */ @@ -802,17 +804,17 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* Using CFF_CONFIG_OPTION_DARKENING_PARAMETER_{X,Y}{1,2,3,4} it is */ - /* possible to set up the default values of the four control points that */ - /* define the stem darkening behaviour of the (new) CFF engine. For */ - /* more details please read the documentation of the */ - /* `darkening-parameters' property (file `ftdriver.h'), which allows the */ - /* control at run-time. */ - /* */ - /* Do *not* undefine these macros! */ - /* */ + /************************************************************************** + * + * Using CFF_CONFIG_OPTION_DARKENING_PARAMETER_{X,Y}{1,2,3,4} it is + * possible to set up the default values of the four control points that + * define the stem darkening behaviour of the (new) CFF engine. For + * more details please read the documentation of the + * `darkening-parameters' property (file `ftdriver.h'), which allows the + * control at run-time. + * + * Do *not* undefine these macros! + */ #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 500 #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 400 @@ -826,13 +828,13 @@ FT_BEGIN_HEADER #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 0 - /*************************************************************************/ - /* */ - /* CFF_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe CFF */ - /* engine gets compiled into FreeType. If defined, it is possible to */ - /* switch between the two engines using the `hinting-engine' property of */ - /* the cff driver module. */ - /* */ + /************************************************************************** + * + * CFF_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe CFF + * engine gets compiled into FreeType. If defined, it is possible to + * switch between the two engines using the `hinting-engine' property of + * the cff driver module. + */ /* #define CFF_CONFIG_OPTION_OLD_ENGINE */ @@ -845,21 +847,21 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* There are many PCF fonts just called `Fixed' which look completely */ - /* different, and which have nothing to do with each other. When */ - /* selecting `Fixed' in KDE or Gnome one gets results that appear rather */ - /* random, the style changes often if one changes the size and one */ - /* cannot select some fonts at all. This option makes the PCF module */ - /* prepend the foundry name (plus a space) to the family name. */ - /* */ - /* We also check whether we have `wide' characters; all put together, we */ - /* get family names like `Sony Fixed' or `Misc Fixed Wide'. */ - /* */ - /* If this option is activated, it can be controlled with the */ - /* `no-long-family-names' property of the pcf driver module. */ - /* */ + /************************************************************************** + * + * There are many PCF fonts just called `Fixed' which look completely + * different, and which have nothing to do with each other. When + * selecting `Fixed' in KDE or Gnome one gets results that appear rather + * random, the style changes often if one changes the size and one + * cannot select some fonts at all. This option makes the PCF module + * prepend the foundry name (plus a space) to the family name. + * + * We also check whether we have `wide' characters; all put together, we + * get family names like `Sony Fixed' or `Misc Fixed Wide'. + * + * If this option is activated, it can be controlled with the + * `no-long-family-names' property of the pcf driver module. + */ /* #define PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */ @@ -872,54 +874,54 @@ FT_BEGIN_HEADER /*************************************************************************/ - /*************************************************************************/ - /* */ - /* Compile autofit module with CJK (Chinese, Japanese, Korean) script */ - /* support. */ - /* */ + /************************************************************************** + * + * Compile autofit module with CJK (Chinese, Japanese, Korean) script + * support. + */ #define AF_CONFIG_OPTION_CJK - /*************************************************************************/ - /* */ - /* Compile autofit module with fallback Indic script support, covering */ - /* some scripts that the `latin' submodule of the autofit module doesn't */ - /* (yet) handle. */ - /* */ + /************************************************************************** + * + * Compile autofit module with fallback Indic script support, covering + * some scripts that the `latin' submodule of the autofit module doesn't + * (yet) handle. + */ #define AF_CONFIG_OPTION_INDIC - /*************************************************************************/ - /* */ - /* Compile autofit module with warp hinting. The idea of the warping */ - /* code is to slightly scale and shift a glyph within a single dimension */ - /* so that as much of its segments are aligned (more or less) on the */ - /* grid. To find out the optimal scaling and shifting value, various */ - /* parameter combinations are tried and scored. */ - /* */ - /* This experimental option is active only if the rendering mode is */ - /* FT_RENDER_MODE_LIGHT; you can switch warping on and off with the */ - /* `warping' property of the auto-hinter (see file `ftdriver.h' for more */ - /* information; by default it is switched off). */ - /* */ -/*#define AF_CONFIG_OPTION_USE_WARPER*/ + /************************************************************************** + * + * Compile autofit module with warp hinting. The idea of the warping + * code is to slightly scale and shift a glyph within a single dimension + * so that as much of its segments are aligned (more or less) on the + * grid. To find out the optimal scaling and shifting value, various + * parameter combinations are tried and scored. + * + * This experimental option is active only if the rendering mode is + * FT_RENDER_MODE_LIGHT; you can switch warping on and off with the + * `warping' property of the auto-hinter (see file `ftdriver.h' for more + * information; by default it is switched off). + */ +/* #define AF_CONFIG_OPTION_USE_WARPER */ - /*************************************************************************/ - /* */ - /* Use TrueType-like size metrics for `light' auto-hinting. */ - /* */ - /* It is strongly recommended to avoid this option, which exists only to */ - /* help some legacy applications retain its appearance and behaviour */ - /* with respect to auto-hinted TrueType fonts. */ - /* */ - /* The very reason this option exists at all are GNU/Linux distributions */ - /* like Fedora that did not un-patch the following change (which was */ - /* present in FreeType between versions 2.4.6 and 2.7.1, inclusive). */ - /* */ - /* 2011-07-16 Steven Chu */ - /* */ - /* [truetype] Fix metrics on size request for scalable fonts. */ - /* */ - /* This problematic commit is now reverted (more or less). */ - /* */ + /************************************************************************** + * + * Use TrueType-like size metrics for `light' auto-hinting. + * + * It is strongly recommended to avoid this option, which exists only to + * help some legacy applications retain its appearance and behaviour + * with respect to auto-hinted TrueType fonts. + * + * The very reason this option exists at all are GNU/Linux distributions + * like Fedora that did not un-patch the following change (which was + * present in FreeType between versions 2.4.6 and 2.7.1, inclusive). + * + * 2011-07-16 Steven Chu + * + * [truetype] Fix metrics on size request for scalable fonts. + * + * This problematic commit is now reverted (more or less). + */ /* #define AF_CONFIG_OPTION_TT_SIZE_METRICS */ /* */ diff --git a/third_party/googletest/BUILD.gn b/third_party/googletest/BUILD.gn index 4b8720768e..5de326ddf7 100644 --- a/third_party/googletest/BUILD.gn +++ b/third_party/googletest/BUILD.gn @@ -111,7 +111,6 @@ source_set("gtest") { if (is_fuchsia) { deps += [ "//third_party/fuchsia-sdk:fdio", - "//third_party/fuchsia-sdk:launchpad", ] } }