Unreviewed, rolling out r179192.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 27 Jan 2015 21:34:32 +0000 (21:34 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 27 Jan 2015 21:34:32 +0000 (21:34 +0000)
https://bugs.webkit.org/show_bug.cgi?id=140953

Caused numerous layout test failures (Requested by mattbaker_
on #webkit).

Reverted changeset:

"Use FastMalloc (bmalloc) instead of BlockAllocator for GC
pages"
https://bugs.webkit.org/show_bug.cgi?id=140900
http://trac.webkit.org/changeset/179192

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

46 files changed:
Source/JavaScriptCore/API/JSBase.cpp
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/heap/BlockAllocator.cpp [new file with mode: 0644]
Source/JavaScriptCore/heap/BlockAllocator.h [new file with mode: 0644]
Source/JavaScriptCore/heap/CodeBlockSet.cpp
Source/JavaScriptCore/heap/CodeBlockSet.h
Source/JavaScriptCore/heap/CopiedBlock.h
Source/JavaScriptCore/heap/CopiedBlockInlines.h
Source/JavaScriptCore/heap/CopiedSpace.cpp
Source/JavaScriptCore/heap/CopiedSpaceInlines.h
Source/JavaScriptCore/heap/CopyWorkList.h
Source/JavaScriptCore/heap/GCSegmentedArray.h
Source/JavaScriptCore/heap/GCSegmentedArrayInlines.h
Source/JavaScriptCore/heap/GCThreadSharedData.cpp
Source/JavaScriptCore/heap/GCThreadSharedData.h
Source/JavaScriptCore/heap/HandleBlock.h
Source/JavaScriptCore/heap/HandleBlockInlines.h
Source/JavaScriptCore/heap/HandleSet.cpp
Source/JavaScriptCore/heap/Heap.cpp
Source/JavaScriptCore/heap/Heap.h
Source/JavaScriptCore/heap/HeapBlock.h
Source/JavaScriptCore/heap/HeapInlines.h
Source/JavaScriptCore/heap/HeapTimer.cpp
Source/JavaScriptCore/heap/MarkStack.cpp
Source/JavaScriptCore/heap/MarkStack.h
Source/JavaScriptCore/heap/MarkedAllocator.cpp
Source/JavaScriptCore/heap/MarkedBlock.cpp
Source/JavaScriptCore/heap/MarkedBlock.h
Source/JavaScriptCore/heap/MarkedSpace.cpp
Source/JavaScriptCore/heap/MarkedSpace.h
Source/JavaScriptCore/heap/Region.h [new file with mode: 0644]
Source/JavaScriptCore/heap/SlotVisitor.cpp
Source/JavaScriptCore/heap/SuperRegion.cpp [new file with mode: 0644]
Source/JavaScriptCore/heap/SuperRegion.h [new file with mode: 0644]
Source/JavaScriptCore/heap/WeakBlock.cpp
Source/JavaScriptCore/heap/WeakBlock.h
Source/JavaScriptCore/heap/WeakSet.cpp
Source/WTF/ChangeLog
Source/WTF/wtf/FastMalloc.cpp
Source/WTF/wtf/FastMalloc.h
Source/WebCore/ChangeLog
Source/WebCore/platform/cocoa/MemoryPressureHandlerCocoa.mm

index e4f5946..2923958 100644 (file)
@@ -30,7 +30,6 @@
 #include "APICast.h"
 #include "CallFrame.h"
 #include "Completion.h"
-#include "GCActivityCallback.h"
 #include "InitializeThreading.h"
 #include "JSGlobalObject.h"
 #include "JSLock.h"
index cdf1e5a..61cda22 100644 (file)
@@ -248,6 +248,7 @@ set(JavaScriptCore_SOURCES
     disassembler/LLVMDisassembler.cpp
     disassembler/X86Disassembler.cpp
 
+    heap/BlockAllocator.cpp
     heap/CodeBlockSet.cpp
     heap/ConservativeRoots.cpp
     heap/CopiedSpace.cpp
@@ -273,6 +274,7 @@ set(JavaScriptCore_SOURCES
     heap/MarkedBlock.cpp
     heap/MarkedSpace.cpp
     heap/SlotVisitor.cpp
+    heap/SuperRegion.cpp
     heap/Weak.cpp
     heap/WeakBlock.cpp
     heap/WeakHandleOwner.cpp
index c5b4bdc..ff0939e 100644 (file)
@@ -1,3 +1,18 @@
+2015-01-27  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r179192.
+        https://bugs.webkit.org/show_bug.cgi?id=140953
+
+        Caused numerous layout test failures (Requested by mattbaker_
+        on #webkit).
+
+        Reverted changeset:
+
+        "Use FastMalloc (bmalloc) instead of BlockAllocator for GC
+        pages"
+        https://bugs.webkit.org/show_bug.cgi?id=140900
+        http://trac.webkit.org/changeset/179192
+
 2015-01-27  Michael Saboff  <msaboff@apple.com>
 
         REGRESSION(r178591): 20% regression in Octane box2d
index f237a69..f66eee6 100644 (file)
     <ClCompile Include="..\ftl\FTLUnwindInfo.cpp" />
     <ClCompile Include="..\ftl\FTLValueFormat.cpp" />
     <ClCompile Include="..\ftl\FTLValueRange.cpp" />
+    <ClCompile Include="..\heap\BlockAllocator.cpp" />
     <ClCompile Include="..\heap\CodeBlockSet.cpp" />
     <ClCompile Include="..\heap\ConservativeRoots.cpp" />
     <ClCompile Include="..\heap\CopiedSpace.cpp" />
     <ClCompile Include="..\heap\MarkedSpace.cpp" />
     <ClCompile Include="..\heap\MarkStack.cpp" />
     <ClCompile Include="..\heap\SlotVisitor.cpp" />
+    <ClCompile Include="..\heap\SuperRegion.cpp" />
     <ClCompile Include="..\heap\Weak.cpp" />
     <ClCompile Include="..\heap\WeakBlock.cpp" />
     <ClCompile Include="..\heap\WeakHandleOwner.cpp" />
     <ClInclude Include="..\ftl\FTLValueRange.h" />
     <ClInclude Include="..\ftl\FTLWeight.h" />
     <ClInclude Include="..\ftl\FTLWeightedTarget.h" />
+    <ClInclude Include="..\heap\BlockAllocator.h" />
     <ClInclude Include="..\heap\CodeBlockSet.h" />
     <ClInclude Include="..\heap\ConservativeRoots.h" />
     <ClInclude Include="..\heap\CopiedAllocator.h" />
     <ClInclude Include="..\heap\MarkedSpace.h" />
     <ClInclude Include="..\heap\MarkStack.h" />
     <ClInclude Include="..\heap\RecursiveAllocationScope.h" />
+    <ClInclude Include="..\heap\Region.h" />
     <ClInclude Include="..\heap\SlotVisitor.h" />
     <ClInclude Include="..\heap\SlotVisitorInlines.h" />
     <ClInclude Include="..\heap\Strong.h" />
     <ClInclude Include="..\heap\StrongInlines.h" />
+    <ClInclude Include="..\heap\SuperRegion.h" />
     <ClInclude Include="..\heap\TinyBloomFilter.h" />
     <ClInclude Include="..\heap\UnconditionalFinalizer.h" />
     <ClInclude Include="..\heap\Weak.h" />
index 390165c..515a32c 100644 (file)
     <ClCompile Include="..\disassembler\Disassembler.cpp">
       <Filter>disassembler</Filter>
     </ClCompile>
+    <ClCompile Include="..\heap\BlockAllocator.cpp">
+      <Filter>heap</Filter>
+    </ClCompile>
     <ClCompile Include="..\heap\ConservativeRoots.cpp">
       <Filter>heap</Filter>
     </ClCompile>
     <ClCompile Include="..\heap\SlotVisitor.cpp">
       <Filter>heap</Filter>
     </ClCompile>
+    <ClCompile Include="..\heap\SuperRegion.cpp">
+      <Filter>heap</Filter>
+    </ClCompile>
     <ClCompile Include="..\heap\Weak.cpp">
       <Filter>heap</Filter>
     </ClCompile>
     <ClInclude Include="..\disassembler\Disassembler.h">
       <Filter>disassembler</Filter>
     </ClInclude>
+    <ClInclude Include="..\heap\BlockAllocator.h">
+      <Filter>heap</Filter>
+    </ClInclude>
     <ClInclude Include="..\heap\ConservativeRoots.h">
       <Filter>heap</Filter>
     </ClInclude>
     <ClInclude Include="..\heap\RecursiveAllocationScope.h">
       <Filter>heap</Filter>
     </ClInclude>
+    <ClInclude Include="..\heap\Region.h">
+      <Filter>heap</Filter>
+    </ClInclude>
     <ClInclude Include="..\heap\SlotVisitor.h">
       <Filter>heap</Filter>
     </ClInclude>
     <ClInclude Include="..\heap\StrongInlines.h">
       <Filter>heap</Filter>
     </ClInclude>
+    <ClInclude Include="..\heap\SuperRegion.h">
+      <Filter>heap</Filter>
+    </ClInclude>
     <ClInclude Include="..\heap\TinyBloomFilter.h">
       <Filter>heap</Filter>
     </ClInclude>
index 212c9ec..4ffe6a0 100644 (file)
                147F39D5107EC37600427A48 /* JSString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC02E9B60E1842FA000F9297 /* JSString.cpp */; };
                147F39D6107EC37600427A48 /* JSCJSValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8870255597D01FF60F7 /* JSCJSValue.cpp */; };
                147F39D7107EC37600427A48 /* JSEnvironmentRecord.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC22A39A0E16E14800AF21C8 /* JSEnvironmentRecord.cpp */; };
+               14816E1B154CC56C00B8054C /* BlockAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14816E19154CC56C00B8054C /* BlockAllocator.cpp */; };
+               14816E1C154CC56C00B8054C /* BlockAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 14816E1A154CC56C00B8054C /* BlockAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1482B74E0A43032800517CFC /* JSStringRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1482B74C0A43032800517CFC /* JSStringRef.cpp */; };
                1482B7E40A43076000517CFC /* JSObjectRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1482B7E20A43076000517CFC /* JSObjectRef.cpp */; };
                14874AE315EBDE4A002E3587 /* JSNameScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14874ADF15EBDE4A002E3587 /* JSNameScope.cpp */; };
                BCFD8C920EEB2EE700283848 /* JumpTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCFD8C900EEB2EE700283848 /* JumpTable.cpp */; };
                BCFD8C930EEB2EE700283848 /* JumpTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BCFD8C910EEB2EE700283848 /* JumpTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C20328201981979D0088B499 /* CustomGlobalObjectClassTest.c in Sources */ = {isa = PBXBuildFile; fileRef = C203281E1981979D0088B499 /* CustomGlobalObjectClassTest.c */; };
