| Index: nspr/lib/ds/plarena.h
|
| ===================================================================
|
| --- nspr/lib/ds/plarena.h (revision 233722)
|
| +++ nspr/lib/ds/plarena.h (working copy)
|
| @@ -58,6 +58,68 @@
|
| };
|
|
|
| /*
|
| + * WARNING: The PL_MAKE_MEM_ macros are for internal use by NSPR. Do NOT use
|
| + * them in your code.
|
| + *
|
| + * NOTE: Valgrind support to be added.
|
| + *
|
| + * The PL_MAKE_MEM_ macros are modeled after the MOZ_MAKE_MEM_ macros in
|
| + * Mozilla's mfbt/MemoryChecking.h. Only AddressSanitizer is supported now.
|
| + *
|
| + * Provides a common interface to the ASan (AddressSanitizer) and Valgrind
|
| + * functions used to mark memory in certain ways. In detail, the following
|
| + * three macros are provided:
|
| + *
|
| + * PL_MAKE_MEM_NOACCESS - Mark memory as unsafe to access (e.g. freed)
|
| + * PL_MAKE_MEM_UNDEFINED - Mark memory as accessible, with content undefined
|
| + * PL_MAKE_MEM_DEFINED - Mark memory as accessible, with content defined
|
| + *
|
| + * With Valgrind in use, these directly map to the three respective Valgrind
|
| + * macros. With ASan in use, the NOACCESS macro maps to poisoning the memory,
|
| + * while the UNDEFINED/DEFINED macros unpoison memory.
|
| + *
|
| + * With no memory checker available, all macros expand to the empty statement.
|
| + */
|
| +
|
| +/* WARNING: PL_SANITIZE_ADDRESS is for internal use by this header. Do NOT
|
| + * define or test this macro in your code.
|
| + */
|
| +#if defined(__has_feature)
|
| +#if __has_feature(address_sanitizer)
|
| +#define PL_SANITIZE_ADDRESS 1
|
| +#endif
|
| +#elif defined(__SANITIZE_ADDRESS__)
|
| +#define PL_SANITIZE_ADDRESS 1
|
| +#endif
|
| +
|
| +#if defined(PL_SANITIZE_ADDRESS)
|
| +
|
| +/* These definitions are usually provided through the
|
| + * sanitizer/asan_interface.h header installed by ASan.
|
| + * See https://code.google.com/p/address-sanitizer/wiki/ManualPoisoning
|
| + */
|
| +
|
| +void __asan_poison_memory_region(void const volatile *addr, size_t size);
|
| +void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
|
| +
|
| +#define PL_MAKE_MEM_NOACCESS(addr, size) \
|
| + __asan_poison_memory_region((addr), (size))
|
| +
|
| +#define PL_MAKE_MEM_UNDEFINED(addr, size) \
|
| + __asan_unpoison_memory_region((addr), (size))
|
| +
|
| +#define PL_MAKE_MEM_DEFINED(addr, size) \
|
| + __asan_unpoison_memory_region((addr), (size))
|
| +
|
| +#else
|
| +
|
| +#define PL_MAKE_MEM_NOACCESS(addr, size)
|
| +#define PL_MAKE_MEM_UNDEFINED(addr, size)
|
| +#define PL_MAKE_MEM_DEFINED(addr, size)
|
| +
|
| +#endif
|
| +
|
| +/*
|
| * If the including .c file uses only one power-of-2 alignment, it may define
|
| * PL_ARENA_CONST_ALIGN_MASK to the alignment mask and save a few instructions
|
| * per ALLOCATE and GROW.
|
| @@ -78,11 +140,13 @@
|
| PRUint32 _nb = PL_ARENA_ALIGN(pool, nb); \
|
| PRUword _p = _a->avail; \
|
| PRUword _q = _p + _nb; \
|
| - if (_q > _a->limit) \
|
| + if (_q > _a->limit) { \
|
| _p = (PRUword)PL_ArenaAllocate(pool, _nb); \
|
| - else \
|
| + } else { \
|
| _a->avail = _q; \
|
| + } \
|
| p = (void *)_p; \
|
| + PL_MAKE_MEM_UNDEFINED(p, nb); \
|
| PL_ArenaCountAllocation(pool, nb); \
|
| PR_END_MACRO
|
|
|
| @@ -94,6 +158,7 @@
|
| PRUword _q = _p + _incr; \
|
| if (_p == (PRUword)(p) + PL_ARENA_ALIGN(pool, size) && \
|
| _q <= _a->limit) { \
|
| + PL_MAKE_MEM_UNDEFINED((unsigned char *)(p) + size, incr); \
|
| _a->avail = _q; \
|
| PL_ArenaCountInplaceGrowth(pool, size, incr); \
|
| } else { \
|
| @@ -106,13 +171,19 @@
|
| #define PR_UPTRDIFF(p,q) ((PRUword)(p) - (PRUword)(q))
|
|
|
| #define PL_CLEAR_UNUSED_PATTERN(a, pattern) \
|
| - (PR_ASSERT((a)->avail <= (a)->limit), \
|
| - memset((void*)(a)->avail, (pattern), (a)->limit - (a)->avail))
|
| + PR_BEGIN_MACRO \
|
| + PR_ASSERT((a)->avail <= (a)->limit); \
|
| + PL_MAKE_MEM_UNDEFINED((void*)(a)->avail, (a)->limit - (a)->avail); \
|
| + memset((void*)(a)->avail, (pattern), (a)->limit - (a)->avail); \
|
| + PR_END_MACRO
|
| #ifdef DEBUG
|
| #define PL_FREE_PATTERN 0xDA
|
| #define PL_CLEAR_UNUSED(a) PL_CLEAR_UNUSED_PATTERN((a), PL_FREE_PATTERN)
|
| -#define PL_CLEAR_ARENA(a) memset((void*)(a), PL_FREE_PATTERN, \
|
| - (a)->limit - (PRUword)(a))
|
| +#define PL_CLEAR_ARENA(a) \
|
| + PR_BEGIN_MACRO \
|
| + PL_MAKE_MEM_UNDEFINED((void*)(a), (a)->limit - (PRUword)(a)); \
|
| + memset((void*)(a), PL_FREE_PATTERN, (a)->limit - (PRUword)(a)); \
|
| + PR_END_MACRO
|
| #else
|
| #define PL_CLEAR_UNUSED(a)
|
| #define PL_CLEAR_ARENA(a)
|
| @@ -125,6 +196,7 @@
|
| if (PR_UPTRDIFF(_m, _a->base) <= PR_UPTRDIFF(_a->avail, _a->base)) { \
|
| _a->avail = (PRUword)PL_ARENA_ALIGN(pool, _m); \
|
| PL_CLEAR_UNUSED(_a); \
|
| + PL_MAKE_MEM_NOACCESS((void*)_a->avail, _a->limit - _a->avail); \
|
| PL_ArenaCountRetract(pool, _m); \
|
| } else { \
|
| PL_ArenaRelease(pool, _m); \
|
|
|