bmalloc: Added an Object helper class
authorggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 24 Mar 2016 00:12:05 +0000 (00:12 +0000)
committerggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 24 Mar 2016 00:12:05 +0000 (00:12 +0000)
https://bugs.webkit.org/show_bug.cgi?id=155818

Reviewed by Gavin Barraclough.

Object is an abstraction that breaks out a void* into its component
metadata pointers.

This is slightly faster than recomputing them, and it enables a future
patch in which Object will tell us whether it is small or large.

* bmalloc.xcodeproj/project.pbxproj: Added to the project.

* bmalloc/Allocator.cpp:
(bmalloc::Allocator::reallocate): Use Object to compute size.

* bmalloc/Deallocator.cpp:
(bmalloc::Deallocator::processObjectLog):
* bmalloc/Heap.cpp:
(bmalloc::Heap::allocateSmallPage):
(bmalloc::Heap::deallocateSmallLine):
* bmalloc/Heap.h:
(bmalloc::Heap::derefSmallLine): Use Object to deallocate.

* bmalloc/Object.h: Added.
(bmalloc::Object::Object):
(bmalloc::Object::chunk):
(bmalloc::Object::line):
(bmalloc::Object::page): Helper class to break out a void* into its
component metadata pointers.

* bmalloc/SmallChunk.h:
(bmalloc::SmallChunk::SmallChunk): SmallPage::get doesn't exist anymore
so we use our new helper functions instead.

(bmalloc::SmallChunk::offset):
(bmalloc::SmallChunk::object):
(bmalloc::SmallChunk::page):
(bmalloc::SmallChunk::line):
(bmalloc::SmallLine::begin):
(bmalloc::SmallLine::end):
(bmalloc::SmallPage::begin): New helpers that operate on the data
stored in Object.

(bmalloc::SmallLine::get): Deleted.
(bmalloc::SmallPage::get): Deleted.

* bmalloc/SmallLine.h:
(bmalloc::SmallLine::refCount): Added a default ref value for convenience.

* bmalloc/SmallPage.h:
(bmalloc::SmallPage::SmallPage):

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

Source/bmalloc/ChangeLog
Source/bmalloc/bmalloc.xcodeproj/project.pbxproj
Source/bmalloc/bmalloc/Allocator.cpp
Source/bmalloc/bmalloc/Deallocator.cpp
Source/bmalloc/bmalloc/Heap.cpp
Source/bmalloc/bmalloc/Heap.h
Source/bmalloc/bmalloc/Object.h [new file with mode: 0644]
Source/bmalloc/bmalloc/SmallChunk.h
Source/bmalloc/bmalloc/SmallLine.h
Source/bmalloc/bmalloc/SmallPage.h

index d385576..4655f4a 100644 (file)
@@ -1,5 +1,60 @@
 2016-03-23  Geoffrey Garen  <ggaren@apple.com>
 
+        bmalloc: Added an Object helper class
+        https://bugs.webkit.org/show_bug.cgi?id=155818
+
+        Reviewed by Gavin Barraclough.
+
+        Object is an abstraction that breaks out a void* into its component
+        metadata pointers.
+
+        This is slightly faster than recomputing them, and it enables a future
+        patch in which Object will tell us whether it is small or large.
+
+        * bmalloc.xcodeproj/project.pbxproj: Added to the project.
+
+        * bmalloc/Allocator.cpp:
+        (bmalloc::Allocator::reallocate): Use Object to compute size.
+
+        * bmalloc/Deallocator.cpp:
+        (bmalloc::Deallocator::processObjectLog):
+        * bmalloc/Heap.cpp:
+        (bmalloc::Heap::allocateSmallPage):
+        (bmalloc::Heap::deallocateSmallLine):
+        * bmalloc/Heap.h:
+        (bmalloc::Heap::derefSmallLine): Use Object to deallocate.
+
+        * bmalloc/Object.h: Added.
+        (bmalloc::Object::Object):
+        (bmalloc::Object::chunk):
+        (bmalloc::Object::line):
+        (bmalloc::Object::page): Helper class to break out a void* into its
+        component metadata pointers.
+
+        * bmalloc/SmallChunk.h:
+        (bmalloc::SmallChunk::SmallChunk): SmallPage::get doesn't exist anymore
+        so we use our new helper functions instead.
+
+        (bmalloc::SmallChunk::offset):
+        (bmalloc::SmallChunk::object):
+        (bmalloc::SmallChunk::page):
+        (bmalloc::SmallChunk::line):
+        (bmalloc::SmallLine::begin):
+        (bmalloc::SmallLine::end):
+        (bmalloc::SmallPage::begin): New helpers that operate on the data
+        stored in Object.
+
+        (bmalloc::SmallLine::get): Deleted.
+        (bmalloc::SmallPage::get): Deleted.
+
+        * bmalloc/SmallLine.h:
+        (bmalloc::SmallLine::refCount): Added a default ref value for convenience.
+
+        * bmalloc/SmallPage.h:
+        (bmalloc::SmallPage::SmallPage):
+
+2016-03-23  Geoffrey Garen  <ggaren@apple.com>
+
         bmalloc: process the object log before asking for new memory
         https://bugs.webkit.org/show_bug.cgi?id=155801
 
index f1ff74c..917c2ee 100644 (file)
@@ -22,6 +22,7 @@
                1440AFCD1A9527AF00837FAA /* Zone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1440AFCC1A9527AF00837FAA /* Zone.cpp */; };
                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, ); }; };
+               144BE11F1CA346520099C8C0 /* Object.h in Headers */ = {isa = PBXBuildFile; fileRef = 144BE11E1CA346520099C8C0 /* Object.h */; settings = {ATTRIBUTES = (Private, ); }; };
                144C07F41C7B70260051BB6A /* XLargeMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 144C07F21C7B70260051BB6A /* XLargeMap.cpp */; };
                144C07F51C7B70260051BB6A /* XLargeMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 144C07F31C7B70260051BB6A /* XLargeMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
                146041E71C7FF2EF00E9F94E /* SortedVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 146041E61C7FF2EF00E9F94E /* SortedVector.h */; settings = {ATTRIBUTES = (Private, ); }; };
                14446A0717A61FA400F9EA1D /* PerProcess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PerProcess.h; path = bmalloc/PerProcess.h; sourceTree = "<group>"; };
                1448C2FE18F3754300502839 /* bmalloc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = bmalloc.h; path = bmalloc/bmalloc.h; sourceTree = "<group>"; };
                1448C2FF18F3754300502839 /* mbmalloc.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = mbmalloc.cpp; path = bmalloc/mbmalloc.cpp; sourceTree = "<group>"; };
+               144BE11E1CA346520099C8C0 /* Object.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Object.h; path = bmalloc/Object.h; sourceTree = "<group>"; };
                144C07F21C7B70260051BB6A /* XLargeMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = XLargeMap.cpp; path = bmalloc/XLargeMap.cpp; sourceTree = "<group>"; };
                144C07F31C7B70260051BB6A /* XLargeMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XLargeMap.h; path = bmalloc/XLargeMap.h; sourceTree = "<group>"; };
                144DCED617A649D90093B2F2 /* Mutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Mutex.h; path = bmalloc/Mutex.h; sourceTree = "<group>"; };
                                14DA320E18875D9F007269E0 /* Heap.cpp */,
                                14DA320C18875B09007269E0 /* Heap.h */,
                                140FA00419CE4B6800FFD3C8 /* LineMetadata.h */,
+                               144BE11E1CA346520099C8C0 /* Object.h */,
                                14105E8318E14374003A106E /* ObjectType.cpp */,
                                1485656018A43DBA00ED6942 /* ObjectType.h */,
                                145F6874179DF84100D65598 /* Sizes.h */,
                                140FA00519CE4B6800FFD3C8 /* LineMetadata.h in Headers */,
                                14DD78CC18F48D7500950702 /* PerThread.h in Headers */,
                                14DD78CA18F48D7500950702 /* Mutex.h in Headers */,
+                               144BE11F1CA346520099C8C0 /* Object.h in Headers */,
                                143CB81D19022BC900B16A45 /* StaticMutex.h in Headers */,
                                1448C30118F3754C00502839 /* bmalloc.h in Headers */,
                                14C6216F1A9A9A6200E72293 /* LargeObject.h in Headers */,
