forked from OSchip/llvm-project
[asan] speedup by more than 2x handling of the small memset/memcpy/etc calls
llvm-svn: 175728
This commit is contained in:
parent
9e722aed4a
commit
ab5be26af5
|
@ -26,6 +26,16 @@
|
||||||
|
|
||||||
namespace __asan {
|
namespace __asan {
|
||||||
|
|
||||||
|
// Return true if we can quickly decide that the region is unpoisoned.
|
||||||
|
static inline bool QuickCheckForUnpoisonedRegion(uptr beg, uptr size) {
|
||||||
|
if (size == 0) return true;
|
||||||
|
if (size <= 32)
|
||||||
|
return !AddressIsPoisoned(beg) &&
|
||||||
|
!AddressIsPoisoned(beg + size - 1) &&
|
||||||
|
!AddressIsPoisoned(beg + size / 2);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE,
|
// We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE,
|
||||||
// and ASAN_WRITE_RANGE as macro instead of function so
|
// and ASAN_WRITE_RANGE as macro instead of function so
|
||||||
// that no extra frames are created, and stack trace contains
|
// that no extra frames are created, and stack trace contains
|
||||||
|
@ -34,7 +44,8 @@ namespace __asan {
|
||||||
#define ACCESS_MEMORY_RANGE(offset, size, isWrite) do { \
|
#define ACCESS_MEMORY_RANGE(offset, size, isWrite) do { \
|
||||||
uptr __offset = (uptr)(offset); \
|
uptr __offset = (uptr)(offset); \
|
||||||
uptr __size = (uptr)(size); \
|
uptr __size = (uptr)(size); \
|
||||||
if (__asan_region_is_poisoned(__offset, __size)) { \
|
if (!QuickCheckForUnpoisonedRegion(__offset, __size) && \
|
||||||
|
__asan_region_is_poisoned(__offset, __size)) { \
|
||||||
GET_CURRENT_PC_BP_SP; \
|
GET_CURRENT_PC_BP_SP; \
|
||||||
__asan_report_error(pc, bp, sp, __offset, isWrite, __size); \
|
__asan_report_error(pc, bp, sp, __offset, isWrite, __size); \
|
||||||
} \
|
} \
|
||||||
|
|
|
@ -206,7 +206,7 @@ static inline bool AddrIsAlignedByGranularity(uptr a) {
|
||||||
static inline bool AddressIsPoisoned(uptr a) {
|
static inline bool AddressIsPoisoned(uptr a) {
|
||||||
PROFILE_ASAN_MAPPING();
|
PROFILE_ASAN_MAPPING();
|
||||||
const uptr kAccessSize = 1;
|
const uptr kAccessSize = 1;
|
||||||
u8 *shadow_address = (u8*)MemToShadow(a);
|
u8 *shadow_address = (u8*)MEM_TO_SHADOW(a);
|
||||||
s8 shadow_value = *shadow_address;
|
s8 shadow_value = *shadow_address;
|
||||||
if (shadow_value) {
|
if (shadow_value) {
|
||||||
u8 last_accessed_byte = (a & (SHADOW_GRANULARITY - 1))
|
u8 last_accessed_byte = (a & (SHADOW_GRANULARITY - 1))
|
||||||
|
|
|
@ -764,7 +764,7 @@ TEST(AddressSanitizerInterface, PoisonedRegion) {
|
||||||
// 10.50% [.] __sanitizer::mem_is_zero
|
// 10.50% [.] __sanitizer::mem_is_zero
|
||||||
// I.e. mem_is_zero should consume ~ SHADOW_GRANULARITY less CPU cycles
|
// I.e. mem_is_zero should consume ~ SHADOW_GRANULARITY less CPU cycles
|
||||||
// than memset itself.
|
// than memset itself.
|
||||||
TEST(AddressSanitizerInterface, DISABLED_Stress_memset) {
|
TEST(AddressSanitizerInterface, DISABLED_StressLargeMemset) {
|
||||||
size_t size = 1 << 20;
|
size_t size = 1 << 20;
|
||||||
char *x = new char[size];
|
char *x = new char[size];
|
||||||
for (int i = 0; i < 100000; i++)
|
for (int i = 0; i < 100000; i++)
|
||||||
|
@ -772,6 +772,15 @@ TEST(AddressSanitizerInterface, DISABLED_Stress_memset) {
|
||||||
delete [] x;
|
delete [] x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Same here, but we run memset with small sizes.
|
||||||
|
TEST(AddressSanitizerInterface, DISABLED_StressSmallMemset) {
|
||||||
|
size_t size = 32;
|
||||||
|
char *x = new char[size];
|
||||||
|
for (int i = 0; i < 100000000; i++)
|
||||||
|
Ident(memset)(x, 0, size);
|
||||||
|
delete [] x;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *kInvalidPoisonMessage = "invalid-poison-memory-range";
|
static const char *kInvalidPoisonMessage = "invalid-poison-memory-range";
|
||||||
static const char *kInvalidUnpoisonMessage = "invalid-unpoison-memory-range";
|
static const char *kInvalidUnpoisonMessage = "invalid-unpoison-memory-range";
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue