Roll chromium_revision 039110971b..52f78b1683 (560284:561464)

Change log: 039110971b..52f78b1683
Full diff: 039110971b..52f78b1683

Roll chromium third_party cc1af82934..008fb7071c
Change log: cc1af82934..008fb7071c

Changed dependencies:
* src/base: 8e89780685..40343e3fbc
* src/build: 66897e4d72..bd04ef7233
* src/ios: 02a22b3900..de97874e25
* src/testing: 671c6a4522..b4c21a01c2
* src/third_party/catapult: https://chromium.googlesource.com/catapult.git/+log/7ca7a59f02..1986f5a957
* src/third_party/depot_tools: 083eb25f9a..4e9b50ab86
* src/third_party/googletest/src: 08d5b1f33a..145d05750b
* src/third_party/libvpx/source/libvpx: d99abe9a9a..e27a331778
* src/tools: ff5c71196b..c923d1173c
DEPS diff: 039110971b..52f78b1683/DEPS

Clang version changed 332335:332838
Details: 039110971b..52f78b1683/tools/clang/scripts/update.py

TBR=buildbot@webrtc.org,marpan@webrtc.org,
BUG=None
CQ_INCLUDE_TRYBOTS=master.internal.tryserver.corp.webrtc:linux_internal
NO_AUTOIMPORT_DEPS_CHECK=true

Change-Id: I0aa2e7087bc0871ddafffb9eae424c6c76cc5b47
Reviewed-on: https://webrtc-review.googlesource.com/78762
Commit-Queue: Artem Titov <titovartem@webrtc.org>
Reviewed-by: Artem Titov <titovartem@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23385}
This commit is contained in:
Artem Titov 2018-05-24 14:17:37 +02:00 committed by Commit Bot
parent 172fd8536e
commit c34e381d61
31 changed files with 1251 additions and 72 deletions

22
DEPS
View File

@ -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': '039110971be048779a21200d0e98d22da689278a',
'chromium_revision': '52f78b1683a099f282aa06aea703d5e2c5ee59c0',
'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': '7ca7a59f02029679bb68bcf5a79be7db1bbc3c3d',
'catapult_revision': '1986f5a957da5e610ede36e73263e361b672e7a9',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling libFuzzer
# 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': 'cc1af829342dfa24713f9a914e5f0065e5bd02ec',
'chromium_third_party_revision': '008fb7071ceda627d6917b925776a7a411b660ec',
}
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' + '@' + '8e89780685c3230cd700003a0e0d5e45d08f1664',
Var('chromium_git') + '/chromium/src/base' + '@' + '40343e3fbc1e4835145f125adedcf15a2eb4542f',
'src/build':
Var('chromium_git') + '/chromium/src/build' + '@' + '66897e4d729dfaeeb84e058290ff0300ca813291',
Var('chromium_git') + '/chromium/src/build' + '@' + 'bd04ef72331a12d57056e95fd13d186739893d37',
'src/buildtools':
Var('chromium_git') + '/chromium/buildtools.git' + '@' + '94288c26d2ffe3aec9848c147839afee597acefd',
# 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' + '@' + '02a22b39007fed435fa0b1582ad77bf6255a89e5',
'url': Var('chromium_git') + '/chromium/src/ios' + '@' + 'de97874e2535ead371aa55350919daddd16ca1b2',
'condition': 'checkout_ios',
},
'src/testing':
Var('chromium_git') + '/chromium/src/testing' + '@' + '671c6a45223774a8131ea94e519163257e688018',
Var('chromium_git') + '/chromium/src/testing' + '@' + 'b4c21a01c2e3d2a21deb39a13b75927cc9cd52e3',
# 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' + '@' + '083eb25f9acbe034db94a1bd5c1659125b6ebf98',
Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '4e9b50ab86b9b9f8ebf0b9ba6bd4954217ebeff9',
'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' + '@' + '08d5b1f33af8c18785fb8ca02792b5fac81e248f',
Var('chromium_git') + '/external/github.com/google/googletest.git' + '@' + '145d05750b15324899473340c8dd5af50d125d33',
'src/third_party/icu': {
'url': Var('chromium_git') + '/chromium/deps/icu.git' + '@' + 'f61e46dbee9d539a32551493e3bcc1dea92f83ec',
},
@ -135,7 +135,7 @@ deps = {
'src/third_party/libsrtp':
Var('chromium_git') + '/chromium/deps/libsrtp.git' + '@' + 'fc2345089a6b3c5aca9ecd2e1941871a78a13e9c',
'src/third_party/libvpx/source/libvpx':
Var('chromium_git') + '/webm/libvpx.git' + '@' + 'd99abe9a9ad78b765386d0ee62559de184ba581e',
Var('chromium_git') + '/webm/libvpx.git' + '@' + 'e27a331778c4c99ec37262ea786a3b4cc2a491ac',
'src/third_party/libyuv':
Var('chromium_git') + '/libyuv/libyuv.git' + '@' + 'a9626b9daf62a9b260737e9c2de821ad087b19a1',
'src/third_party/lss': {
@ -175,7 +175,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' + '@' + 'ff5c71196bbccefb5eb237db626dc7d4f59b00ac',
Var('chromium_git') + '/chromium/src/tools' + '@' + 'c923d1173c6773018f6e68dfe64542e8c10780f2',
'src/tools/gyp':
Var('chromium_git') + '/external/gyp.git' + '@' + 'd61a9397e668fa9843c4aa7da9e79460fe590bfb',
'src/tools/swarming_client':

View File

@ -50,7 +50,13 @@ def _CheckThirdPartyReadmesUpdated(input_api, output_api):
not local_path.startswith('third_party' + input_api.os_path.sep +
'mojo' + input_api.os_path.sep) and
not local_path.startswith('third_party' + input_api.os_path.sep +
'boringssl' + input_api.os_path.sep)):
'boringssl' + input_api.os_path.sep) and
not local_path.startswith('third_party' + input_api.os_path.sep +
'closure_compiler' + input_api.os_path.sep +
'externs' + input_api.os_path.sep) and
not local_path.startswith('third_party' + input_api.os_path.sep +
'closure_compiler' + input_api.os_path.sep +
'interfaces' + input_api.os_path.sep)):
files.append(f)
if local_path.endswith("README.chromium"):
readmes.append(f)

View File

@ -13,7 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
cmake_minimum_required(VERSION 2.8.12)
# We require 3.0 for modern, target-based CMake. We require 3.1 for the use of
# CXX_STANDARD in our targets.
cmake_minimum_required(VERSION 3.1)
project(absl)
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMake)

View File

@ -4,7 +4,7 @@ URL: https://github.com/abseil/abseil-cpp
License: Apache 2.0
License File: LICENSE
Version: 0
Revision: 30de20488bb88dc22d23521c5c222ec6d924e289
Revision: 014f02a3eca93ef88163c3b408c86998ecf6572c
Security Critical: yes
Description:

View File

