Title: [108267] trunk/Source/_javascript_Core
Revision
108267
Author
mhahnenb...@apple.com
Date
2012-02-20 15:42:11 -0800 (Mon, 20 Feb 2012)

Log Message

Factor out allocation in CopySpace into a separate CopyAllocator
https://bugs.webkit.org/show_bug.cgi?id=78610

Reviewed by Oliver Hunt.

Added a new CopyAllocator class, which allows us to do allocations without 
having to load the current offset and store the current offset in the current 
block. This change will allow us to easily do inline assembly in the JIT for 
array allocations.

* GNUmakefile.list.am:
* _javascript_Core.gypi:
* _javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj:
* _javascript_Core.xcodeproj/project.pbxproj:
* heap/CopiedAllocator.h: Added.
(JSC):
(CopiedAllocator):
(JSC::CopiedAllocator::currentBlock):
(JSC::CopiedAllocator::CopiedAllocator):
(JSC::CopiedAllocator::allocate):
(JSC::CopiedAllocator::fitsInCurrentBlock):
(JSC::CopiedAllocator::wasLastAllocation):
(JSC::CopiedAllocator::startedCopying):
(JSC::CopiedAllocator::resetCurrentBlock):
(JSC::CopiedAllocator::currentUtilization):
(JSC::CopiedAllocator::resetLastAllocation):
* heap/CopiedBlock.h:
(CopiedBlock):
* heap/CopiedSpace.cpp: Moved some stuff from CopiedSpaceInlineMethods to here because we 
weren't really getting any benefits from having such big functions in a header file.
(JSC::CopiedSpace::CopiedSpace):
(JSC):
(JSC::CopiedSpace::init):
(JSC::CopiedSpace::tryAllocateSlowCase):
(JSC::CopiedSpace::tryAllocateOversize):
(JSC::CopiedSpace::tryReallocate):
(JSC::CopiedSpace::tryReallocateOversize):
(JSC::CopiedSpace::doneFillingBlock):
(JSC::CopiedSpace::doneCopying):
(JSC::CopiedSpace::getFreshBlock):
* heap/CopiedSpace.h:
(CopiedSpace):
* heap/CopiedSpaceInlineMethods.h:
(JSC):
(JSC::CopiedSpace::startedCopying):
(JSC::CopiedSpace::addNewBlock):
(JSC::CopiedSpace::allocateNewBlock):
(JSC::CopiedSpace::fitsInBlock):
(JSC::CopiedSpace::tryAllocate):
(JSC::CopiedSpace::allocateFromBlock):
* heap/Heap.cpp:
(JSC::Heap::collectAllGarbage):
* heap/HeapBlock.h:
(HeapBlock):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (108266 => 108267)


--- trunk/Source/_javascript_Core/ChangeLog	2012-02-20 23:38:23 UTC (rev 108266)
+++ trunk/Source/_javascript_Core/ChangeLog	2012-02-20 23:42:11 UTC (rev 108267)
@@ -1,3 +1,60 @@
+2012-02-20  Mark Hahnenberg  <mhahnenb...@apple.com>
+
+        Factor out allocation in CopySpace into a separate CopyAllocator
+        https://bugs.webkit.org/show_bug.cgi?id=78610
+
+        Reviewed by Oliver Hunt.
+
+        Added a new CopyAllocator class, which allows us to do allocations without 
+        having to load the current offset and store the current offset in the current 
+        block. This change will allow us to easily do inline assembly in the JIT for 
+        array allocations.
+
+        * GNUmakefile.list.am:
+        * _javascript_Core.gypi:
+        * _javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * heap/CopiedAllocator.h: Added.
+        (JSC):
+        (CopiedAllocator):
+        (JSC::CopiedAllocator::currentBlock):
+        (JSC::CopiedAllocator::CopiedAllocator):
+        (JSC::CopiedAllocator::allocate):
+        (JSC::CopiedAllocator::fitsInCurrentBlock):
+        (JSC::CopiedAllocator::wasLastAllocation):
+        (JSC::CopiedAllocator::startedCopying):
+        (JSC::CopiedAllocator::resetCurrentBlock):
+        (JSC::CopiedAllocator::currentUtilization):
+        (JSC::CopiedAllocator::resetLastAllocation):
+        * heap/CopiedBlock.h:
+        (CopiedBlock):
+        * heap/CopiedSpace.cpp: Moved some stuff from CopiedSpaceInlineMethods to here because we 
+        weren't really getting any benefits from having such big functions in a header file.
+        (JSC::CopiedSpace::CopiedSpace):
+        (JSC):
+        (JSC::CopiedSpace::init):
+        (JSC::CopiedSpace::tryAllocateSlowCase):
+        (JSC::CopiedSpace::tryAllocateOversize):
+        (JSC::CopiedSpace::tryReallocate):
+        (JSC::CopiedSpace::tryReallocateOversize):
+        (JSC::CopiedSpace::doneFillingBlock):
+        (JSC::CopiedSpace::doneCopying):
+        (JSC::CopiedSpace::getFreshBlock):
+        * heap/CopiedSpace.h:
+        (CopiedSpace):
+        * heap/CopiedSpaceInlineMethods.h:
+        (JSC):
+        (JSC::CopiedSpace::startedCopying):
+        (JSC::CopiedSpace::addNewBlock):
+        (JSC::CopiedSpace::allocateNewBlock):
+        (JSC::CopiedSpace::fitsInBlock):
+        (JSC::CopiedSpace::tryAllocate):
+        (JSC::CopiedSpace::allocateFromBlock):
+        * heap/Heap.cpp:
+        (JSC::Heap::collectAllGarbage):
+        * heap/HeapBlock.h:
+        (HeapBlock):
+
 2012-02-20  Patrick Gansterer  <par...@webkit.org>
 
         Fix Visual Studio 2010 build.

