Merge AllocationSpace into MarkedSpace
authormhahnenberg@apple.com <mhahnenberg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Jan 2012 02:30:38 +0000 (02:30 +0000)
committermhahnenberg@apple.com <mhahnenberg@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Jan 2012 02:30:38 +0000 (02:30 +0000)
https://bugs.webkit.org/show_bug.cgi?id=77116

Reviewed by Geoffrey Garen.

Merging AllocationSpace and MarkedSpace in preparation for future refactoring/enhancement to
MarkedSpace allocation.

* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.exp:
* JavaScriptCore.gypi:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
* heap/AllocationSpace.cpp: Removed.
* heap/AllocationSpace.h: Removed.
* heap/BumpSpace.h:
(BumpSpace):
* heap/Heap.h:
(JSC::Heap::objectSpace):
(Heap):
():
* heap/HeapBlock.h:
():
* heap/MarkedSpace.cpp:
(JSC::MarkedSpace::tryAllocateHelper):
(JSC):
(JSC::MarkedSpace::tryAllocate):
(JSC::MarkedSpace::allocateSlowCase):
(JSC::MarkedSpace::allocateBlock):
(JSC::MarkedSpace::freeBlocks):
(TakeIfUnmarked):
(JSC::TakeIfUnmarked::TakeIfUnmarked):
(JSC::TakeIfUnmarked::operator()):
(JSC::TakeIfUnmarked::returnValue):
(JSC::MarkedSpace::shrink):
(GatherDirtyCells):
(JSC::GatherDirtyCells::returnValue):
(JSC::GatherDirtyCells::GatherDirtyCells):
(JSC::GatherDirtyCells::operator()):
(JSC::MarkedSpace::gatherDirtyCells):
* heap/MarkedSpace.h:
(MarkedSpace):
(JSC::MarkedSpace::blocks):
(JSC::MarkedSpace::forEachCell):
(JSC):
(JSC::MarkedSpace::allocate):

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

16 files changed:
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/GNUmakefile.list.am
Source/JavaScriptCore/JavaScriptCore.exp
Source/JavaScriptCore/JavaScriptCore.gypi
Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/Target.pri
Source/JavaScriptCore/heap/AllocationSpace.cpp [deleted file]
Source/JavaScriptCore/heap/AllocationSpace.h [deleted file]
Source/JavaScriptCore/heap/BumpSpace.h
Source/JavaScriptCore/heap/Heap.h
Source/JavaScriptCore/heap/HeapBlock.h
Source/JavaScriptCore/heap/MarkedSpace.cpp
Source/JavaScriptCore/heap/MarkedSpace.h

index 7186cb7..c7cf03a 100644 (file)
@@ -73,7 +73,6 @@ SET(JavaScriptCore_SOURCES
     dfg/DFGSpeculativeJIT64.cpp
     dfg/DFGThunks.cpp
 
-    heap/AllocationSpace.cpp
     heap/BumpSpace.cpp
     heap/DFGCodeBlocks.cpp
     heap/Heap.cpp
index abcb1ac..a03a3f4 100644 (file)
@@ -1,3 +1,55 @@
+2012-01-26  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        Merge AllocationSpace into MarkedSpace
+        https://bugs.webkit.org/show_bug.cgi?id=77116
+
+        Reviewed by Geoffrey Garen.
+
+        Merging AllocationSpace and MarkedSpace in preparation for future refactoring/enhancement to 
+        MarkedSpace allocation.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * JavaScriptCore.exp:
+        * JavaScriptCore.gypi:
+        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * Target.pri:
+        * heap/AllocationSpace.cpp: Removed.
+        * heap/AllocationSpace.h: Removed.
+        * heap/BumpSpace.h:
+        (BumpSpace):
+        * heap/Heap.h:
+        (JSC::Heap::objectSpace):
+        (Heap):
+        ():
+        * heap/HeapBlock.h:
+        ():
+        * heap/MarkedSpace.cpp:
+        (JSC::MarkedSpace::tryAllocateHelper):
+        (JSC):
+        (JSC::MarkedSpace::tryAllocate):
+        (JSC::MarkedSpace::allocateSlowCase):
+        (JSC::MarkedSpace::allocateBlock):
+        (JSC::MarkedSpace::freeBlocks):
+        (TakeIfUnmarked):
+        (JSC::TakeIfUnmarked::TakeIfUnmarked):
+        (JSC::TakeIfUnmarked::operator()):
+        (JSC::TakeIfUnmarked::returnValue):
+        (JSC::MarkedSpace::shrink):
+        (GatherDirtyCells):
+        (JSC::GatherDirtyCells::returnValue):
+        (JSC::GatherDirtyCells::GatherDirtyCells):
+        (JSC::GatherDirtyCells::operator()):
+        (JSC::MarkedSpace::gatherDirtyCells):
+        * heap/MarkedSpace.h:
+        (MarkedSpace):
+        (JSC::MarkedSpace::blocks):
+        (JSC::MarkedSpace::forEachCell):
+        (JSC):
+        (JSC::MarkedSpace::allocate):
+
 2012-01-26  Oliver Hunt  <oliver@apple.com>
 
         MSVC bug fix.
index 54b778d..1fc1338 100644 (file)
@@ -178,8 +178,6 @@ javascriptcore_sources += \
        Source/JavaScriptCore/dfg/DFGThunks.cpp \
        Source/JavaScriptCore/dfg/DFGThunks.h \
        Source/JavaScriptCore/dfg/DFGVariableAccessData.h \
-       Source/JavaScriptCore/heap/AllocationSpace.cpp \
-       Source/JavaScriptCore/heap/AllocationSpace.h \
        Source/JavaScriptCore/heap/BumpBlock.h \
        Source/JavaScriptCore/heap/BumpSpace.cpp \
        Source/JavaScriptCore/heap/BumpSpace.h \
index 8a57df3..1d5bd04 100644 (file)
@@ -127,6 +127,7 @@ __ZN3JSC11JSByteArray3putEPNS_6JSCellEPNS_9ExecStateERKNS_10IdentifierENS_7JSVal
 __ZN3JSC11JSByteArray6s_infoE
 __ZN3JSC11JSByteArray7destroyEPNS_6JSCellE
 __ZN3JSC11JSByteArrayC1EPNS_9ExecStateEPNS_9StructureEPN3WTF9ByteArrayE
+__ZN3JSC11MarkedSpace16allocateSlowCaseERNS0_9SizeClassE
 __ZN3JSC11ParserArena5resetEv
 __ZN3JSC11checkSyntaxEPNS_9ExecStateERKNS_10SourceCodeEPNS_7JSValueE
 __ZN3JSC11createErrorEPNS_9ExecStateERKNS_7UStringE
@@ -190,7 +191,6 @@ __ZN3JSC14TimeoutChecker5resetEv
 __ZN3JSC14VTableSpectrum5countEPNS_6JSCellE
 __ZN3JSC14throwTypeErrorEPNS_9ExecStateE
 __ZN3JSC14throwTypeErrorEPNS_9ExecStateERKNS_7UStringE
-__ZN3JSC15AllocationSpace16allocateSlowCaseERNS_11MarkedSpace9SizeClassE
 __ZN3JSC15WeakHandleOwner26isReachableFromOpaqueRootsENS_6HandleINS_7UnknownEEEPvRNS_11SlotVisitorE
 __ZN3JSC15WeakHandleOwner8finalizeENS_6HandleINS_7UnknownEEEPv
 __ZN3JSC15WeakHandleOwnerD2Ev
index 9a876c2..b59be38 100644 (file)
@@ -27,7 +27,6 @@
             'API/OpaqueJSString.h',
             'assembler/MacroAssemblerCodeRef.h',
             'bytecode/Opcode.h',
-            'heap/AllocationSpace.h',
             'heap/BumpBlock.h',
             'heap/BumpSpace.h',
             'heap/BumpSpaceInlineMethods.h',
             'bytecompiler/LabelScope.h',
             'bytecompiler/NodesCodegen.cpp',
             'bytecompiler/RegisterID.h',
-            'heap/AllocationSpace.cpp',
             'heap/ConservativeRoots.cpp',
             'heap/HandleHeap.cpp',
             'heap/HandleStack.cpp',
index 7296cdd..433135f 100644 (file)
@@ -64,7 +64,7 @@ EXPORTS
     ?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVJSGlobalData@2@PAVStringImpl@4@@Z
     ?addStaticGlobals@JSGlobalObject@JSC@@IAEXPAUGlobalPropertyInfo@12@H@Z
     ?allocatePropertyStorage@JSObject@JSC@@QAEXAAVJSGlobalData@2@II@Z
-    ?allocateSlowCase@AllocationSpace@JSC@@AAEPAXAAUSizeClass@MarkedSpace@2@@Z
+    ?allocateSlowCase@MarkedSpace@JSC@@AAEPAXAAUSizeClass@12@@Z
     ?append@StringBuilder@WTF@@QAEXPBEI@Z
     ?append@StringBuilder@WTF@@QAEXPB_WI@Z
     ?ascii@UString@JSC@@QBE?AVCString@WTF@@XZ
index 4f5768a..cfb1da6 100644 (file)
                        Name="heap"
                        >
                             <File
-                                    RelativePath="..\..\heap\AllocationSpace.cpp"
-                                    >
-                            </File>
-                            <File
-                                    RelativePath="..\..\heap\AllocationSpace.h"
-                                    >
-                            </File>
-                            <File
                                     RelativePath="..\..\heap\BumpBlock.h"
                                     >
                             </File>
index d4bea5d..174dbf5 100644 (file)
                A1712B3F11C7B228007A5315 /* RegExpCache.h in Headers */ = {isa = PBXBuildFile; fileRef = A1712B3E11C7B228007A5315 /* RegExpCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A1712B4111C7B235007A5315 /* RegExpKey.h in Headers */ = {isa = PBXBuildFile; fileRef = A1712B4011C7B235007A5315 /* RegExpKey.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A1D764521354448B00C5C7C0 /* Alignment.h in Headers */ = {isa = PBXBuildFile; fileRef = A1D764511354448B00C5C7C0 /* Alignment.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               A70456B01427FB910037DA68 /* AllocationSpace.h in Headers */ = {isa = PBXBuildFile; fileRef = A70456AF1427FB150037DA68 /* AllocationSpace.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               A70456B11427FB950037DA68 /* AllocationSpace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A70456AE1427FB030037DA68 /* AllocationSpace.cpp */; };
                A71236E51195F33C00BD2174 /* JITOpcodes32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A71236E41195F33C00BD2174 /* JITOpcodes32_64.cpp */; };
                A72700900DAC6BBC00E548D7 /* JSNotAnObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A72700780DAC605600E548D7 /* JSNotAnObject.cpp */; };
                A72701B90DADE94900E548D7 /* ExceptionHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = A72701B30DADE94900E548D7 /* ExceptionHelpers.h */; };
                A1712B3E11C7B228007A5315 /* RegExpCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpCache.h; sourceTree = "<group>"; };
                A1712B4011C7B235007A5315 /* RegExpKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpKey.h; sourceTree = "<group>"; };
                A1D764511354448B00C5C7C0 /* Alignment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Alignment.h; sourceTree = "<group>"; };
-               A70456AE1427FB030037DA68 /* AllocationSpace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AllocationSpace.cpp; sourceTree = "<group>"; };
-               A70456AF1427FB150037DA68 /* AllocationSpace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AllocationSpace.h; sourceTree = "<group>"; };
                A71236E41195F33C00BD2174 /* JITOpcodes32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITOpcodes32_64.cpp; sourceTree = "<group>"; };
                A718F61A11754A21002465A7 /* RegExpJitTables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpJitTables.h; sourceTree = "<group>"; };
                A718F8211178EB4B002465A7 /* create_regex_tables */ = {isa = PBXFileReference; explicitFileType = text.script.python; fileEncoding = 4; path = create_regex_tables; sourceTree = "<group>"; };
                142E312A134FF0A600AFADB5 /* heap */ = {
                        isa = PBXGroup;
                        children = (
-                               A70456AE1427FB030037DA68 /* AllocationSpace.cpp */,
-                               A70456AF1427FB150037DA68 /* AllocationSpace.h */,
                                C2C8D02E14A3CEFC00578E65 /* BumpBlock.h */,
                                C240305314B404C90079EB64 /* BumpSpace.cpp */,
                                C2EAA3F8149A830800FCE112 /* BumpSpace.h */,
                        files = (
                                860161E30F3A83C100F84710 /* AbstractMacroAssembler.h in Headers */,
                                A1D764521354448B00C5C7C0 /* Alignment.h in Headers */,
-                               A70456B01427FB910037DA68 /* AllocationSpace.h in Headers */,
                                BC18C3E40E16F5CD00B34460 /* AlwaysInline.h in Headers */,
                                BC18C3E50E16F5CD00B34460 /* APICast.h in Headers */,
                                865F408810E7D56300947361 /* APIShims.h in Headers */,
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
-                               A70456B11427FB950037DA68 /* AllocationSpace.cpp in Sources */,
                                147F39BD107EC37600427A48 /* ArgList.cpp in Sources */,
                                147F39BE107EC37600427A48 /* Arguments.cpp in Sources */,
                                86D3B2C310156BDE002865E7 /* ARMAssembler.cpp in Sources */,
index 6f44796..f2b2d74 100644 (file)
@@ -65,7 +65,6 @@ SOURCES += \
     bytecode/ValueProfile.cpp \
     bytecompiler/BytecodeGenerator.cpp \
     bytecompiler/NodesCodegen.cpp \
-    heap/AllocationSpace.cpp \
     heap/BumpSpace.cpp \
     heap/ConservativeRoots.cpp \
     heap/DFGCodeBlocks.cpp \
diff --git a/Source/JavaScriptCore/heap/AllocationSpace.cpp b/Source/JavaScriptCore/heap/AllocationSpace.cpp
deleted file mode 100644 (file)
index 290f2a2..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * 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. 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 "AllocationSpace.h"
-
-#include "Heap.h"
-
-namespace JSC {
-
-inline void* AllocationSpace::tryAllocate(MarkedSpace::SizeClass& sizeClass)
-{
-    m_heap->m_operationInProgress = Allocation;
-    void* result = m_markedSpace.allocate(sizeClass);
-    m_heap->m_operationInProgress = NoOperation;
-    return result;
-}
-
-void* AllocationSpace::allocateSlowCase(MarkedSpace::SizeClass& sizeClass)
-{
-#if COLLECT_ON_EVERY_ALLOCATION
-    m_heap->collectAllGarbage();
-    ASSERT(m_heap->m_operationInProgress == NoOperation);
-#endif
-    
-    void* result = tryAllocate(sizeClass);
-    
-    if (LIKELY(result != 0))
-        return result;
-    
-    AllocationEffort allocationEffort;
-    
-    if ((
-#if ENABLE(GGC)
-         m_markedSpace.nurseryWaterMark() < m_heap->m_minBytesPerCycle
-#else
-         m_heap->waterMark() < m_heap->highWaterMark()
-#endif
-         ) || !m_heap->m_isSafeToCollect)
-        allocationEffort = AllocationMustSucceed;
-    else
-        allocationEffort = AllocationCanFail;
-    
-    MarkedBlock* block = allocateBlock(sizeClass.cellSize, allocationEffort);
-    if (block) {
-        m_markedSpace.addBlock(sizeClass, block);
-        void* result = tryAllocate(sizeClass);
-        ASSERT(result);
-        return result;
-    }
-    
-    m_heap->collect(Heap::DoNotSweep);
-    
-    result = tryAllocate(sizeClass);
-    
-    if (result)
-        return result;
-    
-    ASSERT(m_heap->waterMark() < m_heap->highWaterMark());
-    
-    m_markedSpace.addBlock(sizeClass, allocateBlock(sizeClass.cellSize, AllocationMustSucceed));
-    
-    result = tryAllocate(sizeClass);
-    ASSERT(result);
-    return result;
-}
-
-MarkedBlock* AllocationSpace::allocateBlock(size_t cellSize, 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;
-    }
-    if (block)
-        block = MarkedBlock::recycle(block, m_heap, cellSize);
-    else if (allocationEffort == AllocationCanFail)
-        return 0;
-    else
-        block = MarkedBlock::create(m_heap, cellSize);
-    
-    m_blocks.add(block);
-    
-    return block;
-}
-
-void AllocationSpace::freeBlocks(MarkedBlock* head)
-{
-    MarkedBlock* next;
-    for (MarkedBlock* block = head; block; block = next) {
-        next = static_cast<MarkedBlock*>(block->next());
-        
-        m_blocks.remove(block);
-        block->sweep();
-        MutexLocker locker(m_heap->m_freeBlockLock);
-        m_heap->m_freeBlocks.append(block);
-        m_heap->m_numberOfFreeBlocks++;
-    }
-}
-
-class TakeIfUnmarked {
-public:
-    typedef MarkedBlock* ReturnType;
-    
-    TakeIfUnmarked(MarkedSpace*);
-    void operator()(MarkedBlock*);
-    ReturnType returnValue();
-    
-private:
-    MarkedSpace* m_markedSpace;
-    DoublyLinkedList<MarkedBlock> m_empties;
-};
-
-inline TakeIfUnmarked::TakeIfUnmarked(MarkedSpace* newSpace)
-    : m_markedSpace(newSpace)
-{
-}
-
-inline void TakeIfUnmarked::operator()(MarkedBlock* block)
-{
-    if (!block->markCountIsZero())
-        return;
-    
-    m_markedSpace->removeBlock(block);
-    m_empties.append(block);
-}
-
-inline TakeIfUnmarked::ReturnType TakeIfUnmarked::returnValue()
-{
-    return m_empties.head();
-}
-
-void AllocationSpace::shrink()
-{
-    // We record a temporary list of empties to avoid modifying m_blocks while iterating it.
-    TakeIfUnmarked takeIfUnmarked(&m_markedSpace);
-    freeBlocks(forEachBlock(takeIfUnmarked));
-}
-
-#if ENABLE(GGC)
-class GatherDirtyCells {
-    WTF_MAKE_NONCOPYABLE(GatherDirtyCells);
-public:
-    typedef void* ReturnType;
-    
-    explicit GatherDirtyCells(MarkedBlock::DirtyCellVector*);
-    void operator()(MarkedBlock*);
-    ReturnType returnValue() { return 0; }
-    
-private:
-    MarkedBlock::DirtyCellVector* m_dirtyCells;
-};
-
-inline GatherDirtyCells::GatherDirtyCells(MarkedBlock::DirtyCellVector* dirtyCells)
-    : m_dirtyCells(dirtyCells)
-{
-}
-
-inline void GatherDirtyCells::operator()(MarkedBlock* block)
-{
-    block->gatherDirtyCells(*m_dirtyCells);
-}
-
-void AllocationSpace::gatherDirtyCells(MarkedBlock::DirtyCellVector& dirtyCells)
-{
-    GatherDirtyCells gatherDirtyCells(&dirtyCells);
-    forEachBlock(gatherDirtyCells);
-}
-#endif
-
-}
diff --git a/Source/JavaScriptCore/heap/AllocationSpace.h b/Source/JavaScriptCore/heap/AllocationSpace.h
deleted file mode 100644 (file)
index 45a6b5a..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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. 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 AllocationSpace_h
-#define AllocationSpace_h
-
-#include "MarkedBlockSet.h"
-#include "MarkedSpace.h"
-
-#include <wtf/HashSet.h>
-
-namespace JSC {
-
-class Heap;
-class MarkedBlock;
-
-class AllocationSpace {
-public:
-    AllocationSpace(Heap* heap)
-        : m_heap(heap)
-        , m_markedSpace(heap)
-    {
-    }
-    
-    typedef HashSet<MarkedBlock*>::iterator BlockIterator;
-    
-    MarkedBlockSet& blocks() { return m_blocks; }
-    MarkedSpace::SizeClass& sizeClassFor(size_t bytes) { return m_markedSpace.sizeClassFor(bytes); }
-    size_t waterMark() { return m_markedSpace.waterMark(); }
-
-#if ENABLE(GGC)
-    void gatherDirtyCells(MarkedBlock::DirtyCellVector&);
-#endif
-
-    template<typename Functor> typename Functor::ReturnType forEachCell(Functor&);
-    template<typename Functor> typename Functor::ReturnType forEachCell();
-    template<typename Functor> typename Functor::ReturnType forEachBlock(Functor&);
-    template<typename Functor> typename Functor::ReturnType forEachBlock();
-    
-    void canonicalizeCellLivenessData() { m_markedSpace.canonicalizeCellLivenessData(); }
-    void resetAllocator() { m_markedSpace.resetAllocator(); }
-    
-    void* allocate(size_t);
-    void freeBlocks(MarkedBlock*);
-    void shrink();
-    
-private:
-    enum AllocationEffort { AllocationCanFail, AllocationMustSucceed };
-
-    void* allocate(MarkedSpace::SizeClass&);
-    void* tryAllocate(MarkedSpace::SizeClass&);
-    JS_EXPORT_PRIVATE void* allocateSlowCase(MarkedSpace::SizeClass&);
-    MarkedBlock* allocateBlock(size_t cellSize, AllocationEffort);
-    
-    Heap* m_heap;
-    MarkedSpace m_markedSpace;
-    MarkedBlockSet m_blocks;
-};
-
-template<typename Functor> inline typename Functor::ReturnType AllocationSpace::forEachCell(Functor& functor)
-{
-    canonicalizeCellLivenessData();
-
-    BlockIterator end = m_blocks.set().end();
-    for (BlockIterator it = m_blocks.set().begin(); it != end; ++it)
-        (*it)->forEachCell(functor);
-    return functor.returnValue();
-}
-
-template<typename Functor> inline typename Functor::ReturnType AllocationSpace::forEachCell()
-{
-    Functor functor;
-    return forEachCell(functor);
-}
-
-template<typename Functor> inline typename Functor::ReturnType AllocationSpace::forEachBlock(Functor& functor)
-{
-    BlockIterator end = m_blocks.set().end();
-    for (BlockIterator it = m_blocks.set().begin(); it != end; ++it)
-        functor(*it);
-    return functor.returnValue();
-}
-
-template<typename Functor> inline typename Functor::ReturnType AllocationSpace::forEachBlock()
-{
-    Functor functor;
-    return forEachBlock(functor);
-}
-
-inline void* AllocationSpace::allocate(MarkedSpace::SizeClass& sizeClass)
-{
-    // This is a light-weight fast path to cover the most common case.
-    MarkedBlock::FreeCell* firstFreeCell = sizeClass.firstFreeCell;
-    if (UNLIKELY(!firstFreeCell))
-        return allocateSlowCase(sizeClass);
-    
-    sizeClass.firstFreeCell = firstFreeCell->next;
-    return firstFreeCell;
-}
-
-inline void* AllocationSpace::allocate(size_t bytes)
-{
-    MarkedSpace::SizeClass& sizeClass = sizeClassFor(bytes);
-    return allocate(sizeClass);
-}
-
-}
-
-#endif
index 1ffcb46..30e6b74 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef BumpSpace_h
 #define BumpSpace_h
 
+#include "HeapBlock.h"
 #include "TinyBloomFilter.h"
 #include <wtf/Assertions.h>
 #include <wtf/CheckedBoolean.h>
@@ -66,8 +67,6 @@ public:
     static BumpBlock* blockFor(void*);
 
 private:
-    enum AllocationEffort { AllocationCanFail, AllocationMustSucceed };
-
     CheckedBoolean tryAllocateSlowCase(size_t, void**);
     CheckedBoolean addNewBlock();
     CheckedBoolean allocateNewBlock(BumpBlock**);
index 44a6f86..40a8376 100644 (file)
@@ -22,7 +22,6 @@
 #ifndef Heap_h
 #define Heap_h
 
-#include "AllocationSpace.h"
 #include "DFGCodeBlocks.h"
 #include "HandleHeap.h"
 #include "HandleStack.h"
@@ -86,7 +85,7 @@ namespace JSC {
         JS_EXPORT_PRIVATE void destroy(); // JSGlobalData must call destroy() before ~Heap().
 
         JSGlobalData* globalData() const { return m_globalData; }
-        AllocationSpace& objectSpace() { return m_objectSpace; }
+        MarkedSpace& objectSpace() { return m_objectSpace; }
         MachineThreads& machineThreads() { return m_machineThreads; }
 
         JS_EXPORT_PRIVATE GCActivityCallback* activityCallback();
@@ -136,8 +135,8 @@ namespace JSC {
         void getConservativeRegisterRoots(HashSet<JSCell*>& roots);
 
     private:
+        friend class MarkedSpace;
         friend class MarkedBlock;
-        friend class AllocationSpace;
         friend class BumpSpace;
         friend class SlotVisitor;
         friend class CodeBlock;
@@ -191,7 +190,7 @@ namespace JSC {
         size_t m_highWaterMark;
         
         OperationInProgress m_operationInProgress;
-        AllocationSpace m_objectSpace;
+        MarkedSpace m_objectSpace;
         BumpSpace m_storageSpace;
 
         DoublyLinkedList<HeapBlock> m_freeBlocks;
index 1d66aad..b0ecb20 100644 (file)
@@ -31,6 +31,8 @@
 
 namespace JSC {
 
+enum AllocationEffort { AllocationCanFail, AllocationMustSucceed };
+
 class HeapBlock : public DoublyLinkedListNode<HeapBlock> {
 public:
     HeapBlock(PageAllocationAligned& allocation)
index c12e9ba..fcca188 100644 (file)
@@ -81,4 +81,192 @@ void MarkedSpace::canonicalizeCellLivenessData()
         sizeClassFor(cellSize).zapFreeList();
 }
 
+inline void* MarkedSpace::tryAllocateHelper(MarkedSpace::SizeClass& sizeClass)
+{
+    MarkedBlock::FreeCell* firstFreeCell = sizeClass.firstFreeCell;
+    if (!firstFreeCell) {
+        for (MarkedBlock*& block = sizeClass.currentBlock; block; block = static_cast<MarkedBlock*>(block->next())) {
+            firstFreeCell = block->sweep(MarkedBlock::SweepToFreeList);
+            if (firstFreeCell)
+                break;
+            m_nurseryWaterMark += block->capacity() - block->size();
+            m_waterMark += block->capacity();
+            block->didConsumeFreeList();
+        }
+
+        if (!firstFreeCell)
+            return 0;
+    }
+
+    ASSERT(firstFreeCell);
+    sizeClass.firstFreeCell = firstFreeCell->next;
+    return firstFreeCell;
+}
+
+inline void* MarkedSpace::tryAllocate(MarkedSpace::SizeClass& sizeClass)
+{
+    m_heap->m_operationInProgress = Allocation;
+    void* result = tryAllocateHelper(sizeClass);
+    m_heap->m_operationInProgress = NoOperation;
+    return result;
+}
+
+void* MarkedSpace::allocateSlowCase(MarkedSpace::SizeClass& sizeClass)
+{
+#if COLLECT_ON_EVERY_ALLOCATION
+    m_heap->collectAllGarbage();
+    ASSERT(m_heap->m_operationInProgress == NoOperation);
+#endif
+    
+    void* result = tryAllocate(sizeClass);
+    
+    if (LIKELY(result != 0))
+        return result;
+    
+    AllocationEffort allocationEffort;
+    
+    if ((
+#if ENABLE(GGC)
+         nurseryWaterMark() < m_heap->m_minBytesPerCycle
+#else
+         m_heap->waterMark() < m_heap->highWaterMark()
+#endif
+         ) || !m_heap->m_isSafeToCollect)
+        allocationEffort = AllocationMustSucceed;
+    else
+        allocationEffort = AllocationCanFail;
+    
+    MarkedBlock* block = allocateBlock(sizeClass.cellSize, allocationEffort);
+    if (block) {
+        addBlock(sizeClass, block);
+        void* result = tryAllocate(sizeClass);
+        ASSERT(result);
+        return result;
+    }
+    
+    m_heap->collect(Heap::DoNotSweep);
+    
+    result = tryAllocate(sizeClass);
+    
+    if (result)
+        return result;
+    
+    ASSERT(m_heap->waterMark() < m_heap->highWaterMark());
+    
+    addBlock(sizeClass, allocateBlock(sizeClass.cellSize, AllocationMustSucceed));
+    
+    result = tryAllocate(sizeClass);
+    ASSERT(result);
+    return result;
+}
+
+MarkedBlock* MarkedSpace::allocateBlock(size_t cellSize, 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;
+    }
+    if (block)
+        block = MarkedBlock::recycle(block, m_heap, cellSize);
+    else if (allocationEffort == AllocationCanFail)
+        return 0;
+    else
+        block = MarkedBlock::create(m_heap, cellSize);
+    
+    m_blocks.add(block);
+    
+    return block;
+}
+
+void MarkedSpace::freeBlocks(MarkedBlock* head)
+{
+    MarkedBlock* next;
+    for (MarkedBlock* block = head; block; block = next) {
+        next = static_cast<MarkedBlock*>(block->next());
+        
+        m_blocks.remove(block);
+        block->sweep();
+        MutexLocker locker(m_heap->m_freeBlockLock);
+        m_heap->m_freeBlocks.append(block);
+        m_heap->m_numberOfFreeBlocks++;
+    }
+}
+
+class TakeIfUnmarked {
+public:
+    typedef MarkedBlock* ReturnType;
+    
+    TakeIfUnmarked(MarkedSpace*);
+    void operator()(MarkedBlock*);
+    ReturnType returnValue();
+    
+private:
+    MarkedSpace* m_markedSpace;
+    DoublyLinkedList<MarkedBlock> m_empties;
+};
+
+inline TakeIfUnmarked::TakeIfUnmarked(MarkedSpace* newSpace)
+    : m_markedSpace(newSpace)
+{
+}
+
+inline void TakeIfUnmarked::operator()(MarkedBlock* block)
+{
+    if (!block->markCountIsZero())
+        return;
+    
+    m_markedSpace->removeBlock(block);
+    m_empties.append(block);
+}
+
+inline TakeIfUnmarked::ReturnType TakeIfUnmarked::returnValue()
+{
+    return m_empties.head();
+}
+
+void MarkedSpace::shrink()
+{
+    // We record a temporary list of empties to avoid modifying m_blocks while iterating it.
+    TakeIfUnmarked takeIfUnmarked(this);
+    freeBlocks(forEachBlock(takeIfUnmarked));
+}
+
+#if ENABLE(GGC)
+class GatherDirtyCells {
+    WTF_MAKE_NONCOPYABLE(GatherDirtyCells);
+public:
+    typedef void* ReturnType;
+    
+    explicit GatherDirtyCells(MarkedBlock::DirtyCellVector*);
+    void operator()(MarkedBlock*);
+    ReturnType returnValue() { return 0; }
+    
+private:
+    MarkedBlock::DirtyCellVector* m_dirtyCells;
+};
+
+inline GatherDirtyCells::GatherDirtyCells(MarkedBlock::DirtyCellVector* dirtyCells)
+    : m_dirtyCells(dirtyCells)
+{
+}
+
+inline void GatherDirtyCells::operator()(MarkedBlock* block)
+{
+    block->gatherDirtyCells(*m_dirtyCells);
+}
+
+void MarkedSpace::gatherDirtyCells(MarkedBlock::DirtyCellVector& dirtyCells)
+{
+    GatherDirtyCells gatherDirtyCells(&dirtyCells);
+    forEachBlock(gatherDirtyCells);
+}
+#endif
+
 } // namespace JSC
index 3b2c828..0854efc 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "MachineStackMarker.h"
 #include "MarkedBlock.h"
+#include "MarkedBlockSet.h"
 #include "PageAllocationAligned.h"
 #include <wtf/Bitmap.h>
 #include <wtf/DoublyLinkedList.h>
@@ -61,22 +62,36 @@ public:
     MarkedSpace(Heap*);
 
     SizeClass& sizeClassFor(size_t);
+    void* allocate(size_t);
     void* allocate(SizeClass&);
     
     void resetAllocator();
 
     void addBlock(SizeClass&, MarkedBlock*);
     void removeBlock(MarkedBlock*);
+    MarkedBlockSet& blocks() { return m_blocks; }
     
     void canonicalizeCellLivenessData();
 
     size_t waterMark();
     size_t nurseryWaterMark();
 
-    template<typename Functor> typename Functor::ReturnType forEachBlock(Functor&); // Safe to remove the current item while iterating.
+    typedef HashSet<MarkedBlock*>::iterator BlockIterator;
+    
+    template<typename Functor> typename Functor::ReturnType forEachCell(Functor&);
+    template<typename Functor> typename Functor::ReturnType forEachCell();
+    template<typename Functor> typename Functor::ReturnType forEachBlock(Functor&);
     template<typename Functor> typename Functor::ReturnType forEachBlock();
+    
+    void shrink();
+    void freeBlocks(MarkedBlock* head);
 
 private:
+    void* allocateSlowCase(SizeClass&);
+    void* tryAllocateHelper(MarkedSpace::SizeClass&);
+    void* tryAllocate(MarkedSpace::SizeClass&);
+    MarkedBlock* allocateBlock(size_t, AllocationEffort);
+
     // [ 32... 256 ]
     static const size_t preciseStep = MarkedBlock::atomSize;
     static const size_t preciseCutoff = 256;
@@ -92,6 +107,7 @@ private:
     size_t m_waterMark;
     size_t m_nurseryWaterMark;
     Heap* m_heap;
+    MarkedBlockSet m_blocks;
 };
 
 inline size_t MarkedSpace::waterMark()
@@ -104,6 +120,22 @@ inline size_t MarkedSpace::nurseryWaterMark()
     return m_nurseryWaterMark;
 }
 
+template<typename Functor> inline typename Functor::ReturnType MarkedSpace::forEachCell(Functor& functor)
+{
+    canonicalizeCellLivenessData();
+
+    BlockIterator end = m_blocks.set().end();
+    for (BlockIterator it = m_blocks.set().begin(); it != end; ++it)
+        (*it)->forEachCell(functor);
+    return functor.returnValue();
+}
+
+template<typename Functor> inline typename Functor::ReturnType MarkedSpace::forEachCell()
+{
+    Functor functor;
+    return forEachCell(functor);
+}
+
 inline MarkedSpace::SizeClass& MarkedSpace::sizeClassFor(size_t bytes)
 {
     ASSERT(bytes && bytes <= maxCellSize);
@@ -112,25 +144,19 @@ inline MarkedSpace::SizeClass& MarkedSpace::sizeClassFor(size_t bytes)
     return m_impreciseSizeClasses[(bytes - 1) / impreciseStep];
 }
 
+inline void* MarkedSpace::allocate(size_t bytes)
+{
+    SizeClass& sizeClass = sizeClassFor(bytes);
+    return allocate(sizeClass);
+}
+
 inline void* MarkedSpace::allocate(SizeClass& sizeClass)
 {
+    // This is a light-weight fast path to cover the most common case.
     MarkedBlock::FreeCell* firstFreeCell = sizeClass.firstFreeCell;
-    if (!firstFreeCell) {
-        for (MarkedBlock*& block = sizeClass.currentBlock; block; block = static_cast<MarkedBlock*>(block->next())) {
-            firstFreeCell = block->sweep(MarkedBlock::SweepToFreeList);
-            if (firstFreeCell)
-                break;
-            m_nurseryWaterMark += block->capacity() - block->size();
-            m_waterMark += block->capacity();
-            block->didConsumeFreeList();
-        }
-
-        if (!firstFreeCell)
-            return 0;
-    }
-
-    ASSERT(firstFreeCell);
-
+    if (UNLIKELY(!firstFreeCell))
+        return allocateSlowCase(sizeClass);
+    
     sizeClass.firstFreeCell = firstFreeCell->next;
     return firstFreeCell;
 }