Commit 8ff13740 by Abseil Team Committed by Gennadiy Civil

Export of internal Abseil changes.

--
821196cfb2a3b943ffdc4c9e75daec92d7ffb28b by Abseil Team <absl-team@google.com>:

Performance improvements

PiperOrigin-RevId: 212668992

--
704858e2e767016bad27d53eec01d9d48e546b23 by Abseil Team <absl-team@google.com>:

Low-level Portability enchancements for Abseil Mutex on WebAssembly.

Emscripten Pthreads do not use signals, so remove use of pthread_sigmask or
other async-signal-safe related handling code.

PiperOrigin-RevId: 212527958

--
be3e38cb4d493b755132d20c8c2d1a51e45d5449 by Jon Cohen <cohenjon@google.com>:

Internal change.

PiperOrigin-RevId: 212523797
GitOrigin-RevId: 821196cfb2a3b943ffdc4c9e75daec92d7ffb28b
Change-Id: I5694e23e4e09364a15dd6fc4e2e3f15e38835687
parent 02451914
...@@ -401,16 +401,20 @@ bool LowLevelAlloc::DeleteArena(Arena *arena) { ...@@ -401,16 +401,20 @@ bool LowLevelAlloc::DeleteArena(Arena *arena) {
ABSL_RAW_CHECK(munmap_result != 0, ABSL_RAW_CHECK(munmap_result != 0,
"LowLevelAlloc::DeleteArena: VitualFree failed"); "LowLevelAlloc::DeleteArena: VitualFree failed");
#else #else
#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) == 0) { if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) == 0) {
munmap_result = munmap(region, size); munmap_result = munmap(region, size);
} else { } else {
munmap_result = base_internal::DirectMunmap(region, size); munmap_result = base_internal::DirectMunmap(region, size);
} }
#else
munmap_result = munmap(region, size);
#endif // ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
if (munmap_result != 0) { if (munmap_result != 0) {
ABSL_RAW_LOG(FATAL, "LowLevelAlloc::DeleteArena: munmap failed: %d", ABSL_RAW_LOG(FATAL, "LowLevelAlloc::DeleteArena: munmap failed: %d",
errno); errno);
} }
#endif #endif // _WIN32
} }
section.Leave(); section.Leave();
arena->~Arena(); arena->~Arena();
...@@ -545,6 +549,7 @@ static void *DoAllocWithArena(size_t request, LowLevelAlloc::Arena *arena) { ...@@ -545,6 +549,7 @@ static void *DoAllocWithArena(size_t request, LowLevelAlloc::Arena *arena) {
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
ABSL_RAW_CHECK(new_pages != nullptr, "VirtualAlloc failed"); ABSL_RAW_CHECK(new_pages != nullptr, "VirtualAlloc failed");
#else #else
#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) != 0) { if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) != 0) {
new_pages = base_internal::DirectMmap(nullptr, new_pages_size, new_pages = base_internal::DirectMmap(nullptr, new_pages_size,
PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
...@@ -552,10 +557,15 @@ static void *DoAllocWithArena(size_t request, LowLevelAlloc::Arena *arena) { ...@@ -552,10 +557,15 @@ static void *DoAllocWithArena(size_t request, LowLevelAlloc::Arena *arena) {
new_pages = mmap(nullptr, new_pages_size, PROT_WRITE | PROT_READ, new_pages = mmap(nullptr, new_pages_size, PROT_WRITE | PROT_READ,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
} }
#else
new_pages = mmap(nullptr, new_pages_size, PROT_WRITE | PROT_READ,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
#endif // ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
if (new_pages == MAP_FAILED) { if (new_pages == MAP_FAILED) {
ABSL_RAW_LOG(FATAL, "mmap error: %d", errno); ABSL_RAW_LOG(FATAL, "mmap error: %d", errno);
} }
#endif
#endif // _WIN32
arena->mu.Lock(); arena->mu.Lock();
s = reinterpret_cast<AllocList *>(new_pages); s = reinterpret_cast<AllocList *>(new_pages);
s->header.size = new_pages_size; s->header.size = new_pages_size;
......
...@@ -39,10 +39,13 @@ ...@@ -39,10 +39,13 @@
#define ABSL_LOW_LEVEL_ALLOC_MISSING 1 #define ABSL_LOW_LEVEL_ALLOC_MISSING 1
#endif #endif
// Using LowLevelAlloc with kAsyncSignalSafe isn't supported on Windows. // Using LowLevelAlloc with kAsyncSignalSafe isn't supported on Windows or
// asm.js / WebAssembly.
// See https://kripken.github.io/emscripten-site/docs/porting/pthreads.html
// for more information.
#ifdef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING #ifdef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
#error ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING cannot be directly set #error ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING cannot be directly set
#elif defined(_WIN32) #elif defined(_WIN32) || defined(__asmjs__) || defined(__wasm__)
#define ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING 1 #define ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING 1
#endif #endif
......
...@@ -68,6 +68,14 @@ void SetCurrentThreadIdentity( ...@@ -68,6 +68,14 @@ void SetCurrentThreadIdentity(
// NOTE: Not async-safe. But can be open-coded. // NOTE: Not async-safe. But can be open-coded.
absl::call_once(init_thread_identity_key_once, AllocateThreadIdentityKey, absl::call_once(init_thread_identity_key_once, AllocateThreadIdentityKey,
reclaimer); reclaimer);
#ifdef __EMSCRIPTEN__
// Emscripten PThread implementation does not support signals.
// See https://kripken.github.io/emscripten-site/docs/porting/pthreads.html
// for more information.
pthread_setspecific(thread_identity_pthread_key,
reinterpret_cast<void*>(identity));
#else
// We must mask signals around the call to setspecific as with current glibc, // We must mask signals around the call to setspecific as with current glibc,
// a concurrent getspecific (needed for GetCurrentThreadIdentityIfPresent()) // a concurrent getspecific (needed for GetCurrentThreadIdentityIfPresent())
// may zero our value. // may zero our value.
...@@ -81,6 +89,8 @@ void SetCurrentThreadIdentity( ...@@ -81,6 +89,8 @@ void SetCurrentThreadIdentity(
pthread_setspecific(thread_identity_pthread_key, pthread_setspecific(thread_identity_pthread_key,
reinterpret_cast<void*>(identity)); reinterpret_cast<void*>(identity));
pthread_sigmask(SIG_SETMASK, &curr_signals, nullptr); pthread_sigmask(SIG_SETMASK, &curr_signals, nullptr);
#endif // !__EMSCRIPTEN__
#elif ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS #elif ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS
// NOTE: Not async-safe. But can be open-coded. // NOTE: Not async-safe. But can be open-coded.
absl::call_once(init_thread_identity_key_once, AllocateThreadIdentityKey, absl::call_once(init_thread_identity_key_once, AllocateThreadIdentityKey,
......
...@@ -149,7 +149,6 @@ TEST(Make_UniqueTest, NotAmbiguousWithStdMakeUnique) { ...@@ -149,7 +149,6 @@ TEST(Make_UniqueTest, NotAmbiguousWithStdMakeUnique) {
} }
#if 0 #if 0
// TODO(billydonahue): Make a proper NC test.
// These tests shouldn't compile. // These tests shouldn't compile.
TEST(MakeUniqueTestNC, AcceptMoveOnlyLvalue) { TEST(MakeUniqueTestNC, AcceptMoveOnlyLvalue) {
auto m = MoveOnly(); auto m = MoveOnly();
......
...@@ -186,7 +186,7 @@ class StreamedWrapper { ...@@ -186,7 +186,7 @@ class StreamedWrapper {
private: private:
template <typename S> template <typename S>
friend ConvertResult<Conv::s> FormatConvertImpl(const StreamedWrapper<S>& v, friend ConvertResult<Conv::s> FormatConvertImpl(const StreamedWrapper<S>& v,
const ConversionSpec& conv, ConversionSpec conv,
FormatSinkImpl* out); FormatSinkImpl* out);
const T& v_; const T& v_;
}; };
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_ #define ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_
#include <limits.h> #include <limits.h>
#include <cstddef>
#include <cstring> #include <cstring>
#include <ostream> #include <ostream>
...@@ -307,7 +308,12 @@ class ConversionSpec { ...@@ -307,7 +308,12 @@ class ConversionSpec {
public: public:
Flags flags() const { return flags_; } Flags flags() const { return flags_; }
LengthMod length_mod() const { return length_mod_; } LengthMod length_mod() const { return length_mod_; }
ConversionChar conv() const { return conv_; } ConversionChar conv() const {
// Keep this field first in the struct . It generates better code when
// accessing it when ConversionSpec is passed by value in registers.
static_assert(offsetof(ConversionSpec, conv_) == 0, "");
return conv_;
}
// Returns the specified width. If width is unspecfied, it returns a negative // Returns the specified width. If width is unspecfied, it returns a negative
// value. // value.
...@@ -324,9 +330,9 @@ class ConversionSpec { ...@@ -324,9 +330,9 @@ class ConversionSpec {
void set_left(bool b) { flags_.left = b; } void set_left(bool b) { flags_.left = b; }
private: private:
ConversionChar conv_;
Flags flags_; Flags flags_;
LengthMod length_mod_; LengthMod length_mod_;
ConversionChar conv_;
int width_; int width_;
int precision_; int precision_;
}; };
......
...@@ -601,3 +601,39 @@ TEST_F(ParsedFormatTest, RegressionMixPositional) { ...@@ -601,3 +601,39 @@ TEST_F(ParsedFormatTest, RegressionMixPositional) {
} // namespace } // namespace
} // namespace absl } // namespace absl
// Some codegen thunks that we can use to easily dump the generated assembly for
// different StrFormat calls.
inline std::string CodegenAbslStrFormatInt(int i) {
return absl::StrFormat("%d", i);
}
inline std::string CodegenAbslStrFormatIntStringInt64(int i, const std::string& s,
int64_t i64) {
return absl::StrFormat("%d %s %d", i, s, i64);
}
inline void CodegenAbslStrAppendFormatInt(std::string* out, int i) {
absl::StrAppendFormat(out, "%d", i);
}
inline void CodegenAbslStrAppendFormatIntStringInt64(std::string* out, int i,
const std::string& s,
int64_t i64) {
absl::StrAppendFormat(out, "%d %s %d", i, s, i64);
}
auto absl_internal_str_format_force_codegen_funcs = std::make_tuple(
CodegenAbslStrFormatInt, CodegenAbslStrFormatIntStringInt64,
CodegenAbslStrAppendFormatInt, CodegenAbslStrAppendFormatIntStringInt64);
bool absl_internal_str_format_force_codegen_always_false;
// Force the compiler to generate the functions by making it look like we
// escape the function pointers.
// It can't statically know that
// absl_internal_str_format_force_codegen_always_false is not changed by someone
// else.
bool absl_internal_str_format_force_codegen =
absl_internal_str_format_force_codegen_always_false &&
printf("%p", &absl_internal_str_format_force_codegen_funcs) == 0;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment