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) {
ABSL_RAW_CHECK(munmap_result != 0,
"LowLevelAlloc::DeleteArena: VitualFree failed");
#else
#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) == 0) {
munmap_result = munmap(region, size);
} else {
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) {
ABSL_RAW_LOG(FATAL, "LowLevelAlloc::DeleteArena: munmap failed: %d",
errno);
}
#endif
#endif // _WIN32
}
section.Leave();
arena->~Arena();
......@@ -545,6 +549,7 @@ static void *DoAllocWithArena(size_t request, LowLevelAlloc::Arena *arena) {
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
ABSL_RAW_CHECK(new_pages != nullptr, "VirtualAlloc failed");
#else
#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING
if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) != 0) {
new_pages = base_internal::DirectMmap(nullptr, new_pages_size,
PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
......@@ -552,10 +557,15 @@ static void *DoAllocWithArena(size_t request, LowLevelAlloc::Arena *arena) {
new_pages = mmap(nullptr, new_pages_size, PROT_WRITE | PROT_READ,
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) {
ABSL_RAW_LOG(FATAL, "mmap error: %d", errno);
}
#endif
#endif // _WIN32
arena->mu.Lock();
s = reinterpret_cast<AllocList *>(new_pages);
s->header.size = new_pages_size;
......
......@@ -39,10 +39,13 @@
#define ABSL_LOW_LEVEL_ALLOC_MISSING 1
#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
#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
#endif
......
......@@ -68,6 +68,14 @@ void SetCurrentThreadIdentity(
// NOTE: Not async-safe. But can be open-coded.
absl::call_once(init_thread_identity_key_once, AllocateThreadIdentityKey,
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,
// a concurrent getspecific (needed for GetCurrentThreadIdentityIfPresent())
// may zero our value.
......@@ -81,6 +89,8 @@ void SetCurrentThreadIdentity(
pthread_setspecific(thread_identity_pthread_key,
reinterpret_cast<void*>(identity));
pthread_sigmask(SIG_SETMASK, &curr_signals, nullptr);
#endif // !__EMSCRIPTEN__
#elif ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS
// NOTE: Not async-safe. But can be open-coded.
absl::call_once(init_thread_identity_key_once, AllocateThreadIdentityKey,
......
......@@ -149,7 +149,6 @@ TEST(Make_UniqueTest, NotAmbiguousWithStdMakeUnique) {
}
#if 0
// TODO(billydonahue): Make a proper NC test.
// These tests shouldn't compile.
TEST(MakeUniqueTestNC, AcceptMoveOnlyLvalue) {
auto m = MoveOnly();
......
......@@ -186,7 +186,7 @@ class StreamedWrapper {
private:
template <typename S>
friend ConvertResult<Conv::s> FormatConvertImpl(const StreamedWrapper<S>& v,
const ConversionSpec& conv,
ConversionSpec conv,
FormatSinkImpl* out);
const T& v_;
};
......
......@@ -18,6 +18,7 @@
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_
#include <limits.h>
#include <cstddef>
#include <cstring>
#include <ostream>
......@@ -307,7 +308,12 @@ class ConversionSpec {
public:
Flags flags() const { return flags_; }
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
// value.
......@@ -324,9 +330,9 @@ class ConversionSpec {
void set_left(bool b) { flags_.left = b; }
private:
ConversionChar conv_;
Flags flags_;
LengthMod length_mod_;
ConversionChar conv_;
int width_;
int precision_;
};
......
......@@ -601,3 +601,39 @@ TEST_F(ParsedFormatTest, RegressionMixPositional) {
} // namespace
} // 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