+               C20B25991706536200C21F4E /* Region.h in Headers */ = {isa = PBXBuildFile; fileRef = C20B25981706536200C21F4E /* Region.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C20BA92D16BB1C1500B3AEA2 /* StructureRareDataInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C20BA92C16BB1C1500B3AEA2 /* StructureRareDataInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C21122E115DD9AB300790E3A /* GCThreadSharedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C21122DE15DD9AB300790E3A /* GCThreadSharedData.cpp */; };
                C21122E215DD9AB300790E3A /* GCThreadSharedData.h in Headers */ = {isa = PBXBuildFile; fileRef = C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C2CF39C116E15A8100DD69BE /* JSAPIWrapperObject.mm in Sources */ = {isa = PBXBuildFile; fileRef = C2CF39BF16E15A8100DD69BE /* JSAPIWrapperObject.mm */; };
                C2CF39C216E15A8100DD69BE /* JSAPIWrapperObject.h in Headers */ = {isa = PBXBuildFile; fileRef = C2CF39C016E15A8100DD69BE /* JSAPIWrapperObject.h */; };
                C2DA778318E259990066FCB6 /* HeapInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C2DA778218E259990066FCB6 /* HeapInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               C2DF442F1707AC0100A5CA96 /* SuperRegion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2DF442D1707AC0100A5CA96 /* SuperRegion.cpp */; };
+               C2DF44301707AC0100A5CA96 /* SuperRegion.h in Headers */ = {isa = PBXBuildFile; fileRef = C2DF442E1707AC0100A5CA96 /* SuperRegion.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C2E526BD1590EF000054E48D /* HeapTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2E526BB1590EF000054E48D /* HeapTimer.cpp */; };
                C2E526BE1590EF000054E48D /* HeapTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = C2E526BC1590EF000054E48D /* HeapTimer.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C2EAA3FA149A835E00FCE112 /* CopiedSpace.h in Headers */ = {isa = PBXBuildFile; fileRef = C2EAA3F8149A830800FCE112 /* CopiedSpace.h */; settings = {ATTRIBUTES = (Private, ); }; };
                147B83AA0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BatchedTransitionOptimizer.h; sourceTree = "<group>"; };
                147B84620E6DE6B1004775A4 /* PutPropertySlot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PutPropertySlot.h; sourceTree = "<group>"; };
                1480DB9B0DDC227F003CFDF2 /* DebuggerCallFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerCallFrame.h; sourceTree = "<group>"; };
+               14816E19154CC56C00B8054C /* BlockAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BlockAllocator.cpp; sourceTree = "<group>"; };
+               14816E1A154CC56C00B8054C /* BlockAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockAllocator.h; sourceTree = "<group>"; };
                1482B6EA0A4300B300517CFC /* JSValueRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSValueRef.h; sourceTree = "<group>"; };
                1482B74B0A43032800517CFC /* JSStringRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringRef.h; sourceTree = "<group>"; };
                1482B74C0A43032800517CFC /* JSStringRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSStringRef.cpp; sourceTree = "<group>"; };
                BCFD8C910EEB2EE700283848 /* JumpTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JumpTable.h; sourceTree = "<group>"; };
                C203281E1981979D0088B499 /* CustomGlobalObjectClassTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = CustomGlobalObjectClassTest.c; path = API/tests/CustomGlobalObjectClassTest.c; sourceTree = "<group>"; };
                C203281F1981979D0088B499 /* CustomGlobalObjectClassTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CustomGlobalObjectClassTest.h; path = API/tests/CustomGlobalObjectClassTest.h; sourceTree = "<group>"; };
+               C20B25981706536200C21F4E /* Region.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Region.h; sourceTree = "<group>"; };
                C20BA92C16BB1C1500B3AEA2 /* StructureRareDataInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureRareDataInlines.h; sourceTree = "<group>"; };
                C21122DE15DD9AB300790E3A /* GCThreadSharedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCThreadSharedData.cpp; sourceTree = "<group>"; };
                C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCThreadSharedData.h; sourceTree = "<group>"; };
                C2CF39BF16E15A8100DD69BE /* JSAPIWrapperObject.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = JSAPIWrapperObject.mm; sourceTree = "<group>"; };
                C2CF39C016E15A8100DD69BE /* JSAPIWrapperObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSAPIWrapperObject.h; sourceTree = "<group>"; };
                C2DA778218E259990066FCB6 /* HeapInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapInlines.h; sourceTree = "<group>"; };
+               C2DF442D1707AC0100A5CA96 /* SuperRegion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SuperRegion.cpp; sourceTree = "<group>"; };
+               C2DF442E1707AC0100A5CA96 /* SuperRegion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SuperRegion.h; sourceTree = "<group>"; };
                C2E526BB1590EF000054E48D /* HeapTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HeapTimer.cpp; sourceTree = "<group>"; };
                C2E526BC1590EF000054E48D /* HeapTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapTimer.h; sourceTree = "<group>"; };
                C2EAA3F8149A830800FCE112 /* CopiedSpace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopiedSpace.h; sourceTree = "<group>"; };
                                ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */,
                                2AACE63A18CA5A0300ED0191 /* GCActivityCallback.cpp */,
                                2AACE63B18CA5A0300ED0191 /* GCActivityCallback.h */,
+                               14816E19154CC56C00B8054C /* BlockAllocator.cpp */,
+                               14816E1A154CC56C00B8054C /* BlockAllocator.h */,
                                0FD8A31117D4326C00CA2C40 /* CodeBlockSet.cpp */,
                                0FD8A31217D4326C00CA2C40 /* CodeBlockSet.h */,
                                146B14DB12EB5B12001BEC1B /* ConservativeRoots.cpp */,
                                142D6F0E13539A4100B02E86 /* MarkStack.cpp */,
                                142D6F0F13539A4100B02E86 /* MarkStack.h */,
                                2AAD964918569417001F93BE /* RecursiveAllocationScope.h */,
+                               C20B25981706536200C21F4E /* Region.h */,
                                C225494215F7DBAA0065E898 /* SlotVisitor.cpp */,
                                14BA78F013AAB88F005B7C2C /* SlotVisitor.h */,
                                0FCB408515C0A3C30048932B /* SlotVisitorInlines.h */,
                                142E3132134FF0A600AFADB5 /* Strong.h */,
                                145722851437E140005FDE26 /* StrongInlines.h */,
+                               C2DF442D1707AC0100A5CA96 /* SuperRegion.cpp */,
+                               C2DF442E1707AC0100A5CA96 /* SuperRegion.h */,
                                141448CC13A1783700F5BA1A /* TinyBloomFilter.h */,
                                0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */,
                                1ACF7376171CA6FB00C9BB1E /* Weak.cpp */,
                                0F24E54117EA9F5900ABB217 /* AssemblyHelpers.h in Headers */,
                                A784A26111D16622005776AC /* ASTBuilder.h in Headers */,
                                866739D213BFDE710023D87C /* BigInteger.h in Headers */,
+                               14816E1C154CC56C00B8054C /* BlockAllocator.h in Headers */,
                                BC18C3EC0E16F5CD00B34460 /* BooleanObject.h in Headers */,
                                FEA08620182B7A0400F6D851 /* Breakpoint.h in Headers */,
                                A5D2E665195E174000A518E7 /* JSContextRefInternal.h in Headers */,
                                BC18C45B0E16F5CD00B34460 /* RegExpObject.h in Headers */,
                                BC18C52C0E16FCD200B34460 /* RegExpObject.lut.h in Headers */,
                                BCD202C40E1706A7002C7E82 /* RegExpPrototype.h in Headers */,
+                               C20B25991706536200C21F4E /* Region.h in Headers */,
                                BC18C45D0E16F5CD00B34460 /* Register.h in Headers */,
                                969A072B0ED1CE6900F1F681 /* RegisterID.h in Headers */,
                                0F6B1CBA1861244C00845D97 /* RegisterPreservationMode.h in Headers */,
                                0F766D3915AE4A1F008F363E /* StructureStubClearingWatchpoint.h in Headers */,
                                BCCF0D080EF0AAB900413C8F /* StructureStubInfo.h in Headers */,
                                BC9041480EB9250900FE26FA /* StructureTransitionTable.h in Headers */,
+                               C2DF44301707AC0100A5CA96 /* SuperRegion.h in Headers */,
                                BC18C46B0E16F5CD00B34460 /* SymbolTable.h in Headers */,
                                A784A26411D16622005776AC /* SyntaxChecker.h in Headers */,
                                0F24E54F17EE274900ABB217 /* TempRegisterSet.h in Headers */,
                                0F63945415D07055006A597C /* ArrayProfile.cpp in Sources */,
                                147F39C0107EC37600427A48 /* ArrayPrototype.cpp in Sources */,
                                0F24E54017EA9F5900ABB217 /* AssemblyHelpers.cpp in Sources */,
+                               14816E1B154CC56C00B8054C /* BlockAllocator.cpp in Sources */,
                                0F69CC88193AC60A0045759E /* DFGFrozenValue.cpp in Sources */,
                                14280863107EC11A0013E7B2 /* BooleanConstructor.cpp in Sources */,
                                14280864107EC11A0013E7B2 /* BooleanObject.cpp in Sources */,
                                C2F0F2D116BAEEE900187C19 /* StructureRareData.cpp in Sources */,
                                0F766D3815AE4A1C008F363E /* StructureStubClearingWatchpoint.cpp in Sources */,
                                BCCF0D0C0EF0B8A500413C8F /* StructureStubInfo.cpp in Sources */,
+                               C2DF442F1707AC0100A5CA96 /* SuperRegion.cpp in Sources */,
                                0F919D2815856773004A4E7D /* SymbolTable.cpp in Sources */,
                                0FC314131814559100033232 /* TempRegisterSet.cpp in Sources */,
                                0FA2C17B17D7CF84009D015F /* TestRunnerUtils.cpp in Sources */,