@ -102,6 +102,7 @@ cc_library(
cc_library(
name = "base_internal",
hdrs = [
"internal/hide_ptr.h",
"internal/identity.h",
"internal/inline_variable.h",
"internal/invoke.h",

View File

@ -131,6 +131,7 @@ source_set("base_internal") {
]
public_configs = [ "//third_party/abseil-cpp:absl_include_config" ]
public = [
"internal/hide_ptr.h",
"internal/identity.h",
"internal/inline_variable.h",
"internal/invoke.h",

View File

@ -36,6 +36,7 @@ list(APPEND BASE_INTERNAL_HEADERS
"internal/endian.h"
"internal/exception_testing.h"
"internal/exception_safety_testing.h"
"internal/hide_ptr.h"
"internal/identity.h"
"internal/invoke.h"
"internal/inline_variable.h"

View File

@ -32,7 +32,7 @@
/* Each function is empty and called (via a macro) only in debug mode.
The arguments are captured by dynamic tools at runtime. */
#if ABSL_DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0
#if ABSL_DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0 && !defined(__native_client__)
#if __has_feature(memory_sanitizer)
#include <sanitizer/msan_interface.h>

View File

@ -0,0 +1,49 @@
// 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.
#ifndef ABSL_BASE_INTERNAL_HIDE_PTR_H_
#define ABSL_BASE_INTERNAL_HIDE_PTR_H_
#include <cstdint>
namespace absl {
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;
}
// Hide a pointer from the leak checker. For internal use only.
// Differs from absl::IgnoreLeak(ptr) in that absl::IgnoreLeak(ptr) causes ptr
// and all objects reachable from ptr to be ignored by the leak checker.
template <class T>
inline uintptr_t HidePtr(T* ptr) {
return reinterpret_cast<uintptr_t>(ptr) ^ HideMask();
}
// Return a pointer that has been hidden from the leak checker.
// For internal use only.
template <class T>
inline T* UnhidePtr(uintptr_t hidden) {
return reinterpret_cast<T*>(hidden ^ HideMask());
}
} // namespace base_internal
} // namespace absl
#endif // ABSL_BASE_INTERNAL_HIDE_PTR_H_

View File

@ -158,6 +158,8 @@ static bool SetupAlternateStackOnce() {
#endif
#ifdef ABSL_HAVE_SIGACTION
// Sets up an alternate stack for signal handlers once.
// Returns the appropriate flag for sig_action.sa_flags
// if the system supports using an alternate stack.
@ -170,8 +172,6 @@ static int MaybeSetupAlternateStack() {
#endif
}
#ifdef ABSL_HAVE_SIGACTION
static void InstallOneFailureHandler(FailureSignalData* data,
void (*handler)(int, siginfo_t*, void*)) {
struct sigaction act;

View File

@ -40,7 +40,8 @@ namespace absl {
// -----------------------------------------------------------------------------
//
// Adopts ownership from a raw pointer and transfers it to the returned
// `std::unique_ptr`, whose type is deduced.
// `std::unique_ptr`, whose type is deduced. DO NOT specify the template type T
// when calling WrapUnique.
//
// Example:
// X* NewX(int, int);

View File

@ -1,3 +1,17 @@
# 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.
load(
"//absl:copts.bzl",
"ABSL_DEFAULT_COPTS",

View File

@ -13,10 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# -*- mode: python; -*-
# Libraries in this low-level package may not depend on libraries in packages
# that are not low level. For more information, including how to submit
# changes to this file, see http://www/eng/howto/build-monitors.html
load(
"//absl:copts.bzl",
@ -172,6 +168,20 @@ cc_test(
],
)
cc_test(
name = "string_view_benchmark",
srcs = ["string_view_benchmark.cc"],
copts = ABSL_TEST_COPTS,
tags = ["benchmark"],
visibility = ["//visibility:private"],
deps = [
":strings",
"//absl/base",
"//absl/base:core_headers",
"@com_github_google_benchmark//:benchmark",
],
)
cc_test(
name = "string_view_test",
size = "small",
@ -200,6 +210,19 @@ cc_test(
],
)
cc_test(
name = "str_replace_benchmark",
srcs = ["str_replace_benchmark.cc"],
copts = ABSL_TEST_COPTS,
tags = ["benchmark"],
visibility = ["//visibility:private"],
deps = [
":strings",
"//absl/base",
"@com_github_google_benchmark//:benchmark",
],
)
cc_test(
name = "str_replace_test",
size = "small",
@ -225,6 +248,19 @@ cc_test(
],
)
cc_test(
name = "str_split_benchmark",
srcs = ["str_split_benchmark.cc"],
copts = ABSL_TEST_COPTS,
tags = ["benchmark"],
visibility = ["//visibility:private"],
deps = [
":strings",
"//absl/base",
"@com_github_google_benchmark//:benchmark",
],
)
cc_test(
name = "ostringstream_test",
size = "small",
@ -267,6 +303,19 @@ cc_test(
],
)
cc_test(
name = "str_join_benchmark",
srcs = ["str_join_benchmark.cc"],
copts = ABSL_TEST_COPTS,
tags = ["benchmark"],
visibility = ["//visibility:private"],
deps = [
":strings",
"//absl/memory",
"@com_github_google_benchmark//:benchmark",
],
)
cc_test(
name = "str_cat_test",
size = "small",
@ -280,6 +329,18 @@ cc_test(
],
)
cc_test(
name = "str_cat_benchmark",
srcs = ["str_cat_benchmark.cc"],
copts = ABSL_TEST_COPTS,
tags = ["benchmark"],
visibility = ["//visibility:private"],
deps = [
":strings",
"@com_github_google_benchmark//:benchmark",
],
)
cc_test(
name = "numbers_test",
size = "small",

View File

@ -124,17 +124,11 @@ char* FastIntToBuffer(int_type i, char* buffer) {
}
}
} // namespace numbers_internal
// SimpleAtoi()
//
// Converts a std::string to an integer, using `safe_strto?()` functions for actual
// parsing, returning `true` if successful. The `safe_strto?()` functions apply
// strict checking; the std::string must be a base-10 integer, optionally followed or
// preceded by ASCII whitespace, with a value in the range of the corresponding
// integer type.
// Implementation of SimpleAtoi, generalized to support arbitrary base (used
// with base different from 10 elsewhere in Abseil implementation).
template <typename int_type>
ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view s, int_type* out) {
ABSL_MUST_USE_RESULT bool safe_strtoi_base(absl::string_view s, int_type* out,
int base) {
static_assert(sizeof(*out) == 4 || sizeof(*out) == 8,
"SimpleAtoi works only with 32-bit or 64-bit integers.");
static_assert(!std::is_floating_point<int_type>::value,
@ -146,27 +140,41 @@ ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view s, int_type* out) {
if (static_cast<int_type>(1) - 2 < 0) { // Signed
if (sizeof(*out) == 64 / 8) { // 64-bit
int64_t val;
parsed = numbers_internal::safe_strto64_base(s, &val, 10);
parsed = numbers_internal::safe_strto64_base(s, &val, base);
*out = static_cast<int_type>(val);
} else { // 32-bit
int32_t val;
parsed = numbers_internal::safe_strto32_base(s, &val, 10);
parsed = numbers_internal::safe_strto32_base(s, &val, base);
*out = static_cast<int_type>(val);
}
} else { // Unsigned
if (sizeof(*out) == 64 / 8) { // 64-bit
uint64_t val;
parsed = numbers_internal::safe_strtou64_base(s, &val, 10);
parsed = numbers_internal::safe_strtou64_base(s, &val, base);
*out = static_cast<int_type>(val);
} else { // 32-bit
uint32_t val;
parsed = numbers_internal::safe_strtou32_base(s, &val, 10);
parsed = numbers_internal::safe_strtou32_base(s, &val, base);
*out = static_cast<int_type>(val);
}
}
return parsed;
}
} // namespace numbers_internal
// SimpleAtoi()
//
// Converts a std::string to an integer, using `safe_strto?()` functions for actual
// parsing, returning `true` if successful. The `safe_strto?()` functions apply
// strict checking; the std::string must be a base-10 integer, optionally followed or
// preceded by ASCII whitespace, with a value in the range of the corresponding
// integer type.
template <typename int_type>
ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view s, int_type* out) {
return numbers_internal::safe_strtoi_base(s, out, 10);
}
} // namespace absl
#endif // ABSL_STRINGS_NUMBERS_H_

View File

@ -0,0 +1,142 @@
// 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/str_cat.h"
#include <cstdint>
#include <string>
#include "benchmark/benchmark.h"
#include "absl/strings/substitute.h"
namespace {
const char kStringOne[] = "Once Upon A Time, ";
const char kStringTwo[] = "There was a std::string benchmark";
// We want to include negative numbers in the benchmark, so this function
// is used to count 0, 1, -1, 2, -2, 3, -3, ...
inline int IncrementAlternatingSign(int i) {
return i > 0 ? -i : 1 - i;
}
void BM_Sum_By_StrCat(benchmark::State& state) {
int i = 0;
char foo[100];
for (auto _ : state) {
// NOLINTNEXTLINE(runtime/printf)
strcpy(foo, absl::StrCat(kStringOne, i, kStringTwo, i * 65536ULL).c_str());
int sum = 0;
for (char* f = &foo[0]; *f != 0; ++f) {
sum += *f;
}
benchmark::DoNotOptimize(sum);
i = IncrementAlternatingSign(i);
}
}
BENCHMARK(BM_Sum_By_StrCat);
void BM_StrCat_By_snprintf(benchmark::State& state) {
int i = 0;
char on_stack[1000];
for (auto _ : state) {
snprintf(on_stack, sizeof(on_stack), "%s %s:%d", kStringOne, kStringTwo, i);
i = IncrementAlternatingSign(i);
}
}
BENCHMARK(BM_StrCat_By_snprintf);
void BM_StrCat_By_Strings(benchmark::State& state) {
int i = 0;
for (auto _ : state) {
std::string result =
std::string(kStringOne) + " " + kStringTwo + ":" + absl::StrCat(i);
benchmark::DoNotOptimize(result);
i = IncrementAlternatingSign(i);
}
}
BENCHMARK(BM_StrCat_By_Strings);
void BM_StrCat_By_StringOpPlus(benchmark::State& state) {
int i = 0;
for (auto _ : state) {
std::string result = kStringOne;
result += " ";
result += kStringTwo;
result += ":";
result += absl::StrCat(i);
benchmark::DoNotOptimize(result);
i = IncrementAlternatingSign(i);
}
}
BENCHMARK(BM_StrCat_By_StringOpPlus);
void BM_StrCat_By_StrCat(benchmark::State& state) {
int i = 0;
for (auto _ : state) {
std::string result = absl::StrCat(kStringOne, " ", kStringTwo, ":", i);
benchmark::DoNotOptimize(result);
i = IncrementAlternatingSign(i);
}
}
BENCHMARK(BM_StrCat_By_StrCat);
void BM_HexCat_By_StrCat(benchmark::State& state) {
int i = 0;
for (auto _ : state) {
std::string result =
absl::StrCat(kStringOne, " ", absl::Hex(int64_t{i} + 0x10000000));
benchmark::DoNotOptimize(result);
i = IncrementAlternatingSign(i);
}
}
BENCHMARK(BM_HexCat_By_StrCat);
void BM_HexCat_By_Substitute(benchmark::State& state) {
int i = 0;
for (auto _ : state) {
std::string result = absl::Substitute(
"$0 $1", kStringOne, reinterpret_cast<void*>(int64_t{i} + 0x10000000));
benchmark::DoNotOptimize(result);
i = IncrementAlternatingSign(i);
}
}
BENCHMARK(BM_HexCat_By_Substitute);
void BM_FloatToString_By_StrCat(benchmark::State& state) {
int i = 0;
float foo = 0.0f;
for (auto _ : state) {
std::string result = absl::StrCat(foo += 1.001f, " != ", int64_t{i});
benchmark::DoNotOptimize(result);
i = IncrementAlternatingSign(i);
}
}
BENCHMARK(BM_FloatToString_By_StrCat);
void BM_DoubleToString_By_SixDigits(benchmark::State& state) {
int i = 0;
double foo = 0.0;
for (auto _ : state) {
std::string result =
absl::StrCat(absl::SixDigits(foo += 1.001), " != ", int64_t{i});
benchmark::DoNotOptimize(result);
i = IncrementAlternatingSign(i);
}
}
BENCHMARK(BM_DoubleToString_By_SixDigits);
} // namespace
BENCHMARK_MAIN();

View File

@ -0,0 +1,98 @@
//
// 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/str_join.h"
#include <string>
#include <vector>
#include <utility>
#include "benchmark/benchmark.h"
namespace {
void BM_Join2_Strings(benchmark::State& state) {
const int string_len = state.range(0);
const int num_strings = state.range(1);
const std::string s(string_len, 'x');
const std::vector<std::string> v(num_strings, s);
for (auto _ : state) {
std::string s = absl::StrJoin(v, "-");
benchmark::DoNotOptimize(s);
}
}
BENCHMARK(BM_Join2_Strings)
->ArgPair(1 << 0, 1 << 3)
->ArgPair(1 << 10, 1 << 3)
->ArgPair(1 << 13, 1 << 3)
->ArgPair(1 << 0, 1 << 10)
->ArgPair(1 << 10, 1 << 10)
->ArgPair(1 << 13, 1 << 10)
->ArgPair(1 << 0, 1 << 13)
->ArgPair(1 << 10, 1 << 13)
->ArgPair(1 << 13, 1 << 13);
void BM_Join2_Ints(benchmark::State& state) {
const int num_ints = state.range(0);
const std::vector<int> v(num_ints, 42);
for (auto _ : state) {
std::string s = absl::StrJoin(v, "-");
benchmark::DoNotOptimize(s);
}
}
BENCHMARK(BM_Join2_Ints)->Range(0, 1 << 13);
void BM_Join2_KeysAndValues(benchmark::State& state) {
const int string_len = state.range(0);
const int num_pairs = state.range(1);
const std::string s(string_len, 'x');
const std::vector<std::pair<std::string, int>> v(num_pairs, std::make_pair(s, 42));
for (auto _ : state) {
std::string s = absl::StrJoin(v, ",", absl::PairFormatter("="));
benchmark::DoNotOptimize(s);
}
}
BENCHMARK(BM_Join2_KeysAndValues)
->ArgPair(1 << 0, 1 << 3)
->ArgPair(1 << 10, 1 << 3)
->ArgPair(1 << 13, 1 << 3)
->ArgPair(1 << 0, 1 << 10)
->ArgPair(1 << 10, 1 << 10)
->ArgPair(1 << 13, 1 << 10)
->ArgPair(1 << 0, 1 << 13)
->ArgPair(1 << 10, 1 << 13)
->ArgPair(1 << 13, 1 << 13);
void BM_JoinStreamable(benchmark::State& state) {
const int string_len = state.range(0);
const int num_strings = state.range(1);
const std::vector<std::string> v(num_strings, std::string(string_len, 'x'));
for (auto _ : state) {
std::string s = absl::StrJoin(v, "", absl::StreamFormatter());
benchmark::DoNotOptimize(s);
}
}
BENCHMARK(BM_JoinStreamable)
->ArgPair(0, 0)
->ArgPair(16, 1)
->ArgPair(256, 1)
->ArgPair(16, 16)
->ArgPair(256, 16)
->ArgPair(16, 256)
->ArgPair(256, 256);
} // namespace
BENCHMARK_MAIN();

View File

@ -0,0 +1,124 @@
// 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/str_replace.h"
#include <cstring>
#include <string>
#include "benchmark/benchmark.h"
#include "absl/base/internal/raw_logging.h"
namespace {
std::string* big_string;
std::string* after_replacing_the;
std::string* after_replacing_many;
struct Replacement {
const char* needle;
const char* replacement;
} replacements[] = {
{"the", "box"}, //
{"brown", "quick"}, //
{"jumped", "liquored"}, //
{"dozen", "brown"}, //
{"lazy", "pack"}, //
{"liquor", "shakes"}, //
};
// Here, we set up a std::string for use in global-replace benchmarks.
// We started with a million blanks, and then deterministically insert
// 10,000 copies each of two pangrams. The result is a std::string that is
// 40% blank space and 60% these words. 'the' occurs 18,247 times and
// all the substitutions together occur 49,004 times.
//
// We then create "after_replacing_the" to be a std::string that is a result of
// replacing "the" with "box" in big_string.
//
// And then we create "after_replacing_many" to be a std::string that is result
// of preferring several substitutions.
void SetUpStrings() {
if (big_string == nullptr) {
size_t r = 0;
big_string = new std::string(1000 * 1000, ' ');
for (std::string phrase : {"the quick brown fox jumped over the lazy dogs",
"pack my box with the five dozen liquor jugs"}) {
for (int i = 0; i < 10 * 1000; ++i) {
r = r * 237 + 41; // not very random.
memcpy(&(*big_string)[r % (big_string->size() - phrase.size())],
phrase.data(), phrase.size());
}
}
// big_string->resize(50);
// OK, we've set up the std::string, now let's set up expectations - first by
// just replacing "the" with "box"
after_replacing_the = new std::string(*big_string);
for (size_t pos = 0;
(pos = after_replacing_the->find("the", pos)) != std::string::npos;) {
memcpy(&(*after_replacing_the)[pos], "box", 3);
}
// And then with all the replacements.
after_replacing_many = new std::string(*big_string);
for (size_t pos = 0;;) {
size_t next_pos = static_cast<size_t>(-1);
const char* needle_string = nullptr;
const char* replacement_string = nullptr;
for (const auto& r : replacements) {
auto needlepos = after_replacing_many->find(r.needle, pos);
if (needlepos != std::string::npos && needlepos < next_pos) {
next_pos = needlepos;
needle_string = r.needle;
replacement_string = r.replacement;
}
}
if (next_pos > after_replacing_many->size()) break;
after_replacing_many->replace(next_pos, strlen(needle_string),
replacement_string);
next_pos += strlen(replacement_string);
pos = next_pos;
}
}
}
void BM_StrReplaceAllOneReplacement(benchmark::State& state) {
SetUpStrings();
std::string src = *big_string;
for (auto _ : state) {
std::string dest = absl::StrReplaceAll(src, {{"the", "box"}});
ABSL_RAW_CHECK(dest == *after_replacing_the,
"not benchmarking intended behavior");
}
}
BENCHMARK(BM_StrReplaceAllOneReplacement);
void BM_StrReplaceAll(benchmark::State& state) {
SetUpStrings();
std::string src = *big_string;
for (auto _ : state) {
std::string dest = absl::StrReplaceAll(src, {{"the", "box"},
{"brown", "quick"},
{"jumped", "liquored"},
{"dozen", "brown"},
{"lazy", "pack"},
{"liquor", "shakes"}});
ABSL_RAW_CHECK(dest == *after_replacing_many,
"not benchmarking intended behavior");
}
}
BENCHMARK(BM_StrReplaceAll);
} // namespace
BENCHMARK_MAIN();

View File

@ -0,0 +1,158 @@
// 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/str_split.h"
#include <iterator>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "benchmark/benchmark.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/strings/string_view.h"
namespace {
std::string MakeTestString(int desired_length) {
static const int kAverageValueLen = 25;
std::string test(desired_length * kAverageValueLen, 'x');
for (int i = 1; i < test.size(); i += kAverageValueLen) {
test[i] = ';';
}
return test;
}
void BM_Split2StringPiece(benchmark::State& state) {
std::string test = MakeTestString(state.range(0));
for (auto _ : state) {
std::vector<absl::string_view> result = absl::StrSplit(test, ';');
benchmark::DoNotOptimize(result);
}
}
BENCHMARK_RANGE(BM_Split2StringPiece, 0, 1 << 20);
void BM_Split2StringPieceLifted(benchmark::State& state) {
std::string test = MakeTestString(state.range(0));
std::vector<absl::string_view> result;
for (auto _ : state) {
result = absl::StrSplit(test, ';');
}
benchmark::DoNotOptimize(result);
}
BENCHMARK_RANGE(BM_Split2StringPieceLifted, 0, 1 << 20);
void BM_Split2String(benchmark::State& state) {
std::string test = MakeTestString(state.range(0));
for (auto _ : state) {
std::vector<std::string> result = absl::StrSplit(test, ';');
benchmark::DoNotOptimize(result);
}
}
BENCHMARK_RANGE(BM_Split2String, 0, 1 << 20);
// This benchmark is for comparing Split2 to Split1 (SplitStringUsing). In
// particular, this benchmark uses SkipEmpty() to match SplitStringUsing's
// behavior.
void BM_Split2SplitStringUsing(benchmark::State& state) {
std::string test = MakeTestString(state.range(0));
for (auto _ : state) {
std::vector<std::string> result = absl::StrSplit(test, ';', absl::SkipEmpty());
benchmark::DoNotOptimize(result);
}
}
BENCHMARK_RANGE(BM_Split2SplitStringUsing, 0, 1 << 20);
void BM_SplitStringToUnorderedSet(benchmark::State& state) {
const int len = state.range(0);
std::string test(len, 'x');
for (int i = 1; i < len; i += 2) {
test[i] = ';';
}
for (auto _ : state) {
std::unordered_set<std::string> result =
absl::StrSplit(test, ':', absl::SkipEmpty());
benchmark::DoNotOptimize(result);
}
}
BENCHMARK_RANGE(BM_SplitStringToUnorderedSet, 0, 1 << 20);
void BM_SplitStringToUnorderedMap(benchmark::State& state) {
const int len = state.range(0);
std::string test(len, 'x');
for (int i = 1; i < len; i += 2) {
test[i] = ';';
}
for (auto _ : state) {
std::unordered_map<std::string, std::string> result =
absl::StrSplit(test, ':', absl::SkipEmpty());
benchmark::DoNotOptimize(result);
}
}
BENCHMARK_RANGE(BM_SplitStringToUnorderedMap, 0, 1 << 20);
void BM_SplitStringAllowEmpty(benchmark::State& state) {
const int len = state.range(0);
std::string test(len, 'x');
for (int i = 1; i < len; i += 2) {
test[i] = ';';
}
for (auto _ : state) {
std::vector<std::string> result = absl::StrSplit(test, ';');
benchmark::DoNotOptimize(result);
}
}
BENCHMARK_RANGE(BM_SplitStringAllowEmpty, 0, 1 << 20);
struct OneCharLiteral {
char operator()() const { return 'X'; }
};
struct OneCharStringLiteral {
const char* operator()() const { return "X"; }
};
template <typename DelimiterFactory>
void BM_SplitStringWithOneChar(benchmark::State& state) {
const auto delimiter = DelimiterFactory()();
std::vector<absl::string_view> pieces;
size_t v = 0;
for (auto _ : state) {
pieces = absl::StrSplit("The quick brown fox jumps over the lazy dog",
delimiter);
v += pieces.size();
}
ABSL_RAW_CHECK(v == state.iterations(), "");
}
BENCHMARK_TEMPLATE(BM_SplitStringWithOneChar, OneCharLiteral);
BENCHMARK_TEMPLATE(BM_SplitStringWithOneChar, OneCharStringLiteral);
template <typename DelimiterFactory>
void BM_SplitStringWithOneCharNoVector(benchmark::State& state) {
const auto delimiter = DelimiterFactory()();
size_t v = 0;
for (auto _ : state) {
auto splitter = absl::StrSplit(
"The quick brown fox jumps over the lazy dog", delimiter);
v += std::distance(splitter.begin(), splitter.end());
}
ABSL_RAW_CHECK(v == state.iterations(), "");
}
BENCHMARK_TEMPLATE(BM_SplitStringWithOneCharNoVector, OneCharLiteral);
BENCHMARK_TEMPLATE(BM_SplitStringWithOneCharNoVector, OneCharStringLiteral);
} // namespace
BENCHMARK_MAIN();

View File

@ -0,0 +1,331 @@
// 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/string_view.h"
#include <algorithm>
#include <cstdint>
#include <map>
#include <random>
#include <string>
#include <unordered_set>
#include <vector>
#include "benchmark/benchmark.h"
#include "absl/base/attributes.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/macros.h"
#include "absl/strings/str_cat.h"
namespace {
// Provide a forcibly out-of-line wrapper for operator== that can be used in
// benchmarks to measure the impact of inlining.
ABSL_ATTRIBUTE_NOINLINE
bool NonInlinedEq(absl::string_view a, absl::string_view b) { return a == b; }
// We use functions that cannot be inlined to perform the comparison loops so
// that inlining of the operator== can't optimize away *everything*.
ABSL_ATTRIBUTE_NOINLINE
void DoEqualityComparisons(benchmark::State& state, absl::string_view a,
absl::string_view b) {
for (auto _ : state) {
benchmark::DoNotOptimize(a == b);
}
}
void BM_EqualIdentical(benchmark::State& state) {
std::string x(state.range(0), 'a');
DoEqualityComparisons(state, x, x);
}
BENCHMARK(BM_EqualIdentical)->DenseRange(0, 3)->Range(4, 1 << 10);
void BM_EqualSame(benchmark::State& state) {
std::string x(state.range(0), 'a');
std::string y = x;
DoEqualityComparisons(state, x, y);
}
BENCHMARK(BM_EqualSame)
->DenseRange(0, 10)
->Arg(20)
->Arg(40)
->Arg(70)
->Arg(110)
->Range(160, 4096);
void BM_EqualDifferent(benchmark::State& state) {
const int len = state.range(0);
std::string x(len, 'a');
std::string y = x;
if (len > 0) {
y[len - 1] = 'b';
}
DoEqualityComparisons(state, x, y);
}
BENCHMARK(BM_EqualDifferent)->DenseRange(0, 3)->Range(4, 1 << 10);
// This benchmark is intended to check that important simplifications can be
// made with absl::string_view comparisons against constant strings. The idea is
// that if constant strings cause redundant components of the comparison, the
// compiler should detect and eliminate them. Here we use 8 different strings,
// each with the same size. Provided our comparison makes the implementation
// inline-able by the compiler, it should fold all of these away into a single
// size check once per loop iteration.
ABSL_ATTRIBUTE_NOINLINE
void DoConstantSizeInlinedEqualityComparisons(benchmark::State& state,
absl::string_view a) {
for (auto _ : state) {
benchmark::DoNotOptimize(a == "aaa");
benchmark::DoNotOptimize(a == "bbb");
benchmark::DoNotOptimize(a == "ccc");
benchmark::DoNotOptimize(a == "ddd");
benchmark::DoNotOptimize(a == "eee");
benchmark::DoNotOptimize(a == "fff");
benchmark::DoNotOptimize(a == "ggg");
benchmark::DoNotOptimize(a == "hhh");
}
}
void BM_EqualConstantSizeInlined(benchmark::State& state) {
std::string x(state.range(0), 'a');
DoConstantSizeInlinedEqualityComparisons(state, x);
}
// We only need to check for size of 3, and <> 3 as this benchmark only has to
// do with size differences.
BENCHMARK(BM_EqualConstantSizeInlined)->DenseRange(2, 4);
// This benchmark exists purely to give context to the above timings: this is
// what they would look like if the compiler is completely unable to simplify
// between two comparisons when they are comparing against constant strings.
ABSL_ATTRIBUTE_NOINLINE
void DoConstantSizeNonInlinedEqualityComparisons(benchmark::State& state,
absl::string_view a) {
for (auto _ : state) {
// Force these out-of-line to compare with the above function.
benchmark::DoNotOptimize(NonInlinedEq(a, "aaa"));
benchmark::DoNotOptimize(NonInlinedEq(a, "bbb"));
benchmark::DoNotOptimize(NonInlinedEq(a, "ccc"));
benchmark::DoNotOptimize(NonInlinedEq(a, "ddd"));
benchmark::DoNotOptimize(NonInlinedEq(a, "eee"));
benchmark::DoNotOptimize(NonInlinedEq(a, "fff"));
benchmark::DoNotOptimize(NonInlinedEq(a, "ggg"));
benchmark::DoNotOptimize(NonInlinedEq(a, "hhh"));
}
}
void BM_EqualConstantSizeNonInlined(benchmark::State& state) {
std::string x(state.range(0), 'a');
DoConstantSizeNonInlinedEqualityComparisons(state, x);
}
// We only need to check for size of 3, and <> 3 as this benchmark only has to
// do with size differences.
BENCHMARK(BM_EqualConstantSizeNonInlined)->DenseRange(2, 4);
void BM_CompareSame(benchmark::State& state) {
const int len = state.range(0);
std::string x;
for (int i = 0; i < len; i++) {
x += 'a';
}
std::string y = x;
absl::string_view a = x;
absl::string_view b = y;
for (auto _ : state) {
benchmark::DoNotOptimize(a.compare(b));
}
}
BENCHMARK(BM_CompareSame)->DenseRange(0, 3)->Range(4, 1 << 10);
void BM_find_string_view_len_one(benchmark::State& state) {
std::string haystack(state.range(0), '0');
absl::string_view s(haystack);
for (auto _ : state) {
s.find("x"); // not present; length 1
}
}
BENCHMARK(BM_find_string_view_len_one)->Range(1, 1 << 20);
void BM_find_string_view_len_two(benchmark::State& state) {
std::string haystack(state.range(0), '0');
absl::string_view s(haystack);
for (auto _ : state) {
s.find("xx"); // not present; length 2
}
}
BENCHMARK(BM_find_string_view_len_two)->Range(1, 1 << 20);
void BM_find_one_char(benchmark::State& state) {
std::string haystack(state.range(0), '0');
absl::string_view s(haystack);
for (auto _ : state) {
s.find('x'); // not present
}
}
BENCHMARK(BM_find_one_char)->Range(1, 1 << 20);
void BM_rfind_one_char(benchmark::State& state) {
std::string haystack(state.range(0), '0');
absl::string_view s(haystack);
for (auto _ : state) {
s.rfind('x'); // not present
}
}
BENCHMARK(BM_rfind_one_char)->Range(1, 1 << 20);
void BM_worst_case_find_first_of(benchmark::State& state, int haystack_len) {
const int needle_len = state.range(0);
std::string needle;
for (int i = 0; i < needle_len; ++i) {
needle += 'a' + i;
}
std::string haystack(haystack_len, '0'); // 1000 zeros.
absl::string_view s(haystack);
for (auto _ : state) {
s.find_first_of(needle);
}
}
void BM_find_first_of_short(benchmark::State& state) {
BM_worst_case_find_first_of(state, 10);
}
void BM_find_first_of_medium(benchmark::State& state) {
BM_worst_case_find_first_of(state, 100);
}
void BM_find_first_of_long(benchmark::State& state) {
BM_worst_case_find_first_of(state, 1000);
}
BENCHMARK(BM_find_first_of_short)->DenseRange(0, 4)->Arg(8)->Arg(16)->Arg(32);
BENCHMARK(BM_find_first_of_medium)->DenseRange(0, 4)->Arg(8)->Arg(16)->Arg(32);
BENCHMARK(BM_find_first_of_long)->DenseRange(0, 4)->Arg(8)->Arg(16)->Arg(32);
struct EasyMap : public std::map<absl::string_view, uint64_t> {
explicit EasyMap(size_t) {}
};
// This templated benchmark helper function is intended to stress operator== or
// operator< in a realistic test. It surely isn't entirely realistic, but it's
// a start. The test creates a map of type Map, a template arg, and populates
// it with table_size key/value pairs. Each key has WordsPerKey words. After
// creating the map, a number of lookups are done in random order. Some keys
// are used much more frequently than others in this phase of the test.
template <typename Map, int WordsPerKey>
void StringViewMapBenchmark(benchmark::State& state) {
const int table_size = state.range(0);
const double kFractionOfKeysThatAreHot = 0.2;
const int kNumLookupsOfHotKeys = 20;
const int kNumLookupsOfColdKeys = 1;
const char* words[] = {"the", "quick", "brown", "fox", "jumped",
"over", "the", "lazy", "dog", "and",
"found", "a", "large", "mushroom", "and",
"a", "couple", "crickets", "eating", "pie"};
// Create some keys that consist of words in random order.
std::random_device r;
std::seed_seq seed({r(), r(), r(), r(), r(), r(), r(), r()});
std::mt19937 rng(seed);
std::vector<std::string> keys(table_size);
std::vector<int> all_indices;
const int kBlockSize = 1 << 12;
std::unordered_set<std::string> t(kBlockSize);
std::uniform_int_distribution<int> uniform(0, ABSL_ARRAYSIZE(words) - 1);
for (int i = 0; i < table_size; i++) {
all_indices.push_back(i);
do {
keys[i].clear();
for (int j = 0; j < WordsPerKey; j++) {
absl::StrAppend(&keys[i], j > 0 ? " " : "", words[uniform(rng)]);
}
} while (!t.insert(keys[i]).second);
}
// Create a list of strings to lookup: a permutation of the array of
// keys we just created, with repeats. "Hot" keys get repeated more.
std::shuffle(all_indices.begin(), all_indices.end(), rng);
const int num_hot = table_size * kFractionOfKeysThatAreHot;
const int num_cold = table_size - num_hot;
std::vector<int> hot_indices(all_indices.begin(),
all_indices.begin() + num_hot);
std::vector<int> indices;
for (int i = 0; i < kNumLookupsOfColdKeys; i++) {
indices.insert(indices.end(), all_indices.begin(), all_indices.end());
}
for (int i = 0; i < kNumLookupsOfHotKeys - kNumLookupsOfColdKeys; i++) {
indices.insert(indices.end(), hot_indices.begin(), hot_indices.end());
}
std::shuffle(indices.begin(), indices.end(), rng);
ABSL_RAW_CHECK(
num_cold * kNumLookupsOfColdKeys + num_hot * kNumLookupsOfHotKeys ==
indices.size(),
"");
// After constructing the array we probe it with absl::string_views built from
// test_strings. This means operator== won't see equal pointers, so
// it'll have to check for equal lengths and equal characters.
std::vector<std::string> test_strings(indices.size());
for (int i = 0; i < indices.size(); i++) {
test_strings[i] = keys[indices[i]];
}
// Run the benchmark. It includes map construction but is mostly
// map lookups.
for (auto _ : state) {
Map h(table_size);
for (int i = 0; i < table_size; i++) {
h[keys[i]] = i * 2;
}
ABSL_RAW_CHECK(h.size() == table_size, "");
uint64_t sum = 0;
for (int i = 0; i < indices.size(); i++) {
sum += h[test_strings[i]];
}
benchmark::DoNotOptimize(sum);
}
}
void BM_StdMap_4(benchmark::State& state) {
StringViewMapBenchmark<EasyMap, 4>(state);
}
BENCHMARK(BM_StdMap_4)->Range(1 << 10, 1 << 16);
void BM_StdMap_8(benchmark::State& state) {
StringViewMapBenchmark<EasyMap, 8>(state);
}
BENCHMARK(BM_StdMap_8)->Range(1 << 10, 1 << 16);
void BM_CopyToStringNative(benchmark::State& state) {
std::string src(state.range(0), 'x');
absl::string_view sv(src);
std::string dst;
for (auto _ : state) {
dst.assign(sv.begin(), sv.end());
}
}
BENCHMARK(BM_CopyToStringNative)->Range(1 << 3, 1 << 12);
void BM_AppendToStringNative(benchmark::State& state) {
std::string src(state.range(0), 'x');
absl::string_view sv(src);
std::string dst;
for (auto _ : state) {
dst.clear();
dst.insert(dst.end(), sv.begin(), sv.end());
}
}
BENCHMARK(BM_AppendToStringNative)->Range(1 << 3, 1 << 12);
} // namespace
BENCHMARK_MAIN();

View File

@ -39,6 +39,7 @@ cc_library(
],
deps = [
"//absl/base",
"//absl/base:base_internal",
"//absl/base:core_headers",
"//absl/base:malloc_internal",
],
@ -119,6 +120,20 @@ cc_test(
],
)
cc_test(
name = "graphcycles_benchmark",
srcs = ["internal/graphcycles_benchmark.cc"],
copts = ABSL_TEST_COPTS,
tags = [
"benchmark",
],
deps = [
":graphcycles_internal",
"//absl/base",
"@com_github_google_benchmark//:benchmark",
],
)
cc_library(
name = "thread_pool",
testonly = 1,
@ -148,6 +163,20 @@ cc_test(
],
)
cc_test(
name = "mutex_benchmark",
srcs = ["mutex_benchmark.cc"],
copts = ABSL_TEST_COPTS,
tags = ["benchmark"],
visibility = ["//visibility:private"],
deps = [
":synchronization",
":thread_pool",
"//absl/base",
"@com_github_google_benchmark//:benchmark",
],
)
cc_test(
name = "notification_test",
size = "small",

View File

@ -30,6 +30,7 @@ source_set("graphcycles_internal") {
]
deps = [
"../base",
"../base:base_internal",
"../base:core_headers",
"../base:malloc_internal",
]

View File

@ -37,6 +37,7 @@
#include <algorithm>
#include <array>
#include "absl/base/internal/hide_ptr.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/internal/spinlock.h"
@ -276,18 +277,6 @@ inline uint32_t NodeVersion(GraphId id) {
return static_cast<uint32_t>(id.handle >> 32);
}
// We need to hide Mutexes (or other deadlock detection's pointers)
// from the leak detector. Xor with an arbitrary number with high bits set.
static const uintptr_t kHideMask = static_cast<uintptr_t>(0xF03A5F7BF03A5F7Bll);
static inline uintptr_t MaskPtr(void *ptr) {
return reinterpret_cast<uintptr_t>(ptr) ^ kHideMask;
}
static inline void* UnmaskPtr(uintptr_t word) {
return reinterpret_cast<void*>(word ^ kHideMask);
}
struct Node {
int32_t rank; // rank number assigned by Pearce-Kelly algorithm
uint32_t version; // Current version number
@ -309,7 +298,7 @@ class PointerMap {
}
int32_t Find(void* ptr) {
auto masked = MaskPtr(ptr);
auto masked = base_internal::HidePtr(ptr);
for (int32_t i = table_[Hash(ptr)]; i != -1;) {
Node* n = (*nodes_)[i];
if (n->masked_ptr == masked) return i;
@ -327,7 +316,7 @@ class PointerMap {
int32_t Remove(void* ptr) {
// Advance through linked list while keeping track of the
// predecessor slot that points to the current entry.
auto masked = MaskPtr(ptr);
auto masked = base_internal::HidePtr(ptr);
for (int32_t* slot = &table_[Hash(ptr)]; *slot != -1; ) {
int32_t index = *slot;
Node* n = (*nodes_)[index];
@ -395,7 +384,7 @@ bool GraphCycles::CheckInvariants() const {
NodeSet ranks; // Set of ranks seen so far.
for (uint32_t x = 0; x < r->nodes_.size(); x++) {
Node* nx = r->nodes_[x];
void* ptr = UnmaskPtr(nx->masked_ptr);
void* ptr = base_internal::UnhidePtr<void>(nx->masked_ptr);
if (ptr != nullptr && static_cast<uint32_t>(r->ptrmap_.Find(ptr)) != x) {
ABSL_RAW_LOG(FATAL, "Did not find live node in hash table %u %p", x, ptr);
}
@ -427,7 +416,7 @@ GraphId GraphCycles::GetId(void* ptr) {
n->version = 1; // Avoid 0 since it is used by InvalidGraphId()
n->visited = false;
n->rank = rep_->nodes_.size();
n->masked_ptr = MaskPtr(ptr);
n->masked_ptr = base_internal::HidePtr(ptr);
n->nstack = 0;
n->priority = 0;
rep_->nodes_.push_back(n);
@ -439,7 +428,7 @@ GraphId GraphCycles::GetId(void* ptr) {
int32_t r = rep_->free_nodes_.back();
rep_->free_nodes_.pop_back();
Node* n = rep_->nodes_[r];
n->masked_ptr = MaskPtr(ptr);
n->masked_ptr = base_internal::HidePtr(ptr);
n->nstack = 0;
n->priority = 0;
rep_->ptrmap_.Add(ptr, r);
@ -461,7 +450,7 @@ void GraphCycles::RemoveNode(void* ptr) {
}
x->in.clear();
x->out.clear();
x->masked_ptr = MaskPtr(nullptr);
x->masked_ptr = base_internal::HidePtr<void>(nullptr);
if (x->version == std::numeric_limits<uint32_t>::max()) {
// Cannot use x any more
} else {
@ -472,7 +461,8 @@ void GraphCycles::RemoveNode(void* ptr) {
void* GraphCycles::Ptr(GraphId id) {
Node* n = FindNode(rep_, id);
return n == nullptr ? nullptr : UnmaskPtr(n->masked_ptr);
return n == nullptr ? nullptr
: base_internal::UnhidePtr<void>(n->masked_ptr);
}
bool GraphCycles::HasNode(GraphId node) {

View File

@ -0,0 +1,46 @@
// 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/synchronization/internal/graphcycles.h"
#include <algorithm>
#include <cstdint>
#include <vector>
#include "benchmark/benchmark.h"
#include "absl/base/internal/raw_logging.h"
namespace {
void BM_StressTest(benchmark::State& state) {
const int num_nodes = state.range(0);
while (state.KeepRunningBatch(num_nodes)) {
absl::synchronization_internal::GraphCycles g;
std::vector<absl::synchronization_internal::GraphId> nodes(num_nodes);
for (int i = 0; i < num_nodes; i++) {
nodes[i] = g.GetId(reinterpret_cast<void*>(static_cast<uintptr_t>(i)));
}
for (int i = 0; i < num_nodes; i++) {
int end = std::min(num_nodes, i + 5);
for (int j = i + 1; j < end; j++) {
ABSL_RAW_CHECK(g.InsertEdge(nodes[i], nodes[j]), "");
}
}
}
}
BENCHMARK(BM_StressTest)->Range(2048, 1048576);
} // namespace
BENCHMARK_MAIN();

View File

@ -43,6 +43,7 @@
#include "absl/base/dynamic_annotations.h"
#include "absl/base/internal/atomic_hook.h"
#include "absl/base/internal/cycleclock.h"
#include "absl/base/internal/hide_ptr.h"
#include "absl/base/internal/low_level_alloc.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/internal/spinlock.h"
@ -272,13 +273,6 @@ static absl::base_internal::SpinLock synch_event_mu(
// Can't be too small, as it's used for deadlock detection information.
static const uint32_t kNSynchEvent = 1031;
// We need to hide Mutexes (or other deadlock detection's pointers)
// from the leak detector.
static const uintptr_t kHideMask = static_cast<uintptr_t>(0xF03A5F7BF03A5F7BLL);
static uintptr_t MaskMu(const void *mu) {
return reinterpret_cast<uintptr_t>(mu) ^ kHideMask;
}
static struct SynchEvent { // this is a trivial hash table for the events
// struct is freed when refcount reaches 0
int refcount GUARDED_BY(synch_event_mu);
@ -314,7 +308,8 @@ static SynchEvent *EnsureSynchEvent(std::atomic<intptr_t> *addr,
SynchEvent *e;
// first look for existing SynchEvent struct..
synch_event_mu.Lock();
for (e = synch_event[h]; e != nullptr && e->masked_addr != MaskMu(addr);
for (e = synch_event[h];
e != nullptr && e->masked_addr != base_internal::HidePtr(addr);
e = e->next) {
}
if (e == nullptr) { // no SynchEvent struct found; make one.
@ -325,7 +320,7 @@ static SynchEvent *EnsureSynchEvent(std::atomic<intptr_t> *addr,
e = reinterpret_cast<SynchEvent *>(
base_internal::LowLevelAlloc::Alloc(sizeof(*e) + l));
e->refcount = 2; // one for return value, one for linked list
e->masked_addr = MaskMu(addr);
e->masked_addr = base_internal::HidePtr(addr);
e->invariant = nullptr;
e->arg = nullptr;
e->log = false;
@ -367,7 +362,8 @@ static void ForgetSynchEvent(std::atomic<intptr_t> *addr, intptr_t bits,
SynchEvent *e;
synch_event_mu.Lock();
for (pe = &synch_event[h];
(e = *pe) != nullptr && e->masked_addr != MaskMu(addr); pe = &e->next) {
(e = *pe) != nullptr && e->masked_addr != base_internal::HidePtr(addr);
pe = &e->next) {
}
bool del = false;
if (e != nullptr) {
@ -388,7 +384,8 @@ static SynchEvent *GetSynchEvent(const void *addr) {
uint32_t h = reinterpret_cast<intptr_t>(addr) % kNSynchEvent;
SynchEvent *e;
synch_event_mu.Lock();
for (e = synch_event[h]; e != nullptr && e->masked_addr != MaskMu(addr);
for (e = synch_event[h];
e != nullptr && e->masked_addr != base_internal::HidePtr(addr);
e = e->next) {
}
if (e != nullptr) {

View File

@ -854,7 +854,7 @@ class SCOPED_LOCKABLE MutexLockMaybe {
MutexLockMaybe& operator=(MutexLockMaybe&&) = delete;
};
// ReleaseableMutexLock
// ReleasableMutexLock
//
// ReleasableMutexLock is like MutexLock, but permits `Release()` of its
// mutex before destruction. `Release()` may be called at most once.

View File

@ -0,0 +1,96 @@
// 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 <vector>
#include "benchmark/benchmark.h"
#include "absl/base/internal/sysinfo.h"
#include "absl/synchronization/blocking_counter.h"
#include "absl/synchronization/internal/thread_pool.h"
#include "absl/synchronization/mutex.h"
namespace {
// Measure the overhead of conditions on mutex release (when they must be
// evaluated). Mutex has (some) support for equivalence classes allowing
// Conditions with the same function/argument to potentially not be multiply
// evaluated.
//
// num_classes==0 is used for the special case of every waiter being distinct.
void BM_ConditionWaiters(benchmark::State& state) {
int num_classes = state.range(0);
int num_waiters = state.range(1);
struct Helper {
static void Waiter(absl::BlockingCounter* init, absl::Mutex* m, int* p) {
init->DecrementCount();
m->LockWhen(absl::Condition(
static_cast<bool (*)(int*)>([](int* v) { return *v == 0; }), p));
m->Unlock();
}
};
if (num_classes == 0) {
// No equivalence classes.
num_classes = num_waiters;
}
absl::BlockingCounter init(num_waiters);
absl::Mutex mu;
std::vector<int> equivalence_classes(num_classes, 1);
// Must be declared last to be destroyed first.
absl::synchronization_internal::ThreadPool pool(num_waiters);
for (int i = 0; i < num_waiters; i++) {
// Mutex considers Conditions with the same function and argument
// to be equivalent.
pool.Schedule([&, i] {
Helper::Waiter(&init, &mu, &equivalence_classes[i % num_classes]);
});
}
init.Wait();
for (auto _ : state) {
mu.Lock();
mu.Unlock(); // Each unlock requires Condition evaluation for our waiters.
}
mu.Lock();
for (int i = 0; i < num_classes; i++) {
equivalence_classes[i] = 0;
}
mu.Unlock();
}
#ifdef THREAD_SANITIZER
// ThreadSanitizer can't handle 8192 threads.
constexpr int kMaxConditionWaiters = 2048;
#else
constexpr int kMaxConditionWaiters = 8192;
#endif
BENCHMARK(BM_ConditionWaiters)->RangePair(0, 2, 1, kMaxConditionWaiters);
void BM_ContendedMutex(benchmark::State& state) {
static absl::Mutex* mu = new absl::Mutex;
for (auto _ : state) {
absl::MutexLock lock(mu);
}
}
BENCHMARK(BM_ContendedMutex)->Threads(1);
BENCHMARK(BM_ContendedMutex)->ThreadPerCpu();
} // namespace
BENCHMARK_MAIN();

View File

@ -4,3 +4,4 @@ stevenjb@chromium.org
per-file accessibility_private.js=file://ui/accessibility/OWNERS
per-file automation.js=file://ui/accessibility/OWNERS
per-file file_manager_private.js=file://ui/file_manager/OWNERS

View File

@ -803,6 +803,26 @@ chrome.developerPrivate.setShortcutHandlingSuspended = function(isSuspended, cal
*/
chrome.developerPrivate.updateExtensionCommand = function(update, callback) {};
/**
* Adds a new host permission to the extension. The extension will only have
* access to the host if it is within the requested permissions.
* @param {string} extensionId The id of the extension to modify.
* @param {string} host The host to add.
* @param {function():void=} callback
* @see https://developer.chrome.com/extensions/developerPrivate#method-addHostPermission
*/
chrome.developerPrivate.addHostPermission = function(extensionId, host, callback) {};
/**
* Removes a host permission from the extension. This should only be called with
* a host that the extension has access to.
* @param {string} extensionId The id of the extension to modify.
* @param {string} host The host to remove.
* @param {function():void=} callback
* @see https://developer.chrome.com/extensions/developerPrivate#method-removeHostPermission
*/
chrome.developerPrivate.removeHostPermission = function(extensionId, host, callback) {};
/**
* @param {string} id
* @param {boolean} enabled

View File

@ -31,6 +31,7 @@ var IconSet;
* croppedThumbnailUrl: (string|undefined),
* externalFileUrl: (string|undefined),
* alternateUrl: (string|undefined),
* shareUrl: (string|undefined),
* imageWidth: (number|undefined),
* imageHeight: (number|undefined),
* imageRotation: (number|undefined),

View File

@ -5,9 +5,9 @@ License: BSD
License File: source/libvpx/LICENSE
Security Critical: yes
Date: Tuesday May 15 2018
Date: Monday May 21 2018
Branch: master
Commit: d99abe9a9ad78b765386d0ee62559de184ba581e
Commit: e27a331778c4c99ec37262ea786a3b4cc2a491ac
Description:
Contains the sources used to compile libvpx binaries used by Google Chrome and

View File

@ -2,7 +2,7 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 7
#define VERSION_PATCH 0
#define VERSION_EXTRA "377-gd99abe9a9"
#define VERSION_EXTRA "387-ge27a33177"
#define VERSION_PACKED ((VERSION_MAJOR<<16)|(VERSION_MINOR<<8)|(VERSION_PATCH))
#define VERSION_STRING_NOSP "v1.7.0-377-gd99abe9a9"
#define VERSION_STRING " v1.7.0-377-gd99abe9a9"
#define VERSION_STRING_NOSP "v1.7.0-387-ge27a33177"
#define VERSION_STRING " v1.7.0-387-ge27a33177"