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;