From ea42515dadfa3ca0020bc7107787761f026ad2dc Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Mon, 8 Aug 2022 21:38:55 -0700 Subject: [PATCH] [asan] Faster version of QuickCheckForUnpoisonedRegion Slightly helps with performance regression after D128146. --- .../asan/asan_interceptors_memintrinsics.h | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/compiler-rt/lib/asan/asan_interceptors_memintrinsics.h b/compiler-rt/lib/asan/asan_interceptors_memintrinsics.h index 391e72b826d3..bbc5390ceaa4 100644 --- a/compiler-rt/lib/asan/asan_interceptors_memintrinsics.h +++ b/compiler-rt/lib/asan/asan_interceptors_memintrinsics.h @@ -26,17 +26,21 @@ namespace __asan { // Return true if we can quickly decide that the region is unpoisoned. // We assume that a redzone is at least 16 bytes. static inline bool QuickCheckForUnpoisonedRegion(uptr beg, uptr size) { - if (UNLIKELY(size == 0)) + if (UNLIKELY(size == 0 || size > sizeof(uptr) * ASAN_SHADOW_GRANULARITY)) + return !size; + + uptr last = beg + size - 1; + uptr shadow_first = MEM_TO_SHADOW(beg); + uptr shadow_last = MEM_TO_SHADOW(last); + uptr uptr_first = RoundDownTo(shadow_first, sizeof(uptr)); + uptr uptr_last = RoundDownTo(shadow_last, sizeof(uptr)); + if (LIKELY(((*reinterpret_cast(uptr_first) | + *reinterpret_cast(uptr_last)) == 0))) return true; - if (size <= 32) - return !AddressIsPoisoned(beg) && !AddressIsPoisoned(beg + size - 1) && - !AddressIsPoisoned(beg + size / 2); - if (size <= 64) - return !AddressIsPoisoned(beg) && !AddressIsPoisoned(beg + size / 4) && - !AddressIsPoisoned(beg + size - 1) && - !AddressIsPoisoned(beg + 3 * size / 4) && - !AddressIsPoisoned(beg + size / 2); - return false; + u8 shadow = AddressIsPoisoned(last); + for (; shadow_first < shadow_last; ++shadow_first) + shadow |= *((u8 *)shadow_first); + return !shadow; } struct AsanInterceptorContext {