Title: [115590] trunk/Source/_javascript_Core
Revision
115590
Author
[email protected]
Date
2012-04-28 18:44:37 -0700 (Sat, 28 Apr 2012)

Log Message

Factored threaded block allocation into a separate object
https://bugs.webkit.org/show_bug.cgi?id=85148

Reviewed by Sam Weinig.

99% of this patch just moves duplicated block allocation and 
deallocation code into a new object named BlockAllocator, with these 
exceptions:

* heap/BlockAllocator.h: Added.
(BlockAllocator::BlockAllocator): The order of declarations here now 
guards us against an unlikely race condition during startup.

* heap/BlockAllocator.cpp:
JSC::BlockAllocator::blockFreeingThreadMain): Added a FIXME to 
highlight a lack of clarity we have in our block deallocation routines.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/CMakeLists.txt (115589 => 115590)


--- trunk/Source/_javascript_Core/CMakeLists.txt	2012-04-29 01:32:16 UTC (rev 115589)
+++ trunk/Source/_javascript_Core/CMakeLists.txt	2012-04-29 01:44:37 UTC (rev 115590)
@@ -85,6 +85,7 @@
     dfg/DFGThunks.cpp
     dfg/DFGVirtualRegisterAllocationPhase.cpp
 
+    heap/BlockAllocator.cpp
     heap/CopiedSpace.cpp
     heap/ConservativeRoots.cpp
     heap/DFGCodeBlocks.cpp

Modified: trunk/Source/_javascript_Core/ChangeLog (115589 => 115590)


--- trunk/Source/_javascript_Core/ChangeLog	2012-04-29 01:32:16 UTC (rev 115589)
+++ trunk/Source/_javascript_Core/ChangeLog	2012-04-29 01:44:37 UTC (rev 115590)
@@ -1,3 +1,22 @@
+2012-04-28  Geoffrey Garen  <[email protected]>
+
+        Factored threaded block allocation into a separate object
+        https://bugs.webkit.org/show_bug.cgi?id=85148
+
+        Reviewed by Sam Weinig.
+
+        99% of this patch just moves duplicated block allocation and 
+        deallocation code into a new object named BlockAllocator, with these 
+        exceptions:
+
+        * heap/BlockAllocator.h: Added.
+        (BlockAllocator::BlockAllocator): The order of declarations here now 
+        guards us against an unlikely race condition during startup.
+
+        * heap/BlockAllocator.cpp:
+        JSC::BlockAllocator::blockFreeingThreadMain): Added a FIXME to 
+        highlight a lack of clarity we have in our block deallocation routines.
+
 2012-04-28  Sam Weinig  <[email protected]>
 
         Try to fix the Qt build.

Modified: trunk/Source/_javascript_Core/GNUmakefile.list.am (115589 => 115590)


--- trunk/Source/_javascript_Core/GNUmakefile.list.am	2012-04-29 01:32:16 UTC (rev 115589)
+++ trunk/Source/_javascript_Core/GNUmakefile.list.am	2012-04-29 01:44:37 UTC (rev 115590)
@@ -226,6 +226,7 @@
 	Source/_javascript_Core/heap/HandleStack.cpp \
 	Source/_javascript_Core/heap/HandleStack.h \
 	Source/_javascript_Core/heap/HandleTypes.h \
+	Source/_javascript_Core/heap/BlockAllocator.cpp \
 	Source/_javascript_Core/heap/Heap.cpp \
 	Source/_javascript_Core/heap/Heap.h \
 	Source/_javascript_Core/heap/ListableHandler.h \

Modified: trunk/Source/_javascript_Core/_javascript_Core.gypi (115589 => 115590)


--- trunk/Source/_javascript_Core/_javascript_Core.gypi	2012-04-29 01:32:16 UTC (rev 115589)
+++ trunk/Source/_javascript_Core/_javascript_Core.gypi	2012-04-29 01:44:37 UTC (rev 115590)
@@ -401,6 +401,7 @@
             'heap/DFGCodeBlocks.cpp',
             'heap/HandleSet.cpp',
             'heap/HandleStack.cpp',