Modified: trunk/Source/_javascript_Core/GNUmakefile.list.am (108266 => 108267)


--- trunk/Source/_javascript_Core/GNUmakefile.list.am	2012-02-20 23:38:23 UTC (rev 108266)
+++ trunk/Source/_javascript_Core/GNUmakefile.list.am	2012-02-20 23:42:11 UTC (rev 108267)
@@ -193,6 +193,7 @@
 	Source/_javascript_Core/dfg/DFGVariableAccessData.h \
 	Source/_javascript_Core/dfg/DFGVirtualRegisterAllocationPhase.cpp \
 	Source/_javascript_Core/dfg/DFGVirtualRegisterAllocationPhase.h \
+	Source/_javascript_Core/heap/CopiedAllocator.h \
 	Source/_javascript_Core/heap/CopiedBlock.h \
 	Source/_javascript_Core/heap/CopiedSpace.cpp \
 	Source/_javascript_Core/heap/CopiedSpace.h \

Modified: trunk/Source/_javascript_Core/_javascript_Core.gypi (108266 => 108267)


--- trunk/Source/_javascript_Core/_javascript_Core.gypi	2012-02-20 23:38:23 UTC (rev 108266)
+++ trunk/Source/_javascript_Core/_javascript_Core.gypi	2012-02-20 23:42:11 UTC (rev 108267)
@@ -27,6 +27,7 @@
             'API/OpaqueJSString.h',
             'assembler/MacroAssemblerCodeRef.h',
             'bytecode/Opcode.h',
+            'heap/CopiedAllocator.h',
             'heap/CopiedBlock.h',
             'heap/CopiedSpace.h',
             'heap/CopiedSpaceInlineMethods.h',

Modified: trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj (108266 => 108267)


--- trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj	2012-02-20 23:38:23 UTC (rev 108266)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.vcproj	2012-02-20 23:42:11 UTC (rev 108267)
@@ -2038,6 +2038,10 @@
 			Name="heap"
 			>
                             <File
