Refactor Heap allocation logic into separate AllocationSpace class
authoroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Sep 2011 18:31:37 +0000 (18:31 +0000)
committeroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 20 Sep 2011 18:31:37 +0000 (18:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=68409

Reviewed by Gavin Barraclough.

../../../../Volumes/Data/git/WebKit/OpenSource/Source/JavaScriptCore:

This patch hoists direct manipulation of the MarkedSpace and related
data out of Heap and into a separate class.  This will allow us to
have multiple allocation spaces in future, so easing the way towards
having GC'd backing stores for objects.

* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.exp:
* JavaScriptCore.gypi:
* JavaScriptCore.pro:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* debugger/Debugger.cpp:
(JSC::Debugger::recompileAllJSFunctions):
* heap/AllocationSpace.cpp: Added.
(JSC::AllocationSpace::tryAllocate):
(JSC::AllocationSpace::allocateSlowCase):
(JSC::AllocationSpace::allocateBlock):
(JSC::AllocationSpace::freeBlocks):
(JSC::TakeIfEmpty::TakeIfEmpty):
(JSC::TakeIfEmpty::operator()):
(JSC::TakeIfEmpty::returnValue):
(JSC::AllocationSpace::shrink):
* heap/AllocationSpace.h: Added.
(JSC::AllocationSpace::AllocationSpace):
(JSC::AllocationSpace::blocks):
(JSC::AllocationSpace::sizeClassFor):
(JSC::AllocationSpace::setHighWaterMark):
(JSC::AllocationSpace::highWaterMark):
(JSC::AllocationSpace::canonicalizeBlocks):
(JSC::AllocationSpace::resetAllocator):
(JSC::AllocationSpace::forEachCell):
(JSC::AllocationSpace::forEachBlock):
(JSC::AllocationSpace::allocate):
* heap/Heap.cpp:
(JSC::Heap::Heap):
(JSC::Heap::reportExtraMemoryCostSlowCase):
(JSC::Heap::getConservativeRegisterRoots):
(JSC::Heap::markRoots):
(JSC::Heap::clearMarks):
(JSC::Heap::sweep):
(JSC::Heap::objectCount):
(JSC::Heap::size):
(JSC::Heap::capacity):
(JSC::Heap::globalObjectCount):
(JSC::Heap::objectTypeCounts):
(JSC::Heap::collect):
(JSC::Heap::canonicalizeBlocks):
(JSC::Heap::resetAllocator):
(JSC::Heap::freeBlocks):
(JSC::Heap::shrink):
* heap/Heap.h:
(JSC::Heap::objectSpace):
(JSC::Heap::sizeClassForObject):
(JSC::Heap::allocate):
* jit/JITInlineMethods.h:
(JSC::JIT::emitAllocateBasicJSObject):
* runtime/JSGlobalData.cpp:
(JSC::JSGlobalData::recompileAllJSFunctions):
(JSC::JSGlobalData::releaseExecutableMemory):

../../../../Volumes/Data/git/WebKit/OpenSource/Source/WebCore:

Adding a forwarding header.

* ForwardingHeaders/heap/AllocationSpace.h: Added.

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

18 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.pro
Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/debugger/Debugger.cpp
Source/JavaScriptCore/heap/AllocationSpace.cpp [new file with mode: 0644]
Source/JavaScriptCore/heap/AllocationSpace.h [new file with mode: 0644]
Source/JavaScriptCore/heap/Heap.cpp
Source/JavaScriptCore/heap/Heap.h
Source/JavaScriptCore/jit/JITInlineMethods.h
Source/JavaScriptCore/runtime/JSGlobalData.cpp
Source/WebCore/ChangeLog
Source/WebCore/ForwardingHeaders/heap/AllocationSpace.h [new file with mode: 0644]

index 40cbe76..fc526b6 100644 (file)
@@ -45,6 +45,7 @@ SET(JavaScriptCore_SOURCES
     bytecompiler/BytecodeGenerator.cpp
     bytecompiler/NodesCodegen.cpp
 
+    heap/AllocationSpace.cpp
     heap/Heap.cpp
     heap/HandleHeap.cpp
     heap/HandleStack.cpp
index 5321460..1198e29 100644 (file)
@@ -1,3 +1,72 @@
+2011-09-19  Oliver Hunt  <oliver@apple.com>
+
+        Refactor Heap allocation logic into separate AllocationSpace class
+        https://bugs.webkit.org/show_bug.cgi?id=68409
+
+        Reviewed by Gavin Barraclough.
+
+        This patch hoists direct manipulation of the MarkedSpace and related
+        data out of Heap and into a separate class.  This will allow us to
+        have multiple allocation spaces in future, so easing the way towards
+        having GC'd backing stores for objects.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * JavaScriptCore.exp:
+        * JavaScriptCore.gypi:
+        * JavaScriptCore.pro:
+        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * debugger/Debugger.cpp:
+        (JSC::Debugger::recompileAllJSFunctions):
+        * heap/AllocationSpace.cpp: Added.
+        (JSC::AllocationSpace::tryAllocate):
+        (JSC::AllocationSpace::allocateSlowCase):
+        (JSC::AllocationSpace::allocateBlock):
+        (JSC::AllocationSpace::freeBlocks):
+        (JSC::TakeIfEmpty::TakeIfEmpty):
+        (JSC::TakeIfEmpty::operator()):
+        (JSC::TakeIfEmpty::returnValue):
+        (JSC::AllocationSpace::shrink):
+        * heap/AllocationSpace.h: Added.
+        (JSC::AllocationSpace::AllocationSpace):
+        (JSC::AllocationSpace::blocks):
+        (JSC::AllocationSpace::sizeClassFor):
+        (JSC::AllocationSpace::setHighWaterMark):
+        (JSC::AllocationSpace::highWaterMark):
+        (JSC::AllocationSpace::canonicalizeBlocks):
+        (JSC::AllocationSpace::resetAllocator):
+        (JSC::AllocationSpace::forEachCell):
+        (JSC::AllocationSpace::forEachBlock):
+        (JSC::AllocationSpace::allocate):
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap):
+        (JSC::Heap::reportExtraMemoryCostSlowCase):
+        (JSC::Heap::getConservativeRegisterRoots):
+        (JSC::Heap::markRoots):
+        (JSC::Heap::clearMarks):
+        (JSC::Heap::sweep):
+        (JSC::Heap::objectCount):
+        (JSC::Heap::size):
+        (JSC::Heap::capacity):
+        (JSC::Heap::globalObjectCount):
+        (JSC::Heap::objectTypeCounts):
+        (JSC::Heap::collect):
+        (JSC::Heap::canonicalizeBlocks):
+        (JSC::Heap::resetAllocator):
+        (JSC::Heap::freeBlocks):
+        (JSC::Heap::shrink):
+        * heap/Heap.h:
+        (JSC::Heap::objectSpace):
+        (JSC::Heap::sizeClassForObject):
+        (JSC::Heap::allocate):
+        * jit/JITInlineMethods.h:
+        (JSC::JIT::emitAllocateBasicJSObject):
+        * runtime/JSGlobalData.cpp:
+        (JSC::JSGlobalData::recompileAllJSFunctions):
+        (JSC::JSGlobalData::releaseExecutableMemory):
+
 2011-09-19  Geoffrey Garen  <ggaren@apple.com>
 
         Removed BREWMP* platform #ifdefs
index fafe39c..be74c9b 100644 (file)
@@ -133,6 +133,8 @@ javascriptcore_sources += \
        Source/JavaScriptCore/dfg/DFGScoreBoard.h \
        Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp \
        Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h \
+       Source/JavaScriptCore/heap/AllocationSpace.cpp \
+       Source/JavaScriptCore/heap/AllocationSpace.h \
        Source/JavaScriptCore/heap/ConservativeRoots.cpp \
        Source/JavaScriptCore/heap/ConservativeRoots.h \
        Source/JavaScriptCore/heap/Handle.h \
index ca027ee..528a514 100644 (file)
@@ -118,6 +118,7 @@ __ZN3JSC10throwErrorEPNS_9ExecStateEPNS_8JSObjectE
 __ZN3JSC11JSByteArray13s_defaultInfoE
 __ZN3JSC11JSByteArray15createStructureERNS_12JSGlobalDataEPNS_14JSGlobalObjectENS_7JSValueEPKNS_9ClassInfoE
 __ZN3JSC11JSByteArrayC1EPNS_9ExecStateEPNS_9StructureEPN3WTF9ByteArrayE
+__ZN3JSC15AllocationSpace16allocateSlowCaseERNS_11MarkedSpace9SizeClassE
 __ZN3JSC11ParserArena5resetEv
 __ZN3JSC11checkSyntaxEPNS_9ExecStateERKNS_10SourceCodeEPNS_7JSValueE
 __ZN3JSC11createErrorEPNS_9ExecStateERKNS_7UStringE
@@ -233,7 +234,6 @@ __ZN3JSC35createInterruptedExecutionExceptionEPNS_12JSGlobalDataE
 __ZN3JSC41constructFunctionSkippingEvalEnabledCheckEPNS_9ExecStateEPNS_14JSGlobalObjectERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi
 __ZN3JSC4Heap11objectCountEv
 __ZN3JSC4Heap16activityCallbackEv
-__ZN3JSC4Heap16allocateSlowCaseERNS_11MarkedSpace9SizeClassE
 __ZN3JSC4Heap16objectTypeCountsEv
 __ZN3JSC4Heap17collectAllGarbageEv
 __ZN3JSC4Heap17globalObjectCountEv
index 681ad63..ad6361b 100644 (file)
@@ -27,6 +27,7 @@
             'API/OpaqueJSString.h',
             'assembler/MacroAssemblerCodeRef.h',
             'bytecode/Opcode.h',
+            'heap/AllocationSpace.h',
             'heap/ConservativeRoots.h',
             'heap/Handle.h',
             'heap/HandleHeap.h',
             'bytecompiler/LabelScope.h',
             'bytecompiler/NodesCodegen.cpp',
             'bytecompiler/RegisterID.h',
+            'heap/AllocationSpace.cpp',
             'heap/ConservativeRoots.cpp',
             'heap/HandleHeap.cpp',
             'heap/HandleStack.cpp',
index ba827b8..c06e2f9 100644 (file)
@@ -72,6 +72,7 @@ SOURCES += \
     bytecode/ValueProfile.cpp \
     bytecompiler/BytecodeGenerator.cpp \
     bytecompiler/NodesCodegen.cpp \
+    heap/AllocationSpace.cpp \
     heap/ConservativeRoots.cpp \
     heap/HandleHeap.cpp \
     heap/HandleStack.cpp \
index 763dd00..a0d5468 100644 (file)
@@ -59,9 +59,8 @@ EXPORTS
     ?addPropertyWithoutTransition@Structure@JSC@@QAEIAAVJSGlobalData@2@ABVIdentifier@2@IPAVJSCell@2@@Z
     ?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVExecState@2@PAVStringImpl@4@@Z
     ?addStaticGlobals@JSGlobalObject@JSC@@IAEXPAUGlobalPropertyInfo@12@H@Z
-    ?allocate@Heap@JSC@@QAEPAXAAUSizeClass@MarkedSpace@2@@Z
     ?allocatePropertyStorage@JSObject@JSC@@QAEXAAVJSGlobalData@2@II@Z
-    ?allocateSlowCase@Heap@JSC@@AAEPAXAAUSizeClass@MarkedSpace@2@@Z
+    ?allocateSlowCase@AllocationSpace@JSC@@AAEPAXAAUSizeClass@MarkedSpace@2@@Z
     ?append@StringBuilder@WTF@@QAEXPBDI@Z
     ?append@StringBuilder@WTF@@QAEXPB_WI@Z
     ?ascii@UString@JSC@@QBE?AVCString@WTF@@XZ
index 0925d33..3b30834 100644 (file)
                        Name="heap"
                        >
                             <File
+                                    RelativePath="..\..\heap\AllocationSpace.cpp"
+                                    >
+                            </File>
+                            <File
+                                    RelativePath="..\..\heap\AllocationSpace.h"
+                                    >
+                            </File>
+                            <File
                                     RelativePath="..\..\heap\ConservativeRoots.cpp"
                                     >
                             </File>
index f7421d7..dc0b762 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 = (
+                               A70456AF1427FB150037DA68 /* AllocationSpace.h */,
+                               A70456AE1427FB030037DA68 /* AllocationSpace.cpp */,
                                0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */,
                                0FC815141405118D00CFA603 /* VTableSpectrum.h */,
                                0FC815121405118600CFA603 /* VTableSpectrum.cpp */,
                                A7BC0C82140608B000B1BB71 /* CheckedArithmetic.h in Headers */,
                                A781E359141970C700094D90 /* StorageBarrier.h in Headers */,
                                1A08277A142168D70090CCAC /* BinarySemaphore.h in Headers */,
+                               A70456B01427FB910037DA68 /* AllocationSpace.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                C22C52FE13FAF6EF00B7DC0D /* fixed-dtoa.cc in Sources */,
                                C22C531313FAF6EF00B7DC0D /* strtod.cc in Sources */,
                                1A082779142168D70090CCAC /* BinarySemaphore.cpp in Sources */,
+                               A70456B11427FB950037DA68 /* AllocationSpace.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 61044a8..13d6ad8 100644 (file)
@@ -118,7 +118,7 @@ void Debugger::recompileAllJSFunctions(JSGlobalData* globalData)
         return;
 
     Recompiler recompiler(this);
-    globalData->heap.forEachCell(recompiler);
+    globalData->heap.objectSpace().forEachCell(recompiler);
 }
 
 JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSGlobalObject* globalObject)
diff --git a/Source/JavaScriptCore/heap/AllocationSpace.cpp b/Source/JavaScriptCore/heap/AllocationSpace.cpp
new file mode 100644 (file)
index 0000000..41c127b
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * 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"
+
+#define COLLECT_ON_EVERY_ALLOCATION 0
+
+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
+    collectAllGarbage();
+    ASSERT(m_heap->m_operationInProgress == NoOperation);
+#endif
+    
+    void* result = tryAllocate(sizeClass);
+    
+    if (LIKELY(result != 0))
+        return result;
+    
+    AllocationEffort allocationEffort;
+    
+    if (m_markedSpace.waterMark() < m_markedSpace.highWaterMark() || !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_markedSpace.waterMark() < m_markedSpace.highWaterMark());
+    
+    m_markedSpace.addBlock(sizeClass, allocateBlock(sizeClass.cellSize, AllocationMustSucceed));
+    
+    result = tryAllocate(sizeClass);
+    ASSERT(result);
+    return result;
+}
+
+MarkedBlock* AllocationSpace::allocateBlock(size_t cellSize, AllocationSpace::AllocationEffort allocationEffort)
+{
+    MarkedBlock* block;
+    
+    {
+        MutexLocker locker(m_heap->m_freeBlockLock);
+        if (m_heap->m_numberOfFreeBlocks) {
+            block = m_heap->m_freeBlocks.removeHead();
+            ASSERT(block);
+            m_heap->m_numberOfFreeBlocks--;
+        } else
+            block = 0;
+    }
+    if (block)
+        block->initForCellSize(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 = block->next();
+        
+        m_blocks.remove(block);
+        block->reset();
+        MutexLocker locker(m_heap->m_freeBlockLock);
+        m_heap->m_freeBlocks.append(block);
+        m_heap->m_numberOfFreeBlocks++;
+    }
+}
+
+class TakeIfEmpty {
+public:
+    typedef MarkedBlock* ReturnType;
+    
+    TakeIfEmpty(MarkedSpace*);
+    void operator()(MarkedBlock*);
+    ReturnType returnValue();
+    
+private:
+    MarkedSpace* m_markedSpace;
+    DoublyLinkedList<MarkedBlock> m_empties;
+};
+
+inline TakeIfEmpty::TakeIfEmpty(MarkedSpace* newSpace)
+    : m_markedSpace(newSpace)
+{
+}
+
+inline void TakeIfEmpty::operator()(MarkedBlock* block)
+{
+    if (!block->isEmpty())
+        return;
+    
+    m_markedSpace->removeBlock(block);
+    m_empties.append(block);
+}
+
+inline TakeIfEmpty::ReturnType TakeIfEmpty::returnValue()
+{
+    return m_empties.head();
+}
+
+void AllocationSpace::shrink()
+{
+    // We record a temporary list of empties to avoid modifying m_blocks while iterating it.
+    TakeIfEmpty takeIfEmpty(&m_markedSpace);
+    freeBlocks(forEachBlock(takeIfEmpty));
+}
+
+}
diff --git a/Source/JavaScriptCore/heap/AllocationSpace.h b/Source/JavaScriptCore/heap/AllocationSpace.h
new file mode 100644 (file)
index 0000000..25b95e3
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * 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); }
+    void setHighWaterMark(size_t bytes) { m_markedSpace.setHighWaterMark(bytes); }
+    size_t highWaterMark() { return m_markedSpace.highWaterMark(); }
+    
+    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 canonicalizeBlocks() { m_markedSpace.canonicalizeBlocks(); }
+    void resetAllocator() { m_markedSpace.resetAllocator(); }
+    
+    void* allocate(size_t);
+    void freeBlocks(MarkedBlock*);
+    void shrink();
+    
+private:
+    enum AllocationEffort { AllocationMustSucceed, AllocationCanFail };
+    
+    void* allocate(MarkedSpace::SizeClass&);
+    void* tryAllocate(MarkedSpace::SizeClass&);
+    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)
+{
+    canonicalizeBlocks();
+    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)
+{
+    canonicalizeBlocks();
+    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 26e4ef4..9b4ed6a 100644 (file)
@@ -33,7 +33,6 @@
 #include "Tracing.h"
 #include <algorithm>
 
-#define COLLECT_ON_EVERY_ALLOCATION 0
 
 using namespace std;
 using namespace JSC;
@@ -175,38 +174,6 @@ inline void CountIfGlobalObject::operator()(JSCell* cell)
     count(1);
 }
 
-class TakeIfEmpty {
-public:
-    typedef MarkedBlock* ReturnType;
-
-    TakeIfEmpty(MarkedSpace*);
-    void operator()(MarkedBlock*);
-    ReturnType returnValue();
-
-private:
-    MarkedSpace* m_markedSpace;
-    DoublyLinkedList<MarkedBlock> m_empties;
-};
-
-inline TakeIfEmpty::TakeIfEmpty(MarkedSpace* newSpace)
-    : m_markedSpace(newSpace)
-{
-}
-
-inline void TakeIfEmpty::operator()(MarkedBlock* block)
-{
-    if (!block->isEmpty())
-        return;
-
-    m_markedSpace->removeBlock(block);
-    m_empties.append(block);
-}
-
-inline TakeIfEmpty::ReturnType TakeIfEmpty::returnValue()
-{
-    return m_empties.head();
-}
-
 class RecordType {
 public:
     typedef PassOwnPtr<TypeCountSet> ReturnType;
@@ -249,7 +216,7 @@ Heap::Heap(JSGlobalData* globalData, HeapSize heapSize)
     : m_heapSize(heapSize)
     , m_minBytesPerCycle(heapSizeForHint(heapSize))
     , m_operationInProgress(NoOperation)
-    , m_markedSpace(this)
+    , m_objectSpace(this)
     , m_extraCost(0)
     , m_markListSet(0)
     , m_activityCallback(DefaultGCActivityCallback::create(this))
@@ -259,7 +226,7 @@ Heap::Heap(JSGlobalData* globalData, HeapSize heapSize)
     , m_isSafeToCollect(false)
     , m_globalData(globalData)
 {
-    m_markedSpace.setHighWaterMark(m_minBytesPerCycle);
+    m_objectSpace.setHighWaterMark(m_minBytesPerCycle);
     (*m_activityCallback)();
     m_numberOfFreeBlocks = 0;
     m_blockFreeingThread = createThread(blockFreeingThreadStartFunc, this, "JavaScriptCore::BlockFree");
@@ -393,62 +360,11 @@ void Heap::reportExtraMemoryCostSlowCase(size_t cost)
     // if a large value survives one garbage collection, there is not much point to
     // collecting more frequently as long as it stays alive.
 
-    if (m_extraCost > maxExtraCost && m_extraCost > m_markedSpace.highWaterMark() / 2)
+    if (m_extraCost > maxExtraCost && m_extraCost > m_objectSpace.highWaterMark() / 2)
         collectAllGarbage();
     m_extraCost += cost;
 }
 
-inline void* Heap::tryAllocate(MarkedSpace::SizeClass& sizeClass)
-{
-    m_operationInProgress = Allocation;
-    void* result = m_markedSpace.allocate(sizeClass);
-    m_operationInProgress = NoOperation;
-    return result;
-}
-
-void* Heap::allocateSlowCase(MarkedSpace::SizeClass& sizeClass)
-{
-#if COLLECT_ON_EVERY_ALLOCATION
-    collectAllGarbage();
-    ASSERT(m_operationInProgress == NoOperation);
-#endif
-
-    void* result = tryAllocate(sizeClass);
-
-    if (LIKELY(result != 0))
-        return result;
-
-    AllocationEffort allocationEffort;
-    
-    if (m_markedSpace.waterMark() < m_markedSpace.highWaterMark() || !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;
-    }
-
-    collect(DoNotSweep);
-    
-    result = tryAllocate(sizeClass);
-    
-    if (result)
-        return result;
-    
-    ASSERT(m_markedSpace.waterMark() < m_markedSpace.highWaterMark());
-    
-    m_markedSpace.addBlock(sizeClass, allocateBlock(sizeClass.cellSize, AllocationMustSucceed));
-    
-    result = tryAllocate(sizeClass);
-    ASSERT(result);
-    return result;
-}
-
 void Heap::protect(JSValue k)
 {
     ASSERT(k);
@@ -521,7 +437,7 @@ void Heap::getConservativeRegisterRoots(HashSet<JSCell*>& roots)
     if (m_operationInProgress != NoOperation)
         CRASH();
     m_operationInProgress = Collection;
-    ConservativeRoots registerFileRoots(&m_blocks);
+    ConservativeRoots registerFileRoots(&m_objectSpace.blocks());
     registerFile().gatherConservativeRoots(registerFileRoots);
     size_t registerFileRootCount = registerFileRoots.size();
     JSCell** registerRoots = registerFileRoots.roots();
@@ -543,10 +459,10 @@ void Heap::markRoots()
 
     // We gather conservative roots before clearing mark bits because conservative
     // gathering uses the mark bits to determine whether a reference is valid.
-    ConservativeRoots machineThreadRoots(&m_blocks);
+    ConservativeRoots machineThreadRoots(&m_objectSpace.blocks());
     m_machineThreads.gatherConservativeRoots(machineThreadRoots, &dummy);
 
-    ConservativeRoots registerFileRoots(&m_blocks);
+    ConservativeRoots registerFileRoots(&m_objectSpace.blocks());
     registerFile().gatherConservativeRoots(registerFileRoots);
 
     clearMarks();
@@ -599,27 +515,27 @@ void Heap::markRoots()
 
 void Heap::clearMarks()
 {
-    forEachBlock<ClearMarks>();
+    m_objectSpace.forEachBlock<ClearMarks>();
 }
 
 void Heap::sweep()
 {
-    forEachBlock<Sweep>();
+    m_objectSpace.forEachBlock<Sweep>();
 }
 
 size_t Heap::objectCount()
 {
-    return forEachBlock<MarkCount>();
+    return m_objectSpace.forEachBlock<MarkCount>();
 }
 
 size_t Heap::size()
 {
-    return forEachBlock<Size>();
+    return m_objectSpace.forEachBlock<Size>();
 }
 
 size_t Heap::capacity()
 {
-    return forEachBlock<Capacity>();
+    return m_objectSpace.forEachBlock<Capacity>();
 }
 
 size_t Heap::protectedGlobalObjectCount()
@@ -629,7 +545,7 @@ size_t Heap::protectedGlobalObjectCount()
 
 size_t Heap::globalObjectCount()
 {
-    return forEachCell<CountIfGlobalObject>();
+    return m_objectSpace.forEachCell<CountIfGlobalObject>();
 }
 
 size_t Heap::protectedObjectCount()
@@ -644,7 +560,7 @@ PassOwnPtr<TypeCountSet> Heap::protectedObjectTypeCounts()
 
 PassOwnPtr<TypeCountSet> Heap::objectTypeCounts()
 {
-    return forEachCell<RecordType>();
+    return m_objectSpace.forEachCell<RecordType>();
 }
 
 void Heap::collectAllGarbage()
@@ -683,7 +599,7 @@ void Heap::collect(SweepToggle sweepToggle)
     // proportion is a bit arbitrary. A 2X multiplier gives a 1:1 (heap size :
     // new bytes allocated) proportion, and seems to work well in benchmarks.
     size_t proportionalBytes = 2 * size();
-    m_markedSpace.setHighWaterMark(max(proportionalBytes, m_minBytesPerCycle));
+    m_objectSpace.setHighWaterMark(max(proportionalBytes, m_minBytesPerCycle));
     JAVASCRIPTCORE_GC_END();
 
     (*m_activityCallback)();
@@ -691,13 +607,13 @@ void Heap::collect(SweepToggle sweepToggle)
 
 void Heap::canonicalizeBlocks()
 {
-    m_markedSpace.canonicalizeBlocks();
+    m_objectSpace.canonicalizeBlocks();
 }
 
 void Heap::resetAllocator()
 {
     m_extraCost = 0;
-    m_markedSpace.resetAllocator();
+    m_objectSpace.resetAllocator();
 }
 
 void Heap::setActivityCallback(PassOwnPtr<GCActivityCallback> activityCallback)
@@ -724,50 +640,14 @@ bool Heap::isValidAllocation(size_t bytes)
     return true;
 }
 
-MarkedBlock* Heap::allocateBlock(size_t cellSize, Heap::AllocationEffort allocationEffort)
-{
-    MarkedBlock* block;
-    
-    {
-        MutexLocker locker(m_freeBlockLock);
-        if (m_numberOfFreeBlocks) {
-            block = m_freeBlocks.removeHead();
-            ASSERT(block);
-            m_numberOfFreeBlocks--;
-        } else
-            block = 0;
-    }
-    if (block)
-        block->initForCellSize(cellSize);
-    else if (allocationEffort == AllocationCanFail)
-        return 0;
-    else
-        block = MarkedBlock::create(this, cellSize);
-    
-    m_blocks.add(block);
-
-    return block;
-}
-
 void Heap::freeBlocks(MarkedBlock* head)
 {
-    MarkedBlock* next;
-    for (MarkedBlock* block = head; block; block = next) {
-        next = block->next();
-
-        m_blocks.remove(block);
-        block->reset();
-        MutexLocker locker(m_freeBlockLock);
-        m_freeBlocks.append(block);
-        m_numberOfFreeBlocks++;
-    }
+    m_objectSpace.freeBlocks(head);
 }
 
 void Heap::shrink()
 {
-    // We record a temporary list of empties to avoid modifying m_blocks while iterating it.
-    TakeIfEmpty takeIfEmpty(&m_markedSpace);
-    freeBlocks(forEachBlock(takeIfEmpty));
+    m_objectSpace.shrink();
 }
 
 void Heap::releaseFreeBlocks()
index 3d59259..4ff2603 100644 (file)
@@ -22,6 +22,7 @@
 #ifndef Heap_h
 #define Heap_h
 
+#include "AllocationSpace.h"
 #include "HandleHeap.h"
 #include "HandleStack.h"
 #include "MarkedBlock.h"
@@ -37,6 +38,7 @@ namespace JSC {
 
     class GCActivityCallback;
     class GlobalCodeBlock;
+    class Heap;
     class HeapRootVisitor;
     class JSCell;
     class JSGlobalData;
@@ -56,10 +58,11 @@ namespace JSC {
     
     // Heap size hint.
     enum HeapSize { SmallHeap, LargeHeap };
-    
+
     class Heap {
         WTF_MAKE_NONCOPYABLE(Heap);
     public:
+        friend class JIT;
         static Heap* heap(JSValue); // 0 for immediate values
         static Heap* heap(JSCell*);
 
@@ -76,7 +79,7 @@ namespace JSC {
         void destroy(); // JSGlobalData must call destroy() before ~Heap().
 
         JSGlobalData* globalData() const { return m_globalData; }
-        MarkedSpace& markedSpace() { return m_markedSpace; }
+        AllocationSpace& objectSpace() { return m_objectSpace; }
         MachineThreads& machineThreads() { return m_machineThreads; }
 
         GCActivityCallback* activityCallback();
@@ -84,10 +87,10 @@ namespace JSC {
 
         // true if an allocation or collection is in progress
         inline bool isBusy();
-
+        
+        MarkedSpace::SizeClass& sizeClassForObject(size_t bytes) { return m_objectSpace.sizeClassFor(bytes); }
         void* allocate(size_t);
-        MarkedSpace::SizeClass& sizeClassFor(size_t);
-        void* allocate(MarkedSpace::SizeClass&);
+
         void notifyIsSafeToCollect() { m_isSafeToCollect = true; }
         void collectAllGarbage();
 
@@ -112,10 +115,6 @@ namespace JSC {
         
         template<typename Functor> typename Functor::ReturnType forEachProtectedCell(Functor&);
         template<typename Functor> typename Functor::ReturnType forEachProtectedCell();
-        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();
         
         HandleSlot allocateGlobalHandle() { return m_handleHeap.allocate(); }
         HandleSlot allocateLocalHandle() { return m_handleStack.push(); }
@@ -125,14 +124,11 @@ namespace JSC {
 
     private:
         friend class MarkedBlock;
-        
-        typedef HashSet<MarkedBlock*>::iterator BlockIterator;
+        friend class AllocationSpace;
 
         static const size_t minExtraCost = 256;
         static const size_t maxExtraCost = 1024 * 1024;
         
-        enum AllocationEffort { AllocationMustSucceed, AllocationCanFail };
-        
 #if ENABLE(GGC)
         static void writeBarrierFastCase(const JSCell* owner, JSCell*);
 #endif
@@ -142,7 +138,6 @@ namespace JSC {
         void canonicalizeBlocks();
         void resetAllocator();
 
-        MarkedBlock* allocateBlock(size_t cellSize, AllocationEffort);
         void freeBlocks(MarkedBlock*);
 
         void clearMarks();
@@ -150,9 +145,6 @@ namespace JSC {
         void markProtectedObjects(HeapRootVisitor&);
         void markTempSortVectors(HeapRootVisitor&);
         void harvestWeakReferences();
-
-        void* tryAllocate(MarkedSpace::SizeClass&);
-        void* allocateSlowCase(MarkedSpace::SizeClass&);
         
         enum SweepToggle { DoNotSweep, DoSweep };
         void collect(SweepToggle);
@@ -173,8 +165,7 @@ namespace JSC {
         const size_t m_minBytesPerCycle;
         
         OperationInProgress m_operationInProgress;
-        MarkedSpace m_markedSpace;
-        MarkedBlockSet m_blocks;
+        AllocationSpace m_objectSpace;
 
         DoublyLinkedList<MarkedBlock> m_freeBlocks;
         size_t m_numberOfFreeBlocks;
@@ -302,57 +293,10 @@ namespace JSC {
         return forEachProtectedCell(functor);
     }
 
-    template<typename Functor> inline typename Functor::ReturnType Heap::forEachCell(Functor& functor)
-    {
-        canonicalizeBlocks();
-        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 Heap::forEachCell()
-    {
-        Functor functor;
-        return forEachCell(functor);
-    }
-
-    template<typename Functor> inline typename Functor::ReturnType Heap::forEachBlock(Functor& functor)
-    {
-        canonicalizeBlocks();
-        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 Heap::forEachBlock()
-    {
-        Functor functor;
-        return forEachBlock(functor);
-    }
-    
-    inline MarkedSpace::SizeClass& Heap::sizeClassFor(size_t bytes)
-    {
-        return m_markedSpace.sizeClassFor(bytes);
-    }
-    
-    inline void* Heap::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* Heap::allocate(size_t bytes)
     {
         ASSERT(isValidAllocation(bytes));
-        MarkedSpace::SizeClass& sizeClass = sizeClassFor(bytes);
-        return allocate(sizeClass);
+        return m_objectSpace.allocate(bytes);
     }
 
 } // namespace JSC
index 38af0c7..7ef6b29 100644 (file)
@@ -394,7 +394,7 @@ ALWAYS_INLINE bool JIT::isOperandConstantImmediateChar(unsigned src)
 
 template <typename ClassType, typename StructureType> inline void JIT::emitAllocateBasicJSObject(StructureType structure, void* vtable, RegisterID result, RegisterID storagePtr)
 {
-    MarkedSpace::SizeClass* sizeClass = &m_globalData->heap.sizeClassFor(sizeof(ClassType));
+    MarkedSpace::SizeClass* sizeClass = &m_globalData->heap.sizeClassForObject(sizeof(ClassType));
     loadPtr(&sizeClass->firstFreeCell, result);
     addSlowCase(branchTestPtr(Zero, result));
 
index 0a4c9de..49a0db7 100644 (file)
@@ -447,7 +447,7 @@ void JSGlobalData::recompileAllJSFunctions()
     // up throwing away code that is live on the stack.
     ASSERT(!dynamicGlobalObject);
     
-    heap.forEachCell<Recompiler>();
+    heap.objectSpace().forEachCell<Recompiler>();
 }
 
 struct StackPreservingRecompiler : public MarkedBlock::VoidFunctor {
@@ -488,7 +488,7 @@ void JSGlobalData::releaseExecutableMemory()
                 recompiler.currentlyExecutingFunctions.add(static_cast<FunctionExecutable*>(executable));
                 
         }
-        heap.forEachCell<StackPreservingRecompiler>(recompiler);
+        heap.objectSpace().forEachCell<StackPreservingRecompiler>(recompiler);
     }
     m_regExpCache->invalidateCode();
     heap.collectAllGarbage();
index f816d24..6cca310 100644 (file)
@@ -1,3 +1,14 @@
+2011-09-19  Oliver Hunt  <oliver@apple.com>
+
+        Refactor Heap allocation logic into separate AllocationSpace class
+        https://bugs.webkit.org/show_bug.cgi?id=68409
+
+        Reviewed by Gavin Barraclough.
+
+        Adding a forwarding header.
+
+        * ForwardingHeaders/heap/AllocationSpace.h: Added.
+
 2011-09-20  Geoffrey Garen  <ggaren@apple.com>
 
         Build fix.
diff --git a/Source/WebCore/ForwardingHeaders/heap/AllocationSpace.h b/Source/WebCore/ForwardingHeaders/heap/AllocationSpace.h
new file mode 100644 (file)
index 0000000..5e4f5f4
--- /dev/null
@@ -0,0 +1,4 @@
+#ifndef WebCore_FWD_AllocationSpace_h
+#define WebCore_FWD_AllocationSpace_h
+#include <JavaScriptCore/AllocationSpace.h>
+#endif