bmalloc should support system memory analysis tools (part 1)
authorggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 11 Dec 2014 22:17:06 +0000 (22:17 +0000)
committerggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 11 Dec 2014 22:17:06 +0000 (22:17 +0000)
https://bugs.webkit.org/show_bug.cgi?id=139559

Reviewed by Mark Lam.

This patch adds the hooks to disable bmalloc at runtime if certain
environment variables are set, but doesn't actually read from the
environment yet.

No performance change.

* bmalloc.xcodeproj/project.pbxproj: Added the Environment class, which
we'll use to read environment variables and see if memory analysis tools
have been enabled.

* bmalloc/Allocator.cpp:
(bmalloc::Allocator::Allocator):
(bmalloc::Allocator::allocateSlowCase): Added a hook to disable bmalloc
on the allocation path. We cache the setting to make the check fast.

* bmalloc/Allocator.h: Interface changes.

* bmalloc/Cache.cpp:
(bmalloc::Cache::Cache): Pass a heap pointer through to our allocator
and deallocator. This main purpose is to enable them to query the
environment for whether bmalloc is enabled; but this is also a slightly
cleaner way to guarantee to them that the Heap has been pre-initialized.

* bmalloc/Deallocator.cpp:
(bmalloc::Deallocator::Deallocator): If bmalloc is disable, artificially
fill the object log to force us to take the slow path on all deallocations.

(bmalloc::Deallocator::deallocateSlowCase): Do the disabled check.

* bmalloc/Deallocator.h: Interface changes.

* bmalloc/Environment.cpp: Added.
(bmalloc::Environment::Environment):
(bmalloc::Environment::computeIsBmallocEnabled):
* bmalloc/Environment.h: Added.
(bmalloc::Environment::isBmallocEnabled): This is the class that will
encapsulate looking for environment variables that turn on heap
analysis tools.

* bmalloc/Heap.h:
(bmalloc::Heap::environment):

* bmalloc/Mutex.h:
(bmalloc::Mutex::Mutex):
* bmalloc/StaticMutex.h: A little refactoring to clarify these comments,
since I got super confused about them while writing this patch.

* bmalloc/VMHeap.cpp: Fixed an #include.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@177181 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
Source/bmalloc/ChangeLog
Source/bmalloc/bmalloc.xcodeproj/project.pbxproj
Source/bmalloc/bmalloc/Allocator.cpp
Source/bmalloc/bmalloc/Allocator.h
Source/bmalloc/bmalloc/Cache.cpp
Source/bmalloc/bmalloc/Deallocator.cpp
Source/bmalloc/bmalloc/Deallocator.h
Source/bmalloc/bmalloc/Environment.cpp [new file with mode: 0644]
Source/bmalloc/bmalloc/Environment.h [new file with mode: 0644]
Source/bmalloc/bmalloc/Heap.h
Source/bmalloc/bmalloc/Mutex.h
Source/bmalloc/bmalloc/StaticMutex.h
Source/bmalloc/bmalloc/VMHeap.cpp

index 127c019..6c8162d 100644 (file)
@@ -1,3 +1,59 @@
+2014-12-11  Geoffrey Garen  <ggaren@apple.com>
+
+        bmalloc should support system memory analysis tools (part 1)
+        https://bugs.webkit.org/show_bug.cgi?id=139559
+
+        Reviewed by Mark Lam.
+
+        This patch adds the hooks to disable bmalloc at runtime if certain
+        environment variables are set, but doesn't actually read from the
+        environment yet.
+
+        No performance change.
+
+        * bmalloc.xcodeproj/project.pbxproj: Added the Environment class, which
+        we'll use to read environment variables and see if memory analysis tools
+        have been enabled.
+
+        * bmalloc/Allocator.cpp:
+        (bmalloc::Allocator::Allocator):
+        (bmalloc::Allocator::allocateSlowCase): Added a hook to disable bmalloc
+        on the allocation path. We cache the setting to make the check fast.
+
+        * bmalloc/Allocator.h: Interface changes.
+
+        * bmalloc/Cache.cpp:
+        (bmalloc::Cache::Cache): Pass a heap pointer through to our allocator
+        and deallocator. This main purpose is to enable them to query the
+        environment for whether bmalloc is enabled; but this is also a slightly
+        cleaner way to guarantee to them that the Heap has been pre-initialized.
+
+        * bmalloc/Deallocator.cpp:
+        (bmalloc::Deallocator::Deallocator): If bmalloc is disable, artificially
+        fill the object log to force us to take the slow path on all deallocations.
+
+        (bmalloc::Deallocator::deallocateSlowCase): Do the disabled check.
+
+        * bmalloc/Deallocator.h: Interface changes.
+
+        * bmalloc/Environment.cpp: Added.
+        (bmalloc::Environment::Environment):
+        (bmalloc::Environment::computeIsBmallocEnabled):
+        * bmalloc/Environment.h: Added.
+        (bmalloc::Environment::isBmallocEnabled): This is the class that will
+        encapsulate looking for environment variables that turn on heap
+        analysis tools.
+
+        * bmalloc/Heap.h:
+        (bmalloc::Heap::environment):
+
+        * bmalloc/Mutex.h:
+        (bmalloc::Mutex::Mutex):
+        * bmalloc/StaticMutex.h: A little refactoring to clarify these comments,
+        since I got super confused about them while writing this patch.
+
+        * bmalloc/VMHeap.cpp: Fixed an #include.
+
 2014-12-09  David Kilzer  <ddkilzer@apple.com>
 
         Switch from using PLATFORM_NAME to SDK selectors in ANGLE, bmalloc, gtest, JavaScriptCore, WTF