diff --git a/Source/JavaScriptCore/heap/BlockAllocator.cpp b/Source/JavaScriptCore/heap/BlockAllocator.cpp
new file mode 100644 (file)
index 0000000..bf408f8
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "BlockAllocator.h"
+
+#include "CopiedBlock.h"
+#include "CopyWorkList.h"
+#include "MarkedBlock.h"
+#include "JSCInlines.h"
+#include "WeakBlock.h"
+#include <wtf/CurrentTime.h>
+
+namespace JSC {
+
+inline ThreadIdentifier createBlockFreeingThread(BlockAllocator* allocator)
+{
+    if (!GCActivityCallback::s_shouldCreateGCTimer)
+        return 0; // No block freeing thread.
+    ThreadIdentifier identifier = createThread(allocator->blockFreeingThreadStartFunc, allocator, "JavaScriptCore::BlockFree");
+    RELEASE_ASSERT(identifier);
+    return identifier;
+}
+
+BlockAllocator::BlockAllocator()
+    : m_superRegion()
+    , m_copiedRegionSet(CopiedBlock::blockSize)
+    , m_markedRegionSet(MarkedBlock::blockSize)
+    , m_fourKBBlockRegionSet(WeakBlock::blockSize)
+    , m_workListRegionSet(CopyWorkListSegment::blockSize)
+    , m_numberOfEmptyRegions(0)
+    , m_isCurrentlyAllocating(false)
+    , m_blockFreeingThreadShouldQuit(false)
+    , m_blockFreeingThread(createBlockFreeingThread(this))
+{
+    m_regionLock.Init();
+}
+
+BlockAllocator::~BlockAllocator()
+{
+    releaseFreeRegions();
+    {
+        std::lock_guard<std::mutex> lock(m_emptyRegionConditionMutex);
+        m_blockFreeingThreadShouldQuit = true;
+        m_emptyRegionCondition.notify_all();
+    }
+    if (m_blockFreeingThread)
+        waitForThreadCompletion(m_blockFreeingThread);
+    ASSERT(allRegionSetsAreEmpty());
+    ASSERT(m_emptyRegions.isEmpty());
+}
+
+bool BlockAllocator::allRegionSetsAreEmpty() const
+{
+    return m_copiedRegionSet.isEmpty()
+        && m_markedRegionSet.isEmpty()
+        && m_fourKBBlockRegionSet.isEmpty()
+        && m_workListRegionSet.isEmpty();
+}
+
+void BlockAllocator::releaseFreeRegions()
+{
+    while (true) {
+        Region* region;
+        {
+            SpinLockHolder locker(&m_regionLock);
+            if (!m_numberOfEmptyRegions)
+                region = 0;
+            else {
+                region = m_emptyRegions.removeHead();
+                RELEASE_ASSERT(region);
+                m_numberOfEmptyRegions--;
+            }
+        }
+        
+        if (!region)
+            break;
+
+        region->destroy();
+    }
+}
+
+void BlockAllocator::waitForDuration(std::chrono::milliseconds duration)
+{
+    std::unique_lock<std::mutex> lock(m_emptyRegionConditionMutex);
+
+    // If this returns early, that's fine, so long as it doesn't do it too
+    // frequently. It would only be a bug if this function failed to return
+    // when it was asked to do so.
+    if (m_blockFreeingThreadShouldQuit)
+        return;
+
+    m_emptyRegionCondition.wait_for(lock, duration);
+}
+
+void BlockAllocator::blockFreeingThreadStartFunc(void* blockAllocator)
+{
+    static_cast<BlockAllocator*>(blockAllocator)->blockFreeingThreadMain();
+}
+
+void BlockAllocator::blockFreeingThreadMain()
+{
+    size_t currentNumberOfEmptyRegions;
+    while (!m_blockFreeingThreadShouldQuit) {
+        // Generally wait for one second before scavenging free blocks. This
+        // may return early, particularly when we're being asked to quit.
+        waitForDuration(std::chrono::seconds(1));
+        if (m_blockFreeingThreadShouldQuit)
+            break;
+        
+        if (m_isCurrentlyAllocating) {
+            m_isCurrentlyAllocating = false;
+            continue;
+        }
+
+        // Sleep until there is actually work to do rather than waking up every second to check.
+        {
+            std::unique_lock<std::mutex> lock(m_emptyRegionConditionMutex);
+            SpinLockHolder regionLocker(&m_regionLock);
+            while (!m_numberOfEmptyRegions && !m_blockFreeingThreadShouldQuit) {
+                m_regionLock.Unlock();
+                m_emptyRegionCondition.wait(lock);
+                m_regionLock.Lock();
+            }
+            currentNumberOfEmptyRegions = m_numberOfEmptyRegions;
+        }
+        
+        size_t desiredNumberOfEmptyRegions = currentNumberOfEmptyRegions / 2;
+        
+        while (!m_blockFreeingThreadShouldQuit) {
+            Region* region;
+            {
+                SpinLockHolder locker(&m_regionLock);
+                if (m_numberOfEmptyRegions <= desiredNumberOfEmptyRegions)
+                    region = 0;
+                else {
+                    region = m_emptyRegions.removeHead();
+                    RELEASE_ASSERT(region);
+                    m_numberOfEmptyRegions--;
+                }
+            }
+            
+            if (!region)
+                break;
+            
+            region->destroy();
+        }
+    }
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/heap/BlockAllocator.h b/Source/JavaScriptCore/heap/BlockAllocator.h
new file mode 100644 (file)
index 0000000..eb6867f
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BlockAllocator_h
+#define BlockAllocator_h
+
+#include "GCActivityCallback.h"
+#include "HeapBlock.h"
+#include "Region.h"
+#include <condition_variable>
+#include <wtf/DoublyLinkedList.h>
+#include <wtf/Forward.h>
+#include <wtf/PageAllocationAligned.h>
+#include <wtf/TCSpinLock.h>
+#include <wtf/Threading.h>
+
+namespace JSC {
+
+class BlockAllocator;
+class CodeBlock;
+class CopiedBlock;
+class CopyWorkListSegment;
+template <typename T> class GCArraySegment;
+class HandleBlock;
+class JSCell;
+class VM;
+class MarkedBlock;
+class WeakBlock;
+
+// Simple allocator to reduce VM cost by holding onto blocks of memory for
+// short periods of time and then freeing them on a secondary thread.
+
+class BlockAllocator {
+public:
+    BlockAllocator();
+    ~BlockAllocator();
+
+    template <typename T> DeadBlock* allocate();
+    DeadBlock* allocateCustomSize(size_t blockSize, size_t blockAlignment);
+    template <typename T> void deallocate(T*);
+    template <typename T> void deallocateCustomSize(T*);
+
+    JS_EXPORT_PRIVATE void releaseFreeRegions();
+
+private:
+    void waitForDuration(std::chrono::milliseconds);
+
+    friend ThreadIdentifier createBlockFreeingThread(BlockAllocator*);
+    void blockFreeingThreadMain();
+    static void blockFreeingThreadStartFunc(void* heap);
+
+    struct RegionSet {
+        RegionSet(size_t blockSize)
+            : m_numberOfPartialRegions(0)
+            , m_blockSize(blockSize)
+        {
+        }
+
+        bool isEmpty() const
+        {
+            return m_fullRegions.isEmpty() && m_partialRegions.isEmpty();
+        }
+
+        DoublyLinkedList<Region> m_fullRegions;
+        DoublyLinkedList<Region> m_partialRegions;
+        size_t m_numberOfPartialRegions;
+        size_t m_blockSize;
+    };
+
+    DeadBlock* tryAllocateFromRegion(RegionSet&, DoublyLinkedList<Region>&, size_t&);
+
+    bool allRegionSetsAreEmpty() const;
+
+    template <typename T> RegionSet& regionSetFor();
+
+    SuperRegion m_superRegion;
+    RegionSet m_copiedRegionSet;
+    RegionSet m_markedRegionSet;
+    // WeakBlocks and GCArraySegments use the same RegionSet since they're the same size.
+    RegionSet m_fourKBBlockRegionSet;
+    RegionSet m_workListRegionSet;
+
+    DoublyLinkedList<Region> m_emptyRegions;
+    size_t m_numberOfEmptyRegions;
+
+    bool m_isCurrentlyAllocating;
+    bool m_blockFreeingThreadShouldQuit;
+    SpinLock m_regionLock;
+    std::mutex m_emptyRegionConditionMutex;
+    std::condition_variable m_emptyRegionCondition;
+    ThreadIdentifier m_blockFreeingThread;
+};
+
+inline DeadBlock* BlockAllocator::tryAllocateFromRegion(RegionSet& set, DoublyLinkedList<Region>& regions, size_t& numberOfRegions)
+{
+    if (numberOfRegions) {
+        ASSERT(!regions.isEmpty());
+        Region* region = regions.head();
+        ASSERT(!region->isFull());
+
+        if (region->isEmpty()) {
+            ASSERT(region == m_emptyRegions.head());
+            m_numberOfEmptyRegions--;
+            set.m_numberOfPartialRegions++;
+            region = m_emptyRegions.removeHead()->reset(set.m_blockSize);
+            set.m_partialRegions.push(region);
+        }
+
+        DeadBlock* block = region->allocate();
+
+        if (region->isFull()) {
+            set.m_numberOfPartialRegions--;
+            set.m_fullRegions.push(set.m_partialRegions.removeHead());
+        }
+
+        return block;
+    }
+    return 0;
+}
+
+template<typename T>
+inline DeadBlock* BlockAllocator::allocate()
+{
+    RegionSet& set = regionSetFor<T>();
+    DeadBlock* block;
+    m_isCurrentlyAllocating = true;
+    {
+        SpinLockHolder locker(&m_regionLock);
+        if ((block = tryAllocateFromRegion(set, set.m_partialRegions, set.m_numberOfPartialRegions)))
+            return block;
+        if ((block = tryAllocateFromRegion(set, m_emptyRegions, m_numberOfEmptyRegions)))
+            return block;
+    }
+
+    Region* newRegion = Region::create(&m_superRegion, T::blockSize);
+
+    SpinLockHolder locker(&m_regionLock);
+    m_emptyRegions.push(newRegion);
+    m_numberOfEmptyRegions++;
+    block = tryAllocateFromRegion(set, m_emptyRegions, m_numberOfEmptyRegions);
+    ASSERT(block);
+    return block;
+}
+
+inline DeadBlock* BlockAllocator::allocateCustomSize(size_t blockSize, size_t blockAlignment)
+{
+    size_t realSize = WTF::roundUpToMultipleOf(blockAlignment, blockSize);
+    Region* newRegion = Region::createCustomSize(&m_superRegion, realSize, blockAlignment);
+    DeadBlock* block = newRegion->allocate();
+    ASSERT(block);
+    return block;
+}
+
+template<typename T>
+inline void BlockAllocator::deallocate(T* block)
+{
+    RegionSet& set = regionSetFor<T>();
+    bool shouldWakeBlockFreeingThread = false;
+    {
+        SpinLockHolder locker(&m_regionLock);
+        Region* region = block->region();
+        ASSERT(!region->isEmpty());
+        if (region->isFull())
+            set.m_fullRegions.remove(region);
+        else {
+            set.m_partialRegions.remove(region);
+            set.m_numberOfPartialRegions--;
+        }
+
+        region->deallocate(block);
+
+        if (region->isEmpty()) {
+            m_emptyRegions.push(region);
+            shouldWakeBlockFreeingThread = !m_numberOfEmptyRegions;
+            m_numberOfEmptyRegions++;
+        } else {
+            set.m_partialRegions.push(region);
+            set.m_numberOfPartialRegions++;
+        }
+    }
+
+    if (shouldWakeBlockFreeingThread) {
+        std::lock_guard<std::mutex> lock(m_emptyRegionConditionMutex);
+        m_emptyRegionCondition.notify_one();
+    }
+
+    if (!m_blockFreeingThread)
+        releaseFreeRegions();
+}
+
+template<typename T>
+inline void BlockAllocator::deallocateCustomSize(T* block)
+{
+    Region* region = block->region();
+    ASSERT(region->isCustomSize());
+    region->deallocate(block);
+    region->destroy();
+}
+
+#define REGION_SET_FOR(blockType, set) \
+    template <> \
+    inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<blockType>() \
+    { \
+        return set; \
+    } \
+    template <> \
+    inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<blockType>>() \
+    { \
+        return set; \
+    } \
+
+REGION_SET_FOR(MarkedBlock, m_markedRegionSet);
+REGION_SET_FOR(CopiedBlock, m_copiedRegionSet);
+REGION_SET_FOR(WeakBlock, m_fourKBBlockRegionSet);
+REGION_SET_FOR(GCArraySegment<const JSCell*>, m_fourKBBlockRegionSet);
+REGION_SET_FOR(GCArraySegment<CodeBlock*>, m_fourKBBlockRegionSet);
+REGION_SET_FOR(CopyWorkListSegment, m_workListRegionSet);
+REGION_SET_FOR(HandleBlock, m_fourKBBlockRegionSet);
+
+#undef REGION_SET_FOR
+
+template <typename T>
+inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor()
+{
+    RELEASE_ASSERT_NOT_REACHED();
+    return *(RegionSet*)0;
+}
+
+} // namespace JSC
+
+#endif // BlockAllocator_h
index eae1aac..2a818f0 100644 (file)
@@ -35,8 +35,8 @@ namespace JSC {
 
 static const bool verbose = false;
 
-CodeBlockSet::CodeBlockSet()
-    : m_currentlyExecuting()
+CodeBlockSet::CodeBlockSet(BlockAllocator& blockAllocator)
+    : m_currentlyExecuting(blockAllocator)
 {
 }
 
index d248337..e00cefe 100644 (file)
@@ -36,6 +36,7 @@
 
 namespace JSC {
 
+class BlockAllocator;
 class CodeBlock;
 class Heap;
 class JSCell;
@@ -49,7 +50,7 @@ class CodeBlockSet {
     WTF_MAKE_NONCOPYABLE(CodeBlockSet);
 
 public:
-    CodeBlockSet();
+    CodeBlockSet(BlockAllocator&);
     ~CodeBlockSet();
     
     // Add a CodeBlock. This is only called by CodeBlock constructors.
index 199d0c5..6b9c8f8 100644 (file)
 #ifndef CopiedBlock_h
 #define CopiedBlock_h
 
+#include "BlockAllocator.h"
 #include "CopyWorkList.h"
 #include "HeapBlock.h"
 #include "JSCJSValue.h"
 #include "Options.h"
 #include <wtf/Atomics.h>
-#include <wtf/TCSpinLock.h>
 
 namespace JSC {
 
@@ -41,8 +41,8 @@ class CopiedBlock : public HeapBlock<CopiedBlock> {
     friend class CopiedSpace;
     friend class CopiedAllocator;
 public:
-    static CopiedBlock* create(size_t);
-    static CopiedBlock* createNoZeroFill(size_t);
+    static CopiedBlock* create(DeadBlock*);
+    static CopiedBlock* createNoZeroFill(DeadBlock*);
 
     void pin();
     bool isPinned();
@@ -86,7 +86,7 @@ public:
     SpinLock& workListLock() { return m_workListLock; }
 
 private:
-    CopiedBlock(size_t);
+    CopiedBlock(Region*);
     void zeroFillWilderness(); // Can be called at any time to zero-fill to the end of the block.
 
     void checkConsistency();
@@ -94,7 +94,6 @@ private:
     SpinLock m_workListLock;
     std::unique_ptr<CopyWorkList> m_workList;
 
-    size_t m_blockSize;
     size_t m_remaining;
     bool m_isPinned : 1;
     bool m_isOld : 1;
@@ -104,14 +103,15 @@ private:
 #endif
 };
 
-inline CopiedBlock* CopiedBlock::createNoZeroFill(size_t blockSize)
+inline CopiedBlock* CopiedBlock::createNoZeroFill(DeadBlock* block)
 {
-    return new(NotNull, fastAlignedMalloc(CopiedBlock::blockSize, blockSize)) CopiedBlock(blockSize);
+    Region* region = block->region();
+    return new(NotNull, block) CopiedBlock(region);
 }
 
-inline CopiedBlock* CopiedBlock::create(size_t blockSize)
+inline CopiedBlock* CopiedBlock::create(DeadBlock* block)
 {
-    CopiedBlock* newBlock = createNoZeroFill(blockSize);
+    CopiedBlock* newBlock = createNoZeroFill(block);
     newBlock->zeroFillWilderness();
     return newBlock;
 }
@@ -128,9 +128,8 @@ inline void CopiedBlock::zeroFillWilderness()
 #endif
 }
 
-inline CopiedBlock::CopiedBlock(size_t blockSize)
-    : HeapBlock<CopiedBlock>()
-    , m_blockSize(blockSize)
+inline CopiedBlock::CopiedBlock(Region* region)
+    : HeapBlock<CopiedBlock>(region)
     , m_remaining(payloadCapacity())
     , m_isPinned(false)
     , m_isOld(false)
@@ -204,7 +203,7 @@ inline void CopiedBlock::didPromote()
 
 inline bool CopiedBlock::isOversize()
 {
-    return m_blockSize != blockSize;
+    return region()->isCustomSize();
 }
 
 inline unsigned CopiedBlock::liveBytes()
@@ -220,7 +219,7 @@ inline char* CopiedBlock::payload()
 
 inline char* CopiedBlock::payloadEnd()
 {
-    return reinterpret_cast<char*>(this) + m_blockSize;
+    return reinterpret_cast<char*>(this) + region()->blockSize();
 }
 
 inline size_t CopiedBlock::payloadCapacity()
@@ -265,7 +264,7 @@ inline size_t CopiedBlock::size()
 
 inline size_t CopiedBlock::capacity()
 {
-    return m_blockSize;
+    return region()->blockSize();
 }
 
 inline bool CopiedBlock::hasWorkList()
index f1eab88..46e46d1 100644 (file)
@@ -62,7 +62,7 @@ inline void CopiedBlock::reportLiveBytes(SpinLockHolder&, JSCell* owner, CopyTok
     }
 
     if (!m_workList)
-        m_workList = std::make_unique<CopyWorkList>();
+        m_workList = std::make_unique<CopyWorkList>(Heap::heap(owner)->blockAllocator());
 
     m_workList->append(CopyWorklistItem(owner, token));
 }
index 6f1decf..cb1a656 100644 (file)
@@ -45,22 +45,22 @@ CopiedSpace::CopiedSpace(Heap* heap)
 CopiedSpace::~CopiedSpace()
 {
     while (!m_oldGen.toSpace->isEmpty())
-        CopiedBlock::destroy(m_oldGen.toSpace->removeHead());
+        m_heap->blockAllocator().deallocate(CopiedBlock::destroy(m_oldGen.toSpace->removeHead()));
 
     while (!m_oldGen.fromSpace->isEmpty())
-        CopiedBlock::destroy(m_oldGen.fromSpace->removeHead());
+        m_heap->blockAllocator().deallocate(CopiedBlock::destroy(m_oldGen.fromSpace->removeHead()));
 
     while (!m_oldGen.oversizeBlocks.isEmpty())
-        CopiedBlock::destroy(m_oldGen.oversizeBlocks.removeHead());
+        m_heap->blockAllocator().deallocateCustomSize(CopiedBlock::destroy(m_oldGen.oversizeBlocks.removeHead()));
 
     while (!m_newGen.toSpace->isEmpty())
-        CopiedBlock::destroy(m_newGen.toSpace->removeHead());
+        m_heap->blockAllocator().deallocate(CopiedBlock::destroy(m_newGen.toSpace->removeHead()));
 
     while (!m_newGen.fromSpace->isEmpty())
-        CopiedBlock::destroy(m_newGen.fromSpace->removeHead());
+        m_heap->blockAllocator().deallocate(CopiedBlock::destroy(m_newGen.fromSpace->removeHead()));
 
     while (!m_newGen.oversizeBlocks.isEmpty())
-        CopiedBlock::destroy(m_newGen.oversizeBlocks.removeHead());
+        m_heap->blockAllocator().deallocateCustomSize(CopiedBlock::destroy(m_newGen.oversizeBlocks.removeHead()));
 
     ASSERT(m_oldGen.toSpace->isEmpty());
     ASSERT(m_oldGen.fromSpace->isEmpty());
@@ -99,7 +99,7 @@ CheckedBoolean CopiedSpace::tryAllocateOversize(size_t bytes, void** outPtr)
 {
     ASSERT(isOversize(bytes));
     
-    CopiedBlock* block = CopiedBlock::create(sizeof(CopiedBlock) + bytes);
+    CopiedBlock* block = CopiedBlock::create(m_heap->blockAllocator().allocateCustomSize(sizeof(CopiedBlock) + bytes, CopiedBlock::blockSize));
     m_newGen.oversizeBlocks.push(block);
     m_newGen.blockFilter.add(reinterpret_cast<Bits>(block));
     m_blockSet.add(block);
@@ -110,7 +110,7 @@ CheckedBoolean CopiedSpace::tryAllocateOversize(size_t bytes, void** outPtr)
     *outPtr = allocator.forceAllocate(bytes);
     allocator.resetCurrentBlock();
 
-    m_heap->didAllocate(block->capacity());
+    m_heap->didAllocate(block->region()->blockSize());
 
     return true;
 }
@@ -161,7 +161,7 @@ CheckedBoolean CopiedSpace::tryReallocateOversize(void** ptr, size_t oldSize, si
         else
             m_newGen.oversizeBlocks.remove(oldBlock);
         m_blockSet.remove(oldBlock);
-        CopiedBlock::destroy(oldBlock);
+        m_heap->blockAllocator().deallocateCustomSize(CopiedBlock::destroy(oldBlock));
     }
     
     *ptr = newPtr;
index 9921dfa..ec33f58 100644 (file)
@@ -106,12 +106,12 @@ inline void CopiedSpace::recycleEvacuatedBlock(CopiedBlock* block, HeapOperation
         else
             m_oldGen.fromSpace->remove(block);
     }
-    CopiedBlock::destroy(block);
+    m_heap->blockAllocator().deallocate(CopiedBlock::destroy(block));
 }
 
 inline void CopiedSpace::recycleBorrowedBlock(CopiedBlock* block)
 {
-    CopiedBlock::destroy(block);
+    m_heap->blockAllocator().deallocate(CopiedBlock::destroy(block));
 
     {
         MutexLocker locker(m_loanedBlocksLock);
@@ -126,7 +126,7 @@ inline void CopiedSpace::recycleBorrowedBlock(CopiedBlock* block)
 inline CopiedBlock* CopiedSpace::allocateBlockForCopyingPhase()
 {
     ASSERT(m_inCopyingPhase);
-    CopiedBlock* block = CopiedBlock::createNoZeroFill(CopiedBlock::blockSize);
+    CopiedBlock* block = CopiedBlock::createNoZeroFill(m_heap->blockAllocator().allocate<CopiedBlock>());
 
     {
         MutexLocker locker(m_loanedBlocksLock);
@@ -143,7 +143,7 @@ inline void CopiedSpace::allocateBlock()
 
     m_allocator.resetCurrentBlock();
     
-    CopiedBlock* block = CopiedBlock::create(CopiedBlock::blockSize);
+    CopiedBlock* block = CopiedBlock::create(m_heap->blockAllocator().allocate<CopiedBlock>());
         
     m_newGen.toSpace->push(block);
     m_newGen.blockFilter.add(reinterpret_cast<Bits>(block));
@@ -235,7 +235,7 @@ inline void CopiedSpace::startedCopying()
         } else {
             oversizeBlocks->remove(block);
             m_blockSet.remove(block);
-            CopiedBlock::destroy(block);
+            m_heap->blockAllocator().deallocateCustomSize(CopiedBlock::destroy(block));
         } 
         block = next;
     }
index 90ebf7d..76f1c3d 100644 (file)
@@ -27,7 +27,6 @@
 #define CopyWorkList_h
 
 #include "CopyToken.h"
-#include "HeapBlock.h"
 #include <wtf/Vector.h>
 
 namespace JSC {
@@ -60,9 +59,9 @@ private:
 
 class CopyWorkListSegment : public HeapBlock<CopyWorkListSegment> {
 public:
-    static CopyWorkListSegment* create()
+    static CopyWorkListSegment* create(DeadBlock* block)
     {
-        return new (NotNull, fastAlignedMalloc(blockSize, blockSize)) CopyWorkListSegment();
+        return new (NotNull, block) CopyWorkListSegment(block->region());
     }
 
     size_t size() { return m_size; }
@@ -79,8 +78,8 @@ public:
     static const size_t blockSize = 512;
 
 private:
-    CopyWorkListSegment()
-        : HeapBlock<CopyWorkListSegment>()
+    CopyWorkListSegment(Region* region)
+        : HeapBlock<CopyWorkListSegment>(region)
         , m_size(0)
     {
     }
@@ -144,6 +143,7 @@ class CopyWorkList {
 public:
     typedef CopyWorkListIterator iterator;
 
+    CopyWorkList(BlockAllocator&);
     ~CopyWorkList();
 
     void append(CopyWorklistItem);
@@ -152,18 +152,24 @@ public:
 
 private:
     DoublyLinkedList<CopyWorkListSegment> m_segments;
+    BlockAllocator& m_blockAllocator;
 };
 
+inline CopyWorkList::CopyWorkList(BlockAllocator& blockAllocator)
+    : m_blockAllocator(blockAllocator)
+{
+}
+
 inline CopyWorkList::~CopyWorkList()
 {
     while (!m_segments.isEmpty())
-        CopyWorkListSegment::destroy(m_segments.removeHead());
+        m_blockAllocator.deallocate(CopyWorkListSegment::destroy(m_segments.removeHead()));
 }
 
 inline void CopyWorkList::append(CopyWorklistItem item)
 {
     if (m_segments.isEmpty() || m_segments.tail()->isFull())
-        m_segments.append(CopyWorkListSegment::create());
+        m_segments.append(CopyWorkListSegment::create(m_blockAllocator.allocate<CopyWorkListSegment>()));
 
     ASSERT(!m_segments.tail()->isFull());
 
index b94a0ca..8faf16b 100644 (file)
 
 namespace JSC {
 
+class BlockAllocator;
+class DeadBlock;
+
 template <typename T>
 class GCArraySegment : public HeapBlock<GCArraySegment<T>> {
 public:
-    GCArraySegment()
-        : HeapBlock<GCArraySegment>()
+    GCArraySegment(Region* region)
+        : HeapBlock<GCArraySegment>(region)
 #if !ASSERT_DISABLED
         , m_top(0)
 #endif
     {
     }
 
-    static GCArraySegment* create();
+    static GCArraySegment* create(DeadBlock*);
 
     T* data()
     {
@@ -63,7 +66,7 @@ class GCSegmentedArray {
     friend class GCSegmentedArrayIterator<T>;
     friend class GCSegmentedArrayIterator<const T>;
 public:
-    GCSegmentedArray();
+    GCSegmentedArray(BlockAllocator&);
     ~GCSegmentedArray();
 
     void append(T);
@@ -98,6 +101,7 @@ protected:
     void validatePrevious();
 
     DoublyLinkedList<GCArraySegment<T>> m_segments;
+    BlockAllocator& m_blockAllocator;
 
     JS_EXPORT_PRIVATE static const size_t s_segmentCapacity = CapacityFromSize<GCArraySegment<T>::blockSize>::value;
     size_t m_top;
index b148fad..e2eff4d 100644 (file)
 #ifndef GCSegmentedArrayInlines_h
 #define GCSegmentedArrayInlines_h
 
+#include "BlockAllocator.h"
 #include "GCSegmentedArray.h"
 
 namespace JSC {
 
 template <typename T>
-GCSegmentedArray<T>::GCSegmentedArray()
-    : m_top(0)
+GCSegmentedArray<T>::GCSegmentedArray(BlockAllocator& blockAllocator)
+    : m_blockAllocator(blockAllocator)
+    , m_top(0)
     , m_numberOfSegments(0)
 {
-    m_segments.push(GCArraySegment<T>::create());
+    m_segments.push(GCArraySegment<T>::create(m_blockAllocator.allocate<GCArraySegment<T>>()));
     m_numberOfSegments++;
 }
 
@@ -44,7 +46,7 @@ GCSegmentedArray<T>::~GCSegmentedArray()
 {
     ASSERT(m_numberOfSegments == 1);
     ASSERT(m_segments.size() == 1);
-    GCArraySegment<T>::destroy(m_segments.removeHead());
+    m_blockAllocator.deallocate(GCArraySegment<T>::destroy(m_segments.removeHead()));
     m_numberOfSegments--;
     ASSERT(!m_numberOfSegments);
     ASSERT(!m_segments.size());
@@ -59,7 +61,7 @@ void GCSegmentedArray<T>::clear()
     for (GCArraySegment<T>* current = m_segments.head(); current->next(); current = next) {
         next = current->next();
         m_segments.remove(current);
-        GCArraySegment<T>::destroy(current);
+        m_blockAllocator.deallocate(GCArraySegment<T>::destroy(current));
     }
     m_top = 0;
     m_numberOfSegments = 1;
@@ -73,7 +75,7 @@ void GCSegmentedArray<T>::expand()
 {
     ASSERT(m_segments.head()->m_top == s_segmentCapacity);
     
-    GCArraySegment<T>* nextSegment = GCArraySegment<T>::create();
+    GCArraySegment<T>* nextSegment = GCArraySegment<T>::create(m_blockAllocator.allocate<GCArraySegment<T>>());
     m_numberOfSegments++;
     
 #if !ASSERT_DISABLED
@@ -91,7 +93,7 @@ bool GCSegmentedArray<T>::refill()
     validatePrevious();
     if (top())
         return true;
-    GCArraySegment<T>::destroy(m_segments.removeHead());
+    m_blockAllocator.deallocate(GCArraySegment<T>::destroy(m_segments.removeHead()));
     ASSERT(m_numberOfSegments > 1);
     m_numberOfSegments--;
     setTopForFullSegment();
@@ -125,9 +127,9 @@ void GCSegmentedArray<T>::fillVector(Vector<T>& vector)
 }
 
 template <typename T>
-inline GCArraySegment<T>* GCArraySegment<T>::create()
+inline GCArraySegment<T>* GCArraySegment<T>::create(DeadBlock* block)
 {
-    return new (NotNull, fastAlignedMalloc(blockSize, blockSize)) GCArraySegment<T>();
+    return new (NotNull, block) GCArraySegment<T>(block->region());
 }
 
 template <typename T>
index c8847aa..27e59e8 100644 (file)
@@ -73,7 +73,7 @@ GCThreadSharedData::GCThreadSharedData(VM* vm)
     : m_vm(vm)
     , m_copiedSpace(&vm->heap.m_storageSpace)
     , m_shouldHashCons(false)
-    , m_sharedMarkStack()
+    , m_sharedMarkStack(vm->heap.blockAllocator())
     , m_numberOfActiveParallelMarkers(0)
     , m_parallelMarkersShouldExit(false)
     , m_copyIndex(0)
index 81d0734..32c06bd 100644 (file)
@@ -40,7 +40,6 @@ namespace JSC {
 
 class GCThread;
 class VM;
-class CopiedBlock;
 class CopiedSpace;
 class CopyVisitor;
 
index 1e4e7d5..962d37c 100644 (file)
 
 namespace JSC {
 
+class DeadBlock;
 class HandleSet;
 class HandleNode;
 
 class HandleBlock : public HeapBlock<HandleBlock> {
 public:
-    static HandleBlock* create(HandleSet*);
+    static HandleBlock* create(DeadBlock*, HandleSet*);
     static HandleBlock* blockFor(HandleNode*);
 
     static const size_t blockSize = 4 * KB;
@@ -47,7 +48,7 @@ public:
     unsigned nodeCapacity();
 
 private:
-    HandleBlock(HandleSet*);
+    HandleBlock(Region*, HandleSet*);
 
     char* payload();
     char* payloadEnd();
index 10bbfe7..7c77193 100644 (file)
 #ifndef HandleBlockInlines_h
 #define HandleBlockInlines_h
 
+#include "BlockAllocator.h"
 #include "HandleBlock.h"
 
 namespace JSC {
 
-inline HandleBlock* HandleBlock::create(HandleSet* handleSet)
+inline HandleBlock* HandleBlock::create(DeadBlock* block, HandleSet* handleSet)
 {
-    return new (NotNull, fastAlignedMalloc(blockSize, blockSize)) HandleBlock(handleSet);
+    Region* region = block->region();
+    return new (NotNull, block) HandleBlock(region, handleSet);
 }
 
-inline HandleBlock::HandleBlock(HandleSet* handleSet)
-    : HeapBlock<HandleBlock>()
+inline HandleBlock::HandleBlock(Region* region, HandleSet* handleSet)
+    : HeapBlock<HandleBlock>(region)
     , m_handleSet(handleSet)
 {
 }
 
 inline char* HandleBlock::payloadEnd()
 {
-    return reinterpret_cast<char*>(this) + blockSize;
+    return reinterpret_cast<char*>(this) + region()->blockSize();
 }
 
 inline char* HandleBlock::payload()
index dec8370..be667e8 100644 (file)
@@ -44,12 +44,12 @@ HandleSet::HandleSet(VM* vm)
 HandleSet::~HandleSet()
 {
     while (!m_blockList.isEmpty())
-        HandleBlock::destroy(m_blockList.removeHead());
+        m_vm->heap.blockAllocator().deallocate(HandleBlock::destroy(m_blockList.removeHead()));
 }
 
 void HandleSet::grow()
 {
-    HandleBlock* newBlock = HandleBlock::create(this);
+    HandleBlock* newBlock = HandleBlock::create(m_vm->heap.blockAllocator().allocate<HandleBlock>(), this);
     m_blockList.append(newBlock);
 
     for (int i = newBlock->nodeCapacity() - 1; i >= 0; --i) {
index 427879f..3758dd3 100644 (file)
@@ -308,6 +308,7 @@ Heap::Heap(VM* vm, HeapType heapType)
     , m_totalBytesVisited(0)
     , m_totalBytesCopied(0)
     , m_operationInProgress(NoOperation)
+    , m_blockAllocator()
     , m_objectSpace(this)
     , m_storageSpace(this)
     , m_extraMemoryUsage(0)
@@ -316,7 +317,7 @@ Heap::Heap(VM* vm, HeapType heapType)
     , m_slotVisitor(m_sharedData)
     , m_copyVisitor(m_sharedData)
     , m_handleSet(vm)
-    , m_codeBlocks()
+    , m_codeBlocks(m_blockAllocator)
     , m_isSafeToCollect(false)
     , m_writeBarrierBuffer(256)
     , m_vm(vm)
index 5fe578f..7619465 100644 (file)
@@ -23,6 +23,7 @@
 #define Heap_h
 
 #include "ArrayBuffer.h"
+#include "BlockAllocator.h"
 #include "CodeBlockSet.h"
 #include "CopyVisitor.h"
 #include "GCIncomingRefCountedSet.h"
@@ -214,6 +215,7 @@ public:
     
     bool isDeferred() const { return !!m_deferralDepth || Options::disableGC(); }
 
+    BlockAllocator& blockAllocator();
     StructureIDTable& structureIDTable() { return m_structureIDTable; }
 
 #if USE(CF)
@@ -243,6 +245,7 @@ private:
     friend class CopyVisitor;
     friend class RecursiveAllocationScope;
     friend class SlotVisitor;
+    friend class SuperRegion;
     friend class IncrementalSweeper;
     friend class HeapStatistics;
     friend class VM;
@@ -339,6 +342,7 @@ private:
     size_t m_totalBytesCopied;
     
     HeapOperation m_operationInProgress;
+    BlockAllocator m_blockAllocator;
     StructureIDTable m_structureIDTable;
     MarkedSpace m_objectSpace;
     CopiedSpace m_storageSpace;
index 987d726..a5b8d7e 100644 (file)
 #define HeapBlock_h
 
 #include <wtf/DoublyLinkedList.h>
-#include <wtf/FastMalloc.h>
 #include <wtf/StdLibExtras.h>
 
 namespace JSC {
 
 enum AllocationEffort { AllocationCanFail, AllocationMustSucceed };
 
+class Region;
+
 template<typename T>
 class HeapBlock : public DoublyLinkedListNode<T> {
     friend class WTF::DoublyLinkedListNode<T>;
 public:
-    static void destroy(HeapBlock* block)
+    static HeapBlock* destroy(HeapBlock* block) WARN_UNUSED_RETURN
     {
         static_cast<T*>(block)->~T();
-        fastAlignedFree(block);
+        return block;
     }
 
-    HeapBlock()
+    HeapBlock(Region* region)
         : DoublyLinkedListNode<T>()
+        , m_region(region)
         , m_prev(0)
         , m_next(0)
     {
+        ASSERT(m_region);
     }
 
+    Region* region() const { return m_region; }
+
 private:
+    Region* m_region;
     T* m_prev;
     T* m_next;
 };
index e670412..1e42c6a 100644 (file)
@@ -240,6 +240,11 @@ inline void Heap::ascribeOwner(JSCell* intendedOwner, void* storage)
 #endif
 }
 
+inline BlockAllocator& Heap::blockAllocator()
+{
+    return m_blockAllocator;
+}
+
 #if USE(CF)
 template <typename T>
 inline void Heap::releaseSoon(RetainPtr<T>&& object)
index 5aa3399..9660d66 100644 (file)
@@ -26,7 +26,6 @@
 #include "config.h"
 #include "HeapTimer.h"
 
-#include "GCActivityCallback.h"
 #include "IncrementalSweeper.h"
 #include "JSObject.h"
 #include "JSString.h"
index da6ef94..66201f4 100644 (file)
@@ -30,8 +30,8 @@
 
 namespace JSC {
 
-MarkStackArray::MarkStackArray()
-    : GCSegmentedArray<const JSCell*>()
+MarkStackArray::MarkStackArray(BlockAllocator& blockAllocator)
+    : GCSegmentedArray<const JSCell*>(blockAllocator)
 {
 }
 
index 04f19c6..17a6019 100644 (file)
@@ -34,7 +34,7 @@ class JSCell;
 
 class MarkStackArray : public GCSegmentedArray<const JSCell*> {
 public:
-    MarkStackArray();
+    MarkStackArray(BlockAllocator&);
 
     void donateSomeCellsTo(MarkStackArray& other);
     void stealSomeCellsFrom(MarkStackArray& other, size_t idleThreadCount);
index 7bf2aa9..b8f01fd 100644 (file)
@@ -198,7 +198,9 @@ MarkedBlock* MarkedAllocator::allocateBlock(size_t bytes)
 
     size_t cellSize = m_cellSize ? m_cellSize : WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(bytes);
 
-    return MarkedBlock::create(this, blockSize, cellSize, m_destructorType);
+    if (blockSize == MarkedBlock::blockSize)
+        return MarkedBlock::create(m_heap->blockAllocator().allocate<MarkedBlock>(), this, cellSize, m_destructorType);
+    return MarkedBlock::create(m_heap->blockAllocator().allocateCustomSize(blockSize, MarkedBlock::blockSize), this, cellSize, m_destructorType);
 }
 
 void MarkedAllocator::addBlock(MarkedBlock* block)
index 66392ca..db8e371 100644 (file)
 
 namespace JSC {
 
-MarkedBlock* MarkedBlock::create(MarkedAllocator* allocator, size_t blockSize, size_t cellSize, DestructorType destructorType)
+MarkedBlock* MarkedBlock::create(DeadBlock* block, MarkedAllocator* allocator, size_t cellSize, DestructorType destructorType)
 {
-    return new (NotNull, fastAlignedMalloc(MarkedBlock::blockSize, blockSize)) MarkedBlock(allocator, blockSize, cellSize, destructorType);
+    ASSERT(reinterpret_cast<size_t>(block) == (reinterpret_cast<size_t>(block) & blockMask));
+    Region* region = block->region();
+    return new (NotNull, block) MarkedBlock(region, allocator, cellSize, destructorType);
 }
 
-MarkedBlock::MarkedBlock(MarkedAllocator* allocator, size_t blockSize, size_t cellSize, DestructorType destructorType)
-    : HeapBlock<MarkedBlock>()
+MarkedBlock::MarkedBlock(Region* region, MarkedAllocator* allocator, size_t cellSize, DestructorType destructorType)
+    : HeapBlock<MarkedBlock>(region)
     , m_atomsPerCell((cellSize + atomSize - 1) / atomSize)
-    , m_endAtom((allocator->cellSize() ? atomsPerBlock : blockSize / atomSize) - m_atomsPerCell + 1)
+    , m_endAtom((allocator->cellSize() ? atomsPerBlock : region->blockSize() / atomSize) - m_atomsPerCell + 1)
     , m_destructorType(destructorType)
     , m_allocator(allocator)
     , m_state(New) // All cells start out unmarked.
     , m_weakSet(allocator->heap()->vm())
-    , m_blockSize(blockSize)
 {
     ASSERT(allocator);
     HEAP_LOG_BLOCK_STATE_TRANSITION(this);
index c06cd97..097badd 100644 (file)
@@ -22,7 +22,9 @@
 #ifndef MarkedBlock_h
 #define MarkedBlock_h
 
+#include "BlockAllocator.h"
 #include "HeapBlock.h"
+
 #include "HeapOperation.h"
 #include "WeakSet.h"
 #include <wtf/Bitmap.h>
@@ -111,7 +113,7 @@ namespace JSC {
         };
 
         enum DestructorType { None, ImmortalStructure, Normal };
-        static MarkedBlock* create(MarkedAllocator*, size_t blockSize, size_t cellSize, DestructorType);
+        static MarkedBlock* create(DeadBlock*, MarkedAllocator*, size_t cellSize, DestructorType);
 
         static bool isAtomAligned(const void*);
         static MarkedBlock* blockFor(const void*);
@@ -192,7 +194,7 @@ namespace JSC {
 
         typedef char Atom[atomSize];
 
-        MarkedBlock(MarkedAllocator*, size_t blockSize, size_t cellSize, DestructorType);
+        MarkedBlock(Region*, MarkedAllocator*, size_t cellSize, DestructorType);
         Atom* atoms();
         size_t atomNumber(const void*);
         template<DestructorType> void callDestructor(JSCell*);
@@ -213,7 +215,6 @@ namespace JSC {
         MarkedAllocator* m_allocator;
         BlockState m_state;
         WeakSet m_weakSet;
-        size_t m_blockSize;
     };
 
     inline MarkedBlock::FreeList::FreeList()
@@ -332,7 +333,7 @@ namespace JSC {
 
     inline size_t MarkedBlock::capacity()
     {
-        return m_blockSize;
+        return region()->blockSize();
     }
 
     inline size_t MarkedBlock::atomNumber(const void* p)
index 5e5c0ee..6c48fb5 100644 (file)
@@ -251,7 +251,11 @@ void MarkedSpace::freeBlock(MarkedBlock* block)
     block->allocator()->removeBlock(block);
     m_capacity -= block->capacity();
     m_blocks.remove(block);
-    MarkedBlock::destroy(block);
+    if (block->capacity() == MarkedBlock::blockSize) {
+        m_heap->blockAllocator().deallocate(MarkedBlock::destroy(block));
+        return;
+    }
+    m_heap->blockAllocator().deallocateCustomSize(MarkedBlock::destroy(block));
 }
 
 void MarkedSpace::freeOrShrinkBlock(MarkedBlock* block)
index 1ab85d5..ff0ba50 100644 (file)
@@ -32,7 +32,6 @@
 #include <wtf/DoublyLinkedList.h>
 #include <wtf/HashSet.h>
 #include <wtf/Noncopyable.h>
-#include <wtf/RetainPtr.h>
 #include <wtf/Vector.h>
 
 namespace JSC {
diff --git a/Source/JavaScriptCore/heap/Region.h b/Source/JavaScriptCore/heap/Region.h
new file mode 100644 (file)
index 0000000..3255f56
--- /dev/null
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2013 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 JSC_Region_h
+#define JSC_Region_h
+
+#include "HeapBlock.h"
+#include "SuperRegion.h"
+#include <wtf/DoublyLinkedList.h>
+#include <wtf/MetaAllocatorHandle.h>
+#include <wtf/PageAllocationAligned.h>
+
+#define HEAP_MEMORY_ID reinterpret_cast<void*>(static_cast<intptr_t>(-3))
+
+#define ENABLE_SUPER_REGION 0
+
+#ifndef ENABLE_SUPER_REGION
+#if USE(JSVALUE64) && !CPU(ARM64)
+#define ENABLE_SUPER_REGION 1
+#else
+#define ENABLE_SUPER_REGION 0
+#endif
+#endif
+
+namespace JSC {
+
+class DeadBlock : public HeapBlock<DeadBlock> {
+public:
+    DeadBlock(Region*);
+};
+
+inline DeadBlock::DeadBlock(Region* region)
+    : HeapBlock<DeadBlock>(region)
+{
+}
+
+class Region : public DoublyLinkedListNode<Region> {
+    WTF_MAKE_FAST_ALLOCATED;
+
+    friend class WTF::DoublyLinkedListNode<Region>;
+    friend class BlockAllocator;
+public:
+    ~Region();
+    static Region* create(SuperRegion*, size_t blockSize);
+    static Region* createCustomSize(SuperRegion*, size_t blockSize, size_t blockAlignment);
+    Region* reset(size_t blockSize);
+    void destroy();
+
+    size_t blockSize() const { return m_blockSize; }
+    bool isFull() const { return m_blocksInUse == m_totalBlocks; }
+    bool isEmpty() const { return !m_blocksInUse; }
+    bool isCustomSize() const { return m_isCustomSize; }
+
+    DeadBlock* allocate();
+    void deallocate(void*);
+
+    static const size_t s_regionSize = 64 * KB;
+    static const size_t s_regionMask = ~(s_regionSize - 1);
+
+protected:
+    Region(size_t blockSize, size_t totalBlocks, bool isExcess);
+    void initializeBlockList();
+
+    bool m_isExcess;
+
+private:
+    void* base();
+    size_t size();
+
+    size_t m_totalBlocks;
+    size_t m_blocksInUse;
+    size_t m_blockSize;
+    bool m_isCustomSize;
+    Region* m_prev;
+    Region* m_next;
+    DoublyLinkedList<DeadBlock> m_deadBlocks;
+};
+
+
+class NormalRegion : public Region {
+    friend class Region;
+private:
+    NormalRegion(PassRefPtr<WTF::MetaAllocatorHandle>, size_t blockSize, size_t totalBlocks);
+
+    static NormalRegion* tryCreate(SuperRegion*, size_t blockSize);
+    static NormalRegion* tryCreateCustomSize(SuperRegion*, size_t blockSize, size_t blockAlignment);
+
+    void* base() { return m_allocation->start(); }
+    size_t size() { return m_allocation->sizeInBytes(); }
+
+    NormalRegion* reset(size_t blockSize);
+
+    RefPtr<WTF::MetaAllocatorHandle> m_allocation;
+};
+
+class ExcessRegion : public Region {
+    friend class Region;
+private:
+    ExcessRegion(PageAllocationAligned&, size_t blockSize, size_t totalBlocks);
+
+    ~ExcessRegion();
+
+    static ExcessRegion* create(size_t blockSize);
+    static ExcessRegion* createCustomSize(size_t blockSize, size_t blockAlignment);
+
+    void* base() { return m_allocation.base(); }
+    size_t size() { return m_allocation.size(); }
+
+    ExcessRegion* reset(size_t blockSize);
+
+    PageAllocationAligned m_allocation;
+};
+
+inline NormalRegion::NormalRegion(PassRefPtr<WTF::MetaAllocatorHandle> allocation, size_t blockSize, size_t totalBlocks)
+    : Region(blockSize, totalBlocks, false)
+    , m_allocation(allocation)
+{
+    initializeBlockList();
+}
+
+inline NormalRegion* NormalRegion::tryCreate(SuperRegion* superRegion, size_t blockSize)
+{
+    RefPtr<WTF::MetaAllocatorHandle> allocation = superRegion->allocate(s_regionSize, HEAP_MEMORY_ID);
+    if (!allocation)
+        return 0;
+    return new NormalRegion(allocation, blockSize, s_regionSize / blockSize);
+}
+
+inline NormalRegion* NormalRegion::tryCreateCustomSize(SuperRegion* superRegion, size_t blockSize, size_t blockAlignment)
+{
+    ASSERT_UNUSED(blockAlignment, blockAlignment <= s_regionSize);
+    RefPtr<WTF::MetaAllocatorHandle> allocation = superRegion->allocate(blockSize, HEAP_MEMORY_ID);
+    if (!allocation)
+        return 0;
+    return new NormalRegion(allocation, blockSize, 1);
+}
+
+inline NormalRegion* NormalRegion::reset(size_t blockSize)
+{
+    ASSERT(!m_isExcess);
+    RefPtr<WTF::MetaAllocatorHandle> allocation = m_allocation.release();
+    return new (NotNull, this) NormalRegion(allocation.release(), blockSize, s_regionSize / blockSize);
+}
+
+inline ExcessRegion::ExcessRegion(PageAllocationAligned& allocation, size_t blockSize, size_t totalBlocks)
+    : Region(blockSize, totalBlocks, true)
+    , m_allocation(allocation)
+{
+    initializeBlockList();
+}
+
+inline ExcessRegion::~ExcessRegion()
+{
+    m_allocation.deallocate();
+}
+
+inline ExcessRegion* ExcessRegion::create(size_t blockSize)
+{
+    PageAllocationAligned allocation = PageAllocationAligned::allocate(s_regionSize, s_regionSize, OSAllocator::JSGCHeapPages);
+    ASSERT(static_cast<bool>(allocation));
+    return new ExcessRegion(allocation, blockSize, s_regionSize / blockSize); 
+}
+
+inline ExcessRegion* ExcessRegion::createCustomSize(size_t blockSize, size_t blockAlignment)
+{
+    PageAllocationAligned allocation = PageAllocationAligned::allocate(blockSize, blockAlignment, OSAllocator::JSGCHeapPages);
+    ASSERT(static_cast<bool>(allocation));
+    return new ExcessRegion(allocation, blockSize, 1);
+}
+
+inline ExcessRegion* ExcessRegion::reset(size_t blockSize)
+{
+    ASSERT(m_isExcess);
+    PageAllocationAligned allocation = m_allocation;
+    return new (NotNull, this) ExcessRegion(allocation, blockSize, s_regionSize / blockSize);
+}
+
+inline Region::Region(size_t blockSize, size_t totalBlocks, bool isExcess)
+    : DoublyLinkedListNode<Region>()
+    , m_isExcess(isExcess)
+    , m_totalBlocks(totalBlocks)
+    , m_blocksInUse(0)
+    , m_blockSize(blockSize)
+    , m_isCustomSize(false)
+    , m_prev(0)
+    , m_next(0)
+{
+}
+
+inline void Region::initializeBlockList()
+{
+    char* start = static_cast<char*>(base());
+    char* current = start;
+    for (size_t i = 0; i < m_totalBlocks; i++) {
+        ASSERT(current < start + size());
+        m_deadBlocks.append(new (NotNull, current) DeadBlock(this));
+        current += m_blockSize;
+    }
+}
+
+inline Region* Region::create(SuperRegion* superRegion, size_t blockSize)
+{
+#if ENABLE(SUPER_REGION)
+    ASSERT(blockSize <= s_regionSize);
+    ASSERT(!(s_regionSize % blockSize));
+    Region* region = NormalRegion::tryCreate(superRegion, blockSize);
+    if (LIKELY(!!region))
+        return region;
+#else
+    UNUSED_PARAM(superRegion);
+#endif
+    return ExcessRegion::create(blockSize);
+}
+
+inline Region* Region::createCustomSize(SuperRegion* superRegion, size_t blockSize, size_t blockAlignment)
+{
+#if ENABLE(SUPER_REGION)
+    Region* region = NormalRegion::tryCreateCustomSize(superRegion, blockSize, blockAlignment);
+    if (UNLIKELY(!region))
+        region = ExcessRegion::createCustomSize(blockSize, blockAlignment);
+#else
+    UNUSED_PARAM(superRegion);
+    Region* region = ExcessRegion::createCustomSize(blockSize, blockAlignment);
+#endif
+    region->m_isCustomSize = true;
+    return region;
+}
+
+inline Region::~Region()
+{
+    ASSERT(isEmpty());
+}
+
+inline void Region::destroy()
+{
+#if ENABLE(SUPER_REGION)
+    if (UNLIKELY(m_isExcess))
+        delete static_cast<ExcessRegion*>(this);
+    else
+        delete static_cast<NormalRegion*>(this);
+#else
+    delete static_cast<ExcessRegion*>(this);
+#endif
+}
+
+inline Region* Region::reset(size_t blockSize)
+{
+#if ENABLE(SUPER_REGION)
+    ASSERT(isEmpty());
+    if (UNLIKELY(m_isExcess))
+        return static_cast<ExcessRegion*>(this)->reset(blockSize);
+    return static_cast<NormalRegion*>(this)->reset(blockSize);
+#else
+    return static_cast<ExcessRegion*>(this)->reset(blockSize);
+#endif
+}
+
+inline DeadBlock* Region::allocate()
+{
+    ASSERT(!isFull());
+    m_blocksInUse++;
+    return m_deadBlocks.removeHead();
+}
+
+inline void Region::deallocate(void* base)
+{
+    ASSERT(base);
+    ASSERT(m_blocksInUse);
+    ASSERT(base >= this->base() && base < static_cast<char*>(this->base()) + size());
+    DeadBlock* block = new (NotNull, base) DeadBlock(this);
+    m_deadBlocks.push(block);
+    m_blocksInUse--;
+}
+
+inline void* Region::base()
+{
+#if ENABLE(SUPER_REGION)
+    if (UNLIKELY(m_isExcess))
+        return static_cast<ExcessRegion*>(this)->ExcessRegion::base();
+    return static_cast<NormalRegion*>(this)->NormalRegion::base();
+#else
+    return static_cast<ExcessRegion*>(this)->ExcessRegion::base();
+#endif
+}
+
+inline size_t Region::size()
+{
+#if ENABLE(SUPER_REGION)
+    if (UNLIKELY(m_isExcess))
+        return static_cast<ExcessRegion*>(this)->ExcessRegion::size();
+    return static_cast<NormalRegion*>(this)->NormalRegion::size();
+#else
+    return static_cast<ExcessRegion*>(this)->ExcessRegion::size();
+#endif
+}
+
+} // namespace JSC
+
+#endif // JSC_Region_h
index 4de4966..d45c381 100644 (file)
@@ -17,7 +17,7 @@
 namespace JSC {
 
 SlotVisitor::SlotVisitor(GCThreadSharedData& shared)
-    : m_stack()
+    : m_stack(shared.m_vm->heap.blockAllocator())
     , m_bytesVisited(0)
     , m_bytesCopied(0)
     , m_visitCount(0)
diff --git a/Source/JavaScriptCore/heap/SuperRegion.cpp b/Source/JavaScriptCore/heap/SuperRegion.cpp
new file mode 100644 (file)
index 0000000..157fe2e
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2013 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 "SuperRegion.h"
+
+#include "JSCInlines.h"
+#include "Region.h"
+
+namespace JSC {
+
+const uint64_t SuperRegion::s_fixedHeapMemoryPoolSize = 4 * 1024 * static_cast<uint64_t>(MB);
+
+SuperRegion::SuperRegion()
+    : MetaAllocator(Region::s_regionSize, Region::s_regionSize)
+    , m_reservationBase(0)
+{
+#if ENABLE(SUPER_REGION)
+    // Over-allocate so that we can make sure that we're aligned to the size of Regions.
+    m_reservation = PageReservation::reserve(s_fixedHeapMemoryPoolSize + Region::s_regionSize, OSAllocator::JSGCHeapPages);
+    m_reservationBase = getAlignedBase(m_reservation);
+    addFreshFreeSpace(m_reservationBase, s_fixedHeapMemoryPoolSize);
+#else
+    UNUSED_PARAM(m_reservation);
+    UNUSED_PARAM(m_reservationBase);
+#endif
+}
+
+SuperRegion::~SuperRegion()
+{
+#if ENABLE(SUPER_REGION)
+    m_reservation.deallocate();
+#endif
+}
+
+void* SuperRegion::getAlignedBase(PageReservation& reservation)
+{
+    for (char* current = static_cast<char*>(reservation.base()); current < static_cast<char*>(reservation.base()) + Region::s_regionSize; current += pageSize()) {
+        if (!(reinterpret_cast<size_t>(current) & ~Region::s_regionMask))
+            return current;
+    }
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+void* SuperRegion::allocateNewSpace(size_t&)
+{
+    return 0;
+}
+
+void SuperRegion::notifyNeedPage(void* page)
+{
+    m_reservation.commit(page, Region::s_regionSize);
+}
+
+void SuperRegion::notifyPageIsFree(void* page)
+{
+    m_reservation.decommit(page, Region::s_regionSize);
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/heap/SuperRegion.h b/Source/JavaScriptCore/heap/SuperRegion.h
new file mode 100644 (file)
index 0000000..e21526b
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2013 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 SuperRegion_h
+#define SuperRegion_h
+
+#include <wtf/MetaAllocator.h>
+#include <wtf/PageBlock.h>
+#include <wtf/PageReservation.h>
+
+namespace JSC {
+
+class VM;
+
+class SuperRegion : public WTF::MetaAllocator {
+public:
+    SuperRegion();
+    virtual ~SuperRegion();
+
+protected:
+    virtual void* allocateNewSpace(size_t&) override;
+    virtual void notifyNeedPage(void*) override;
+    virtual void notifyPageIsFree(void*) override;
+
+private:
+    static const uint64_t s_fixedHeapMemoryPoolSize;
+
+    static void* getAlignedBase(PageReservation&);
+
+    PageReservation m_reservation;
+    void* m_reservationBase;
+};
+
+} // namespace JSC
+
+#endif // SuperRegion_h
index b6c27e4..54127ca 100644 (file)
 
 namespace JSC {
 
-WeakBlock* WeakBlock::create()
+WeakBlock* WeakBlock::create(DeadBlock* block)
 {
-    return new (NotNull, fastAlignedMalloc(blockSize, blockSize)) WeakBlock();
+    Region* region = block->region();
+    return new (NotNull, block) WeakBlock(region);
 }
 
-WeakBlock::WeakBlock()
-    : HeapBlock<WeakBlock>()
+WeakBlock::WeakBlock(Region* region)
+    : HeapBlock<WeakBlock>(region)
 {
     for (size_t i = 0; i < weakImplCount(); ++i) {
         WeakImpl* weakImpl = &weakImpls()[i];
index c82930e..b6b631e 100644 (file)
@@ -34,6 +34,7 @@
 
 namespace JSC {
 
+class DeadBlock;
 class HeapRootVisitor;
 class JSValue;
 class WeakHandleOwner;
@@ -55,7 +56,7 @@ public:
         FreeCell* freeList;
     };
 
-    static WeakBlock* create();
+    static WeakBlock* create(DeadBlock*);
 
     static WeakImpl* asWeakImpl(FreeCell*);
 
@@ -72,7 +73,7 @@ public:
 private:
     static FreeCell* asFreeCell(WeakImpl*);
 
-    WeakBlock();
+    WeakBlock(Region*);
     WeakImpl* firstWeakImpl();
     void finalize(WeakImpl*);
     WeakImpl* weakImpls();
index 37ddfac..556c851 100644 (file)
@@ -37,7 +37,7 @@ WeakSet::~WeakSet()
     WeakBlock* next = 0;
     for (WeakBlock* block = m_blocks.head(); block; block = next) {
         next = block->next();
-        WeakBlock::destroy(block);
+        heap()->blockAllocator().deallocate(WeakBlock::destroy(block));
     }
     m_blocks.clear();
 }
@@ -74,7 +74,7 @@ WeakBlock::FreeCell* WeakSet::tryFindAllocator()
 
 WeakBlock::FreeCell* WeakSet::addAllocator()
 {
-    WeakBlock* block = WeakBlock::create();
+    WeakBlock* block = WeakBlock::create(heap()->blockAllocator().allocate<WeakBlock>());
     heap()->didAllocate(WeakBlock::blockSize);
     m_blocks.append(block);
     WeakBlock::SweepResult sweepResult = block->takeSweepResult();
@@ -85,7 +85,7 @@ WeakBlock::FreeCell* WeakSet::addAllocator()
 void WeakSet::removeAllocator(WeakBlock* block)
 {
     m_blocks.remove(block);
-    WeakBlock::destroy(block);
+    heap()->blockAllocator().deallocate(WeakBlock::destroy(block));
 }
 
 } // namespace JSC
index 8f08917..1c0fd38 100644 (file)
@@ -1,3 +1,18 @@
+2015-01-27  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r179192.
+        https://bugs.webkit.org/show_bug.cgi?id=140953
+
+        Caused numerous layout test failures (Requested by mattbaker_
+        on #webkit).
+
+        Reverted changeset:
+
+        "Use FastMalloc (bmalloc) instead of BlockAllocator for GC
+        pages"
+        https://bugs.webkit.org/show_bug.cgi?id=140900
+        http://trac.webkit.org/changeset/179192
+
 2015-01-26  Geoffrey Garen  <ggaren@apple.com>
 
         Use FastMalloc (bmalloc) instead of BlockAllocator for GC pages
index cc7c666..18a9c84 100644 (file)
@@ -244,34 +244,6 @@ size_t fastMallocGoodSize(size_t bytes)
 #endif
 }
 
-#if OS(WINDOWS)
-
-void* fastAlignedMalloc(size_t alignment, size_t size) 
-{
-    return _aligned_malloc(alignment, size);
-}
-
-void fastAlignedFree(void* p) 
-{
-    _aligned_free(p);
-}
-
-#else
-
-void* fastAlignedMalloc(size_t alignment, size_t size) 
-{
-    void* p = nullptr;
-    posix_memalign(&p, alignment, size);
-    return p;
-}
-
-void fastAlignedFree(void* p) 
-{
-    free(p);
-}
-
-#endif // OS(WINDOWS)
-
 TryMallocReturnValue tryFastMalloc(size_t n) 
 {
     ASSERT(!isForbidden());
@@ -482,16 +454,6 @@ size_t fastMallocGoodSize(size_t size)
     return size;
 }
     
-void* fastAlignedMalloc(size_t alignment, size_t size) 
-{
-    return bmalloc::api::memalign(alignment, size);
-}
-
-void fastAlignedFree(void* p) 
-{
-    bmalloc::api::free(p);
-}
-
 TryMallocReturnValue tryFastMalloc(size_t size)
 {
     return fastMalloc(size);
@@ -4242,6 +4204,7 @@ static ALWAYS_INLINE void do_free(void* ptr) {
   }
 }
 
+#ifndef WTF_CHANGES
 // For use by exported routines below that want specific alignments
 //
 // Note: this code can be slow, and can significantly fragment memory.
@@ -4312,6 +4275,7 @@ static void* do_memalign(size_t align, size_t size) {
   }
   return SpanToMallocResult(span);
 }
+#endif
 
 // Helpers for use by exported routines below:
 
@@ -4368,16 +4332,6 @@ extern "C"
 template <bool crashOnFailure>
 ALWAYS_INLINE void* malloc(size_t);
 
-void* fastAlignedMalloc(size_t alignment, size_t size) 
-{
-    return do_memalign(alignment, size);
-}
-
-void fastAlignedFree(void* p) 
-{
-    do_free(p);
-}
-
 void* fastMalloc(size_t size)
 {
     void* result = malloc<true>(size);
index b7dca06..c9b2d41 100644 (file)
@@ -37,10 +37,6 @@ namespace WTF {
     WTF_EXPORT_PRIVATE size_t fastMallocSize(const void*);
     WTF_EXPORT_PRIVATE size_t fastMallocGoodSize(size_t);
 
-    // Allocations from fastAlignedMalloc() must be freed using fastAlignedFree().
-    WTF_EXPORT_PRIVATE void* fastAlignedMalloc(size_t alignment, size_t);
-    WTF_EXPORT_PRIVATE void fastAlignedFree(void*);
-
     struct TryMallocReturnValue {
         TryMallocReturnValue(void* data)
             : m_data(data)
@@ -235,8 +231,6 @@ using WTF::tryFastCalloc;
 using WTF::tryFastMalloc;
 using WTF::tryFastRealloc;
 using WTF::tryFastZeroedMalloc;
-using WTF::fastAlignedMalloc;
-using WTF::fastAlignedFree;
 
 #ifndef NDEBUG    
 using WTF::fastMallocForbid;
index 2420ca2..10eaa11 100644 (file)
@@ -1,3 +1,18 @@
+2015-01-27  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r179192.
+        https://bugs.webkit.org/show_bug.cgi?id=140953
+
+        Caused numerous layout test failures (Requested by mattbaker_
+        on #webkit).
+
+        Reverted changeset:
+
+        "Use FastMalloc (bmalloc) instead of BlockAllocator for GC
+        pages"
+        https://bugs.webkit.org/show_bug.cgi?id=140900
+        http://trac.webkit.org/changeset/179192
+
 2015-01-27  Benjamin Poulain  <bpoulain@apple.com>
 
         Modernize some constructors of the CSS JIT
index 12ea972..3441aba 100644 (file)
@@ -115,11 +115,14 @@ void MemoryPressureHandler::install()
 
     // Allow simulation of memory pressure with "notifyutil -p org.WebKit.lowMemory"
     notify_register_dispatch("org.WebKit.lowMemory", &_notifyToken, dispatch_get_main_queue(), ^(int) {
+        memoryPressureHandler().respondToMemoryPressure(true);
+
         // We only do a synchronous GC when *simulating* memory pressure.
         // This gives us a more consistent picture of live objects at the end of testing.
         gcController().garbageCollectNow();
 
-        memoryPressureHandler().respondToMemoryPressure(true);
+        // Release any freed up blocks from the JS heap back to the system.
+        JSDOMWindowBase::commonVM().heap.blockAllocator().releaseFreeRegions();
 
         malloc_zone_pressure_relief(nullptr, 0);
     });