Bug 1436773 - Clean-up mem check instrumentation of LifoAlloc's BumpChunks. r=tcampbell
authorNicolas B. Pierron <nicolas.b.pierron@gmail.com>
Thu, 08 Feb 2018 17:32:25 +0000
changeset 403445 47b2a7db1ac316ca61d17ec01560b0209e03935d
parent 403444 06a6ef1bb701521a1eb359fc938aa4ce15d4cc14
child 403446 d12cc905dbcdd92e7bb60f2d492441c8c91ca1bd
push id33433
push useraciure@mozilla.com
push dateMon, 12 Feb 2018 22:08:56 +0000
treeherdermozilla-central@6d8f470b2579 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstcampbell
bugs1436773
milestone60.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1436773 - Clean-up mem check instrumentation of LifoAlloc's BumpChunks. r=tcampbell
js/src/ds/LifoAlloc.h
--- a/js/src/ds/LifoAlloc.h
+++ b/js/src/ds/LifoAlloc.h
@@ -219,18 +219,49 @@ class BumpChunk : public SingleLinkedLis
 
 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
     // Magic number used to check against poisoned values.
     const uintptr_t magic_;
     static constexpr uintptr_t magicNumber =
         sizeof(uintptr_t) == 4 ? uintptr_t(0x4c69666f) : uintptr_t(0x4c69666f42756d70);
 #endif
 
+    // Poison the memory with memset, in order to catch errors due to
+    // use-after-free, with undefinedChunkMemory pattern, or to catch
+    // use-before-init with uninitializedChunkMemory.
+#if defined(DEBUG)
+# define LIFO_HAVE_MEM_CHECKS 1
+
     // Byte used for poisoning unused memory after releasing memory.
     static constexpr int undefinedChunkMemory = 0xcd;
+    // Byte used for poisoning uninitialized memory after reserving memory.
+    static constexpr int uninitializedChunkMemory = 0xce;
+
+# define LIFO_MAKE_MEM_NOACCESS(addr, size)      \
+    do {                                         \
+        uint8_t* base = (addr);                  \
+        size_t sz = (size);                      \
+        memset(base, undefinedChunkMemory, sz);  \
+        MOZ_MAKE_MEM_NOACCESS(base, sz);         \
+    } while (0)
+
+# define LIFO_MAKE_MEM_UNDEFINED(addr, size)         \
+    do {                                             \
+        uint8_t* base = (addr);                      \
+        size_t sz = (size);                          \
+        MOZ_MAKE_MEM_UNDEFINED(base, sz);            \
+        memset(base, uninitializedChunkMemory, sz);  \
+        MOZ_MAKE_MEM_UNDEFINED(base, sz);            \
+    } while(0)
+
+#elif defined(MOZ_HAVE_MEM_CHECKS)
+# define LIFO_HAVE_MEM_CHECKS 1
+# define LIFO_MAKE_MEM_NOACCESS(addr, size) MOZ_MAKE_MEM_NOACCESS((addr), (size))
+# define LIFO_MAKE_MEM_UNDEFINED(addr, size) MOZ_MAKE_MEM_UNDEFINED((addr), (size))
+#endif
 
     void assertInvariants() {
         MOZ_DIAGNOSTIC_ASSERT(magic_ == magicNumber);
         MOZ_ASSERT(begin() <= end());
         MOZ_ASSERT(end() <= capacity_);
     }
 
     BumpChunk& operator=(const BumpChunk&) = delete;
@@ -269,32 +300,24 @@ class BumpChunk : public SingleLinkedLis
     // to unwind previous allocations.
     //
     // The memory is flagged as undefined when the bump pointer is moving
     // forward.
     void setBump(uint8_t* newBump) {
         assertInvariants();
         MOZ_ASSERT(begin() <= newBump);
         MOZ_ASSERT(newBump <= capacity_);
-#if defined(DEBUG) || defined(MOZ_HAVE_MEM_CHECKS)
-        uint8_t* prev = bump_;
+#if defined(LIFO_HAVE_MEM_CHECKS)
+        // Poison/Unpoison memory that we just free'd/allocated.
+        if (bump_ > newBump)
+            LIFO_MAKE_MEM_NOACCESS(newBump, bump_ - newBump);
+        else if (newBump > bump_)
+            LIFO_MAKE_MEM_UNDEFINED(bump_, newBump - bump_);
 #endif
         bump_ = newBump;
-#ifdef DEBUG
-        // Clobber the now-free space.
-        if (prev > bump_)
-            memset(bump_, undefinedChunkMemory, prev - bump_);
-#endif
-#if defined(MOZ_HAVE_MEM_CHECKS)
-        // Poison/Unpoison memory that we just free'd/allocated.
-        if (prev > bump_)
-            MOZ_MAKE_MEM_NOACCESS(bump_, prev - bump_);
-        else if (bump_ > prev)
-            MOZ_MAKE_MEM_UNDEFINED(prev, bump_ - prev);
-#endif
     }
 
   public:
     ~BumpChunk() {
         release();
     }
 
     // Space reserved for the BumpChunk internal data, and the alignment of the