index 58176da..1ab9234 100644 (file)
@@ -17,6 +17,8 @@
                143CB81D19022BC900B16A45 /* StaticMutex.h in Headers */ = {isa = PBXBuildFile; fileRef = 143CB81B19022BC900B16A45 /* StaticMutex.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1448C30018F3754600502839 /* mbmalloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1448C2FF18F3754300502839 /* mbmalloc.cpp */; };
                1448C30118F3754C00502839 /* bmalloc.h in Headers */ = {isa = PBXBuildFile; fileRef = 1448C2FE18F3754300502839 /* bmalloc.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               14895D911A3A319C0006235D /* Environment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14895D8F1A3A319C0006235D /* Environment.cpp */; };
+               14895D921A3A319C0006235D /* Environment.h in Headers */ = {isa = PBXBuildFile; fileRef = 14895D901A3A319C0006235D /* Environment.h */; };
                14C919C918FCC59F0028DB43 /* BPlatform.h in Headers */ = {isa = PBXBuildFile; fileRef = 14C919C818FCC59F0028DB43 /* BPlatform.h */; settings = {ATTRIBUTES = (Private, ); }; };
                14CC394C18EA8858004AFE34 /* libbmalloc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14F271BE18EA3963008C152F /* libbmalloc.a */; };
                14DD788C18F48CAE00950702 /* LargeChunk.h in Headers */ = {isa = PBXBuildFile; fileRef = 147AAA8818CD17CE002201E4 /* LargeChunk.h */; settings = {ATTRIBUTES = (Private, ); }; };
                147AAA9718CE5FB6002201E4 /* SmallTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SmallTraits.h; path = bmalloc/SmallTraits.h; sourceTree = "<group>"; };
                1485655E18A43AF900ED6942 /* BoundaryTag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BoundaryTag.h; path = bmalloc/BoundaryTag.h; sourceTree = "<group>"; };
                1485656018A43DBA00ED6942 /* ObjectType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjectType.h; path = bmalloc/ObjectType.h; sourceTree = "<group>"; };
+               14895D8F1A3A319C0006235D /* Environment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Environment.cpp; path = bmalloc/Environment.cpp; sourceTree = "<group>"; };
+               14895D901A3A319C0006235D /* Environment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Environment.h; path = bmalloc/Environment.h; sourceTree = "<group>"; };
                14B650C518F39F4800751968 /* Base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Base.xcconfig; sourceTree = "<group>"; };
                14B650C618F39F4800751968 /* bmalloc.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = bmalloc.xcconfig; sourceTree = "<group>"; };
                14B650C718F39F4800751968 /* DebugRelease.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DebugRelease.xcconfig; sourceTree = "<group>"; };
                        isa = PBXGroup;
                        children = (
                                140FA00219CE429C00FFD3C8 /* BumpRange.h */,
+                               14895D8F1A3A319C0006235D /* Environment.cpp */,
+                               14895D901A3A319C0006235D /* Environment.h */,
                                14DA320E18875D9F007269E0 /* Heap.cpp */,
                                14DA320C18875B09007269E0 /* Heap.h */,
                                140FA00419CE4B6800FFD3C8 /* LineMetadata.h */,
                                14DD78BA18F48D6B00950702 /* Page.h in Headers */,
                                14DD78BB18F48D6B00950702 /* SmallChunk.h in Headers */,
                                14DD78C918F48D7500950702 /* Inline.h in Headers */,
