[llvm-branch-commits] [compiler-rt] e9cc5fe - [scudo][standalone] Enable death tests on Fuchsia

2021-01-25 Thread Kostya Kortchinsky via llvm-branch-commits

Author: Kostya Kortchinsky
Date: 2021-01-25T09:19:10-08:00
New Revision: e9cc5fef64631a16f284e5dc09a2eaa8fd34a4a1

URL: 
https://github.com/llvm/llvm-project/commit/e9cc5fef64631a16f284e5dc09a2eaa8fd34a4a1
DIFF: 
https://github.com/llvm/llvm-project/commit/e9cc5fef64631a16f284e5dc09a2eaa8fd34a4a1.diff

LOG: [scudo][standalone] Enable death tests on Fuchsia

zxtest doesn't have `EXPECT_DEATH` and the Scudo unit-tests were
defining it as a no-op.

This enables death tests on Fuchsia by using `ASSERT_DEATH` instead.
I used a lambda to wrap the expressions as this appears to not be
working the same way as `EXPECT_DEATH`.

Additionnally, a death test using `alarm` was failing with the change,
as it's currently not implemented in Fuchsia, so move that test within
a `!SCUDO_FUCHSIA` block.

Differential Revision: https://reviews.llvm.org/D94362

Added: 


Modified: 
compiler-rt/lib/scudo/standalone/tests/scudo_unit_test.h
compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp

Removed: 




diff  --git a/compiler-rt/lib/scudo/standalone/tests/scudo_unit_test.h 
b/compiler-rt/lib/scudo/standalone/tests/scudo_unit_test.h
index 55d039ef77c3..22356c73a86b 100644
--- a/compiler-rt/lib/scudo/standalone/tests/scudo_unit_test.h
+++ b/compiler-rt/lib/scudo/standalone/tests/scudo_unit_test.h
@@ -16,10 +16,15 @@
 
 // If EXPECT_DEATH isn't defined, make it a no-op.
 #ifndef EXPECT_DEATH
+// If ASSERT_DEATH is defined, make EXPECT_DEATH a wrapper to it.
+#ifdef ASSERT_DEATH
+#define EXPECT_DEATH(X, Y) ASSERT_DEATH(([&] { X; }), "")
+#else
 #define EXPECT_DEATH(X, Y) 
\
   do { 
\
   } while (0)
-#endif
+#endif // ASSERT_DEATH
+#endif // EXPECT_DEATH
 
 // If EXPECT_STREQ isn't defined, define our own simple one.
 #ifndef EXPECT_STREQ

diff  --git a/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp 
b/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp
index 3ddc4ec81832..e01ac38cd806 100644
--- a/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp
+++ b/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp
@@ -303,8 +303,10 @@ TEST(ScudoWrappersCTest, MallocIterateBoundary) {
   }
 }
 
