Title: [204393] trunk/Source/_javascript_Core
Revision
204393
Author
[email protected]
Date
2016-08-11 17:22:20 -0700 (Thu, 11 Aug 2016)

Log Message

[JSC] Revert most of r203808
https://bugs.webkit.org/show_bug.cgi?id=160784

Patch by Benjamin Poulain <[email protected]> on 2016-08-11
Reviewed by Geoffrey Garen.

Switching to fastMalloc() caused regressions on Jetstream and Octane
on MacBook Air. I was able to get back some of it in the following
patches but the tests that never go to FTL are still regressed.

This patch revert r203808 except of the node index.
Nodes are allocated with the custom allocator like before but they are
now also kept in a table, addressed by the node index.

* CMakeLists.txt:
* _javascript_Core.xcodeproj/project.pbxproj:
* b3/B3SparseCollection.h:
(JSC::B3::SparseCollection::packIndices): Deleted.
* dfg/DFGAllocator.h: Added.
(JSC::DFG::Allocator::Region::size):
(JSC::DFG::Allocator::Region::headerSize):
(JSC::DFG::Allocator::Region::numberOfThingsPerRegion):
(JSC::DFG::Allocator::Region::data):
(JSC::DFG::Allocator::Region::isInThisRegion):
(JSC::DFG::Allocator::Region::regionFor):
(JSC::DFG::Allocator<T>::Allocator):
(JSC::DFG::Allocator<T>::~Allocator):
(JSC::DFG::Allocator<T>::allocate):
(JSC::DFG::Allocator<T>::free):
(JSC::DFG::Allocator<T>::freeAll):
(JSC::DFG::Allocator<T>::reset):
(JSC::DFG::Allocator<T>::indexOf):
(JSC::DFG::Allocator<T>::allocatorOf):
(JSC::DFG::Allocator<T>::bumpAllocate):
(JSC::DFG::Allocator<T>::freeListAllocate):
(JSC::DFG::Allocator<T>::allocateSlow):
(JSC::DFG::Allocator<T>::freeRegionsStartingAt):
(JSC::DFG::Allocator<T>::startBumpingIn):
* dfg/DFGDriver.cpp:
(JSC::DFG::compileImpl):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::Graph):
(JSC::DFG::Graph::~Graph):
(JSC::DFG::Graph::addNodeToMapByIndex):
(JSC::DFG::Graph::deleteNode):
(JSC::DFG::Graph::packNodeIndices):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::addNode):
(JSC::DFG::Graph::maxNodeCount):
(JSC::DFG::Graph::nodeAt):
* dfg/DFGLongLivedState.cpp: Added.
(JSC::DFG::LongLivedState::LongLivedState):
(JSC::DFG::LongLivedState::~LongLivedState):
(JSC::DFG::LongLivedState::shrinkToFit):
* dfg/DFGLongLivedState.h: Added.
* dfg/DFGNode.h:
* dfg/DFGNodeAllocator.h: Added.
(operator new ):
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThread):
(JSC::DFG::Plan::compileInThreadImpl):
* dfg/DFGPlan.h:
* dfg/DFGWorklist.cpp:
(JSC::DFG::Worklist::runThread):
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/CMakeLists.txt (204392 => 204393)


--- trunk/Source/_javascript_Core/CMakeLists.txt	2016-08-12 00:08:50 UTC (rev 204392)
+++ trunk/Source/_javascript_Core/CMakeLists.txt	2016-08-12 00:22:20 UTC (rev 204393)
@@ -312,6 +312,7 @@
     dfg/DFGLazyJSValue.cpp
     dfg/DFGLazyNode.cpp
     dfg/DFGLivenessAnalysisPhase.cpp
+    dfg/DFGLongLivedState.cpp
     dfg/DFGLoopPreHeaderCreationPhase.cpp
     dfg/DFGMaximalFlushInsertionPhase.cpp
     dfg/DFGMayExit.cpp

Modified: trunk/Source/_javascript_Core/ChangeLog (204392 => 204393)