+                               14895D921A3A319C0006235D /* Environment.h in Headers */,
                                1400274A18F89C2300115C97 /* VMHeap.h in Headers */,
                                1400274918F89C1300115C97 /* Heap.h in Headers */,
                                14DD78B818F48D6B00950702 /* MediumPage.h in Headers */,
                                143CB81C19022BC900B16A45 /* StaticMutex.cpp in Sources */,
                                14F271C618EA3983008C152F /* SegregatedFreeList.cpp in Sources */,
                                14F271C318EA3978008C152F /* Allocator.cpp in Sources */,
+                               14895D911A3A319C0006235D /* Environment.cpp in Sources */,
                                14F271C718EA3990008C152F /* Heap.cpp in Sources */,
                                14F271C918EA3990008C152F /* VMHeap.cpp in Sources */,
                                14F271C818EA3990008C152F /* ObjectType.cpp in Sources */,
index 15c5b71..6ad8c97 100644 (file)
@@ -35,8 +35,9 @@ using namespace std;
 
 namespace bmalloc {
 
-Allocator::Allocator(Deallocator& deallocator)
-    : m_deallocator(deallocator)
+Allocator::Allocator(Heap* heap, Deallocator& deallocator)
+    : m_isBmallocEnabled(heap->environment().isBmallocEnabled())
+    , m_deallocator(deallocator)
 {
     for (unsigned short size = alignment; size <= mediumMax; size += alignment)
         m_bumpAllocators[sizeClass(size)].init(size);
@@ -103,6 +104,9 @@ NO_INLINE void* Allocator::allocateXLarge(size_t size)
 
 void* Allocator::allocateSlowCase(size_t size)
 {
+    if (!m_isBmallocEnabled)
+        return malloc(size);
+
     if (size <= mediumMax) {
         size_t sizeClass = bmalloc::sizeClass(size);
         BumpAllocator& allocator = m_bumpAllocators[sizeClass];
index 729342c..2db1728 100644 (file)
 #define Allocator_h
 
 #include "BumpAllocator.h"
-#include "FixedVector.h"
-#include "Heap.h"
-#include "Sizes.h"
-#include "SmallLine.h"
 #include <array>
 
 namespace bmalloc {
 
 class Deallocator;
+class Heap;
 
 // Per-cache object allocator.
 
 class Allocator {
 public:
-    Allocator(Deallocator&);
+    Allocator(Heap*, Deallocator&);
     ~Allocator();
 
     void* allocate(size_t);
@@ -58,10 +55,11 @@ private:
     BumpRange allocateBumpRange(size_t sizeClass);
     BumpRange allocateBumpRangeSlowCase(size_t sizeClass);
     
-    Deallocator& m_deallocator;
-
     std::array<BumpAllocator, mediumMax / alignment> m_bumpAllocators;
     std::array<BumpRangeCache, mediumMax / alignment> m_bumpRangeCaches;
+
+    bool m_isBmallocEnabled;
+    Deallocator& m_deallocator;
 };
 
 inline bool Allocator::allocateFastCase(size_t size, void*& object)
index 4f8fc34..6cbe9b7 100644 (file)
@@ -41,11 +41,9 @@ void Cache::operator delete(void* p, size_t size)
 }
 
 Cache::Cache()
-    : m_deallocator()
-    , m_allocator(m_deallocator)
+    : m_deallocator(PerProcess<Heap>::get())
+    , m_allocator(PerProcess<Heap>::get(), m_deallocator)
 {
-    // Ensure that the heap exists, so Allocator and Deallocator can assume it does.
-    PerProcess<Heap>::get();
 }
     
 void Cache::scavenge()
index 1a23af5..180a495 100644 (file)
@@ -38,8 +38,14 @@ using namespace std;
 
 namespace bmalloc {
 
-Deallocator::Deallocator()
+Deallocator::Deallocator(Heap* heap)
+    : m_isBmallocEnabled(heap->environment().isBmallocEnabled())
 {
+    if (!m_isBmallocEnabled) {
+        // Fill the object log in order to disable the fast path.
+        while (m_objectLog.size() != m_objectLog.capacity())
+            m_objectLog.push(nullptr);
+    }
 }
 
 Deallocator::~Deallocator()
@@ -86,6 +92,11 @@ void Deallocator::processObjectLog()
 void Deallocator::deallocateSlowCase(void* object)
 {
     BASSERT(!deallocateFastCase(object));
+    
+    if (!m_isBmallocEnabled) {
+        free(object);
+        return;
+    }
 
     if (!object)
         return;
index ac53da6..7caa41c 100644 (file)
 #define Deallocator_h
 
 #include "FixedVector.h"
-#include "MediumLine.h"
-#include "Sizes.h"
-#include "SmallLine.h"
 
 namespace bmalloc {
 
+class Heap;
+
 // Per-cache object deallocator.
 
 class Deallocator {
 public:
-    Deallocator();
+    Deallocator(Heap*);
     ~Deallocator();
 
     void deallocate(void*);
@@ -52,6 +51,7 @@ private:
     void processObjectLog();
 
     FixedVector<void*, deallocatorLogCapacity> m_objectLog;
+    bool m_isBmallocEnabled;
 };
 
 inline bool Deallocator::deallocateFastCase(void* object)
diff --git a/Source/bmalloc/bmalloc/Environment.cpp b/Source/bmalloc/bmalloc/Environment.cpp
new file mode 100644 (file)
index 0000000..4e3536a
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "Environment.h"
+
+namespace bmalloc {
+
+Environment::Environment()
+    : m_isBmallocEnabled(computeIsBmallocEnabled())
+{
+}
+
+bool Environment::computeIsBmallocEnabled()
+{
+    return true;
+}
+
+} // namespace bmalloc
diff --git a/Source/bmalloc/bmalloc/Environment.h b/Source/bmalloc/bmalloc/Environment.h
new file mode 100644 (file)
index 0000000..887776d
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef Environment_h
+#define Environment_h
+
+namespace bmalloc {
+
+class Environment {
+public:
+    Environment();
+    
+    bool isBmallocEnabled() { return m_isBmallocEnabled; }
+
+private:
+    bool computeIsBmallocEnabled();
+
+    bool m_isBmallocEnabled;
+};
+
+} // namespace bmalloc
+
+#endif // Environment_h
index c5834f5..4f37f55 100644 (file)
@@ -27,6 +27,7 @@
 #define Heap_h
 
 #include "BumpRange.h"
+#include "Environment.h"
 #include "LineMetadata.h"
 #include "MediumChunk.h"
 #include "MediumLine.h"
@@ -49,6 +50,8 @@ class EndTag;
 class Heap {
 public:
     Heap(std::lock_guard<StaticMutex>&);
+    
+    Environment& environment() { return m_environment; }
 
     void refillSmallBumpRangeCache(std::lock_guard<StaticMutex>&, size_t sizeClass, BumpRangeCache&);
     void derefSmallLine(std::lock_guard<StaticMutex>&, SmallLine*);
@@ -101,6 +104,8 @@ private:
 
     bool m_isAllocatingPages;
 
+    Environment m_environment;
+
     VMHeap m_vmHeap;
     AsyncTask<Heap, decltype(&Heap::concurrentScavenge)> m_scavenger;
 };
index 334df77..f0e5998 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "StaticMutex.h"
 
-// A fast replacement for std::mutex.
+// A fast replacement for std::mutex, for use in standard storage.
 
 namespace bmalloc {
 
@@ -39,6 +39,7 @@ public:
 
 inline Mutex::Mutex()
 {
+    // StaticMutex requires explicit initialization when used in non-static storage.
     init();
 }
 
index 3194f1c..ec47dd1 100644 (file)
 #include "BAssert.h"
 #include <atomic>
 
-// A fast replacement for std::mutex for use in static storage, where global
-// constructors and exit-time destructors are prohibited.
+// A fast replacement for std::mutex, for use in static storage.
+
+// Use StaticMutex in static storage, where global constructors and exit-time
+// destructors are prohibited, but all memory is zero-initialized automatically.
 
 namespace bmalloc {
 
 class StaticMutex {
+protected:
+    // Subclasses that support non-static storage must use explicit initialization.
+    void init();
+
 public:
     void lock();
     bool try_lock();
     void unlock();
 
 private:
-    friend class Mutex;
-
-    // Static storage will zero-initialize us automatically, but Mutex needs an
-    // API for explicit initialization.
-    void init();
-
     void lockSlowCase();
 
     std::atomic_flag m_flag;
index ed39ebd..bc7db38 100644 (file)
  */
 
 #include "BoundaryTagInlines.h"
-#include "Heap.h"
 #include "LargeChunk.h"
 #include "Line.h"
 #include "PerProcess.h"
+#include "VMHeap.h"
 #include <thread>
 
 namespace bmalloc {