+            'heap/BlockAllocator.cpp',
             'heap/Heap.cpp',
             'heap/MachineStackMarker.cpp',
             'heap/MarkedAllocator.cpp',

Modified: trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj (115589 => 115590)


--- trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj	2012-04-29 01:32:16 UTC (rev 115589)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj	2012-04-29 01:44:37 UTC (rev 115590)
@@ -2170,6 +2170,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\heap\BlockAllocator.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\heap\BlockAllocator.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\heap\Heap.cpp"
 				>
 			</File>

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (115589 => 115590)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2012-04-29 01:32:16 UTC (rev 115589)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2012-04-29 01:44:37 UTC (rev 115590)
@@ -298,6 +298,8 @@
 		147F39D5107EC37600427A48 /* JSString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC02E9B60E1842FA000F9297 /* JSString.cpp */; };
 		147F39D6107EC37600427A48 /* JSValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8870255597D01FF60F7 /* JSValue.cpp */; };
 		147F39D7107EC37600427A48 /* JSVariableObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC22A39A0E16E14800AF21C8 /* JSVariableObject.cpp */; };
+		14816E1B154CC56C00B8054C /* BlockAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14816E19154CC56C00B8054C /* BlockAllocator.cpp */; };
+		14816E1C154CC56C00B8054C /* BlockAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 14816E1A154CC56C00B8054C /* BlockAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		1482B74E0A43032800517CFC /* JSStringRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1482B74C0A43032800517CFC /* JSStringRef.cpp */; };
 		1482B7E40A43076000517CFC /* JSObjectRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1482B7E20A43076000517CFC /* JSObjectRef.cpp */; };
 		148CD1D8108CF902008163C6 /* JSContextRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 148CD1D7108CF902008163C6 /* JSContextRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -915,6 +917,8 @@
 		147B83AA0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BatchedTransitionOptimizer.h; sourceTree = "<group>"; };
 		147B84620E6DE6B1004775A4 /* PutPropertySlot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PutPropertySlot.h; sourceTree = "<group>"; };
 		1480DB9B0DDC227F003CFDF2 /* DebuggerCallFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerCallFrame.h; sourceTree = "<group>"; };
+		14816E19154CC56C00B8054C /* BlockAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BlockAllocator.cpp; sourceTree = "<group>"; };
+		14816E1A154CC56C00B8054C /* BlockAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockAllocator.h; sourceTree = "<group>"; };
 		1482B6EA0A4300B300517CFC /* JSValueRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSValueRef.h; sourceTree = "<group>"; };
 		1482B74B0A43032800517CFC /* JSStringRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringRef.h; sourceTree = "<group>"; };
 		1482B74C0A43032800517CFC /* JSStringRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSStringRef.cpp; sourceTree = "<group>"; };
@@ -1560,6 +1564,8 @@
 		142E312A134FF0A600AFADB5 /* heap */ = {
 			isa = PBXGroup;
 			children = (
+				14816E19154CC56C00B8054C /* BlockAllocator.cpp */,
+				14816E1A154CC56C00B8054C /* BlockAllocator.h */,
 				A7521E121429169A003C8D0C /* CardSet.h */,
 				146B14DB12EB5B12001BEC1B /* ConservativeRoots.cpp */,
 				149DAAF212EB559D0083B12B /* ConservativeRoots.h */,
@@ -2567,6 +2573,7 @@
 				0F1E3A461534CBAF000F9456 /* DFGArgumentPosition.h in Headers */,
 				0F1E3A471534CBB9000F9456 /* DFGDoubleFormatState.h in Headers */,
 				14150133154BB13F005D8C98 /* WeakSetInlines.h in Headers */,
+				14816E1C154CC56C00B8054C /* BlockAllocator.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -3129,6 +3136,7 @@
 				8642C510151C06A90046D4EF /* RegExpCachedResult.cpp in Sources */,
 				8642C512151C083D0046D4EF /* RegExpMatchesArray.cpp in Sources */,
 				863C6D9C1521111A00585E4E /* YarrCanonicalizeUCS2.cpp in Sources */,
+				14816E1B154CC56C00B8054C /* BlockAllocator.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: trunk/Source/_javascript_Core/Target.pri (115589 => 115590)


--- trunk/Source/_javascript_Core/Target.pri	2012-04-29 01:32:16 UTC (rev 115589)
+++ trunk/Source/_javascript_Core/Target.pri	2012-04-29 01:44:37 UTC (rev 115590)
@@ -76,6 +76,7 @@
     heap/WeakBlock.cpp \
     heap/HandleSet.cpp \
     heap/HandleStack.cpp \
+    heap/BlockAllocator.cpp \
     heap/Heap.cpp \
     heap/MachineStackMarker.cpp \
     heap/MarkStack.cpp \

Added: trunk/Source/_javascript_Core/heap/BlockAllocator.cpp (0 => 115590)


--- trunk/Source/_javascript_Core/heap/BlockAllocator.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/heap/BlockAllocator.cpp	2012-04-29 01:44:37 UTC (rev 115590)
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2012 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. AND ITS CONTRIBUTORS ``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 ITS 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 "config.h"
+#include "BlockAllocator.h"
+
+#include "MarkedBlock.h"
+#include <wtf/CurrentTime.h>
+
+namespace JSC {
+
+BlockAllocator::BlockAllocator()
+    : m_numberOfFreeBlocks(0)
+    , m_blockFreeingThreadShouldQuit(false)
+    , m_blockFreeingThread(createThread(blockFreeingThreadStartFunc, this, "_javascript_Core::BlockFree"))
+{
+    ASSERT(m_blockFreeingThread);
+}
+
+BlockAllocator::~BlockAllocator()
+{
+    releaseFreeBlocks();
+    {
+        MutexLocker locker(m_freeBlockLock);
+        m_blockFreeingThreadShouldQuit = true;
+        m_freeBlockCondition.broadcast();
+    }
+    waitForThreadCompletion(m_blockFreeingThread);
+}
+
+void BlockAllocator::releaseFreeBlocks()
+{
+    while (true) {
+        MarkedBlock* block;
+        {
+            MutexLocker locker(m_freeBlockLock);
+            if (!m_numberOfFreeBlocks)
+                block = 0;
+            else {
+                // FIXME: How do we know this is a MarkedBlock? It could be a CopiedBlock.
+                block = static_cast<MarkedBlock*>(m_freeBlocks.removeHead());
+                ASSERT(block);
+                m_numberOfFreeBlocks--;
+            }
+        }
+        
+        if (!block)
+            break;
+        
+        MarkedBlock::destroy(block);
+    }
+}
+
+void BlockAllocator::waitForRelativeTimeWhileHoldingLock(double relative)
+{
+    if (m_blockFreeingThreadShouldQuit)
+        return;
+    m_freeBlockCondition.timedWait(m_freeBlockLock, currentTime() + relative);
+}
+
+void BlockAllocator::waitForRelativeTime(double relative)
+{
+    // If this returns early, that's fine, so long as it doesn't do it too
+    // frequently. It would only be a bug if this function failed to return
+    // when it was asked to do so.
+    
+    MutexLocker locker(m_freeBlockLock);
+    waitForRelativeTimeWhileHoldingLock(relative);
+}
+
+void BlockAllocator::blockFreeingThreadStartFunc(void* blockAllocator)
+{
+    static_cast<BlockAllocator*>(blockAllocator)->blockFreeingThreadMain();
+}
+
+void BlockAllocator::blockFreeingThreadMain()
+{
+    while (!m_blockFreeingThreadShouldQuit) {
+        // Generally wait for one second before scavenging free blocks. This
+        // may return early, particularly when we're being asked to quit.
+        waitForRelativeTime(1.0);
+        if (m_blockFreeingThreadShouldQuit)
+            break;
+        
+        // Now process the list of free blocks. Keep freeing until half of the
+        // blocks that are currently on the list are gone. Assume that a size_t
+        // field can be accessed atomically.
+        size_t currentNumberOfFreeBlocks = m_numberOfFreeBlocks;
+        if (!currentNumberOfFreeBlocks)
+            continue;
+        
+        size_t desiredNumberOfFreeBlocks = currentNumberOfFreeBlocks / 2;
+        
+        while (!m_blockFreeingThreadShouldQuit) {
+            MarkedBlock* block;
+            {
+                MutexLocker locker(m_freeBlockLock);
+                if (m_numberOfFreeBlocks <= desiredNumberOfFreeBlocks)
+                    block = 0;
+                else {
+                    // FIXME: How do we know this is a MarkedBlock? It could be a CopiedBlock.
+                    block = static_cast<MarkedBlock*>(m_freeBlocks.removeHead());
+                    ASSERT(block);
+                    m_numberOfFreeBlocks--;
+                }
+            }
+            
+            if (!block)
+                break;
+            
+            MarkedBlock::destroy(block);
+        }
+    }
+}
+
+} // namespace JSC

Added: trunk/Source/_javascript_Core/heap/BlockAllocator.h (0 => 115590)


--- trunk/Source/_javascript_Core/heap/BlockAllocator.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/heap/BlockAllocator.h	2012-04-29 01:44:37 UTC (rev 115590)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2012 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. AND ITS CONTRIBUTORS ``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 ITS 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 BlockAllocator_h
+#define BlockAllocator_h
+
+#include <wtf/DoublyLinkedList.h>
+#include <wtf/Forward.h>
+#include <wtf/Threading.h>
+
+namespace JSC {
+
+class HeapBlock;
+
+// Simple allocator to reduce VM cost by holding onto blocks of memory for
+// short periods of time and then freeing them on a secondary thread.
+
+class BlockAllocator {
+public:
+    BlockAllocator();
+    ~BlockAllocator();
+
+    HeapBlock* allocate();
+    void deallocate(HeapBlock*);
+
+private:
+    void waitForRelativeTimeWhileHoldingLock(double relative);
+    void waitForRelativeTime(double relative);
+
+    void blockFreeingThreadMain();
+    static void blockFreeingThreadStartFunc(void* heap);
+
+    void releaseFreeBlocks();
+
+    DoublyLinkedList<HeapBlock> m_freeBlocks;
+    size_t m_numberOfFreeBlocks;
+    bool m_blockFreeingThreadShouldQuit;
+    Mutex m_freeBlockLock;
+    ThreadCondition m_freeBlockCondition;
+    ThreadIdentifier m_blockFreeingThread;
+};
+
+inline HeapBlock* BlockAllocator::allocate()
+{
+    MutexLocker locker(m_freeBlockLock);
+    if (!m_numberOfFreeBlocks) {
+        ASSERT(m_freeBlocks.isEmpty());
+        return 0;
+    }
+
+    ASSERT(!m_freeBlocks.isEmpty());
+    m_numberOfFreeBlocks--;
+    return m_freeBlocks.removeHead();
+}
+
+inline void BlockAllocator::deallocate(HeapBlock* block)
+{
+    MutexLocker locker(m_freeBlockLock);
+    m_freeBlocks.push(block);
+    m_numberOfFreeBlocks++;
+}
+
+} // namespace JSC
+
+#endif // BlockAllocator_h

Modified: trunk/Source/_javascript_Core/heap/CopiedSpace.cpp (115589 => 115590)


--- trunk/Source/_javascript_Core/heap/CopiedSpace.cpp	2012-04-29 01:32:16 UTC (rev 115589)
+++ trunk/Source/_javascript_Core/heap/CopiedSpace.cpp	2012-04-29 01:44:37 UTC (rev 115590)
@@ -188,11 +188,7 @@
         }
 
         m_toSpaceSet.remove(block);
-        {
-            MutexLocker locker(m_heap->m_freeBlockLock);
-            m_heap->m_freeBlocks.push(block);
-            m_heap->m_numberOfFreeBlocks++;
-        }
+        m_heap->blockAllocator().deallocate(block);
     }
 
     CopiedBlock* curr = static_cast<CopiedBlock*>(m_oversizeBlocks.head());
@@ -215,16 +211,8 @@
 
 CheckedBoolean CopiedSpace::getFreshBlock(AllocationEffort allocationEffort, CopiedBlock** outBlock)
 {
-    HeapBlock* heapBlock = 0;
     CopiedBlock* block = 0;
-    {
-        MutexLocker locker(m_heap->m_freeBlockLock);
-        if (!m_heap->m_freeBlocks.isEmpty()) {
-            heapBlock = m_heap->m_freeBlocks.removeHead();
-            m_heap->m_numberOfFreeBlocks--;
-        }
-    }
-    if (heapBlock)
+    if (HeapBlock* heapBlock = m_heap->blockAllocator().allocate())
         block = new (NotNull, heapBlock) CopiedBlock(heapBlock->m_allocation);
     else if (allocationEffort == AllocationMustSucceed) {
         if (!allocateNewBlock(&block)) {
@@ -251,24 +239,14 @@
 
 void CopiedSpace::freeAllBlocks()
 {
-    while (!m_toSpace->isEmpty()) {
-        CopiedBlock* block = static_cast<CopiedBlock*>(m_toSpace->removeHead());
-        MutexLocker locker(m_heap->m_freeBlockLock);
-        m_heap->m_freeBlocks.append(block);
-        m_heap->m_numberOfFreeBlocks++;
-    }
+    while (!m_toSpace->isEmpty())
+        m_heap->blockAllocator().deallocate(m_toSpace->removeHead());
 
-    while (!m_fromSpace->isEmpty()) {
-        CopiedBlock* block = static_cast<CopiedBlock*>(m_fromSpace->removeHead());
-        MutexLocker locker(m_heap->m_freeBlockLock);
-        m_heap->m_freeBlocks.append(block);
-        m_heap->m_numberOfFreeBlocks++;
-    }
+    while (!m_fromSpace->isEmpty())
+        m_heap->blockAllocator().deallocate(m_fromSpace->removeHead());
 
-    while (!m_oversizeBlocks.isEmpty()) {
-        CopiedBlock* block = static_cast<CopiedBlock*>(m_oversizeBlocks.removeHead());
-        block->m_allocation.deallocate();
-    }
+    while (!m_oversizeBlocks.isEmpty())
+        m_oversizeBlocks.removeHead()->m_allocation.deallocate();
 }
 
 size_t CopiedSpace::size()

Modified: trunk/Source/_javascript_Core/heap/CopiedSpaceInlineMethods.h (115589 => 115590)


--- trunk/Source/_javascript_Core/heap/CopiedSpaceInlineMethods.h	2012-04-29 01:32:16 UTC (rev 115589)
+++ trunk/Source/_javascript_Core/heap/CopiedSpaceInlineMethods.h	2012-04-29 01:44:37 UTC (rev 115590)
@@ -63,11 +63,7 @@
 
 inline void CopiedSpace::recycleBlock(CopiedBlock* block)
 {
-    {
-        MutexLocker locker(m_heap->m_freeBlockLock);
-        m_heap->m_freeBlocks.push(block);
-        m_heap->m_numberOfFreeBlocks++;
-    }
+    m_heap->blockAllocator().deallocate(block);
 
     {
         MutexLocker locker(m_loanedBlocksLock);

Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (115589 => 115590)


--- trunk/Source/_javascript_Core/heap/Heap.cpp	2012-04-29 01:32:16 UTC (rev 115589)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp	2012-04-29 01:44:37 UTC (rev 115590)
@@ -319,7 +319,6 @@
     , m_operationInProgress(NoOperation)
     , m_objectSpace(this)
     , m_storageSpace(this)
-    , m_blockFreeingThreadShouldQuit(false)
     , m_markListSet(0)
     , m_activityCallback(DefaultGCActivityCallback::create(this))
     , m_machineThreads(this)
@@ -332,10 +331,6 @@
     , m_lastGCLength(0)
     , m_lastCodeDiscardTime(WTF::currentTime())
 {
-    m_numberOfFreeBlocks = 0;
-    m_blockFreeingThread = createThread(blockFreeingThreadStartFunc, this, "_javascript_Core::BlockFree");
-    
-    ASSERT(m_blockFreeingThread);
     m_storageSpace.init();
 }
 
@@ -345,13 +340,6 @@
 
     m_objectSpace.shrink();
     m_storageSpace.freeAllBlocks();
-    releaseFreeBlocks();
-    {
-        MutexLocker locker(m_freeBlockLock);
-        m_blockFreeingThreadShouldQuit = true;
-        m_freeBlockCondition.broadcast();
-    }
-    waitForThreadCompletion(m_blockFreeingThread);
 
     ASSERT(!size());
     ASSERT(!capacity());
@@ -380,67 +368,6 @@
 #endif
 }
 
-void Heap::waitForRelativeTimeWhileHoldingLock(double relative)
-{
-    if (m_blockFreeingThreadShouldQuit)
-        return;
-    m_freeBlockCondition.timedWait(m_freeBlockLock, currentTime() + relative);
-}
-
-void Heap::waitForRelativeTime(double relative)
-{
-    // If this returns early, that's fine, so long as it doesn't do it too
-    // frequently. It would only be a bug if this function failed to return
-    // when it was asked to do so.
-    
-    MutexLocker locker(m_freeBlockLock);
-    waitForRelativeTimeWhileHoldingLock(relative);
-}
-
-void Heap::blockFreeingThreadStartFunc(void* heap)
-{
-    static_cast<Heap*>(heap)->blockFreeingThreadMain();
-}
-
-void Heap::blockFreeingThreadMain()
-{
-    while (!m_blockFreeingThreadShouldQuit) {
-        // Generally wait for one second before scavenging free blocks. This
-        // may return early, particularly when we're being asked to quit.
-        waitForRelativeTime(1.0);
-        if (m_blockFreeingThreadShouldQuit)
-            break;
-        
-        // Now process the list of free blocks. Keep freeing until half of the
-        // blocks that are currently on the list are gone. Assume that a size_t
-        // field can be accessed atomically.
-        size_t currentNumberOfFreeBlocks = m_numberOfFreeBlocks;
-        if (!currentNumberOfFreeBlocks)
-            continue;
-        
-        size_t desiredNumberOfFreeBlocks = currentNumberOfFreeBlocks / 2;
-        
-        while (!m_blockFreeingThreadShouldQuit) {
-            MarkedBlock* block;
-            {
-                MutexLocker locker(m_freeBlockLock);
-                if (m_numberOfFreeBlocks <= desiredNumberOfFreeBlocks)
-                    block = 0;
-                else {
-                    block = static_cast<MarkedBlock*>(m_freeBlocks.removeHead());
-                    ASSERT(block);
-                    m_numberOfFreeBlocks--;
-                }
-            }
-            
-            if (!block)
-                break;
-            
-            MarkedBlock::destroy(block);
-        }
-    }
-}
-
 void Heap::reportExtraMemoryCostSlowCase(size_t cost)
 {
     // Our frequency of garbage collection tries to balance memory use against speed
@@ -912,33 +839,6 @@
     return true;
 }
 
-void Heap::freeBlocks(MarkedBlock* head)
-{
-    m_objectSpace.freeBlocks(head);
-}
-
-void Heap::releaseFreeBlocks()
-{
-    while (true) {
-        MarkedBlock* block;
-        {
-            MutexLocker locker(m_freeBlockLock);
-            if (!m_numberOfFreeBlocks)
-                block = 0;
-            else {
-                block = static_cast<MarkedBlock*>(m_freeBlocks.removeHead());
-                ASSERT(block);
-                m_numberOfFreeBlocks--;
-            }
-        }
-        
-        if (!block)
-            break;
-        
-        MarkedBlock::destroy(block);
-    }
-}
-
 void Heap::addFinalizer(JSCell* cell, Finalizer finalizer)
 {
     WeakSet::allocate(cell, &m_finalizerOwner, reinterpret_cast<void*>(finalizer)); // Balanced by FinalizerOwner::finalize().

Modified: trunk/Source/_javascript_Core/heap/Heap.h (115589 => 115590)


--- trunk/Source/_javascript_Core/heap/Heap.h	2012-04-29 01:32:16 UTC (rev 115589)
+++ trunk/Source/_javascript_Core/heap/Heap.h	2012-04-29 01:44:37 UTC (rev 115590)
@@ -22,6 +22,7 @@
 #ifndef Heap_h
 #define Heap_h
 
+#include "BlockAllocator.h"
 #include "DFGCodeBlocks.h"
 #include "HandleSet.h"
 #include "HandleStack.h"
@@ -33,8 +34,6 @@
 #include "WeakHandleOwner.h"
 #include "WeakSet.h"
 #include "WriteBarrierSupport.h"
-#include <wtf/DoublyLinkedList.h>
-#include <wtf/Forward.h>
 #include <wtf/HashCountedSet.h>
 #include <wtf/HashSet.h>
 
@@ -184,7 +183,6 @@
         void canonicalizeCellLivenessData();
 
         void resetAllocators();
-        void freeBlocks(MarkedBlock*);
 
         void clearMarks();
         void markRoots(bool fullGC);
@@ -193,16 +191,11 @@
         void harvestWeakReferences();
         void finalizeUnconditionalFinalizers();
         
-        void releaseFreeBlocks();
         void sweep();
 
         RegisterFile& registerFile();
+        BlockAllocator& blockAllocator();
 
-        void waitForRelativeTimeWhileHoldingLock(double relative);
-        void waitForRelativeTime(double relative);
-        void blockFreeingThreadMain();
-        static void blockFreeingThreadStartFunc(void* heap);
-        
         const HeapSize m_heapSize;
         const size_t m_minBytesPerCycle;
         size_t m_sizeAfterLastCollect;
@@ -214,13 +207,7 @@
         MarkedSpace m_objectSpace;
         CopiedSpace m_storageSpace;
 
-        DoublyLinkedList<HeapBlock> m_freeBlocks;
-        size_t m_numberOfFreeBlocks;
-        
-        ThreadIdentifier m_blockFreeingThread;
-        Mutex m_freeBlockLock;
-        ThreadCondition m_freeBlockCondition;
-        bool m_blockFreeingThreadShouldQuit;
+        BlockAllocator m_blockAllocator;
 
 #if ENABLE(SIMPLE_HEAP_PROFILING)
         VTableSpectrum m_destroyedTypeCounts;
@@ -372,6 +359,11 @@
         return m_storageSpace.tryReallocate(ptr, oldSize, newSize);
     }
 
+    inline BlockAllocator& Heap::blockAllocator()
+    {
+        return m_blockAllocator;
+    }
+
 } // namespace JSC
 
 #endif // Heap_h

Modified: trunk/Source/_javascript_Core/heap/MarkedAllocator.cpp (115589 => 115590)


--- trunk/Source/_javascript_Core/heap/MarkedAllocator.cpp	2012-04-29 01:32:16 UTC (rev 115589)
+++ trunk/Source/_javascript_Core/heap/MarkedAllocator.cpp	2012-04-29 01:44:37 UTC (rev 115590)
@@ -82,17 +82,7 @@
     
 MarkedBlock* MarkedAllocator::allocateBlock(AllocationEffort allocationEffort)
 {
-    MarkedBlock* block;
-    
-    {
-        MutexLocker locker(m_heap->m_freeBlockLock);
-        if (m_heap->m_numberOfFreeBlocks) {
-            block = static_cast<MarkedBlock*>(m_heap->m_freeBlocks.removeHead());
-            ASSERT(block);
-            m_heap->m_numberOfFreeBlocks--;
-        } else
-            block = 0;
-    }
+    MarkedBlock* block = static_cast<MarkedBlock*>(m_heap->blockAllocator().allocate());
     if (block)
         block = MarkedBlock::recycle(block, m_heap, m_cellSize, m_cellsNeedDestruction);
     else if (allocationEffort == AllocationCanFail)

Modified: trunk/Source/_javascript_Core/heap/MarkedSpace.cpp (115589 => 115590)


--- trunk/Source/_javascript_Core/heap/MarkedSpace.cpp	2012-04-29 01:32:16 UTC (rev 115589)
+++ trunk/Source/_javascript_Core/heap/MarkedSpace.cpp	2012-04-29 01:44:37 UTC (rev 115590)
@@ -79,9 +79,8 @@
         
         m_blocks.remove(block);
         block->sweep();
-        MutexLocker locker(m_heap->m_freeBlockLock);
-        m_heap->m_freeBlocks.append(block);
-        m_heap->m_numberOfFreeBlocks++;
+
+        m_heap->blockAllocator().deallocate(block);
     }
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to