--- trunk/Source/_javascript_Core/ChangeLog	2016-08-12 00:08:50 UTC (rev 204392)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-08-12 00:22:20 UTC (rev 204393)
@@ -1,3 +1,72 @@
+2016-08-11  Benjamin Poulain  <[email protected]>
+
+        [JSC] Revert most of r203808
+        https://bugs.webkit.org/show_bug.cgi?id=160784
+
+        Reviewed by Geoffrey Garen.
+
+        Switching to fastMalloc() caused regressions on Jetstream and Octane
+        on MacBook Air. I was able to get back some of it in the following
+        patches but the tests that never go to FTL are still regressed.
+
+        This patch revert r203808 except of the node index.
+        Nodes are allocated with the custom allocator like before but they are
+        now also kept in a table, addressed by the node index.
+
+        * CMakeLists.txt:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * b3/B3SparseCollection.h:
+        (JSC::B3::SparseCollection::packIndices): Deleted.
+        * dfg/DFGAllocator.h: Added.
+        (JSC::DFG::Allocator::Region::size):
+        (JSC::DFG::Allocator::Region::headerSize):
+        (JSC::DFG::Allocator::Region::numberOfThingsPerRegion):
+        (JSC::DFG::Allocator::Region::data):
+        (JSC::DFG::Allocator::Region::isInThisRegion):
+        (JSC::DFG::Allocator::Region::regionFor):
+        (JSC::DFG::Allocator<T>::Allocator):
+        (JSC::DFG::Allocator<T>::~Allocator):
+        (JSC::DFG::Allocator<T>::allocate):
+        (JSC::DFG::Allocator<T>::free):
+        (JSC::DFG::Allocator<T>::freeAll):
+        (JSC::DFG::Allocator<T>::reset):
+        (JSC::DFG::Allocator<T>::indexOf):
+        (JSC::DFG::Allocator<T>::allocatorOf):
+        (JSC::DFG::Allocator<T>::bumpAllocate):
+        (JSC::DFG::Allocator<T>::freeListAllocate):
+        (JSC::DFG::Allocator<T>::allocateSlow):
+        (JSC::DFG::Allocator<T>::freeRegionsStartingAt):
+        (JSC::DFG::Allocator<T>::startBumpingIn):
+        * dfg/DFGDriver.cpp:
+        (JSC::DFG::compileImpl):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::Graph):
+        (JSC::DFG::Graph::~Graph):
+        (JSC::DFG::Graph::addNodeToMapByIndex):
+        (JSC::DFG::Graph::deleteNode):
+        (JSC::DFG::Graph::packNodeIndices):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::addNode):
+        (JSC::DFG::Graph::maxNodeCount):
+        (JSC::DFG::Graph::nodeAt):
+        * dfg/DFGLongLivedState.cpp: Added.
+        (JSC::DFG::LongLivedState::LongLivedState):
+        (JSC::DFG::LongLivedState::~LongLivedState):
+        (JSC::DFG::LongLivedState::shrinkToFit):
+        * dfg/DFGLongLivedState.h: Added.
+        * dfg/DFGNode.h:
+        * dfg/DFGNodeAllocator.h: Added.
+        (operator new ):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThread):
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGPlan.h:
+        * dfg/DFGWorklist.cpp:
+        (JSC::DFG::Worklist::runThread):
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+
 2016-08-11  Mark Lam  <[email protected]>
 
         The jsc shell's Element host constructor should throw if it fails to construct an object.

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (204392 => 204393)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2016-08-12 00:08:50 UTC (rev 204392)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2016-08-12 00:22:20 UTC (rev 204393)
@@ -885,6 +885,8 @@
 		0FEFC9AB1681A3B600567F53 /* DFGOSRExitJumpPlaceholder.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEFC9A81681A3B000567F53 /* DFGOSRExitJumpPlaceholder.h */; };
 		0FF054F91AC35B4400E5BE57 /* ExecutableAllocationFuzz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF054F71AC35B4400E5BE57 /* ExecutableAllocationFuzz.cpp */; };
 		0FF054FA1AC35B4400E5BE57 /* ExecutableAllocationFuzz.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF054F81AC35B4400E5BE57 /* ExecutableAllocationFuzz.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FF0F19916B729F6005DF95B /* DFGLongLivedState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB4B51C16B62772003F696B /* DFGLongLivedState.cpp */; };
+		0FF0F19B16B729FA005DF95B /* DFGLongLivedState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB4B51D16B62772003F696B /* DFGLongLivedState.h */; };
 		0FF0F19C16B72A03005DF95B /* DFGNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB4B51E16B62772003F696B /* DFGNode.cpp */; };
 		0FF0F19D16B72A08005DF95B /* DFGCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB4B51A16B62772003F696B /* DFGCommon.cpp */; };
 		0FF0F19E16B72A0B005DF95B /* DFGEdge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB4B51B16B62772003F696B /* DFGEdge.cpp */; };
@@ -937,7 +939,9 @@
 		0FFA549816B8835300B3A982 /* A64DOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 652A3A231651C69700A80AFE /* A64DOpcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0FFB6C381AF48DDC00DB1BF7 /* TypeofType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FFB6C361AF48DDC00DB1BF7 /* TypeofType.cpp */; };
 		0FFB6C391AF48DDC00DB1BF7 /* TypeofType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFB6C371AF48DDC00DB1BF7 /* TypeofType.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FFB921816D02EB20055A5DB /* DFGAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB4B51916B62772003F696B /* DFGAllocator.h */; };
 		0FFB921A16D02EC50055A5DB /* DFGBasicBlockInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD5652216AB780A00197653 /* DFGBasicBlockInlines.h */; };