-// We expect heap operations within a disable/enable scope to deadlock.
+// Fuchsia doesn't have alarm, fork or malloc_info.
+#if !SCUDO_FUCHSIA
 TEST(ScudoWrappersCTest, MallocDisableDeadlock) {
+  // We expect heap operations within a disable/enable scope to deadlock.
   EXPECT_DEATH(
   {
 void *P = malloc(Size);
@@ -318,9 +320,6 @@ TEST(ScudoWrappersCTest, MallocDisableDeadlock) {
   "");
 }
 
-// Fuchsia doesn't have fork or malloc_info.
-#if !SCUDO_FUCHSIA
-
 TEST(ScudoWrappersCTest, MallocInfo) {
   // Use volatile so that the allocations don't get optimized away.
   void *volatile P1 = malloc(1234);



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [compiler-rt] 1dbf2c9 - [scudo][standalone] Allow the release of smaller sizes

2020-12-17 Thread Kostya Kortchinsky via llvm-branch-commits

Author: Kostya Kortchinsky
Date: 2020-12-17T10:01:57-08:00
New Revision: 1dbf2c96bce93e0a954806d9bdcafcb702a06672

URL: 
https://github.com/llvm/llvm-project/commit/1dbf2c96bce93e0a954806d9bdcafcb702a06672
DIFF: 
https://github.com/llvm/llvm-project/commit/1dbf2c96bce93e0a954806d9bdcafcb702a06672.diff

LOG: [scudo][standalone] Allow the release of smaller sizes

Initially we were avoiding the release of smaller size classes due to
the fact that it was an expensive operation, particularly on 32-bit
platforms. With a lot of batches, and given that there are a lot of
blocks per page, this was a lengthy operation with little results.

There has been some improvements since then to the 32-bit release,
and we still have some criterias preventing us from wasting time
(eg, 9x% free blocks in the class size, etc).

Allowing to release blocks < 128 bytes helps in situations where a lot
of small chunks would not have been reclaimed if not for a forced
reclaiming.

Additionally change some `CHECK` to `DCHECK` and rearrange a bit the
code.

I didn't experience any regressions in my benchmarks.

Differential Revision: https://reviews.llvm.org/D93141

Added: 


Modified: 
compiler-rt/lib/scudo/standalone/primary32.h
compiler-rt/lib/scudo/standalone/primary64.h
compiler-rt/lib/scudo/standalone/release.h

Removed: 




diff  --git a/compiler-rt/lib/scudo/standalone/primary32.h 
b/compiler-rt/lib/scudo/standalone/primary32.h
index 016a96bd2dfa..0db95d2e1f11 100644
--- a/compiler-rt/lib/scudo/standalone/primary32.h
+++ b/compiler-rt/lib/scudo/standalone/primary32.h
@@ -76,17 +76,12 @@ class SizeClassAllocator32 {
 if (UNLIKELY(!getRandom(reinterpret_cast(&Seed), sizeof(Seed
   Seed = static_cast(
   Time ^ (reinterpret_cast(SizeClassInfoArray) >> 6));
-const uptr PageSize = getPageSizeCached();
 for (uptr I = 0; I < NumClasses; I++) {
   SizeClassInfo *Sci = getSizeClassInfo(I);
   Sci->RandState = getRandomU32(&Seed);
   // Sci->MaxRegionIndex is already initialized to 0.
   Sci->MinRegionIndex = NumRegions;
-  // See comment in the 64-bit primary about releasing smaller size 
classes.
-  Sci->CanRelease = (I != SizeClassMap::BatchClassId) &&
-(getSizeByClassId(I) >= (PageSize / 32));
-  if (Sci->CanRelease)
-Sci->ReleaseInfo.LastReleaseAtNs = Time;
+  Sci->ReleaseInfo.LastReleaseAtNs = Time;
 }
 setOption(Option::ReleaseInterval, static_cast(ReleaseToOsInterval));
   }
@@ -137,7 +132,7 @@ class SizeClassAllocator32 {
 ScopedLock L(Sci->Mutex);
 Sci->FreeList.push_front(B);
 Sci->Stats.PushedBlocks += B->getCount();
-if (Sci->CanRelease)
+if (ClassId != SizeClassMap::BatchClassId)
   releaseToOSMaybe(Sci, ClassId);
   }
 
@@ -217,6 +212,8 @@ class SizeClassAllocator32 {
   uptr releaseToOS() {
 uptr TotalReleasedBytes = 0;
 for (uptr I = 0; I < NumClasses; I++) {
+  if (I == SizeClassMap::BatchClassId)
+continue;
   SizeClassInfo *Sci = getSizeClassInfo(I);
   ScopedLock L(Sci->Mutex);
   TotalReleasedBytes += releaseToOSMaybe(Sci, I, /*Force=*/true);
@@ -262,7 +259,6 @@ class SizeClassAllocator32 {
 uptr CurrentRegion;
 uptr CurrentRegionAllocated;
 SizeClassStats Stats;
-bool CanRelease;
 u32 RandState;
 uptr AllocatedUser;
 // Lowest & highest region index allocated for this size class, to avoid

diff  --git a/compiler-rt/lib/scudo/standalone/primary64.h 
b/compiler-rt/lib/scudo/standalone/primary64.h
index f6c4d8cf8bb0..f9854cbfd4d6 100644
--- a/compiler-rt/lib/scudo/standalone/primary64.h
+++ b/compiler-rt/lib/scudo/standalone/primary64.h
@@ -80,17 +80,7 @@ class SizeClassAllocator64 {
   Region->RegionBeg =
   getRegionBaseByClassId(I) + (getRandomModN(&Seed, 16) + 1) * 
PageSize;
   Region->RandState = getRandomU32(&Seed);
-  // Releasing smaller size classes doesn't necessarily yield to a
-  // meaningful RSS impact: there are more blocks per page, they are
-  // randomized around, and thus pages are less likely to be entirely 
empty.
-  // On top of this, attempting to release those require more iterations 
and
-  // memory accesses which ends up being fairly costly. The current lower
-  // limit is mostly arbitrary and based on empirical observations.
-  // TODO(kostyak): make the lower limit a runtime option
-  Region->CanRelease = (I != SizeClassMap::BatchClassId) &&
-   (getSizeByClassId(I) >= (PageSize / 32));
-  if (Region->CanRelease)
-Region->ReleaseInfo.LastReleaseAtNs = Time;
+  Region->ReleaseInfo.LastReleaseAtNs = Time;
 }
 setOption(Option::ReleaseInterval, static_cast(ReleaseToOsInterval));
 
@@ -129,7 +119,7 @@ class SizeClassAllocator64 {
 ScopedLock L(Region->Mutex);
 Region->FreeList.push_front(B);
 Region->Stat

[llvm-branch-commits] [compiler-rt] c904c32 - [GWP-ASan] Fix flaky test on Fuchsia

2020-12-02 Thread Kostya Kortchinsky via llvm-branch-commits

Author: Kostya Kortchinsky
Date: 2020-12-02T09:00:51-08:00
New Revision: c904c32b9c9243b11ffc18e46b7350f000e9c088

URL: 
https://github.com/llvm/llvm-project/commit/c904c32b9c9243b11ffc18e46b7350f000e9c088
DIFF: 
https://github.com/llvm/llvm-project/commit/c904c32b9c9243b11ffc18e46b7350f000e9c088.diff

LOG: [GWP-ASan] Fix flaky test on Fuchsia

The LateInit test might be reusing some already initialized thread
specific data if run within the main thread. This means that there
is a chance that the current value will not be enough for the 100
iterations, hence the test flaking.

Fix this by making the test run in its own thread.

Differential Revision: https://reviews.llvm.org/D92415

Added: 


Modified: 
compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp

Removed: 




diff  --git a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp 
b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp
index a895032c7c8f..13888cbbe3c3 100644
--- a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp
+++ b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp
@@ -148,6 +148,7 @@ void GuardedPoolAllocator::uninitTestOnly() {
 State.PageSize));
 FreeSlots = nullptr;
   }
+  *getThreadLocals() = ThreadLocalPackedVariables();
 }
 
 void *GuardedPoolAllocator::allocate(size_t Size) {



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [compiler-rt] 0a09c1c - [scudo][standalone] Add missing va_end() in ScopedString::append

2020-12-02 Thread Kostya Kortchinsky via llvm-branch-commits

Author: Kostya Kortchinsky
Date: 2020-12-02T16:10:50-08:00
New Revision: 0a09c1cc9dcbec8126344123e9481bed6524e5ec

URL: 
https://github.com/llvm/llvm-project/commit/0a09c1cc9dcbec8126344123e9481bed6524e5ec
DIFF: 
https://github.com/llvm/llvm-project/commit/0a09c1cc9dcbec8126344123e9481bed6524e5ec.diff

LOG:  [scudo][standalone] Add missing va_end() in ScopedString::append

In ScopedString::append va_list ArgsCopy is created but never cleanuped
which can lead to undefined behaviour, like stack corruption.

Reviewed By: cryptoad

Differential Revision: https://reviews.llvm.org/D92383

Added: 


Modified: 
compiler-rt/lib/scudo/standalone/string_utils.cpp

Removed: 




diff  --git a/compiler-rt/lib/scudo/standalone/string_utils.cpp 
b/compiler-rt/lib/scudo/standalone/string_utils.cpp
index 7578123da361..f304491019b2 100644
--- a/compiler-rt/lib/scudo/standalone/string_utils.cpp
+++ b/compiler-rt/lib/scudo/standalone/string_utils.cpp
@@ -222,6 +222,7 @@ void ScopedString::append(const char *Format, va_list Args) 
{
   static_cast(formatString(C, sizeof(C), Format, Args)) + 1;
   String.resize(Length + AdditionalLength);
   formatString(String.data() + Length, AdditionalLength, Format, ArgsCopy);
+  va_end(ArgsCopy);
   Length = strlen(String.data());
   CHECK_LT(Length, String.size());
 }



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [compiler-rt] 3f70987 - [scudo][standalone] Small changes to the fastpath

2020-12-10 Thread Kostya Kortchinsky via llvm-branch-commits

Author: Kostya Kortchinsky
Date: 2020-12-10T10:25:59-08:00
New Revision: 3f70987b352c44329db8f339d4c537a20cc98329

URL: 
https://github.com/llvm/llvm-project/commit/3f70987b352c44329db8f339d4c537a20cc98329
DIFF: 
https://github.com/llvm/llvm-project/commit/3f70987b352c44329db8f339d4c537a20cc98329.diff

LOG: [scudo][standalone] Small changes to the fastpath

There are a few things that I wanted to reorganize for a while:
- the loop that incrementally goes through classes on failure looked
  horrible in assembly, mostly because of `LIKELY`/`UNLIKELY` within
  the loop. So remove those, we are already in an unlikely scenario
- hooks are not used by default on Android/Fuchsia/etc so mark the
  tests for the existence of the weak functions as unlikely
- mark of couple of conditions as likely/unlikely
- in `reallocate`, the old size was computed again while we already
  have it in a variable. So just use the one we have.
- remove the bitwise AND trick and use a logical AND, that has one
  less test by using a purposeful underflow when `Size` is 0 (I
  actually looked at the assembly of the previous code to steal that
  trick)
- move the read of the options closer to where they are used, mark them
  as `const`

Overall this makes things a tiny bit faster, but cleaner.

Differential Revision: https://reviews.llvm.org/D92689

Added: 


Modified: 
compiler-rt/lib/scudo/standalone/combined.h

Removed: 




diff  --git a/compiler-rt/lib/scudo/standalone/combined.h 
b/compiler-rt/lib/scudo/standalone/combined.h
index 95988443d5b3..e214b0158bf4 100644
--- a/compiler-rt/lib/scudo/standalone/combined.h
+++ b/compiler-rt/lib/scudo/standalone/combined.h
@@ -277,7 +277,6 @@ class Allocator {
   uptr Alignment = MinAlignment,
   bool ZeroContents = false) {
 initThreadMaybe();
-Options Options = Primary.Options.load();
 
 #ifdef GWP_ASAN_HOOKS
 if (UNLIKELY(GuardedAlloc.shouldSample())) {
@@ -286,6 +285,7 @@ class Allocator {
 }
 #endif // GWP_ASAN_HOOKS
 
+const Options Options = Primary.Options.load();
 const FillContentsMode FillContents = ZeroContents ? ZeroFill
   : TSDRegistry.getDisableMemInit()
   ? NoFill
@@ -296,7 +296,7 @@ class Allocator {
 return nullptr;
   reportAlignmentTooBig(Alignment, MaxAlignment);
 }
-if (UNLIKELY(Alignment < MinAlignment))
+if (Alignment < MinAlignment)
   Alignment = MinAlignment;
 
 // If the requested size happens to be 0 (more common than you might 
think),
@@ -331,12 +331,9 @@ class Allocator {
   // larger class until it fits. If it fails to fit in the largest class,
   // fallback to the Secondary.
   if (UNLIKELY(!Block)) {
-while (ClassId < SizeClassMap::LargestClassId) {
+while (ClassId < SizeClassMap::LargestClassId && !Block)
   Block = TSD->Cache.allocate(++ClassId);
-  if (LIKELY(Block))
-break;
-}
-if (UNLIKELY(!Block))
+if (!Block)
   ClassId = 0;
   }
   if (UnlockRequired)
@@ -467,7 +464,7 @@ class Allocator {
 Chunk::SizeOrUnusedBytesMask;
 Chunk::storeHeader(Cookie, Ptr, &Header);
 
-if (&__scudo_allocate_hook)
+if (UNLIKELY(&__scudo_allocate_hook))
   __scudo_allocate_hook(TaggedPtr, Size);
 
 return TaggedPtr;
@@ -482,7 +479,6 @@ class Allocator {
 // the TLS destructors, ending up in initialized thread specific data never
 // being destroyed properly. Any other heap operation will do a full init.
 initThreadMaybe(/*MinimalInit=*/true);
-Options Options = Primary.Options.load();
 
 #ifdef GWP_ASAN_HOOKS
 if (UNLIKELY(GuardedAlloc.pointerIsMine(Ptr))) {
@@ -491,7 +487,7 @@ class Allocator {
 }
 #endif // GWP_ASAN_HOOKS
 
-if (&__scudo_deallocate_hook)
+if (UNLIKELY(&__scudo_deallocate_hook))
   __scudo_deallocate_hook(Ptr);
 
 if (UNLIKELY(!Ptr))
@@ -506,11 +502,13 @@ class Allocator {
 
 if (UNLIKELY(Header.State != Chunk::State::Allocated))
   reportInvalidChunkState(AllocatorAction::Deallocating, Ptr);
+
+const Options Options = Primary.Options.load();
 if (Options.get(OptionBit::DeallocTypeMismatch)) {
-  if (Header.OriginOrWasZeroed != Origin) {
+  if (UNLIKELY(Header.OriginOrWasZeroed != Origin)) {
 // With the exception of memalign'd chunks, that can be still be 
free'd.
-if (UNLIKELY(Header.OriginOrWasZeroed != Chunk::Origin::Memalign ||
- Origin != Chunk::Origin::Malloc))
+if (Header.OriginOrWasZeroed != Chunk::Origin::Memalign ||
+Origin != Chunk::Origin::Malloc)
   reportDeallocTypeMismatch(AllocatorAction::Deallocating, Ptr,
 Header.OriginOrWasZeroed, Origin);
   }
@@ -527,8 +525,8 @@ class Al

[llvm-branch-commits] [compiler-rt] 11d203a - Add vendor identity check for Hygon Dhyana processor in Scudo

2020-05-11 Thread Kostya Kortchinsky via llvm-branch-commits

Author: Kostya Kortchinsky
Date: 2020-05-11T09:09:18-07:00
New Revision: 11d203a2bbb17f123bb4370277bf36250efd07ef

URL: 
https://github.com/llvm/llvm-project/commit/11d203a2bbb17f123bb4370277bf36250efd07ef
DIFF: 
https://github.com/llvm/llvm-project/commit/11d203a2bbb17f123bb4370277bf36250efd07ef.diff

LOG: Add vendor identity check for Hygon Dhyana processor in Scudo

Summary:
The Hygon Dhyana processor supports hardware CRC32.

Related link:
https://reviews.llvm.org/D78874

Result of "make check":
Testing Time: 1364.04s
  Unsupported Tests:   317
  Expected Passes  : 36802
  Expected Failures:   161
[100%] Built target check-llvm
[100%] Built target check

Reviewers: cryptoad

Reviewed By: cryptoad

Subscribers: craig.topper, cryptoad, cfe-commits, #sanitizers, llvm-commits

Tags: #clang, #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D62368

Added: 


Modified: 
compiler-rt/lib/scudo/scudo_utils.cpp
compiler-rt/lib/scudo/standalone/checksum.cpp

Removed: 




diff  --git a/compiler-rt/lib/scudo/scudo_utils.cpp 
b/compiler-rt/lib/scudo/scudo_utils.cpp
index 5e76a4a30f10..f31d68058acb 100644
--- a/compiler-rt/lib/scudo/scudo_utils.cpp
+++ b/compiler-rt/lib/scudo/scudo_utils.cpp
@@ -62,6 +62,14 @@ FORMAT(1, 2) void NORETURN dieWithMessage(const char 
*Format, ...) {
 # ifndef bit_SSE4_2
 #  define bit_SSE4_2 bit_SSE42  // clang and gcc have 
diff erent defines.
 # endif
+
+#ifndef signature_HYGON_ebx // They are not defined in gcc.
+// HYGON: "HygonGenuine".
+#define signature_HYGON_ebx 0x6f677948
+#define signature_HYGON_edx 0x6e65476e
+#define signature_HYGON_ecx 0x656e6975
+#endif
+
 bool hasHardwareCRC32() {
   u32 Eax, Ebx, Ecx, Edx;
   __get_cpuid(0, &Eax, &Ebx, &Ecx, &Edx);
@@ -71,7 +79,10 @@ bool hasHardwareCRC32() {
   const bool IsAMD = (Ebx == signature_AMD_ebx) &&
  (Edx == signature_AMD_edx) &&
  (Ecx == signature_AMD_ecx);
-  if (!IsIntel && !IsAMD)
+  const bool IsHygon = (Ebx == signature_HYGON_ebx) &&
+   (Edx == signature_HYGON_edx) &&
+   (Ecx == signature_HYGON_ecx);
+  if (!IsIntel && !IsAMD && !IsHygon)
 return false;
   __get_cpuid(1, &Eax, &Ebx, &Ecx, &Edx);
   return !!(Ecx & bit_SSE4_2);

diff  --git a/compiler-rt/lib/scudo/standalone/checksum.cpp 
b/compiler-rt/lib/scudo/standalone/checksum.cpp
index 5de049a0931b..05d4ba54bfc8 100644
--- a/compiler-rt/lib/scudo/standalone/checksum.cpp
+++ b/compiler-rt/lib/scudo/standalone/checksum.cpp
@@ -31,6 +31,13 @@ Checksum HashAlgorithm = {Checksum::BSD};
 #define bit_SSE4_2 bit_SSE42 // clang and gcc have 
diff erent defines.
 #endif
 
+#ifndef signature_HYGON_ebx // They are not defined in gcc.
+// HYGON: "HygonGenuine".
+#define signature_HYGON_ebx 0x6f677948
+#define signature_HYGON_edx 0x6e65476e
+#define signature_HYGON_ecx 0x656e6975
+#endif
+
 bool hasHardwareCRC32() {
   u32 Eax, Ebx = 0, Ecx = 0, Edx = 0;
   __get_cpuid(0, &Eax, &Ebx, &Ecx, &Edx);
@@ -39,7 +46,10 @@ bool hasHardwareCRC32() {
(Ecx == signature_INTEL_ecx);
   const bool IsAMD = (Ebx == signature_AMD_ebx) && (Edx == signature_AMD_edx) 
&&
  (Ecx == signature_AMD_ecx);
-  if (!IsIntel && !IsAMD)
+  const bool IsHygon = (Ebx == signature_HYGON_ebx) &&
+   (Edx == signature_HYGON_edx) &&
+   (Ecx == signature_HYGON_ecx);
+  if (!IsIntel && !IsAMD && !IsHygon)
 return false;
   __get_cpuid(1, &Eax, &Ebx, &Ecx, &Edx);
   return !!(Ecx & bit_SSE4_2);



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [compiler-rt] Update maintainers (PR #119166)

2024-12-09 Thread Kostya Kortchinsky via llvm-branch-commits

https://github.com/cryptoad approved this pull request.


https://github.com/llvm/llvm-project/pull/119166
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits