From dc969f34a79d019497abb61c2a3f79b5b4be2ea9 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 17 Aug 2020 15:25:15 -0700 Subject: Export of internal Abseil changes -- caf65de1a20b1ad286796a9eaee38f8b59e93f3b by Samuel Benzaquen : Add a benchmark for StrAppend. PiperOrigin-RevId: 327111569 -- 2faa53fb3f4090f9609c7dea8951a82e1d72ce3a by Derek Mauro : Add the inline namespace to the code generated by gaussian_distribution_gentables A previous changed manually added it to the output PiperOrigin-RevId: 327022780 -- 29edfd86e49e4d7665e843463f8df3c72467e909 by Derek Mauro : Re-write the logic for detecting which stacktrace implementation to use on Linux. The visible change is to detect the presence of the `` header, which allows using the `backtrace`-based implementation when it is available. The logic has been simplified as well. Fixes #746 PiperOrigin-RevId: 326911875 -- ce198204b77aac240e98fc8d5931b17a8b26bac3 by Abseil Team : Demangle exception spec. PiperOrigin-RevId: 326909460 -- c41b89954545bdc4430d10e785d3ba64a55122d5 by Abseil Team : Add support for inheriting ctor. PiperOrigin-RevId: 326904919 GitOrigin-RevId: caf65de1a20b1ad286796a9eaee38f8b59e93f3b Change-Id: Ifd28b6a85a032839cbeafd1b16f88046dfd6c1d4 --- absl/debugging/internal/demangle.cc | 54 ++++++++++++++++++---- absl/debugging/internal/stacktrace_config.h | 52 ++++++++++----------- .../internal/gaussian_distribution_gentables.cc | 16 +++---- absl/strings/str_cat_benchmark.cc | 47 +++++++++++++++++++ 4 files changed, 123 insertions(+), 46 deletions(-) diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc index 87f13e50..b980d1b2 100644 --- a/absl/debugging/internal/demangle.cc +++ b/absl/debugging/internal/demangle.cc @@ -1082,20 +1082,28 @@ static bool ParseVOffset(State *state) { return false; } -// ::= C1 | C2 | C3 +// ::= C1 | C2 | C3 | CI1 | CI2 +// // ::= D0 | D1 | D2 // # GCC extensions: "unified" constructor/destructor. See -// # https://github.com/gcc-mirror/gcc/blob/7ad17b583c3643bd4557f29b8391ca7ef08391f5/gcc/cp/mangle.c#L1847 +// # +// https://github.com/gcc-mirror/gcc/blob/7ad17b583c3643bd4557f29b8391ca7ef08391f5/gcc/cp/mangle.c#L1847 // ::= C4 | D4 static bool ParseCtorDtorName(State *state) { ComplexityGuard guard(state); if (guard.IsTooComplex()) return false; ParseState copy = state->parse_state; - if (ParseOneCharToken(state, 'C') && ParseCharClass(state, "1234")) { - const char *const prev_name = state->out + state->parse_state.prev_name_idx; - MaybeAppendWithLength(state, prev_name, - state->parse_state.prev_name_length); - return true; + if (ParseOneCharToken(state, 'C')) { + if (ParseCharClass(state, "1234")) { + const char *const prev_name = + state->out + state->parse_state.prev_name_idx; + MaybeAppendWithLength(state, prev_name, + state->parse_state.prev_name_length); + return true; + } else if (ParseOneCharToken(state, 'I') && ParseCharClass(state, "12") && + ParseClassEnumType(state)) { + return true; + } } state->parse_state = copy; @@ -1265,12 +1273,40 @@ static bool ParseBuiltinType(State *state) { return false; } -// ::= F [Y] [O] E +// ::= Do # non-throwing +// exception-specification (e.g., +// noexcept, throw()) +// ::= DO E # computed (instantiation-dependent) +// noexcept +// ::= Dw + E # dynamic exception specification +// with instantiation-dependent types +static bool ParseExceptionSpec(State *state) { + ComplexityGuard guard(state); + if (guard.IsTooComplex()) return false; + + if (ParseTwoCharToken(state, "Do")) return true; + + ParseState copy = state->parse_state; + if (ParseTwoCharToken(state, "DO") && ParseExpression(state) && + ParseOneCharToken(state, 'E')) { + return true; + } + state->parse_state = copy; + if (ParseTwoCharToken(state, "Dw") && OneOrMore(ParseType, state) && + ParseOneCharToken(state, 'E')) { + return true; + } + state->parse_state = copy; + + return false; +} + +// ::= [exception-spec] F [Y] [O] E static bool ParseFunctionType(State *state) { ComplexityGuard guard(state); if (guard.IsTooComplex()) return false; ParseState copy = state->parse_state; - if (ParseOneCharToken(state, 'F') && + if (Optional(ParseExceptionSpec(state)) && ParseOneCharToken(state, 'F') && Optional(ParseOneCharToken(state, 'Y')) && ParseBareFunctionType(state) && Optional(ParseOneCharToken(state, 'O')) && ParseOneCharToken(state, 'E')) { diff --git a/absl/debugging/internal/stacktrace_config.h b/absl/debugging/internal/stacktrace_config.h index d5cc1740..90af8528 100644 --- a/absl/debugging/internal/stacktrace_config.h +++ b/absl/debugging/internal/stacktrace_config.h @@ -44,48 +44,46 @@ !(TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0) #define ABSL_STACKTRACE_INL_HEADER \ "absl/debugging/internal/stacktrace_generic-inl.inc" -#else -#define ABSL_STACKTRACE_INL_HEADER \ - "absl/debugging/internal/stacktrace_unimplemented-inl.inc" #endif #elif defined(__linux__) && !defined(__ANDROID__) -#if !defined(NO_FRAME_POINTER) -# if defined(__i386__) || defined(__x86_64__) -#define ABSL_STACKTRACE_INL_HEADER \ - "absl/debugging/internal/stacktrace_x86-inl.inc" -# elif defined(__ppc__) || defined(__PPC__) +#if defined(NO_FRAME_POINTER) && \ + (defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)) +// Note: The libunwind-based implementation is not available to open-source +// users. #define ABSL_STACKTRACE_INL_HEADER \ - "absl/debugging/internal/stacktrace_powerpc-inl.inc" -# elif defined(__aarch64__) -#define ABSL_STACKTRACE_INL_HEADER \ - "absl/debugging/internal/stacktrace_aarch64-inl.inc" -#elif defined(__arm__) && defined(__GLIBC__) + "absl/debugging/internal/stacktrace_libunwind-inl.inc" +#define STACKTRACE_USES_LIBUNWIND 1 +#elif defined(NO_FRAME_POINTER) && defined(__has_include) +#if __has_include() // Note: When using glibc this may require -funwind-tables to function properly. #define ABSL_STACKTRACE_INL_HEADER \ "absl/debugging/internal/stacktrace_generic-inl.inc" -# else +#endif +#elif defined(__i386__) || defined(__x86_64__) #define ABSL_STACKTRACE_INL_HEADER \ - "absl/debugging/internal/stacktrace_unimplemented-inl.inc" -# endif -#else // defined(NO_FRAME_POINTER) -# if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) + "absl/debugging/internal/stacktrace_x86-inl.inc" +#elif defined(__ppc__) || defined(__PPC__) #define ABSL_STACKTRACE_INL_HEADER \ - "absl/debugging/internal/stacktrace_generic-inl.inc" -# elif defined(__ppc__) || defined(__PPC__) + "absl/debugging/internal/stacktrace_powerpc-inl.inc" +#elif defined(__aarch64__) #define ABSL_STACKTRACE_INL_HEADER \ - "absl/debugging/internal/stacktrace_generic-inl.inc" -# else + "absl/debugging/internal/stacktrace_aarch64-inl.inc" +#elif defined(__has_include) +#if __has_include() +// Note: When using glibc this may require -funwind-tables to function properly. #define ABSL_STACKTRACE_INL_HEADER \ - "absl/debugging/internal/stacktrace_unimplemented-inl.inc" -# endif -#endif // NO_FRAME_POINTER + "absl/debugging/internal/stacktrace_generic-inl.inc" +#endif +#endif -#else +#endif + +// Fallback to the empty implementation. +#if !defined(ABSL_STACKTRACE_INL_HEADER) #define ABSL_STACKTRACE_INL_HEADER \ "absl/debugging/internal/stacktrace_unimplemented-inl.inc" - #endif #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_CONFIG_H_ diff --git a/absl/random/internal/gaussian_distribution_gentables.cc b/absl/random/internal/gaussian_distribution_gentables.cc index a2bf0394..a95333d5 100644 --- a/absl/random/internal/gaussian_distribution_gentables.cc +++ b/absl/random/internal/gaussian_distribution_gentables.cc @@ -111,12 +111,9 @@ void TableGenerator::Print(std::ostream* os) { "\n" "#include \"absl/random/gaussian_distribution.h\"\n" "\n" - // "namespace " and "absl" are broken apart so as not to conflict with - // script that adds the LTS inline namespace. - "namespace " - "absl {\n" - "namespace " - "random_internal {\n" + "namespace absl {\n" + "ABSL_NAMESPACE_BEGIN\n" + "namespace random_internal {\n" "\n" "const gaussian_distribution_base::Tables\n" " gaussian_distribution_base::zg_ = {\n"; @@ -125,10 +122,9 @@ void TableGenerator::Print(std::ostream* os) { FormatArrayContents(os, tables_.f); *os << "};\n" "\n" - "} // namespace " - "random_internal\n" - "} // namespace " - "absl\n" + "} // namespace random_internal\n" + "ABSL_NAMESPACE_END\n" + "} // namespace absl\n" "\n" "// clang-format on\n" "// END GENERATED CODE"; diff --git a/absl/strings/str_cat_benchmark.cc b/absl/strings/str_cat_benchmark.cc index ee4ad112..02c4dbe6 100644 --- a/absl/strings/str_cat_benchmark.cc +++ b/absl/strings/str_cat_benchmark.cc @@ -137,4 +137,51 @@ void BM_DoubleToString_By_SixDigits(benchmark::State& state) { } BENCHMARK(BM_DoubleToString_By_SixDigits); +template +void BM_StrAppendImpl(benchmark::State& state, size_t total_bytes, + Chunks... chunks) { + for (auto s : state) { + std::string result; + while (result.size() < total_bytes) { + absl::StrAppend(&result, chunks...); + benchmark::DoNotOptimize(result); + } + } +} + +void BM_StrAppend(benchmark::State& state) { + const int total_bytes = state.range(0); + const int chunks_at_a_time = state.range(1); + const absl::string_view kChunk = "0123456789"; + + switch (chunks_at_a_time) { + case 1: + return BM_StrAppendImpl(state, total_bytes, kChunk); + case 2: + return BM_StrAppendImpl(state, total_bytes, kChunk, kChunk); + case 4: + return BM_StrAppendImpl(state, total_bytes, kChunk, kChunk, kChunk, + kChunk); + case 8: + return BM_StrAppendImpl(state, total_bytes, kChunk, kChunk, kChunk, + kChunk, kChunk, kChunk, kChunk, kChunk); + default: + std::abort(); + } +} + +template +void StrAppendConfig(B* benchmark) { + for (int bytes : {10, 100, 1000, 10000}) { + for (int chunks : {1, 2, 4, 8}) { + // Only add the ones that divide properly. Otherwise we are over counting. + if (bytes % (10 * chunks) == 0) { + benchmark->Args({bytes, chunks}); + } + } + } +} + +BENCHMARK(BM_StrAppend)->Apply(StrAppendConfig); + } // namespace -- cgit v1.2.3