+		0FFB921B16D02F010055A5DB /* DFGNodeAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB4B51F16B62772003F696B /* DFGNodeAllocator.h */; };
 		0FFB921C16D02F110055A5DB /* DFGOSRExitCompilationInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 65987F2C167FE84B003C2F8D /* DFGOSRExitCompilationInfo.h */; };
 		0FFB921D16D02F300055A5DB /* DFGSlowPathGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1E3A501537C2CB000F9456 /* DFGSlowPathGenerator.h */; };
 		0FFB922016D033B70055A5DB /* NodeConstructors.h in Headers */ = {isa = PBXBuildFile; fileRef = 930DAD030FB1EB1A0082D205 /* NodeConstructors.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -2793,9 +2797,13 @@
 		0FB387911BFD31A100E3AB1E /* FTLCompile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLCompile.cpp; path = ftl/FTLCompile.cpp; sourceTree = "<group>"; };
 		0FB438A219270B1D00E1FBC9 /* StructureSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureSet.cpp; sourceTree = "<group>"; };
 		0FB4B51016B3A964003F696B /* DFGMinifiedID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGMinifiedID.h; path = dfg/DFGMinifiedID.h; sourceTree = "<group>"; };
+		0FB4B51916B62772003F696B /* DFGAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAllocator.h; path = dfg/DFGAllocator.h; sourceTree = "<group>"; };
 		0FB4B51A16B62772003F696B /* DFGCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCommon.cpp; path = dfg/DFGCommon.cpp; sourceTree = "<group>"; };
 		0FB4B51B16B62772003F696B /* DFGEdge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGEdge.cpp; path = dfg/DFGEdge.cpp; sourceTree = "<group>"; };
+		0FB4B51C16B62772003F696B /* DFGLongLivedState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGLongLivedState.cpp; path = dfg/DFGLongLivedState.cpp; sourceTree = "<group>"; };
+		0FB4B51D16B62772003F696B /* DFGLongLivedState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGLongLivedState.h; path = dfg/DFGLongLivedState.h; sourceTree = "<group>"; };
 		0FB4B51E16B62772003F696B /* DFGNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGNode.cpp; path = dfg/DFGNode.cpp; sourceTree = "<group>"; };
+		0FB4B51F16B62772003F696B /* DFGNodeAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGNodeAllocator.h; path = dfg/DFGNodeAllocator.h; sourceTree = "<group>"; };
 		0FB4B52116B6278D003F696B /* FunctionExecutableDump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FunctionExecutableDump.cpp; sourceTree = "<group>"; };
 		0FB4B52216B6278D003F696B /* FunctionExecutableDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionExecutableDump.h; sourceTree = "<group>"; };
 		0FB4FB701BC843140025CA5A /* FTLLazySlowPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLLazySlowPath.cpp; path = ftl/FTLLazySlowPath.cpp; sourceTree = "<group>"; };
@@ -6193,6 +6201,7 @@
 				0F18D3CD1B55A6E0002C5C9F /* DFGAdaptiveStructureWatchpoint.cpp */,
 				0F18D3CE1B55A6E0002C5C9F /* DFGAdaptiveStructureWatchpoint.h */,
 				0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */,
+				0FB4B51916B62772003F696B /* DFGAllocator.h */,
 				0F1E3A431534CBAD000F9456 /* DFGArgumentPosition.h */,
 				0F2DD80C1AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.cpp */,
 				0F2DD80D1AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.h */,
@@ -6342,6 +6351,8 @@
 				79C4B15C1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.h */,
 				A7D89CEC17A0B8CC00773AD8 /* DFGLivenessAnalysisPhase.cpp */,
 				A7D89CED17A0B8CC00773AD8 /* DFGLivenessAnalysisPhase.h */,
+				0FB4B51C16B62772003F696B /* DFGLongLivedState.cpp */,
+				0FB4B51D16B62772003F696B /* DFGLongLivedState.h */,
 				A767B5B317A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.cpp */,
 				A767B5B417A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.h */,
 				79F8FC1C1B9FED0F00CA66AB /* DFGMaximalFlushInsertionPhase.cpp */,
@@ -6361,6 +6372,7 @@
 				A737810B1799EA2E00817533 /* DFGNaturalLoops.h */,
 				0FB4B51E16B62772003F696B /* DFGNode.cpp */,
 				86ECA3E9132DEF1C002B2AD7 /* DFGNode.h */,
+				0FB4B51F16B62772003F696B /* DFGNodeAllocator.h */,
 				0FA581B7150E952A00B9A2D9 /* DFGNodeFlags.cpp */,
 				0FA581B8150E952A00B9A2D9 /* DFGNodeFlags.h */,
 				0F5D085C1B8CF99D001143B4 /* DFGNodeOrigin.cpp */,
@@ -7298,6 +7310,7 @@
 				998ED6751BED768C00DD8017 /* RemoteControllableTarget.h in Headers */,
 				0F33FCF81C136E2500323F67 /* B3StackmapGenerationParams.h in Headers */,
 				0F66E16B14DF3F1600B7B2E4 /* DFGAdjacencyList.h in Headers */,
+				0FFB921816D02EB20055A5DB /* DFGAllocator.h in Headers */,
 				0F1E3A461534CBAF000F9456 /* DFGArgumentPosition.h in Headers */,
 				0F2DD8121AB3D8BE00BBB8E8 /* DFGArgumentsEliminationPhase.h in Headers */,
 				0F2DD8141AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.h in Headers */,
@@ -7395,6 +7408,7 @@
 				99D6A1161BEAD34D00E25C37 /* RemoteAutomationTarget.h in Headers */,
 				79C4B15E1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.h in Headers */,
 				A7D89CFC17A0B8CC00773AD8 /* DFGLivenessAnalysisPhase.h in Headers */,
+				0FF0F19B16B729FA005DF95B /* DFGLongLivedState.h in Headers */,
 				0F338DF21BE93AD10013C88F /* B3StackmapValue.h in Headers */,
 				A767B5B617A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.h in Headers */,
 				79F8FC1F1B9FED0F00CA66AB /* DFGMaximalFlushInsertionPhase.h in Headers */,
@@ -7407,6 +7421,7 @@
 				0FF2CD5C1B61A4F8004955A8 /* DFGMultiGetByOffsetData.h in Headers */,
 				A737810E1799EA2E00817533 /* DFGNaturalLoops.h in Headers */,
 				86ECA3EA132DEF1C002B2AD7 /* DFGNode.h in Headers */,
+				0FFB921B16D02F010055A5DB /* DFGNodeAllocator.h in Headers */,
 				70B791931C024A28002481E2 /* GeneratorFrame.h in Headers */,
 				0FA581BB150E953000B9A2D9 /* DFGNodeFlags.h in Headers */,
 				0F300B7818AB051100A6D72E /* DFGNodeOrigin.h in Headers */,
@@ -8972,6 +8987,7 @@
 				A7D9A29717A0BC7400EE2618 /* DFGLICMPhase.cpp in Sources */,
 				79C4B15D1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.cpp in Sources */,
 				A7D89CFB17A0B8CC00773AD8 /* DFGLivenessAnalysisPhase.cpp in Sources */,
+				0FF0F19916B729F6005DF95B /* DFGLongLivedState.cpp in Sources */,
 				A767B5B517A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.cpp in Sources */,
 				79F8FC1E1B9FED0F00CA66AB /* DFGMaximalFlushInsertionPhase.cpp in Sources */,
 				0F5874ED194FEB1200AAB2C1 /* DFGMayExit.cpp in Sources */,

Modified: trunk/Source/_javascript_Core/b3/B3SparseCollection.h (204392 => 204393)


--- trunk/Source/_javascript_Core/b3/B3SparseCollection.h	2016-08-12 00:08:50 UTC (rev 204392)
+++ trunk/Source/_javascript_Core/b3/B3SparseCollection.h	2016-08-12 00:22:20 UTC (rev 204393)
@@ -26,6 +26,8 @@
 #ifndef B3SparseCollection_h
 #define B3SparseCollection_h
 
+#if ENABLE(B3_JIT)
+
 #include <wtf/StdLibExtras.h>
 #include <wtf/Vector.h>
 
@@ -74,42 +76,6 @@
         m_vector[value->m_index] = nullptr;
     }
 