+                                    RelativePath="..\..\heap\CopiedAllocator.h"
+                                    >
+                            </File>
+                            <File
                                     RelativePath="..\..\heap\CopiedBlock.h"
                                     >
                             </File>

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (108266 => 108267)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2012-02-20 23:38:23 UTC (rev 108266)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2012-02-20 23:42:11 UTC (rev 108267)
@@ -761,6 +761,7 @@
 		C2C8D03114A3CEFC00578E65 /* HeapBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = C2C8D02F14A3CEFC00578E65 /* HeapBlock.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		C2D9CA1314BCC04600304B46 /* CheckedBoolean.h in Headers */ = {isa = PBXBuildFile; fileRef = C2D9CA1214BCC04600304B46 /* CheckedBoolean.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		C2EAA3FA149A835E00FCE112 /* CopiedSpace.h in Headers */ = {isa = PBXBuildFile; fileRef = C2EAA3F8149A830800FCE112 /* CopiedSpace.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		C2EAD2FC14F0249800A4B159 /* CopiedAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = C2EAD2FB14F0249800A4B159 /* CopiedAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		C2EE59A013FC973F009CEAFE /* DecimalNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = C2EE599E13FC972A009CEAFE /* DecimalNumber.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		C2EE59A113FC9768009CEAFE /* DecimalNumber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2EE599D13FC972A009CEAFE /* DecimalNumber.cpp */; };
 		D7A46A4F1338FFEA00ED695C /* DynamicAnnotations.h in Headers */ = {isa = PBXBuildFile; fileRef = D75AF59612F8CB9500FC0ADF /* DynamicAnnotations.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -1578,6 +1579,7 @@
 		C2C8D02F14A3CEFC00578E65 /* HeapBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapBlock.h; sourceTree = "<group>"; };
 		C2D9CA1214BCC04600304B46 /* CheckedBoolean.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CheckedBoolean.h; sourceTree = "<group>"; };
 		C2EAA3F8149A830800FCE112 /* CopiedSpace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopiedSpace.h; sourceTree = "<group>"; };
+		C2EAD2FB14F0249800A4B159 /* CopiedAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopiedAllocator.h; sourceTree = "<group>"; };
 		C2EE599D13FC972A009CEAFE /* DecimalNumber.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DecimalNumber.cpp; sourceTree = "<group>"; };
 		C2EE599E13FC972A009CEAFE /* DecimalNumber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DecimalNumber.h; sourceTree = "<group>"; };
 		D21202280AD4310C00ED79B6 /* DateConversion.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DateConversion.cpp; sourceTree = "<group>"; };
@@ -1844,6 +1846,7 @@
 		142E312A134FF0A600AFADB5 /* heap */ = {
 			isa = PBXGroup;
 			children = (
+				C2EAD2FB14F0249800A4B159 /* CopiedAllocator.h */,
 				C2C8D02E14A3CEFC00578E65 /* CopiedBlock.h */,
 				C240305314B404C90079EB64 /* CopiedSpace.cpp */,
 				C2EAA3F8149A830800FCE112 /* CopiedSpace.h */,
@@ -2801,6 +2804,7 @@
 				A73BE169148420520091204B /* ArrayBuffer.h in Headers */,
 				C2D9CA1314BCC04600304B46 /* CheckedBoolean.h in Headers */,
 				A73BE16B148420520091204B /* ArrayBufferView.h in Headers */,
+				C2EAD2FC14F0249800A4B159 /* CopiedAllocator.h in Headers */,
 				C2B916C214DA014E00CBAC86 /* MarkedAllocator.h in Headers */,
 				BC18C3E60E16F5CD00B34460 /* ArrayConstructor.h in Headers */,
 				BC18C3E70E16F5CD00B34460 /* ArrayPrototype.h in Headers */,

Added: trunk/Source/_javascript_Core/heap/CopiedAllocator.h (0 => 108267)


--- trunk/Source/_javascript_Core/heap/CopiedAllocator.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/heap/CopiedAllocator.h	2012-02-20 23:42:11 UTC (rev 108267)
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2011 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 CopiedAllocator_h
+#define CopiedAllocator_h
+
+#include "CopiedBlock.h"
+
+namespace JSC {
+
+class CopiedAllocator {
+public:
+    CopiedAllocator();
+    void* allocate(size_t);
+    bool fitsInCurrentBlock(size_t);
+    bool wasLastAllocation(void*, size_t);
+    void startedCopying();
+    void resetCurrentBlock(CopiedBlock*);
+    void resetLastAllocation(void*);
+    size_t currentUtilization();
+
+private:
+    CopiedBlock* currentBlock() { return m_currentBlock; }
+
+    char* m_currentOffset;
+    CopiedBlock* m_currentBlock; 
+};
+
+inline CopiedAllocator::CopiedAllocator()
+    : m_currentOffset(0)
+    , m_currentBlock(0)
+{
+}
+
+inline void* CopiedAllocator::allocate(size_t bytes)
+{
+    ASSERT(m_currentOffset);
+    ASSERT(fitsInCurrentBlock(bytes));
+    void* ptr = static_cast<void*>(m_currentOffset);
+    m_currentOffset += bytes;
+    ASSERT(isPointerAligned(ptr));
+    return ptr;
+}
+
+inline bool CopiedAllocator::fitsInCurrentBlock(size_t bytes)
+{
+    return m_currentOffset + bytes < reinterpret_cast<char*>(m_currentBlock) + HeapBlock::s_blockSize && m_currentOffset + bytes > m_currentOffset;
+}
+
+inline bool CopiedAllocator::wasLastAllocation(void* ptr, size_t size)
+{
+    return static_cast<char*>(ptr) + size == m_currentOffset && ptr > m_currentBlock && ptr < reinterpret_cast<char*>(m_currentBlock) + HeapBlock::s_blockSize;
+}
+
+inline void CopiedAllocator::startedCopying()
+{
+    if (m_currentBlock)
+        m_currentBlock->m_offset = static_cast<void*>(m_currentOffset);
+    m_currentOffset = 0;
+    m_currentBlock = 0;
+}
+
+inline void CopiedAllocator::resetCurrentBlock(CopiedBlock* newBlock)
+{
+    if (m_currentBlock)
+        m_currentBlock->m_offset = static_cast<void*>(m_currentOffset);
+    m_currentBlock = newBlock;
+    m_currentOffset = static_cast<char*>(newBlock->m_offset);
+}
+
+inline size_t CopiedAllocator::currentUtilization()
+{
+    return static_cast<size_t>(m_currentOffset - m_currentBlock->m_payload);
+}
+
+inline void CopiedAllocator::resetLastAllocation(void* ptr)
+{
+    m_currentOffset = static_cast<char*>(ptr);
+}
+
+} // namespace JSC
+
+#endif

Modified: trunk/Source/_javascript_Core/heap/CopiedBlock.h (108266 => 108267)


--- trunk/Source/_javascript_Core/heap/CopiedBlock.h	2012-02-20 23:38:23 UTC (rev 108266)
+++ trunk/Source/_javascript_Core/heap/CopiedBlock.h	2012-02-20 23:42:11 UTC (rev 108267)
@@ -34,6 +34,7 @@
 
 class CopiedBlock : public HeapBlock {
     friend class CopiedSpace;
+    friend class CopiedAllocator;
 public:
     CopiedBlock(PageAllocationAligned& allocation)
         : HeapBlock(allocation)

Modified: trunk/Source/_javascript_Core/heap/CopiedSpace.cpp (108266 => 108267)


--- trunk/Source/_javascript_Core/heap/CopiedSpace.cpp	2012-02-20 23:38:23 UTC (rev 108266)
+++ trunk/Source/_javascript_Core/heap/CopiedSpace.cpp	2012-02-20 23:42:11 UTC (rev 108267)
@@ -30,20 +30,235 @@
 
 namespace JSC {
 
+CopiedSpace::CopiedSpace(Heap* heap)
+    : m_heap(heap)
+    , m_toSpace(0)
+    , m_fromSpace(0)
+    , m_totalMemoryAllocated(0)
+    , m_totalMemoryUtilized(0)
+    , m_inCopyingPhase(false)
+    , m_numberOfLoanedBlocks(0)
+{
+}
+
+void CopiedSpace::init()
+{
+    m_toSpace = &m_blocks1;
+    m_fromSpace = &m_blocks2;
+    
+    m_totalMemoryAllocated += HeapBlock::s_blockSize * s_initialBlockNum;
+
+    if (!addNewBlock())
+        CRASH();
+}   
+
 CheckedBoolean CopiedSpace::tryAllocateSlowCase(size_t bytes, void** outPtr)
 {
     if (isOversize(bytes))
         return tryAllocateOversize(bytes, outPtr);
     
-    m_totalMemoryUtilized += static_cast<size_t>(static_cast<char*>(m_currentBlock->m_offset) - m_currentBlock->m_payload);
+    m_totalMemoryUtilized += m_allocator.currentUtilization();
     if (!addNewBlock()) {
         *outPtr = 0;
         return false;
     }
-    m_toSpaceFilter.add(reinterpret_cast<Bits>(m_currentBlock));
-    m_toSpaceSet.add(m_currentBlock);
-    *outPtr = allocateFromBlock(m_currentBlock, bytes);
+    *outPtr = m_allocator.allocate(bytes);
+    ASSERT(*outPtr);
     return true;
 }
 
+CheckedBoolean CopiedSpace::tryAllocateOversize(size_t bytes, void** outPtr)
+{
+    ASSERT(isOversize(bytes));
+    
+    size_t blockSize = WTF::roundUpToMultipleOf<s_pageSize>(sizeof(CopiedBlock) + bytes);
+    PageAllocationAligned allocation = PageAllocationAligned::allocate(blockSize, s_pageSize, OSAllocator::JSGCHeapPages);
+    if (!static_cast<bool>(allocation)) {
+        *outPtr = 0;
+        return false;
+    }
+    CopiedBlock* block = new (NotNull, allocation.base()) CopiedBlock(allocation);
+    m_oversizeBlocks.push(block);
+    ASSERT(isPointerAligned(block->m_offset));
+
+    m_oversizeFilter.add(reinterpret_cast<Bits>(block));
+    
+    m_totalMemoryAllocated += blockSize;
+    m_totalMemoryUtilized += bytes;
+
+    *outPtr = block->m_offset;
+    return true;
+}
+
+CheckedBoolean CopiedSpace::tryReallocate(void** ptr, size_t oldSize, size_t newSize)
+{
+    if (oldSize >= newSize)
+        return true;
+    
+    void* oldPtr = *ptr;
+    ASSERT(!m_heap->globalData()->isInitializingObject());
+
+    if (isOversize(oldSize) || isOversize(newSize))
+        return tryReallocateOversize(ptr, oldSize, newSize);
+
+    if (m_allocator.wasLastAllocation(oldPtr, oldSize)) {
+        m_allocator.resetLastAllocation(oldPtr);
+        if (m_allocator.fitsInCurrentBlock(newSize)) {
+            m_totalMemoryUtilized += newSize - oldSize;
+            return m_allocator.allocate(newSize);
+        }
+    }
+    m_totalMemoryUtilized -= oldSize;
+
+    void* result = 0;
+    if (!tryAllocate(newSize, &result)) {
+        *ptr = 0;
+        return false;
+    }
+    memcpy(result, oldPtr, oldSize);
+    *ptr = result;
+    return true;
+}
+
+CheckedBoolean CopiedSpace::tryReallocateOversize(void** ptr, size_t oldSize, size_t newSize)
+{
+    ASSERT(isOversize(oldSize) || isOversize(newSize));
+    ASSERT(newSize > oldSize);
+
+    void* oldPtr = *ptr;
+    
+    void* newPtr = 0;
+    if (!tryAllocateOversize(newSize, &newPtr)) {
+        *ptr = 0;
+        return false;
+    }
+    memcpy(newPtr, oldPtr, oldSize);
+
+    if (isOversize(oldSize)) {
+        CopiedBlock* oldBlock = oversizeBlockFor(oldPtr);
+        m_oversizeBlocks.remove(oldBlock);
+        oldBlock->m_allocation.deallocate();
+        m_totalMemoryAllocated -= oldSize + sizeof(CopiedBlock);
+    }
+    
+    m_totalMemoryUtilized -= oldSize;
+
+    *ptr = newPtr;
+    return true;
+}
+
+void CopiedSpace::doneFillingBlock(CopiedBlock* block)
+{
+    ASSERT(block);
+    ASSERT(block->m_offset < reinterpret_cast<char*>(block) + HeapBlock::s_blockSize);
+    ASSERT(m_inCopyingPhase);
+
+    if (block->m_offset == block->m_payload) {
+        recycleBlock(block);
+        return;
+    }
+
+    {
+        MutexLocker locker(m_toSpaceLock);
+        m_toSpace->push(block);
+        m_toSpaceSet.add(block);
+        m_toSpaceFilter.add(reinterpret_cast<Bits>(block));
+    }
+
+    {
+        MutexLocker locker(m_memoryStatsLock);
+        m_totalMemoryUtilized += static_cast<size_t>(static_cast<char*>(block->m_offset) - block->m_payload);
+    }
+
+    {
+        MutexLocker locker(m_loanedBlocksLock);
+        ASSERT(m_numberOfLoanedBlocks > 0);
+        m_numberOfLoanedBlocks--;
+        if (!m_numberOfLoanedBlocks)
+            m_loanedBlocksCondition.signal();
+    }
+}
+
+void CopiedSpace::doneCopying()
+{
+    {
+        MutexLocker locker(m_loanedBlocksLock);
+        while (m_numberOfLoanedBlocks > 0)
+            m_loanedBlocksCondition.wait(m_loanedBlocksLock);
+    }
+
+    ASSERT(m_inCopyingPhase);
+    m_inCopyingPhase = false;
+    while (!m_fromSpace->isEmpty()) {
+        CopiedBlock* block = static_cast<CopiedBlock*>(m_fromSpace->removeHead());
+        if (block->m_isPinned) {
+            block->m_isPinned = false;
+            m_toSpace->push(block);
+            continue;
+        }
+
+        m_toSpaceSet.remove(block);
+        {
+            MutexLocker locker(m_heap->m_freeBlockLock);
+            m_heap->m_freeBlocks.push(block);
+            m_heap->m_numberOfFreeBlocks++;
+        }
+    }
+
+    CopiedBlock* curr = static_cast<CopiedBlock*>(m_oversizeBlocks.head());
+    while (curr) {
+        CopiedBlock* next = static_cast<CopiedBlock*>(curr->next());
+        if (!curr->m_isPinned) {
+            m_oversizeBlocks.remove(curr);
+            m_totalMemoryAllocated -= curr->m_allocation.size();
+            m_totalMemoryUtilized -= curr->m_allocation.size() - sizeof(CopiedBlock);
+            curr->m_allocation.deallocate();
+        } else
+            curr->m_isPinned = false;
+        curr = next;
+    }
+
+    if (!m_toSpace->head()) {
+        if (!addNewBlock())
+            CRASH();
+    } else
+        m_allocator.resetCurrentBlock(static_cast<CopiedBlock*>(m_toSpace->head()));
+}
+
+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)
+        block = new (NotNull, heapBlock) CopiedBlock(heapBlock->m_allocation);
+    else if (allocationEffort == AllocationMustSucceed) {
+        if (!allocateNewBlock(&block)) {
+            *outBlock = 0;
+            ASSERT_NOT_REACHED();
+            return false;
+        }
+    } else {
+        ASSERT(allocationEffort == AllocationCanFail);
+        if (m_heap->waterMark() >= m_heap->highWaterMark() && m_heap->m_isSafeToCollect)
+            m_heap->collect(Heap::DoNotSweep);
+        
+        if (!getFreshBlock(AllocationMustSucceed, &block)) {
+            *outBlock = 0;
+            ASSERT_NOT_REACHED();
+            return false;
+        }
+    }
+    ASSERT(block);
+    ASSERT(isPointerAligned(block->m_offset));
+    *outBlock = block;
+    return true;
+}
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/heap/CopiedSpace.h (108266 => 108267)


--- trunk/Source/_javascript_Core/heap/CopiedSpace.h	2012-02-20 23:38:23 UTC (rev 108266)
+++ trunk/Source/_javascript_Core/heap/CopiedSpace.h	2012-02-20 23:42:11 UTC (rev 108267)
@@ -26,6 +26,7 @@
 #ifndef CopiedSpace_h
 #define CopiedSpace_h
 
+#include "CopiedAllocator.h"
 #include "HeapBlock.h"
 #include "TinyBloomFilter.h"
 #include <wtf/Assertions.h>
@@ -70,7 +71,6 @@
     CheckedBoolean tryAllocateSlowCase(size_t, void**);
     CheckedBoolean addNewBlock();
     CheckedBoolean allocateNewBlock(CopiedBlock**);
-    bool fitsInCurrentBlock(size_t);
     
     static void* allocateFromBlock(CopiedBlock*, size_t);
     CheckedBoolean tryAllocateOversize(size_t, void**);
@@ -87,7 +87,7 @@
 
     Heap* m_heap;
 
-    CopiedBlock* m_currentBlock;
+    CopiedAllocator m_allocator;
 
     TinyBloomFilter m_toSpaceFilter;
     TinyBloomFilter m_oversizeFilter;
@@ -112,12 +112,11 @@
     ThreadCondition m_loanedBlocksCondition;
     size_t m_numberOfLoanedBlocks;
 
-    static const size_t s_blockSize = 64 * KB;
     static const size_t s_maxAllocationSize = 32 * KB;
     static const size_t s_pageSize = 4 * KB;
     static const size_t s_pageMask = ~(s_pageSize - 1);
     static const size_t s_initialBlockNum = 16;
-    static const size_t s_blockMask = ~(s_blockSize - 1);
+    static const size_t s_blockMask = ~(HeapBlock::s_blockSize - 1);
 };
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/heap/CopiedSpaceInlineMethods.h (108266 => 108267)


--- trunk/Source/_javascript_Core/heap/CopiedSpaceInlineMethods.h	2012-02-20 23:38:23 UTC (rev 108266)
+++ trunk/Source/_javascript_Core/heap/CopiedSpaceInlineMethods.h	2012-02-20 23:42:11 UTC (rev 108267)
@@ -35,29 +35,6 @@
 
 namespace JSC {
 
-inline CopiedSpace::CopiedSpace(Heap* heap)
-    : m_heap(heap)
-    , m_currentBlock(0)
-    , m_toSpace(0)
-    , m_fromSpace(0)
-    , m_totalMemoryAllocated(0)
-    , m_totalMemoryUtilized(0)
-    , m_inCopyingPhase(false)
-    , m_numberOfLoanedBlocks(0)
-{
-}
-
-inline void CopiedSpace::init()
-{
-    m_toSpace = &m_blocks1;
-    m_fromSpace = &m_blocks2;
-    
-    m_totalMemoryAllocated += s_blockSize * s_initialBlockNum;
-
-    if (!addNewBlock())
-        CRASH();
-}   
-
 inline bool CopiedSpace::contains(void* ptr, CopiedBlock*& result)
 {
     CopiedBlock* block = blockFor(ptr);
@@ -77,6 +54,7 @@
     m_toSpace = temp;
 
     m_toSpaceFilter.reset();
+    m_allocator.startedCopying();
 
     m_totalMemoryUtilized = 0;
 
@@ -85,82 +63,6 @@
     m_inCopyingPhase = true;
 }
 
-inline void CopiedSpace::doneCopying()
-{
-    {
-        MutexLocker locker(m_loanedBlocksLock);
-        while (m_numberOfLoanedBlocks > 0)
-            m_loanedBlocksCondition.wait(m_loanedBlocksLock);
-    }
-
-    ASSERT(m_inCopyingPhase);
-    m_inCopyingPhase = false;
-    while (!m_fromSpace->isEmpty()) {
-        CopiedBlock* block = static_cast<CopiedBlock*>(m_fromSpace->removeHead());
-        if (block->m_isPinned) {
-            block->m_isPinned = false;
-            m_toSpace->push(block);
-            continue;
-        }
-
-        m_toSpaceSet.remove(block);
-        {
-            MutexLocker locker(m_heap->m_freeBlockLock);
-            m_heap->m_freeBlocks.push(block);
-            m_heap->m_numberOfFreeBlocks++;
-        }
-    }
-
-    CopiedBlock* curr = static_cast<CopiedBlock*>(m_oversizeBlocks.head());
-    while (curr) {
-        CopiedBlock* next = static_cast<CopiedBlock*>(curr->next());
-        if (!curr->m_isPinned) {
-            m_oversizeBlocks.remove(curr);
-            m_totalMemoryAllocated -= curr->m_allocation.size();
-            m_totalMemoryUtilized -= curr->m_allocation.size() - sizeof(CopiedBlock);
-            curr->m_allocation.deallocate();
-        } else
-            curr->m_isPinned = false;
-        curr = next;
-    }
-
-    if (!(m_currentBlock = static_cast<CopiedBlock*>(m_toSpace->head())))
-        if (!addNewBlock())
-            CRASH();
-}
-
-inline void CopiedSpace::doneFillingBlock(CopiedBlock* block)
-{
-    ASSERT(block);
-    ASSERT(block->m_offset < reinterpret_cast<char*>(block) + s_blockSize);
-    ASSERT(m_inCopyingPhase);
-
-    if (block->m_offset == block->m_payload) {
-        recycleBlock(block);
-        return;
-    }
-
-    {
-        MutexLocker locker(m_toSpaceLock);
-        m_toSpace->push(block);
-        m_toSpaceSet.add(block);
-        m_toSpaceFilter.add(reinterpret_cast<Bits>(block));
-    }
-
-    {
-        MutexLocker locker(m_memoryStatsLock);
-        m_totalMemoryUtilized += static_cast<size_t>(static_cast<char*>(block->m_offset) - block->m_payload);
-    }
-
-    {
-        MutexLocker locker(m_loanedBlocksLock);
-        ASSERT(m_numberOfLoanedBlocks > 0);
-        m_numberOfLoanedBlocks--;
-        if (!m_numberOfLoanedBlocks)
-            m_loanedBlocksCondition.signal();
-    }
-}
-
 inline void CopiedSpace::recycleBlock(CopiedBlock* block)
 {
     {
@@ -178,42 +80,6 @@
     }
 }
 
-inline 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)
-        block = new (NotNull, heapBlock) CopiedBlock(heapBlock->m_allocation);
-    else if (allocationEffort == AllocationMustSucceed) {
-        if (!allocateNewBlock(&block)) {
-            *outBlock = 0;
-            ASSERT_NOT_REACHED();
-            return false;
-        }
-    } else {
-        ASSERT(allocationEffort == AllocationCanFail);
-        if (m_heap->waterMark() >= m_heap->highWaterMark() && m_heap->m_isSafeToCollect)
-            m_heap->collect(Heap::DoNotSweep);
-        
-        if (!getFreshBlock(AllocationMustSucceed, &block)) {
-            *outBlock = 0;
-            ASSERT_NOT_REACHED();
-            return false;
-        }
-    }
-    ASSERT(block);
-    ASSERT(isPointerAligned(block->m_offset));
-    *outBlock = block;
-    return true;
-}
-
 inline CheckedBoolean CopiedSpace::borrowBlock(CopiedBlock** outBlock)
 {
     CopiedBlock* block = 0;
@@ -238,13 +104,15 @@
         return false;
         
     m_toSpace->push(block);
-    m_currentBlock = block;
+    m_toSpaceFilter.add(reinterpret_cast<Bits>(block));
+    m_toSpaceSet.add(block);
+    m_allocator.resetCurrentBlock(block);
     return true;
 }
 
 inline CheckedBoolean CopiedSpace::allocateNewBlock(CopiedBlock** outBlock)
 {
-    PageAllocationAligned allocation = PageAllocationAligned::allocate(s_blockSize, s_blockSize, OSAllocator::JSGCHeapPages);
+    PageAllocationAligned allocation = PageAllocationAligned::allocate(HeapBlock::s_blockSize, HeapBlock::s_blockSize, OSAllocator::JSGCHeapPages);
     if (!static_cast<bool>(allocation)) {
         *outBlock = 0;
         return false;
@@ -252,7 +120,7 @@
 
     {
         MutexLocker locker(m_memoryStatsLock);
-        m_totalMemoryAllocated += s_blockSize;
+        m_totalMemoryAllocated += HeapBlock::s_blockSize;
     }
 
     *outBlock = new (NotNull, allocation.base()) CopiedBlock(allocation);
@@ -261,48 +129,21 @@
 
 inline bool CopiedSpace::fitsInBlock(CopiedBlock* block, size_t bytes)
 {
-    return static_cast<char*>(block->m_offset) + bytes < reinterpret_cast<char*>(block) + s_blockSize && static_cast<char*>(block->m_offset) + bytes > block->m_offset;
+    return static_cast<char*>(block->m_offset) + bytes < reinterpret_cast<char*>(block) + HeapBlock::s_blockSize && static_cast<char*>(block->m_offset) + bytes > block->m_offset;
 }
 
-inline bool CopiedSpace::fitsInCurrentBlock(size_t bytes)
-{
-    return fitsInBlock(m_currentBlock, bytes);
-}
-
 inline CheckedBoolean CopiedSpace::tryAllocate(size_t bytes, void** outPtr)
 {
     ASSERT(!m_heap->globalData()->isInitializingObject());
 
-    if (isOversize(bytes) || !fitsInCurrentBlock(bytes))
+    if (isOversize(bytes) || !m_allocator.fitsInCurrentBlock(bytes))
         return tryAllocateSlowCase(bytes, outPtr);
     
-    *outPtr = allocateFromBlock(m_currentBlock, bytes);
+    *outPtr = m_allocator.allocate(bytes);
+    ASSERT(*outPtr);
     return true;
 }
 
-inline CheckedBoolean CopiedSpace::tryAllocateOversize(size_t bytes, void** outPtr)
-{
-    ASSERT(isOversize(bytes));
-    
-    size_t blockSize = WTF::roundUpToMultipleOf<s_pageSize>(sizeof(CopiedBlock) + bytes);
-    PageAllocationAligned allocation = PageAllocationAligned::allocate(blockSize, s_pageSize, OSAllocator::JSGCHeapPages);
-    if (!static_cast<bool>(allocation)) {
-        *outPtr = 0;
-        return false;
-    }
-    CopiedBlock* block = new (NotNull, allocation.base()) CopiedBlock(allocation);
-    m_oversizeBlocks.push(block);
-    ASSERT(isPointerAligned(block->m_offset));
-
-    m_oversizeFilter.add(reinterpret_cast<Bits>(block));
-    
-    m_totalMemoryAllocated += blockSize;
-    m_totalMemoryUtilized += bytes;
-
-    *outPtr = block->m_offset;
-    return true;
-}
-
 inline void* CopiedSpace::allocateFromBlock(CopiedBlock* block, size_t bytes)
 {
     ASSERT(!isOversize(bytes));
@@ -310,71 +151,14 @@
     ASSERT(isPointerAligned(block->m_offset));
     
     void* ptr = block->m_offset;
-    ASSERT(block->m_offset >= block->m_payload && block->m_offset < reinterpret_cast<char*>(block) + s_blockSize);
+    ASSERT(block->m_offset >= block->m_payload && block->m_offset < reinterpret_cast<char*>(block) + HeapBlock::s_blockSize);
     block->m_offset = static_cast<void*>((static_cast<char*>(ptr) + bytes));
-    ASSERT(block->m_offset >= block->m_payload && block->m_offset < reinterpret_cast<char*>(block) + s_blockSize);
+    ASSERT(block->m_offset >= block->m_payload && block->m_offset < reinterpret_cast<char*>(block) + HeapBlock::s_blockSize);
 
     ASSERT(isPointerAligned(ptr));
     return ptr;
 }
 
-inline CheckedBoolean CopiedSpace::tryReallocate(void** ptr, size_t oldSize, size_t newSize)
-{
-    if (oldSize >= newSize)
-        return true;
-    
-    void* oldPtr = *ptr;
-    ASSERT(!m_heap->globalData()->isInitializingObject());
-
-    if (isOversize(oldSize) || isOversize(newSize))
-        return tryReallocateOversize(ptr, oldSize, newSize);
-
-    if (static_cast<char*>(oldPtr) + oldSize == m_currentBlock->m_offset && oldPtr > m_currentBlock && oldPtr < reinterpret_cast<char*>(m_currentBlock) + s_blockSize) {
-        m_currentBlock->m_offset = oldPtr;
-        if (fitsInCurrentBlock(newSize)) {
-            m_totalMemoryUtilized += newSize - oldSize;
-            return allocateFromBlock(m_currentBlock, newSize);
-        }
-    }
-    m_totalMemoryUtilized -= oldSize;
-
-    void* result = 0;
-    if (!tryAllocate(newSize, &result)) {
-        *ptr = 0;
-        return false;
-    }
-    memcpy(result, oldPtr, oldSize);
-    *ptr = result;
-    return true;
-}
-
-inline CheckedBoolean CopiedSpace::tryReallocateOversize(void** ptr, size_t oldSize, size_t newSize)
-{
-    ASSERT(isOversize(oldSize) || isOversize(newSize));
-    ASSERT(newSize > oldSize);
-
-    void* oldPtr = *ptr;
-    
-    void* newPtr = 0;
-    if (!tryAllocateOversize(newSize, &newPtr)) {
-        *ptr = 0;
-        return false;
-    }
-    memcpy(newPtr, oldPtr, oldSize);
-
-    if (isOversize(oldSize)) {
-        CopiedBlock* oldBlock = oversizeBlockFor(oldPtr);
-        m_oversizeBlocks.remove(oldBlock);
-        oldBlock->m_allocation.deallocate();
-        m_totalMemoryAllocated -= oldSize + sizeof(CopiedBlock);
-    }
-    
-    m_totalMemoryUtilized -= oldSize;
-
-    *ptr = newPtr;
-    return true;
-}
-
 inline bool CopiedSpace::isOversize(size_t bytes)
 {
     return bytes > s_maxAllocationSize;

Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (108266 => 108267)


--- trunk/Source/_javascript_Core/heap/Heap.cpp	2012-02-20 23:38:23 UTC (rev 108266)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp	2012-02-20 23:42:11 UTC (rev 108267)
@@ -767,8 +767,8 @@
 {
     if (!m_isSafeToCollect)
         return;
-    if (!m_globalData->dynamicGlobalObject)
-        m_globalData->recompileAllJSFunctions();
+    //if (!m_globalData->dynamicGlobalObject)
+    //    m_globalData->recompileAllJSFunctions();
 
     collect(DoSweep);
 }

Modified: trunk/Source/_javascript_Core/heap/HeapBlock.h (108266 => 108267)


--- trunk/Source/_javascript_Core/heap/HeapBlock.h	2012-02-20 23:38:23 UTC (rev 108266)
+++ trunk/Source/_javascript_Core/heap/HeapBlock.h	2012-02-20 23:42:11 UTC (rev 108267)
@@ -28,6 +28,7 @@
 
 #include <wtf/DoublyLinkedList.h>
 #include <wtf/PageAllocationAligned.h>
+#include <wtf/StdLibExtras.h>
 
 namespace JSC {
 
@@ -47,6 +48,8 @@
     HeapBlock* m_prev;
     HeapBlock* m_next;
     PageAllocationAligned m_allocation;
+    
+    static const size_t s_blockSize = 64 * KB;
 };
 
 } // namespace JSC
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to