Successfully identified regression in *llvm* in CI configuration tcwg_bmk_llvm_tk1/llvm-release-arm-spec2k6-O3_LTO. So far, this commit has regressed CI configurations: - tcwg_bmk_llvm_tk1/llvm-release-arm-spec2k6-O3_LTO
Culprit: <cut> commit bb1e5399e4586239d6424f5eea5a9f06c52ebe9b Author: Vitaly Buka vitalybuka@google.com Date: Fri Apr 2 00:58:09 2021 -0700
[NFC][scudo] Inline some functions into ScudoPrimaryTest </cut>
Results regressed to (for first_bad == bb1e5399e4586239d6424f5eea5a9f06c52ebe9b) # reset_artifacts: -10 # build_abe binutils: -9 # build_abe stage1 -- --set gcc_override_configure=--with-mode=arm --set gcc_override_configure=--disable-libsanitizer: -8 # build_abe linux: -7 # build_abe glibc: -6 # build_abe stage2 -- --set gcc_override_configure=--with-mode=arm --set gcc_override_configure=--disable-libsanitizer: -5 # build_llvm true: -3 # true: 0 # benchmark -- -O3_LTO_marm artifacts/build-bb1e5399e4586239d6424f5eea5a9f06c52ebe9b/results_id: 1 # 462.libquantum,libquantum_base.default regressed by 105
from (for last_good == f343a730596b6b02039a91d71dc16c113d09cfe6) # reset_artifacts: -10 # build_abe binutils: -9 # build_abe stage1 -- --set gcc_override_configure=--with-mode=arm --set gcc_override_configure=--disable-libsanitizer: -8 # build_abe linux: -7 # build_abe glibc: -6 # build_abe stage2 -- --set gcc_override_configure=--with-mode=arm --set gcc_override_configure=--disable-libsanitizer: -5 # build_llvm true: -3 # true: 0 # benchmark -- -O3_LTO_marm artifacts/build-baseline/results_id: 1
Artifacts of last_good build: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release-... Results ID of last_good: tk1_32/tcwg_bmk_llvm_tk1/baseline-llvm-release-arm-spec2k6-O3_LTO/4201 Artifacts of first_bad build: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release-... Results ID of first_bad: tk1_32/tcwg_bmk_llvm_tk1/bisect-llvm-release-arm-spec2k6-O3_LTO/4234 Build top page/logs: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release-...
Configuration details:
Reproduce builds: <cut> mkdir investigate-llvm-bb1e5399e4586239d6424f5eea5a9f06c52ebe9b cd investigate-llvm-bb1e5399e4586239d6424f5eea5a9f06c52ebe9b
git clone https://git.linaro.org/toolchain/jenkins-scripts
mkdir -p artifacts/manifests curl -o artifacts/manifests/build-baseline.sh https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release-... --fail curl -o artifacts/manifests/build-parameters.sh https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release-... --fail curl -o artifacts/test.sh https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release-... --fail chmod +x artifacts/test.sh
# Reproduce the baseline build (build all pre-requisites) ./jenkins-scripts/tcwg_bmk-build.sh @@ artifacts/manifests/build-baseline.sh
# Save baseline build state (which is then restored in artifacts/test.sh) mkdir -p ./bisect rsync -a --del --delete-excluded --exclude /bisect/ --exclude /artifacts/ --exclude /llvm/ ./ ./bisect/baseline/
cd llvm
# Reproduce first_bad build git checkout --detach bb1e5399e4586239d6424f5eea5a9f06c52ebe9b ../artifacts/test.sh
# Reproduce last_good build git checkout --detach f343a730596b6b02039a91d71dc16c113d09cfe6 ../artifacts/test.sh
cd .. </cut>
History of pending regressions and results: https://git.linaro.org/toolchain/ci/base-artifacts.git/log/?h=linaro-local/c...
Artifacts: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release-... Build log: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release-...
Full commit (up to 1000 lines): <cut> commit bb1e5399e4586239d6424f5eea5a9f06c52ebe9b Author: Vitaly Buka vitalybuka@google.com Date: Fri Apr 2 00:58:09 2021 -0700
[NFC][scudo] Inline some functions into ScudoPrimaryTest --- .../lib/scudo/standalone/tests/primary_test.cpp | 173 +++++++++------------ 1 file changed, 71 insertions(+), 102 deletions(-)
diff --git a/compiler-rt/lib/scudo/standalone/tests/primary_test.cpp b/compiler-rt/lib/scudo/standalone/tests/primary_test.cpp index 07f3d6b77c17..2707985b5c72 100644 --- a/compiler-rt/lib/scudo/standalone/tests/primary_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/primary_test.cpp @@ -21,37 +21,6 @@ // 32-bit architectures. It's not something we want to encourage, but we still // should ensure the tests pass.
-template <typename Primary> static void testPrimary() { - const scudo::uptr NumberOfAllocations = 32U; - auto Deleter = [](Primary *P) { - P->unmapTestOnly(); - delete P; - }; - std::unique_ptr<Primary, decltype(Deleter)> Allocator(new Primary, Deleter); - Allocator->init(/*ReleaseToOsInterval=*/-1); - typename Primary::CacheT Cache; - Cache.init(nullptr, Allocator.get()); - for (scudo::uptr I = 0; I <= 16U; I++) { - const scudo::uptr Size = 1UL << I; - if (!Primary::canAllocate(Size)) - continue; - const scudo::uptr ClassId = Primary::SizeClassMap::getClassIdBySize(Size); - void *Pointers[NumberOfAllocations]; - for (scudo::uptr J = 0; J < NumberOfAllocations; J++) { - void *P = Cache.allocate(ClassId); - memset(P, 'B', Size); - Pointers[J] = P; - } - for (scudo::uptr J = 0; J < NumberOfAllocations; J++) - Cache.deallocate(ClassId, Pointers[J]); - } - Cache.destroy(nullptr); - Allocator->releaseToOS(); - scudo::ScopedString Str(1024); - Allocator->getStats(&Str); - Str.output(); -} - struct TestConfig1 { static const scudo::uptr PrimaryRegionSizeLog = 18U; static const scudo::s32 PrimaryMinReleaseToOsIntervalMs = INT32_MIN; @@ -84,13 +53,16 @@ struct Config : public BaseConfig { using SizeClassMap = SizeClassMapT; };
-template <typename BaseConfig, typename SizeClassMapT> struct MakeAllocator { - using Value = scudo::SizeClassAllocator64<Config<BaseConfig, SizeClassMapT>>; -}; - +template <typename BaseConfig, typename SizeClassMapT> +struct SizeClassAllocator + : public scudo::SizeClassAllocator64<Config<BaseConfig, SizeClassMapT>> {}; template <typename SizeClassMapT> -struct MakeAllocator<TestConfig1, SizeClassMapT> { - using Value = scudo::SizeClassAllocator32<Config<TestConfig1, SizeClassMapT>>; +struct SizeClassAllocator<TestConfig1, SizeClassMapT> + : public scudo::SizeClassAllocator32<Config<TestConfig1, SizeClassMapT>> {}; + +template <typename BaseConfig, typename SizeClassMapT> +struct TestAllocator : public SizeClassAllocator<BaseConfig, SizeClassMapT> { + ~TestAllocator() { this->unmapTestOnly(); } };
namespace testing { @@ -114,8 +86,31 @@ using ScudoPrimaryTestTypes = testing::Types< TYPED_TEST_CASE(ScudoPrimaryTest, ScudoPrimaryTestTypes);
TYPED_TEST(ScudoPrimaryTest, BasicPrimary) { - using SizeClassMap = scudo::DefaultSizeClassMap; - testPrimary<typename MakeAllocator<TypeParam, SizeClassMap>::Value>(); + using Primary = TestAllocator<TypeParam, scudo::DefaultSizeClassMap>; + std::unique_ptr<Primary> Allocator(new Primary); + Allocator->init(/*ReleaseToOsInterval=*/-1); + typename Primary::CacheT Cache; + Cache.init(nullptr, Allocator.get()); + const scudo::uptr NumberOfAllocations = 32U; + for (scudo::uptr I = 0; I <= 16U; I++) { + const scudo::uptr Size = 1UL << I; + if (!Primary::canAllocate(Size)) + continue; + const scudo::uptr ClassId = Primary::SizeClassMap::getClassIdBySize(Size); + void *Pointers[NumberOfAllocations]; + for (scudo::uptr J = 0; J < NumberOfAllocations; J++) { + void *P = Cache.allocate(ClassId); + memset(P, 'B', Size); + Pointers[J] = P; + } + for (scudo::uptr J = 0; J < NumberOfAllocations; J++) + Cache.deallocate(ClassId, Pointers[J]); + } + Cache.destroy(nullptr); + Allocator->releaseToOS(); + scudo::ScopedString Str(1024); + Allocator->getStats(&Str); + Str.output(); }
struct SmallRegionsConfig { @@ -166,12 +161,9 @@ TEST(ScudoPrimaryTest, Primary64OOM) { Allocator.unmapTestOnly(); }
-template <typename Primary> static void testIteratePrimary() { - auto Deleter = [](Primary *P) { - P->unmapTestOnly(); - delete P; - }; - std::unique_ptr<Primary, decltype(Deleter)> Allocator(new Primary, Deleter); +TYPED_TEST(ScudoPrimaryTest, PrimaryIterate) { + using Primary = TestAllocator<TypeParam, scudo::DefaultSizeClassMap>; + std::unique_ptr<Primary> Allocator(new Primary); Allocator->init(/*ReleaseToOsInterval=*/-1); typename Primary::CacheT Cache; Cache.init(nullptr, Allocator.get()); @@ -205,50 +197,40 @@ template <typename Primary> static void testIteratePrimary() { Str.output(); }
-TYPED_TEST(ScudoPrimaryTest, PrimaryIterate) { - using SizeClassMap = scudo::DefaultSizeClassMap; - testIteratePrimary<typename MakeAllocator<TypeParam, SizeClassMap>::Value>(); -} - -static std::mutex Mutex; -static std::condition_variable Cv; -static bool Ready; - -template <typename Primary> static void performAllocations(Primary *Allocator) { - static thread_local typename Primary::CacheT Cache; - Cache.init(nullptr, Allocator); - std::vector<std::pair<scudo::uptr, void *>> V; - { - std::unique_lockstd::mutex Lock(Mutex); - while (!Ready) - Cv.wait(Lock); - } - for (scudo::uptr I = 0; I < 256U; I++) { - const scudo::uptr Size = std::rand() % Primary::SizeClassMap::MaxSize / 4; - const scudo::uptr ClassId = Primary::SizeClassMap::getClassIdBySize(Size); - void *P = Cache.allocate(ClassId); - if (P) - V.push_back(std::make_pair(ClassId, P)); - } - while (!V.empty()) { - auto Pair = V.back(); - Cache.deallocate(Pair.first, Pair.second); - V.pop_back(); - } - Cache.destroy(nullptr); -} - -template <typename Primary> static void testPrimaryThreaded() { - Ready = false; - auto Deleter = [](Primary *P) { - P->unmapTestOnly(); - delete P; - }; - std::unique_ptr<Primary, decltype(Deleter)> Allocator(new Primary, Deleter); +TYPED_TEST(ScudoPrimaryTest, PrimaryThreaded) { + using Primary = TestAllocator<TypeParam, scudo::SvelteSizeClassMap>; + std::unique_ptr<Primary> Allocator(new Primary); Allocator->init(/*ReleaseToOsInterval=*/-1); + std::mutex Mutex; + std::condition_variable Cv; + bool Ready = false; std::thread Threads[32]; for (scudo::uptr I = 0; I < ARRAY_SIZE(Threads); I++) - Threads[I] = std::thread(performAllocations<Primary>, Allocator.get()); + Threads[I] = std::thread([&]() { + static thread_local typename Primary::CacheT Cache; + Cache.init(nullptr, Allocator.get()); + std::vector<std::pair<scudo::uptr, void *>> V; + { + std::unique_lockstd::mutex Lock(Mutex); + while (!Ready) + Cv.wait(Lock); + } + for (scudo::uptr I = 0; I < 256U; I++) { + const scudo::uptr Size = + std::rand() % Primary::SizeClassMap::MaxSize / 4; + const scudo::uptr ClassId = + Primary::SizeClassMap::getClassIdBySize(Size); + void *P = Cache.allocate(ClassId); + if (P) + V.push_back(std::make_pair(ClassId, P)); + } + while (!V.empty()) { + auto Pair = V.back(); + Cache.deallocate(Pair.first, Pair.second); + V.pop_back(); + } + Cache.destroy(nullptr); + }); { std::unique_lockstd::mutex Lock(Mutex); Ready = true; @@ -262,20 +244,12 @@ template <typename Primary> static void testPrimaryThreaded() { Str.output(); }
-TYPED_TEST(ScudoPrimaryTest, PrimaryThreaded) { - using SizeClassMap = scudo::SvelteSizeClassMap; - testPrimaryThreaded<typename MakeAllocator<TypeParam, SizeClassMap>::Value>(); -} - // Through a simple allocation that spans two pages, verify that releaseToOS // actually releases some bytes (at least one page worth). This is a regression // test for an error in how the release criteria were computed. -template <typename Primary> static void testReleaseToOS() { - auto Deleter = [](Primary *P) { - P->unmapTestOnly(); - delete P; - }; - std::unique_ptr<Primary, decltype(Deleter)> Allocator(new Primary, Deleter); +TYPED_TEST(ScudoPrimaryTest, ReleaseToOS) { + using Primary = TestAllocator<TypeParam, scudo::DefaultSizeClassMap>; + std::unique_ptr<Primary> Allocator(new Primary); Allocator->init(/*ReleaseToOsInterval=*/-1); typename Primary::CacheT Cache; Cache.init(nullptr, Allocator.get()); @@ -288,8 +262,3 @@ template <typename Primary> static void testReleaseToOS() { Cache.destroy(nullptr); EXPECT_GT(Allocator->releaseToOS(), 0U); } - -TYPED_TEST(ScudoPrimaryTest, ReleaseToOS) { - using SizeClassMap = scudo::DefaultSizeClassMap; - testReleaseToOS<typename MakeAllocator<TypeParam, SizeClassMap>::Value>(); -} </cut>
linaro-toolchain@lists.linaro.org