-    void packIndices()
-    {
-        if (m_indexFreeList.isEmpty())
-            return;
-
-        unsigned holeIndex = 0;
-        unsigned endIndex = m_vector.size();
-
-        while (true) {
-            while (holeIndex < endIndex && m_vector[holeIndex])
-                ++holeIndex;
-
-            if (holeIndex == endIndex)
-                break;
-            ASSERT(holeIndex < m_vector.size());
-            ASSERT(!m_vector[holeIndex]);
-
-            do {
-                --endIndex;
-            } while (!m_vector[endIndex] && endIndex > holeIndex);
-
-            if (holeIndex == endIndex)
-                break;
-            ASSERT(endIndex > holeIndex);
-            ASSERT(m_vector[endIndex]);
-
-            auto& value = m_vector[endIndex];
-            value->m_index = holeIndex;
-            m_vector[holeIndex] = WTFMove(value);
-            ++holeIndex;
-        }
-
-        m_indexFreeList.resize(0);
-        m_vector.resize(endIndex);
-    }
-
     unsigned size() const { return m_vector.size(); }
     bool isEmpty() const { return m_vector.isEmpty(); }
     
@@ -174,5 +140,7 @@
 
 } } // namespace JSC::B3
 
+#endif // ENABLE(B3_JIT)
+
 #endif // B3SparseCollection_h
 

Added: trunk/Source/_javascript_Core/dfg/DFGAllocator.h (0 => 204393)


--- trunk/Source/_javascript_Core/dfg/DFGAllocator.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/dfg/DFGAllocator.h	2016-08-12 00:22:20 UTC (rev 204393)
@@ -0,0 +1,239 @@
+/*
+ * 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. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGAllocator_h
+#define DFGAllocator_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGCommon.h"
+#include <wtf/StdLibExtras.h>
+
+namespace JSC { namespace DFG {
+
+// Custom pool allocator for exactly one type (type T). It has fast (O(1), only a few
+// instructions) allocator, and a similarly fast free(). Recycling works if either of
+// the following is true:
+// - T has a trivial destructor. In that case you don't have to ever call free() on
+//   anything. You can just call freeAll() instead.
+// - You call free() on all T's that you allocated, and never use freeAll().
+
+template<typename T>
+class Allocator {
+public:
+    Allocator();
+    ~Allocator();
+    
+    void* allocate(); // Use placement new to allocate, and avoid using this method.
+    void free(T*); // Call this method to delete; never use 'delete' directly.
+    
+    void freeAll(); // Only call this if you've either freed everything or if T has a trivial destructor.
+    void reset(); // Like freeAll(), but also returns all memory to the OS.
+    
+    unsigned indexOf(const T*);
+    
+    static Allocator* allocatorOf(const T*);
+    
+private:
+    void* bumpAllocate();
+    void* freeListAllocate();
+    void* allocateSlow();
+
+    struct Region {
+        static size_t size() { return 64 * KB; }
+        static size_t headerSize() { return std::max(sizeof(Region), sizeof(T)); }
+        static unsigned numberOfThingsPerRegion() { return (size() - headerSize()) / sizeof(T); }
+        T* data() { return bitwise_cast<T*>(bitwise_cast<char*>(this) + headerSize()); }
+        bool isInThisRegion(const T* pointer) { return static_cast<unsigned>(pointer - data()) < numberOfThingsPerRegion(); }
+        static Region* regionFor(const T* pointer) { return bitwise_cast<Region*>(bitwise_cast<uintptr_t>(pointer) & ~(size() - 1)); }
+        
+        void* m_allocation;
+        Allocator* m_allocator;
+        Region* m_next;
+    };
+    
+    void freeRegionsStartingAt(Region*);
+    void startBumpingIn(Region*);
+    
+    Region* m_regionHead;
+    void** m_freeListHead;
+    T* m_bumpEnd;
+    unsigned m_bumpRemaining;
+};
+
+template<typename T>
+inline Allocator<T>::Allocator()
+    : m_regionHead(0)
+    , m_freeListHead(0)
+    , m_bumpRemaining(0)
+{
+}
+
+template<typename T>
+inline Allocator<T>::~Allocator()
+{
+    reset();
+}
+
+template<typename T>
+ALWAYS_INLINE void* Allocator<T>::allocate()
+{
+    void* result = bumpAllocate();
+    if (LIKELY(!!result))
+        return result;
+    return freeListAllocate();
+}
+
+template<typename T>
+void Allocator<T>::free(T* object)
+{
+    object->~T();
+    
+    void** cell = bitwise_cast<void**>(object);
+    *cell = m_freeListHead;
+    m_freeListHead = cell;
+}
+
+template<typename T>
+void Allocator<T>::freeAll()
+{
+    if (!m_regionHead) {
+        ASSERT(!m_bumpRemaining);
+        ASSERT(!m_freeListHead);
+        return;
+    }
+    
+    // Since the caller is opting out of calling the destructor for any allocated thing,
+    // we have two choices, plus a continuum between: we can either just delete all regions
+    // (i.e. call reset()), or we can make all regions available for reuse. We do something
+    // that optimizes for (a) speed of freeAll(), (b) the assumption that if the user calls
+    // freeAll() then they will probably be calling allocate() in the near future. Namely,
+    // we free all but one region, and make the remaining region a bump allocation region.
+    
+    freeRegionsStartingAt(m_regionHead->m_next);
+    
+    m_regionHead->m_next = 0;
+    m_freeListHead = 0;
+    startBumpingIn(m_regionHead);
+}
+
+template<typename T>
+void Allocator<T>::reset()
+{
+    freeRegionsStartingAt(m_regionHead);
+    
+    m_regionHead = 0;
+    m_freeListHead = 0;
+    m_bumpRemaining = 0;
+}
+
+template<typename T>
+unsigned Allocator<T>::indexOf(const T* object)
+{
+    unsigned numRegions = 0;
+    for (Region* region = m_regionHead; region; region = region->m_next)
+        numRegions++;
+    unsigned regionIndex = 0;
+    for (Region* region = m_regionHead; region; region = region->m_next) {
+        if (region->isInThisRegion(object))
+            return (numRegions - 1 - regionIndex) * Region::numberOfThingsPerRegion() + (object - region->data());
+        regionIndex++;
+    }
+    CRASH();
+    return 0;
+}
+
+template<typename T>
+Allocator<T>* Allocator<T>::allocatorOf(const T* object)
+{
+    return Region::regionFor(object)->m_allocator;
+}
+
+template<typename T>
+ALWAYS_INLINE void* Allocator<T>::bumpAllocate()
+{
+    if (unsigned remaining = m_bumpRemaining) {
+        remaining--;
+        m_bumpRemaining = remaining;
+        return m_bumpEnd - (remaining + 1);
+    }
+    return 0;
+}
+
+template<typename T>
+void* Allocator<T>::freeListAllocate()
+{
+    void** result = m_freeListHead;
+    if (UNLIKELY(!result))
+        return allocateSlow();
+    m_freeListHead = bitwise_cast<void**>(*result);
+    return result;
+}
+
+template<typename T>
+void* Allocator<T>::allocateSlow()
+{
+    ASSERT(!m_freeListHead);
+    ASSERT(!m_bumpRemaining);
+    
+    if (logCompilationChanges())
+        dataLog("Allocating another allocator region.\n");
+
+    void* allocation = fastAlignedMalloc(Region::size(), Region::size());
+    Region* region = static_cast<Region*>(allocation);
+    region->m_allocation = allocation;
+    region->m_allocator = this;
+    startBumpingIn(region);
+    region->m_next = m_regionHead;
+    m_regionHead = region;
+    
+    void* result = bumpAllocate();
+    ASSERT(result);
+    return result;
+}
+
+template<typename T>
+void Allocator<T>::freeRegionsStartingAt(typename Allocator<T>::Region* region)
+{
+    while (region) {
+        Region* nextRegion = region->m_next;
+        fastAlignedFree(region->m_allocation);
+        region = nextRegion;
+    }
+}
+
+template<typename T>
+void Allocator<T>::startBumpingIn(typename Allocator<T>::Region* region)
+{
+    m_bumpEnd = region->data() + Region::numberOfThingsPerRegion();
+    m_bumpRemaining = Region::numberOfThingsPerRegion();
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGAllocator_h
+

Modified: trunk/Source/_javascript_Core/dfg/DFGDriver.cpp (204392 => 204393)


--- trunk/Source/_javascript_Core/dfg/DFGDriver.cpp	2016-08-12 00:08:50 UTC (rev 204392)
+++ trunk/Source/_javascript_Core/dfg/DFGDriver.cpp	2016-08-12 00:22:20 UTC (rev 204393)
@@ -108,7 +108,7 @@
         return CompilationDeferred;
     }
     
-    plan->compileInThread(nullptr);
+    plan->compileInThread(*vm.dfgState, 0);
     return plan->finalizeWithoutNotifyingCallback();
 }
 #else // ENABLE(DFG_JIT)

Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.cpp (204392 => 204393)


--- trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2016-08-12 00:08:50 UTC (rev 204392)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2016-08-12 00:22:20 UTC (rev 204393)
@@ -66,11 +66,12 @@
 #undef STRINGIZE_DFG_OP_ENUM
 };
 
-Graph::Graph(VM& vm, Plan& plan)
+Graph::Graph(VM& vm, Plan& plan, LongLivedState& longLivedState)
     : m_vm(vm)
     , m_plan(plan)
     , m_codeBlock(m_plan.codeBlock)
     , m_profiledBlock(m_codeBlock->alternative())
+    , m_allocator(longLivedState.m_allocator)
     , m_cfg(std::make_unique<CFG>(*this))
     , m_nextMachineLocal(0)
     , m_fixpointState(BeforeFixpoint)
@@ -86,6 +87,17 @@
 
 Graph::~Graph()
 {
+    for (BlockIndex blockIndex = numBlocks(); blockIndex--;) {
+        BasicBlock* block = this->block(blockIndex);
+        if (!block)
+            continue;
+
+        for (unsigned phiIndex = block->phis.size(); phiIndex--;)
+            m_allocator.free(block->phis[phiIndex]);
+        for (unsigned nodeIndex = block->size(); nodeIndex--;)
+            m_allocator.free(block->at(nodeIndex));
+    }
+    m_allocator.freeAll();
 }
 
 const char *Graph::opName(NodeType op)
@@ -567,6 +579,19 @@
     }
 }
 
+void Graph::addNodeToMapByIndex(Node* node)
+{
+    if (m_nodeIndexFreeList.isEmpty()) {
+        node->m_index = m_nodesByIndex.size();
+        m_nodesByIndex.append(node);
+        return;
+    }
+    unsigned index = m_nodeIndexFreeList.takeLast();
+    node->m_index = index;
+    ASSERT(!m_nodesByIndex[index]);
+    m_nodesByIndex[index] = node;
+}
+
 void Graph::deleteNode(Node* node)
 {
     if (validationEnabled() && m_form == SSA) {
@@ -575,12 +600,49 @@
             DFG_ASSERT(*this, node, !block->ssa->liveAtTail.contains(node));
         }
     }
-    m_nodes.remove(node);
+
+    RELEASE_ASSERT(m_nodesByIndex[node->m_index] == node);
+    unsigned nodeIndex = node->m_index;
+    m_nodesByIndex[nodeIndex] = nullptr;
+    m_nodeIndexFreeList.append(nodeIndex);
+
+    m_allocator.free(node);
 }
 
 void Graph::packNodeIndices()
 {
-    m_nodes.packIndices();
+    if (m_nodeIndexFreeList.isEmpty())
+        return;
+
+    unsigned holeIndex = 0;
+    unsigned endIndex = m_nodesByIndex.size();
+
+    while (true) {
+        while (holeIndex < endIndex && m_nodesByIndex[holeIndex])
+            ++holeIndex;
+
+        if (holeIndex == endIndex)
+            break;
+        ASSERT(holeIndex < m_nodesByIndex.size());
+        ASSERT(!m_nodesByIndex[holeIndex]);
+
+        do {
+            --endIndex;
+        } while (!m_nodesByIndex[endIndex] && endIndex > holeIndex);
+
+        if (holeIndex == endIndex)
+            break;
+        ASSERT(endIndex > holeIndex);
+        ASSERT(m_nodesByIndex[endIndex]);
+
+        auto& value = m_nodesByIndex[endIndex];
+        value->m_index = holeIndex;
+        m_nodesByIndex[holeIndex] = WTFMove(value);
+        ++holeIndex;
+    }
+
+    m_nodeIndexFreeList.resize(0);
+    m_nodesByIndex.resize(endIndex);
 }
 
 void Graph::dethread()

Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.h (204392 => 204393)


--- trunk/Source/_javascript_Core/dfg/DFGGraph.h	2016-08-12 00:08:50 UTC (rev 204392)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.h	2016-08-12 00:22:20 UTC (rev 204393)
@@ -29,13 +29,14 @@
 #if ENABLE(DFG_JIT)
 
 #include "AssemblyHelpers.h"
-#include "B3SparseCollection.h"
 #include "BytecodeLivenessAnalysisInlines.h"
 #include "CodeBlock.h"
 #include "DFGArgumentPosition.h"
 #include "DFGBasicBlock.h"
 #include "DFGFrozenValue.h"
+#include "DFGLongLivedState.h"
 #include "DFGNode.h"
+#include "DFGNodeAllocator.h"
 #include "DFGPlan.h"
 #include "DFGPropertyTypeKey.h"
 #include "DFGScannable.h"
@@ -123,7 +124,7 @@
 // Nodes that are 'dead' remain in the vector with refCount 0.
 class Graph : public virtual Scannable {
 public:
-    Graph(VM&, Plan&);
+    Graph(VM&, Plan&, LongLivedState&);
     ~Graph();
     
     void changeChild(Edge& edge, Node* newNode)
@@ -183,20 +184,22 @@
     template<typename... Params>
     Node* addNode(Params... params)
     {
-        Node* node = new Node(params...);
-        m_nodes.add(std::unique_ptr<Node>(node));
+        Node* node = new (m_allocator) Node(params...);
+        addNodeToMapByIndex(node);
         return node;
     }
     template<typename... Params>
     Node* addNode(SpeculatedType type, Params... params)
     {
-        Node* node = addNode(params...);
+        Node* node = new (m_allocator) Node(params...);
         node->predict(type);
+        addNodeToMapByIndex(node);
         return node;
     }
+
     void deleteNode(Node*);
-    unsigned maxNodeCount() const { return m_nodes.size(); }
-    Node* nodeAt(unsigned index) const { return m_nodes[index]; }
+    unsigned maxNodeCount() const { return m_nodesByIndex.size(); }
+    Node* nodeAt(unsigned index) const { return m_nodesByIndex[index]; }
     void packNodeIndices();
 
     Vector<AbstractValue, 0, UnsafeVectorOverflow>& abstractValuesCache() { return m_abstractValuesCache; }
@@ -834,6 +837,8 @@
     Plan& m_plan;
     CodeBlock* m_codeBlock;
     CodeBlock* m_profiledBlock;
+    
+    NodeAllocator& m_allocator;
 
     Vector< RefPtr<BasicBlock> , 8> m_blocks;
     Vector<Edge, 16> m_varArgChildren;
@@ -922,7 +927,7 @@
     bool m_hasDebuggerEnabled;
     bool m_hasExceptionHandlers { false };
 private:
-    void adoptNodeOutOfLine(Node&);
+    void addNodeToMapByIndex(Node*);
 
     bool isStringPrototypeMethodSane(JSGlobalObject*, UniquedStringImpl*);
 
@@ -956,7 +961,8 @@
         return bytecodeCanTruncateInteger(add->arithNodeFlags()) ? SpeculateInt32AndTruncateConstants : DontSpeculateInt32;
     }
 
-    B3::SparseCollection<Node> m_nodes;
+    Vector<Node*, 0, UnsafeVectorOverflow> m_nodesByIndex;
+    Vector<unsigned, 0, UnsafeVectorOverflow> m_nodeIndexFreeList;
     Vector<AbstractValue, 0, UnsafeVectorOverflow> m_abstractValuesCache;
 };
 

Added: trunk/Source/_javascript_Core/dfg/DFGLongLivedState.cpp (0 => 204393)


--- trunk/Source/_javascript_Core/dfg/DFGLongLivedState.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/dfg/DFGLongLivedState.cpp	2016-08-12 00:22:20 UTC (rev 204393)
@@ -0,0 +1,51 @@
+/*
+ * 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. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGLongLivedState.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "JSCInlines.h"
+
+namespace JSC { namespace DFG {
+
+LongLivedState::LongLivedState()
+{
+}
+
+LongLivedState::~LongLivedState()
+{
+}
+
+void LongLivedState::shrinkToFit()
+{
+    m_allocator.reset();
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+

Added: trunk/Source/_javascript_Core/dfg/DFGLongLivedState.h (0 => 204393)


--- trunk/Source/_javascript_Core/dfg/DFGLongLivedState.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/dfg/DFGLongLivedState.h	2016-08-12 00:22:20 UTC (rev 204393)
@@ -0,0 +1,53 @@
+/*
+ * 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. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGLongLivedState_h
+#define DFGLongLivedState_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGNodeAllocator.h"
+#include <wtf/FastMalloc.h>
+#include <wtf/Noncopyable.h>
+
+namespace JSC { namespace DFG {
+
+class LongLivedState {
+    WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_NONCOPYABLE(LongLivedState);
+public:
+    LongLivedState();
+    ~LongLivedState();
+    
+    void shrinkToFit();
+    
+    NodeAllocator m_allocator;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGLongLivedState_h
+

Modified: trunk/Source/_javascript_Core/dfg/DFGNode.h (204392 => 204393)


--- trunk/Source/_javascript_Core/dfg/DFGNode.h	2016-08-12 00:08:50 UTC (rev 204392)
+++ trunk/Source/_javascript_Core/dfg/DFGNode.h	2016-08-12 00:22:20 UTC (rev 204393)
@@ -28,7 +28,6 @@
 
 #if ENABLE(DFG_JIT)
 
-#include "B3SparseCollection.h"
 #include "BasicBlockLocation.h"
 #include "CodeBlock.h"
 #include "DFGAbstractValue.h"
@@ -231,7 +230,6 @@
 //
 // Node represents a single operation in the data flow graph.
 struct Node {
-    WTF_MAKE_FAST_ALLOCATED;
 public:
     enum VarArgTag { VarArg };
     
@@ -2346,7 +2344,7 @@
     AdjacencyList children;
 
 private:
-    friend class B3::SparseCollection<Node>;
+    friend class Graph;
 
     unsigned m_index { std::numeric_limits<unsigned>::max() };
     unsigned m_op : 10; // real type is NodeType

Added: trunk/Source/_javascript_Core/dfg/DFGNodeAllocator.h (0 => 204393)


--- trunk/Source/_javascript_Core/dfg/DFGNodeAllocator.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeAllocator.h	2016-08-12 00:22:20 UTC (rev 204393)
@@ -0,0 +1,49 @@
+/*
+ * 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. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGNodeAllocator_h
+#define DFGNodeAllocator_h
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGAllocator.h"
+#include "DFGNode.h"
+
+namespace JSC { namespace DFG {
+
+typedef Allocator<Node> NodeAllocator;
+
+} } // namespace JSC::DFG
+
+inline void* operator new (size_t size, JSC::DFG::NodeAllocator& allocator)
+{
+    ASSERT_UNUSED(size, size == sizeof(JSC::DFG::Node));
+    return allocator.allocate();
+}
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGNodeAllocator_h
+

Modified: trunk/Source/_javascript_Core/dfg/DFGPlan.cpp (204392 => 204393)


--- trunk/Source/_javascript_Core/dfg/DFGPlan.cpp	2016-08-12 00:08:50 UTC (rev 204392)
+++ trunk/Source/_javascript_Core/dfg/DFGPlan.cpp	2016-08-12 00:22:20 UTC (rev 204393)
@@ -170,7 +170,7 @@
         || (Options::reportFTLCompileTimes() && isFTL(mode));
 }
 
-void Plan::compileInThread(ThreadData* threadData)
+void Plan::compileInThread(LongLivedState& longLivedState, ThreadData* threadData)
 {
     this->threadData = threadData;
     
@@ -186,7 +186,7 @@
     if (logCompilationChanges(mode))
         dataLog("DFG(Plan) compiling ", *codeBlock, " with ", mode, ", number of instructions = ", codeBlock->instructionCount(), "\n");
 
-    CompilationPath path = compileInThreadImpl();
+    CompilationPath path = compileInThreadImpl(longLivedState);
 
     RELEASE_ASSERT(path == CancelPath || finalizer);
     RELEASE_ASSERT((path == CancelPath) == (stage == Cancelled));
@@ -236,7 +236,7 @@
     }
 }
 
-Plan::CompilationPath Plan::compileInThreadImpl()
+Plan::CompilationPath Plan::compileInThreadImpl(LongLivedState& longLivedState)
 {
     cleanMustHandleValuesIfNecessary();
     
@@ -246,7 +246,7 @@
         dataLog("\n");
     }
     
-    Graph dfg(*vm, *this);
+    Graph dfg(*vm, *this, longLivedState);
     
     if (!parse(dfg)) {
         finalizer = std::make_unique<FailedFinalizer>(*this);

Modified: trunk/Source/_javascript_Core/dfg/DFGPlan.h (204392 => 204393)


--- trunk/Source/_javascript_Core/dfg/DFGPlan.h	2016-08-12 00:08:50 UTC (rev 204392)
+++ trunk/Source/_javascript_Core/dfg/DFGPlan.h	2016-08-12 00:22:20 UTC (rev 204393)
@@ -48,6 +48,7 @@
 
 namespace DFG {
 
+class LongLivedState;
 class ThreadData;
 
 #if ENABLE(DFG_JIT)
@@ -59,7 +60,7 @@
         const Operands<JSValue>& mustHandleValues);
     ~Plan();
 
-    void compileInThread(ThreadData*);
+    void compileInThread(LongLivedState&, ThreadData*);
     
     CompilationResult finalizeWithoutNotifyingCallback();
     void finalizeAndNotifyCallback();
@@ -120,7 +121,7 @@
     bool reportCompileTimes() const;
     
     enum CompilationPath { FailPath, DFGPath, FTLPath, CancelPath };
-    CompilationPath compileInThreadImpl();
+    CompilationPath compileInThreadImpl(LongLivedState&);
     
     bool isStillValid();
     void reallyAdd(CommonData*);

Modified: trunk/Source/_javascript_Core/dfg/DFGWorklist.cpp (204392 => 204393)


--- trunk/Source/_javascript_Core/dfg/DFGWorklist.cpp	2016-08-12 00:08:50 UTC (rev 204392)
+++ trunk/Source/_javascript_Core/dfg/DFGWorklist.cpp	2016-08-12 00:22:20 UTC (rev 204393)
@@ -29,8 +29,9 @@
 #if ENABLE(DFG_JIT)
 
 #include "CodeBlock.h"
+#include "DFGLongLivedState.h"
+#include "DFGSafepoint.h"
 #include "DeferGC.h"
-#include "DFGSafepoint.h"
 #include "JSCInlines.h"
 #include <mutex>
 
@@ -361,6 +362,8 @@
     if (Options::verboseCompilationQueue())
         dataLog(*this, ": Thread started\n");
     
+    LongLivedState longLivedState;
+    
     for (;;) {
         RefPtr<Plan> plan;
         {
@@ -396,7 +399,7 @@
                 dataLog(*this, ": Compiling ", plan->key(), " asynchronously\n");
         
             RELEASE_ASSERT(!plan->vm->heap.isCollecting());
-            plan->compileInThread(data);
+            plan->compileInThread(longLivedState, data);
             RELEASE_ASSERT(plan->stage == Plan::Cancelled || !plan->vm->heap.isCollecting());
             
             {

Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (204392 => 204393)


--- trunk/Source/_javascript_Core/runtime/VM.cpp	2016-08-12 00:08:50 UTC (rev 204392)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp	2016-08-12 00:22:20 UTC (rev 204393)
@@ -38,6 +38,7 @@
 #include "CommonIdentifiers.h"
 #include "CommonSlowPaths.h"
 #include "CustomGetterSetter.h"
+#include "DFGLongLivedState.h"
 #include "DFGWorklist.h"
 #include "Disassembler.h"
 #include "ErrorInstance.h"
@@ -290,6 +291,11 @@
     }
 
     callFrameForCatch = nullptr;
+
+#if ENABLE(DFG_JIT)
+    if (canUseJIT())
+        dfgState = std::make_unique<DFG::LongLivedState>();
+#endif
     
     // Initialize this last, as a free way of asserting that VM initialization itself
     // won't use this.

Modified: trunk/Source/_javascript_Core/runtime/VM.h (204392 => 204393)


--- trunk/Source/_javascript_Core/runtime/VM.h	2016-08-12 00:08:50 UTC (rev 204392)
+++ trunk/Source/_javascript_Core/runtime/VM.h	2016-08-12 00:22:20 UTC (rev 204393)
@@ -120,6 +120,11 @@
 class Watchpoint;
 class WatchpointSet;
 
+#if ENABLE(DFG_JIT)
+namespace DFG {
+class LongLivedState;
+}
+#endif // ENABLE(DFG_JIT)
 #if ENABLE(FTL_JIT)
 namespace FTL {
 class Thunks;
@@ -267,6 +272,10 @@
     // destructed after all the objects that reference it.
     Heap heap;
 
+#if ENABLE(DFG_JIT)
+    std::unique_ptr<DFG::LongLivedState> dfgState;
+#endif // ENABLE(DFG_JIT)
+
     VMType vmType;
     ClientData* clientData;
     VMEntryFrame* topVMEntryFrame;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to