index 2fb6ded..cb8a4b1 100644 (file)
@@ -115,8 +115,8 @@ void* Allocator::reallocate(void* object, size_t newSize)
     size_t oldSize = 0;
     switch (objectType(object)) {
     case Small: {
-        SmallPage* page = SmallPage::get(SmallLine::get(object));
-        oldSize = objectSize(page->sizeClass());
+        size_t sizeClass = Object(object).page()->sizeClass();
+        oldSize = objectSize(sizeClass);
         break;
     }
     case Large: {
index 8a6bb74..8103aeb 100644 (file)
@@ -28,6 +28,7 @@
 #include "Deallocator.h"
 #include "Heap.h"
 #include "Inline.h"
+#include "Object.h"
 #include "PerProcess.h"
 #include "SmallChunk.h"
 #include <algorithm>
@@ -75,11 +76,9 @@ void Deallocator::processObjectLog(std::lock_guard<StaticMutex>& lock)
 {
     Heap* heap = PerProcess<Heap>::getFastCase();
     
-    for (auto* object : m_objectLog) {
-        SmallLine* line = SmallLine::get(object);
-        heap->derefSmallLine(lock, line);
-    }
-    
+    for (Object object : m_objectLog)
+        heap->derefSmallLine(lock, object);
+
     m_objectLog.clear();
 }
 
index 2e432db..5093546 100644 (file)
@@ -193,10 +193,10 @@ SmallPage* Heap::allocateSmallPage(std::lock_guard<StaticMutex>& lock, size_t si
     return page;
 }
 
-void Heap::deallocateSmallLine(std::lock_guard<StaticMutex>& lock, SmallLine* line)
+void Heap::deallocateSmallLine(std::lock_guard<StaticMutex>& lock, Object object)
 {
-    BASSERT(!line->refCount(lock));
-    SmallPage* page = SmallPage::get(line);
+    BASSERT(!object.line()->refCount(lock));
+    SmallPage* page = object.page();
     page->deref(lock);
 
     if (!page->hasFreeLines(lock)) {
index b257bee..2767701 100644 (file)
@@ -31,6 +31,7 @@
 #include "LineMetadata.h"
 #include "List.h"
 #include "Mutex.h"
+#include "Object.h"
 #include "SegregatedFreeList.h"
 #include "SmallChunk.h"
 #include "SmallLine.h"
@@ -54,7 +55,7 @@ public:
     Environment& environment() { return m_environment; }
 
     void allocateSmallBumpRanges(std::lock_guard<StaticMutex>&, size_t sizeClass, BumpAllocator&, BumpRangeCache&);
-    void derefSmallLine(std::lock_guard<StaticMutex>&, SmallLine*);
+    void derefSmallLine(std::lock_guard<StaticMutex>&, Object);
 
     void* allocateLarge(std::lock_guard<StaticMutex>&, size_t);
     void* allocateLarge(std::lock_guard<StaticMutex>&, size_t alignment, size_t, size_t unalignedSize);
@@ -76,7 +77,7 @@ private:
 
     SmallPage* allocateSmallPage(std::lock_guard<StaticMutex>&, size_t sizeClass);
 
-    void deallocateSmallLine(std::lock_guard<StaticMutex>&, SmallLine*);
+    void deallocateSmallLine(std::lock_guard<StaticMutex>&, Object);
     void deallocateLarge(std::lock_guard<StaticMutex>&, const LargeObject&);
 
     LargeObject& splitAndAllocate(LargeObject&, size_t);
@@ -110,11 +111,11 @@ private:
     VMHeap m_vmHeap;
 };
 
-inline void Heap::derefSmallLine(std::lock_guard<StaticMutex>& lock, SmallLine* line)
+inline void Heap::derefSmallLine(std::lock_guard<StaticMutex>& lock, Object object)
 {
-    if (!line->deref(lock))
+    if (!object.line()->deref(lock))
         return;
-    deallocateSmallLine(lock, line);
+    deallocateSmallLine(lock, object);
 }
 
 } // namespace bmalloc
diff --git a/Source/bmalloc/bmalloc/Object.h b/Source/bmalloc/bmalloc/Object.h
new file mode 100644 (file)
index 0000000..ba7817c
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2016 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 Object_h
+#define Object_h
+
+namespace bmalloc {
+
+class SmallChunk;
+class SmallLine;
+class SmallPage;
+
+class Object {
+public:
+    Object(void*);
+    Object(SmallChunk*, void*);
+    
+    SmallChunk* chunk() { return m_chunk; }
+
+    SmallLine* line();
+    SmallPage* page();
+
+private:
+    SmallChunk* m_chunk;
+    size_t m_offset;
+};
+
+}; // namespace bmalloc
+
+#endif // Object_h
index d38a914..68eb532 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef SmallChunk_h
 #define SmallChunk_h
 
+#include "Object.h"
 #include "Sizes.h"
 #include "SmallLine.h"
 #include "SmallPage.h"
@@ -38,8 +39,13 @@ public:
     SmallChunk(std::lock_guard<StaticMutex>&);
 
     static SmallChunk* get(void*);
+    size_t offset(void*);
 
-    SmallPage* begin() { return SmallPage::get(SmallLine::get(m_memory)); }
+    void* object(size_t offset);
+    SmallPage* page(size_t offset);
+    SmallLine* line(size_t offset);
+
+    SmallPage* begin() { return Object(m_memory).page(); }
     SmallPage* end() { return m_pages.end(); }
     
     SmallLine* lines() { return m_lines.begin(); }
@@ -60,15 +66,11 @@ static_assert(
 inline SmallChunk::SmallChunk(std::lock_guard<StaticMutex>& lock)
 {
     // Track the memory used for metadata by allocating imaginary objects.
-    for (SmallLine* line = m_lines.begin(); line < SmallLine::get(m_memory); ++line) {
-        line->ref(lock, 1);
-
-        SmallPage* page = SmallPage::get(line);
-        page->ref(lock);
+    for (char* it = reinterpret_cast<char*>(this); it < m_memory; it += smallLineSize) {
+        Object object(it);
+        object.line()->ref(lock);
+        object.page()->ref(lock);
     }
-
-    for (SmallPage* page = begin(); page != end(); ++page)
-        page->setHasFreeLines(lock, true);
 }
 
 inline SmallChunk* SmallChunk::get(void* object)
@@ -77,12 +79,28 @@ inline SmallChunk* SmallChunk::get(void* object)
     return static_cast<SmallChunk*>(mask(object, smallChunkMask));
 }
 
-inline SmallLine* SmallLine::get(void* object)
+inline size_t SmallChunk::offset(void* object)
 {
-    BASSERT(isSmall(object));
-    SmallChunk* chunk = SmallChunk::get(object);
-    size_t lineNumber = (reinterpret_cast<char*>(object) - reinterpret_cast<char*>(chunk)) / smallLineSize;
-    return &chunk->lines()[lineNumber];
+    BASSERT(object >= this);
+    BASSERT(object < reinterpret_cast<char*>(this) + smallChunkSize);
+    return static_cast<char*>(object) - reinterpret_cast<char*>(this);
+}
+
+inline void* SmallChunk::object(size_t offset)
+{
+    return reinterpret_cast<char*>(this) + offset;
+}
+
+inline SmallPage* SmallChunk::page(size_t offset)
+{
+    size_t pageNumber = offset / vmPageSize;
+    return &m_pages[pageNumber];
+}
+
+inline SmallLine* SmallChunk::line(size_t offset)
+{
+    size_t lineNumber = offset / smallLineSize;
+    return &m_lines[lineNumber];
 }
 
 inline char* SmallLine::begin()
@@ -98,14 +116,6 @@ inline char* SmallLine::end()
     return begin() + smallLineSize;
 }
 
-inline SmallPage* SmallPage::get(SmallLine* line)
-{
-    SmallChunk* chunk = SmallChunk::get(line);
-    size_t lineNumber = line - chunk->lines();
-    size_t pageNumber = lineNumber * smallLineSize / vmPageSize;
-    return &chunk->pages()[pageNumber];
-}
-
 inline SmallLine* SmallPage::begin()
 {
     SmallChunk* chunk = SmallChunk::get(this);
@@ -119,6 +129,29 @@ inline SmallLine* SmallPage::end()
     return begin() + smallLineCount;
 }
 
+inline Object::Object(void* object)
+    : m_chunk(SmallChunk::get(object))
+    , m_offset(m_chunk->offset(object))
+{
+}
+
+inline Object::Object(SmallChunk* chunk, void* object)
+    : m_chunk(chunk)
+    , m_offset(m_chunk->offset(object))
+{
+    BASSERT(chunk == SmallChunk::get(object));
+}
+
+inline SmallLine* Object::line()
+{
+    return m_chunk->line(m_offset);
+}
+
+inline SmallPage* Object::page()
+{
+    return m_chunk->page(m_offset);
+}
+
 }; // namespace bmalloc
 
 #endif // Chunk
index 70824d6..188930e 100644 (file)
@@ -35,9 +35,7 @@ namespace bmalloc {
 
 class SmallLine {
 public:
-    static SmallLine* get(void*);
-
-    void ref(std::lock_guard<StaticMutex>&, unsigned char);
+    void ref(std::lock_guard<StaticMutex>&, unsigned char = 1);
     bool deref(std::lock_guard<StaticMutex>&);
     unsigned refCount(std::lock_guard<StaticMutex>&) { return m_refCount; }
     
index 6a0d6e0..412d511 100644 (file)
@@ -36,8 +36,6 @@ namespace bmalloc {
 
 class SmallPage : public ListNode<SmallPage> {
 public:
-    static SmallPage* get(SmallLine*);
-
     SmallPage()
         : m_hasFreeLines(true)
     {