Source/JavaScriptCore/CMakeLists.txt

@@set(JavaScriptCore_SOURCES
126126 dfg/DFGBasicBlock.cpp
127127 dfg/DFGBinarySwitch.cpp
128128 dfg/DFGBlockInsertionSet.cpp
 129 dfg/DFGBlockWorklist.cpp
129130 dfg/DFGByteCodeParser.cpp
130131 dfg/DFGCFAPhase.cpp
131132 dfg/DFGCFGSimplificationPhase.cpp

@@set(JavaScriptCore_SOURCES
175176 dfg/DFGLoopPreHeaderCreationPhase.cpp
176177 dfg/DFGMayExit.cpp
177178 dfg/DFGMinifiedNode.cpp
 179 dfg/DFGNaiveDominators.cpp
178180 dfg/DFGNaturalLoops.cpp
179181 dfg/DFGNode.cpp
180182 dfg/DFGNodeFlags.cpp
172947

Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj

372372 <ClCompile Include="..\dfg\DFGBasicBlock.cpp" />
373373 <ClCompile Include="..\dfg\DFGBinarySwitch.cpp" />
374374 <ClCompile Include="..\dfg\DFGBlockInsertionSet.cpp" />
 375 <ClCompile Include="..\dfg\DFGBlockWorklist.cpp" />
375376 <ClCompile Include="..\dfg\DFGByteCodeParser.cpp" />
376377 <ClCompile Include="..\dfg\DFGCapabilities.cpp" />
377378 <ClCompile Include="..\dfg\DFGCFAPhase.cpp" />

421422 <ClCompile Include="..\dfg\DFGLoopPreHeaderCreationPhase.cpp" />
422423 <ClCompile Include="..\dfg\DFGMayExit.cpp" />
423424 <ClCompile Include="..\dfg\DFGMinifiedNode.cpp" />
 425 <ClCompile Include="..\dfg\DFGNaiveDominators.cpp" />
424426 <ClCompile Include="..\dfg\DFGNaturalLoops.cpp" />
425427 <ClCompile Include="..\dfg\DFGNode.cpp" />
426428 <ClCompile Include="..\dfg\DFGNodeFlags.cpp" />

993995 <ClInclude Include="..\dfg\DFGBasicBlockInlines.h" />
994996 <ClInclude Include="..\dfg\DFGBinarySwitch.h" />
995997 <ClInclude Include="..\dfg\DFGBlockInsertionSet.h" />
 998 <ClInclude Include="..\dfg\DFGBlockMap.h" />
 999 <ClInclude Include="..\dfg\DFGBlockMapInlines.h" />
 1000 <ClInclude Include="..\dfg\DFGBlockWorklist.h" />
 1001 <ClInclude Include="..\dfg\DFGBlockSet.h" />
9961002 <ClInclude Include="..\dfg\DFGBranchDirection.h" />
9971003 <ClInclude Include="..\dfg\DFGByteCodeParser.h" />
9981004 <ClInclude Include="..\dfg\DFGCallArrayAllocatorSlowPathGenerator.h" />

10561062 <ClInclude Include="..\dfg\DFGMinifiedGraph.h" />
10571063 <ClInclude Include="..\dfg\DFGMinifiedID.h" />
10581064 <ClInclude Include="..\dfg\DFGMinifiedNode.h" />
 1065 <ClInclude Include="..\dfg\DFGNaiveDominators.h" />
10591066 <ClInclude Include="..\dfg\DFGNaturalLoops.h" />
10601067 <ClInclude Include="..\dfg\DFGNode.h" />
10611068 <ClInclude Include="..\dfg\DFGNodeAllocator.h" />
172947

Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

498498 0FC314121814559100033232 /* RegisterSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC314101814559100033232 /* RegisterSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
499499 0FC314131814559100033232 /* TempRegisterSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC314111814559100033232 /* TempRegisterSet.cpp */; };
500500 0FC3141518146D7000033232 /* RegisterSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC3141418146D7000033232 /* RegisterSet.cpp */; };
 501 0FC3CCFC19ADA410006AC72A /* DFGBlockMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC3CCF519ADA410006AC72A /* DFGBlockMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
 502 0FC3CCFD19ADA410006AC72A /* DFGBlockMapInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC3CCF619ADA410006AC72A /* DFGBlockMapInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
 503 0FC3CCFE19ADA410006AC72A /* DFGBlockSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC3CCF719ADA410006AC72A /* DFGBlockSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
 504 0FC3CCFF19ADA410006AC72A /* DFGBlockWorklist.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC3CCF819ADA410006AC72A /* DFGBlockWorklist.cpp */; };
 505 0FC3CD0019ADA410006AC72A /* DFGBlockWorklist.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC3CCF919ADA410006AC72A /* DFGBlockWorklist.h */; settings = {ATTRIBUTES = (Private, ); }; };
 506 0FC3CD0119ADA411006AC72A /* DFGNaiveDominators.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC3CCFA19ADA410006AC72A /* DFGNaiveDominators.cpp */; };
 507 0FC3CD0219ADA411006AC72A /* DFGNaiveDominators.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC3CCFB19ADA410006AC72A /* DFGNaiveDominators.h */; settings = {ATTRIBUTES = (Private, ); }; };
501508 0FC712DE17CD8779008CC93C /* DeferredCompilationCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC712DC17CD8778008CC93C /* DeferredCompilationCallback.cpp */; };
502509 0FC712DF17CD877C008CC93C /* DeferredCompilationCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC712DD17CD8778008CC93C /* DeferredCompilationCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
503510 0FC712E217CD8791008CC93C /* JITToDFGDeferredCompilationCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC712E017CD878F008CC93C /* JITToDFGDeferredCompilationCallback.cpp */; };

24212428 0FC314101814559100033232 /* RegisterSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterSet.h; sourceTree = "<group>"; };
24222429 0FC314111814559100033232 /* TempRegisterSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TempRegisterSet.cpp; sourceTree = "<group>"; };
24232430 0FC3141418146D7000033232 /* RegisterSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterSet.cpp; sourceTree = "<group>"; };
 2431 0FC3CCF519ADA410006AC72A /* DFGBlockMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBlockMap.h; path = dfg/DFGBlockMap.h; sourceTree = "<group>"; };
 2432 0FC3CCF619ADA410006AC72A /* DFGBlockMapInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBlockMapInlines.h; path = dfg/DFGBlockMapInlines.h; sourceTree = "<group>"; };
 2433 0FC3CCF719ADA410006AC72A /* DFGBlockSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBlockSet.h; path = dfg/DFGBlockSet.h; sourceTree = "<group>"; };
 2434 0FC3CCF819ADA410006AC72A /* DFGBlockWorklist.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGBlockWorklist.cpp; path = dfg/DFGBlockWorklist.cpp; sourceTree = "<group>"; };
 2435 0FC3CCF919ADA410006AC72A /* DFGBlockWorklist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBlockWorklist.h; path = dfg/DFGBlockWorklist.h; sourceTree = "<group>"; };
 2436 0FC3CCFA19ADA410006AC72A /* DFGNaiveDominators.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGNaiveDominators.cpp; path = dfg/DFGNaiveDominators.cpp; sourceTree = "<group>"; };
 2437 0FC3CCFB19ADA410006AC72A /* DFGNaiveDominators.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGNaiveDominators.h; path = dfg/DFGNaiveDominators.h; sourceTree = "<group>"; };
24242438 0FC712DC17CD8778008CC93C /* DeferredCompilationCallback.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DeferredCompilationCallback.cpp; sourceTree = "<group>"; };
24252439 0FC712DD17CD8778008CC93C /* DeferredCompilationCallback.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeferredCompilationCallback.h; sourceTree = "<group>"; };
24262440 0FC712E017CD878F008CC93C /* JITToDFGDeferredCompilationCallback.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JITToDFGDeferredCompilationCallback.cpp; sourceTree = "<group>"; };

48194833 A70B083117A0B79B00DAF14B /* DFGBinarySwitch.h */,
48204834 A7D89CE417A0B8CC00773AD8 /* DFGBlockInsertionSet.cpp */,
48214835 A7D89CE517A0B8CC00773AD8 /* DFGBlockInsertionSet.h */,
 4836 0FC3CCF519ADA410006AC72A /* DFGBlockMap.h */,
 4837 0FC3CCF619ADA410006AC72A /* DFGBlockMapInlines.h */,
 4838 0FC3CCF719ADA410006AC72A /* DFGBlockSet.h */,
 4839 0FC3CCF819ADA410006AC72A /* DFGBlockWorklist.cpp */,
 4840 0FC3CCF919ADA410006AC72A /* DFGBlockWorklist.h */,
48224841 0F8364B5164B0C0E0053329A /* DFGBranchDirection.h */,
48234842 86EC9DB41328DF82002B2AD7 /* DFGByteCodeParser.cpp */,
48244843 86EC9DB51328DF82002B2AD7 /* DFGByteCodeParser.h */,

49304949 0FB4B51016B3A964003F696B /* DFGMinifiedID.h */,
49314950 0F2BDC4C1522818300CD8910 /* DFGMinifiedNode.cpp */,
49324951 0F2BDC3E1522801700CD8910 /* DFGMinifiedNode.h */,
 4952 0FC3CCFA19ADA410006AC72A /* DFGNaiveDominators.cpp */,
 4953 0FC3CCFB19ADA410006AC72A /* DFGNaiveDominators.h */,
49334954 A737810A1799EA2E00817533 /* DFGNaturalLoops.cpp */,
49344955 A737810B1799EA2E00817533 /* DFGNaturalLoops.h */,
49354956 0FB4B51E16B62772003F696B /* DFGNode.cpp */,

58425863 C2FC9BD316644DFB00810D33 /* CopiedBlockInlines.h in Headers */,
58435864 C2EAA3FA149A835E00FCE112 /* CopiedSpace.h in Headers */,
58445865 C2C8D02D14A3C6E000578E65 /* CopiedSpaceInlines.h in Headers */,
 5866 0FC3CCFD19ADA410006AC72A /* DFGBlockMapInlines.h in Headers */,
58455867 0F5A52D017ADD717008ECB2D /* CopyToken.h in Headers */,
58465868 C2239D1816262BDD005AC5FD /* CopyVisitor.h in Headers */,
58475869 C2239D1916262BDD005AC5FD /* CopyVisitorInlines.h in Headers */,

59175939 A7BFF3C0179868940002F462 /* DFGFiltrationResult.h in Headers */,
59185940 A78A9777179738B8009DF744 /* DFGFinalizer.h in Headers */,
59195941 0F2BDC16151C5D4F00CD8910 /* DFGFixupPhase.h in Headers */,
 5942 0FC3CCFC19ADA410006AC72A /* DFGBlockMap.h in Headers */,
59205943 0F9D339717FFC4E60073C2BC /* DFGFlushedAt.h in Headers */,
59215944 A7D89CF817A0B8CC00773AD8 /* DFGFlushFormat.h in Headers */,
59225945 86EC9DC61328DF82002B2AD7 /* DFGGenerationInfo.h in Headers */,

63176340 0F431738146BAC69007E3890 /* ListableHandler.h in Headers */,
63186341 A7E2EA6B0FB460CF00601F06 /* LiteralParser.h in Headers */,
63196342 0F0FC45A14BD15F500B81154 /* LLIntCallLinkInfo.h in Headers */,
 6343 0FC3CD0019ADA410006AC72A /* DFGBlockWorklist.h in Headers */,
63206344 FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */,
63216345 0F4680CA14BBB16C00BFE272 /* LLIntCommon.h in Headers */,
63226346 0F4680D314BBD16700BFE272 /* LLIntData.h in Headers */,

63296353 0F0123331944EA1B00843A0C /* DFGValueStrength.h in Headers */,
63306354 0FCEFACE1805E75500472CE4 /* LLVMAPI.h in Headers */,
63316355 0FCEFACF1805E75500472CE4 /* LLVMAPIFunctions.h in Headers */,
 6356 0FC3CCFE19ADA410006AC72A /* DFGBlockSet.h in Headers */,
63326357 A7E5AB381799E4B200D2833D /* LLVMDisassembler.h in Headers */,
63336358 0FCEFAD31805EDCC00472CE4 /* LLVMHeaders.h in Headers */,
63346359 142E3139134FF0A600AFADB5 /* Local.h in Headers */,

63746399 7EFF00640EC05A9A00AA7C93 /* NodeInfo.h in Headers */,
63756400 BC18C43F0E16F5CD00B34460 /* Nodes.h in Headers */,
63766401 99E45A2818A1B2590026D88F /* NondeterministicInput.h in Headers */,
 6402 0FC3CD0219ADA411006AC72A /* DFGNaiveDominators.h in Headers */,
63776403 BC18C4410E16F5CD00B34460 /* NumberConstructor.h in Headers */,
63786404 0F5780A218FE1E98001E72D9 /* PureNaN.h in Headers */,
63796405 BC18C4420E16F5CD00B34460 /* NumberConstructor.lut.h in Headers */,

72977323 A7D89CFF17A0B8CC00773AD8 /* DFGSSAConversionPhase.cpp in Sources */,
72987324 2A05ABD51961DF2400341750 /* JSPropertyNameEnumerator.cpp in Sources */,
72997325 0FC20CB918556A3500C9E954 /* DFGSSALoweringPhase.cpp in Sources */,
 7326 0FC3CD0119ADA411006AC72A /* DFGNaiveDominators.cpp in Sources */,
73007327 0F9FB4F417FCB91700CB67F8 /* DFGStackLayoutPhase.cpp in Sources */,
73017328 0F4F29DF18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp in Sources */,
73027329 0FE7211D193B9C590031F6ED /* DFGTransition.cpp in Sources */,

73577384 0FD8A31917D51F2200CA2C40 /* FTLForOSREntryJITCode.cpp in Sources */,
73587385 0F25F1AF181635F300522F39 /* FTLInlineCacheSize.cpp in Sources */,
73597386 0FEA0A281709623B00BB722C /* FTLIntrinsicRepository.cpp in Sources */,
 7387 0FC3CCFF19ADA410006AC72A /* DFGBlockWorklist.cpp in Sources */,
73607388 0FEA0A0D170513DB00BB722C /* FTLJITCode.cpp in Sources */,
73617389 A78A9780179738D5009DF744 /* FTLJITFinalizer.cpp in Sources */,
73627390 0F6B1CB5185FC9E900845D97 /* FTLJSCall.cpp in Sources */,
172947

Source/JavaScriptCore/dfg/DFGAnalysis.h

@@public:
5353 {
5454 if (m_valid)
5555 return;
 56 // It's best to run dependent analyses from this method.
 57 static_cast<T*>(this)->computeDependencies(graph);
5658 // Set to true early, since the analysis may choose to call its own methods in
5759 // compute() and it may want to ASSERT() validity in those methods.
5860 m_valid = true;

@@public:
6163
6264 bool isValid() const { return m_valid; }
6365
 66 // Override this to compute any dependent analyses. See
 67 // NaturalLoops::computeDependencies(Graph&) for an example. This isn't strictly necessary but
 68 // it makes debug dumps in cases of error work a bit better because this analysis wouldn't yet
 69 // be pretending to be valid.
 70 void computeDependencies(Graph&) { }
 71
6472private:
6573 bool m_valid;
6674};
172947

Source/JavaScriptCore/dfg/DFGBlockMap.h

 1/*
 2 * Copyright (C) 2014 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef DFGBlockMap_h
 27#define DFGBlockMap_h
 28
 29#if ENABLE(DFG_JIT)
 30
 31#include "DFGBasicBlock.h"
 32
 33namespace JSC { namespace DFG {
 34
 35class Graph;
 36
 37template<typename T>
 38class BlockMap {
 39public:
 40 BlockMap()
 41 {
 42 }
 43
 44 BlockMap(Graph&);
 45
 46 BlockIndex size() const
 47 {
 48 return m_vector.size();
 49 }
 50
 51 T& atIndex(BlockIndex blockIndex)
 52 {
 53 return m_vector[blockIndex];
 54 }
 55
 56 const T& atIndex(BlockIndex blockIndex) const
 57 {
 58 return m_vector[blockIndex];
 59 }
 60
 61 T& operator[](BlockIndex blockIndex)
 62 {
 63 return m_vector[blockIndex];
 64 }
 65
 66 const T& operator[](BlockIndex blockIndex) const
 67 {
 68 return m_vector[blockIndex];
 69 }
 70
 71 T& operator[](BasicBlock* block)
 72 {
 73 return m_vector[block->index];
 74 }
 75
 76 const T& operator[](BasicBlock* block) const
 77 {
 78 return m_vector[block->index];
 79 }
 80
 81private:
 82 Vector<T> m_vector;
 83};
 84
 85} } // namespace JSC::DFG
 86
 87#endif // ENABLE(DFG_JIT)
 88
 89#endif // DFGBlockMap_h
 90
0

Source/JavaScriptCore/dfg/DFGBlockMapInlines.h

 1/*
 2 * Copyright (C) 2014 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef DFGBlockMapInlines_h
 27#define DFGBlockMapInlines_h
 28
 29#if ENABLE(DFG_JIT)
 30
 31#include "DFGBlockMap.h"
 32#include "DFGGraph.h"
 33
 34namespace JSC { namespace DFG {
 35
 36template<typename T>
 37BlockMap<T>::BlockMap(Graph& graph)
 38{
 39 m_vector.resize(graph.numBlocks());
 40}
 41
 42} } // namespace JSC::DFG
 43
 44#endif // ENABLE(DFG_JIT)
 45
 46#endif // DFGBlockMapInlines_h
0

Source/JavaScriptCore/dfg/DFGBlockSet.h

 1/*
 2 * Copyright (C) 2014 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef DFGBlockSet_h
 27#define DFGBlockSet_h
 28
 29#if ENABLE(DFG_JIT)
 30
 31#include "DFGBasicBlock.h"
 32
 33namespace JSC { namespace DFG {
 34
 35class BlockSet {
 36public:
 37 BlockSet() { }
 38
 39 // Return true if the block was added, false if it was already present.
 40 bool add(BasicBlock* block)
 41 {
 42 return !m_set.set(block->index);
 43 }
 44
 45 bool contains(BasicBlock* block) const
 46 {
 47 if (!block)
 48 return false;
 49 return m_set.get(block->index);
 50 }
 51
 52private:
 53 BitVector m_set;
 54};
 55
 56} } // namespace JSC::DFG
 57
 58#endif // ENABLE(DFG_JIT)
 59
 60#endif // DFGBlockSet_h
 61
0

Source/JavaScriptCore/dfg/DFGBlockWorklist.cpp

 1/*
 2 * Copyright (C) 2014 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "DFGBlockWorklist.h"
 28
 29#if ENABLE(DFG_JIT)
 30
 31#include "DFGBasicBlock.h"
 32
 33namespace JSC { namespace DFG {
 34
 35BlockWorklist::BlockWorklist()
 36{
 37}
 38
 39BlockWorklist::~BlockWorklist()
 40{
 41}
 42
 43bool BlockWorklist::push(BasicBlock* block)
 44{
 45 if (!m_seen.add(block))
 46 return false;
 47
 48 m_stack.append(block);
 49 return true;
 50}
 51
 52BasicBlock* BlockWorklist::pop()
 53{
 54 if (m_stack.isEmpty())
 55 return nullptr;
 56
 57 return m_stack.takeLast();
 58}
 59
 60PostOrderBlockWorklist::PostOrderBlockWorklist()
 61{
 62}
 63
 64PostOrderBlockWorklist::~PostOrderBlockWorklist()
 65{
 66}
 67
 68bool PostOrderBlockWorklist::pushPre(BasicBlock* block)
 69{
 70 return m_worklist.push(block, PreOrder);
 71}
 72
 73void PostOrderBlockWorklist::pushPost(BasicBlock* block)
 74{
 75 m_worklist.forcePush(block, PostOrder);
 76}
 77
 78BlockWithOrder PostOrderBlockWorklist::pop()
 79{
 80 BlockWith<VisitOrder> result = m_worklist.pop();
 81 return BlockWithOrder(result.block, result.data);
 82}
 83
 84} } // namespace JSC::DFG
 85
 86#endif // ENABLE(DFG_JIT)
0

Source/JavaScriptCore/dfg/DFGBlockWorklist.h

 1/*
 2 * Copyright (C) 2014 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef DFGBlockWorklist_h
 27#define DFGBlockWorklist_h
 28
 29#if ENABLE(DFG_JIT)
 30
 31#include "DFGBasicBlock.h"
 32#include "DFGBlockSet.h"
 33#include <wtf/Vector.h>
 34
 35namespace JSC { namespace DFG {
 36
 37struct BasicBlock;
 38
 39class BlockWorklist {
 40public:
 41 BlockWorklist();
 42 ~BlockWorklist();
 43
 44 bool push(BasicBlock*); // Returns true if we didn't know about the block before.
 45
 46 bool notEmpty() const { return !m_stack.isEmpty(); }
 47 BasicBlock* pop();
 48
 49private:
 50 BlockSet m_seen;
 51 Vector<BasicBlock*, 16> m_stack;
 52};
 53
 54// When you say BlockWith<int> you should read it as "block with an int".
 55template<typename T>
 56struct BlockWith {
 57 BlockWith()
 58 : block(nullptr)
 59 {
 60 }
 61
 62 BlockWith(BasicBlock* block, const T& data)
 63 : block(block)
 64 , data(data)
 65 {
 66 }
 67
 68 typedef void* (BlockWith<T>::*UnspecifiedBoolType);
 69 operator UnspecifiedBoolType*() const
 70 {
 71 return block ? reinterpret_cast<UnspecifiedBoolType*>(1) : nullptr;
 72 }
 73
 74 BasicBlock* block;
 75 T data;
 76};
 77
 78// Extended block worklist is useful for enqueueing some meta-data along with the block. It also
 79// permits forcibly enqueueing things even if the block has already been seen.
 80template<typename T>
 81class ExtendedBlockWorklist {
 82public:
 83 ExtendedBlockWorklist() { }
 84
 85 void forcePush(const BlockWith<T>& entry)
 86 {
 87 m_stack.append(entry);
 88 }
 89
 90 void forcePush(BasicBlock* block, const T& data)
 91 {
 92 forcePush(BlockWith<T>(block, data));
 93 }
 94
 95 bool push(const BlockWith<T>& entry)
 96 {
 97 if (!m_seen.add(entry.block))
 98 return false;
 99
 100 forcePush(entry);
 101 return true;
 102 }
 103
 104 bool push(BasicBlock* block, const T& data)
 105 {
 106 return push(BlockWith<T>(block, data));
 107 }
 108
 109 bool notEmpty() const { return !m_stack.isEmpty(); }
 110
 111 BlockWith<T> pop()
 112 {
 113 if (m_stack.isEmpty())
 114 return BlockWith<T>();
 115
 116 return m_stack.takeLast();
 117 }
 118
 119private:
 120 BlockSet m_seen;
 121 Vector<BlockWith<T>> m_stack;
 122};
 123
 124enum VisitOrder {
 125 PreOrder,
 126 PostOrder
 127};
 128
 129struct BlockWithOrder {
 130 BlockWithOrder()
 131 : block(nullptr)
 132 , order(PreOrder)
 133 {
 134 }
 135
 136 BlockWithOrder(BasicBlock* block, VisitOrder order)
 137 : block(block)
 138 , order(order)
 139 {
 140 }
 141
 142 typedef void* (BlockWithOrder::*UnspecifiedBoolType);
 143 operator UnspecifiedBoolType*() const
 144 {
 145 return block ? reinterpret_cast<UnspecifiedBoolType*>(1) : nullptr;
 146 }
 147
 148 BasicBlock* block;
 149 VisitOrder order;
 150};
 151
 152// Block worklist suitable for post-order traversal.
 153class PostOrderBlockWorklist {
 154public:
 155 PostOrderBlockWorklist();
 156 ~PostOrderBlockWorklist();
 157
 158 bool pushPre(BasicBlock*);
 159 void pushPost(BasicBlock*);
 160
 161 bool push(BasicBlock* block, VisitOrder order = PreOrder)
 162 {
 163 switch (order) {
 164 case PreOrder:
 165 return pushPre(block);
 166 case PostOrder:
 167 pushPost(block);
 168 return true;
 169 }
 170 RELEASE_ASSERT_NOT_REACHED();
 171 return false;
 172 }
 173 bool push(const BlockWithOrder& data)
 174 {
 175 return push(data.block, data.order);
 176 }
 177
 178 bool notEmpty() const { return m_worklist.notEmpty(); }
 179 BlockWithOrder pop();
 180
 181private:
 182 ExtendedBlockWorklist<VisitOrder> m_worklist;
 183};
 184
 185} } // namespace JSC::DFG
 186
 187#endif // ENABLE(DFG_JIT)
 188
 189#endif // DFGBlockWorklist_h
 190
0

Source/JavaScriptCore/dfg/DFGCSEPhase.cpp

2929#if ENABLE(DFG_JIT)
3030
3131#include "DFGAbstractHeap.h"
 32#include "DFGBlockMapInlines.h"
3233#include "DFGClobberSet.h"
3334#include "DFGClobberize.h"
3435#include "DFGEdgeUsesStructure.h"

@@class GlobalCSEPhase : public Phase {
364365public:
365366 GlobalCSEPhase(Graph& graph)
366367 : Phase(graph, "global common subexpression elimination")
 368 , m_impureDataMap(graph)
367369 {
368370 }
369371

@@public:
377379
378380 m_graph.getBlocksInPreOrder(m_preOrder);
379381
380  m_impureDataMap.resize(m_graph.numBlocks());
381 
382382 // First figure out what gets clobbered by blocks. Node that this uses the preOrder list
383383 // for convenience only.
384384 for (unsigned i = m_preOrder.size(); i--;) {
385385 m_block = m_preOrder[i];
386  m_impureData = &m_impureDataMap[m_block->index];
 386 m_impureData = &m_impureDataMap[m_block];
387387 for (unsigned nodeIndex = m_block->size(); nodeIndex--;)
388388 addWrites(m_graph, m_block->at(nodeIndex), m_impureData->writes);
389389 }

@@public:
407407 {
408408 m_pureValues.clear();
409409
410  for (unsigned i = m_impureDataMap.size(); i--;) {
 410 for (BlockIndex i = m_impureDataMap.size(); i--;) {
411411 m_impureDataMap[i].availableAtTail.clear();
412412 m_impureDataMap[i].didVisit = false;
413413 }

@@public:
423423
424424 for (unsigned i = 0; i < m_preOrder.size(); ++i) {
425425 m_block = m_preOrder[i];
426  m_impureData = &m_impureDataMap[m_block->index];
 426 m_impureData = &m_impureDataMap[m_block];
427427 m_writesSoFar.clear();
428428
429429 if (verbose)

@@public:
562562
563563 if (verbose)
564564 dataLog(" Searching in block ", *block, "\n");
565  ImpureBlockData& data = m_impureDataMap[block->index];
 565 ImpureBlockData& data = m_impureDataMap[block];
566566
567567 // We require strict domination because this would only see things in our own block if
568568 // they came *after* our position in the block. Clearly, while our block dominates
569569 // itself, the things in the block after us don't dominate us.
570  if (m_graph.m_dominators.dominates(block, m_block) && block != m_block) {
 570 if (m_graph.m_dominators.strictlyDominates(block, m_block)) {
571571 if (verbose)
572572 dataLog(" It strictly dominates.\n");
573573 DFG_ASSERT(m_graph, m_node, data.didVisit);

@@public:
612612 // the reduction in compile time would warrant the increase in complexity, though.
613613 // https://bugs.webkit.org/show_bug.cgi?id=134876
614614 for (BasicBlock* block : seenList)
615  m_impureDataMap[block->index].availableAtTail.add(location, match);
 615 m_impureDataMap[block].availableAtTail.add(location, match);
616616 m_impureData->availableAtTail.add(location, match);
617617
618618 return match;

@@public:
654654 Vector<BasicBlock*> m_preOrder;
655655
656656 PureMultiMap m_pureValues;
657  Vector<ImpureBlockData> m_impureDataMap;
 657 BlockMap<ImpureBlockData> m_impureDataMap;
658658
659659 BasicBlock* m_block;
660660 Node* m_node;
172947

Source/JavaScriptCore/dfg/DFGDominators.cpp

11/*
2  * Copyright (C) 2011 Apple Inc. All rights reserved.
 2 * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
33 *
44 * Redistribution and use in source and binary forms, with or without
55 * modification, are permitted provided that the following conditions

2828
2929#if ENABLE(DFG_JIT)
3030
 31#include "DFGBlockMapInlines.h"
 32#include "DFGBlockWorklist.h"
3133#include "DFGGraph.h"
 34#include "DFGNaiveDominators.h"
3235#include "JSCInlines.h"
3336
3437namespace JSC { namespace DFG {
3538
 39static const bool verbose = false;
 40static const bool usePathCompression = true;
 41
3642Dominators::Dominators()
3743{
3844}

@@Dominators::~Dominators()
4147{
4248}
4349
44 void Dominators::compute(Graph& graph)
45 {
46  // This implements a naive dominator solver.
 50namespace {
 51
 52// This implements Lengauer and Tarjan's "A Fast Algorithm for Finding Dominators in a Flowgraph"
 53// (TOPLAS 1979). It uses the "simple" implementation of LINK and EVAL. The full paper is linked
 54// below; this code attempts to closely follow the algorithm as it is presented in the paper; in
 55// particular sections 3 and 4.
 56// https://www.cs.princeton.edu/courses/archive/fall03/cs528/handouts/a%20fast%20algorithm%20for%20finding.pdf
 57
 58class LengauerTarjan {
 59public:
 60 LengauerTarjan(Graph& graph)
 61 : m_graph(graph)
 62 , m_data(graph)
 63 {
 64 for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
 65 BasicBlock* block = m_graph.block(blockIndex);
 66 if (!block)
 67 continue;
 68 m_data[block].label = block;
 69 }
 70 }
 71
 72 void compute()
 73 {
 74 if (verbose)
 75 dataLog("Performing Lengauer-Tarjan dominator calculation...\n");
 76
 77 computeDepthFirstPreNumbering(); // Step 1.
 78 computeSemiDominatorsAndImplicitImmediateDominators(); // Steps 2 and 3.
 79 computeExplicitImmediateDominators(); // Step 4.
 80 }
 81
 82 BasicBlock* immediateDominator(BasicBlock* block)
 83 {
 84 return m_data[block].dom;
 85 }
 86
 87private:
 88 void computeDepthFirstPreNumbering()
 89 {
 90 BlockWorklist worklist;
 91 worklist.push(m_graph.block(0));
 92
 93 while (BasicBlock* block = worklist.pop()) {
 94 m_data[block].semiNumber = m_blockByPreNumber.size();
 95 m_blockByPreNumber.append(block);
 96 for (unsigned i = block->numSuccessors(); i--;) {
 97 BasicBlock* successorBlock = block->successor(i);
 98 if (!worklist.push(successorBlock))
 99 continue;
 100 m_data[successorBlock].parent = block;
 101 }
 102 }
 103 }
 104
 105 void computeSemiDominatorsAndImplicitImmediateDominators()
 106 {
 107 for (unsigned currentPreNumber = m_blockByPreNumber.size(); currentPreNumber-- > 1;) {
 108 BasicBlock* block = m_blockByPreNumber[currentPreNumber];
 109 BlockData& blockData = m_data[block];
 110
 111 // Step 2:
 112 for (BasicBlock* predecessorBlock : block->predecessors) {
 113 BasicBlock* intermediateBlock = eval(predecessorBlock);
 114 blockData.semiNumber = std::min(
 115 m_data[intermediateBlock].semiNumber, blockData.semiNumber);
 116 if (verbose)
 117 dataLog(" Setting block ", *block, " semi to ", *m_blockByPreNumber[blockData.semiNumber], " because intermediate block ", *intermediateBlock, " has semi ", *m_blockByPreNumber[m_data[intermediateBlock].semiNumber], ".\n");
 118 }
 119 unsigned bucketPreNumber = blockData.semiNumber;
 120 ASSERT(bucketPreNumber <= currentPreNumber);
 121 m_data[m_blockByPreNumber[bucketPreNumber]].bucket.append(block);
 122 link(blockData.parent, block);
 123
 124 // Step 3:
 125 for (BasicBlock* semiDominee : m_data[blockData.parent].bucket) {
 126 BasicBlock* possibleDominator = eval(semiDominee);
 127 if (verbose)
 128 dataLog(" Block = ", *block, ", parent = ", *blockData.parent, ", semiDomiee = ", *semiDominee, ", possibleDominator = ", *possibleDominator, "\n");
 129 BlockData& semiDomineeData = m_data[semiDominee];
 130 BlockData& possibleDominatorData = m_data[possibleDominator];
 131 if (possibleDominatorData.semiNumber < semiDomineeData.semiNumber) {
 132 if (verbose)
 133 dataLog(" Setting ", *semiDominee, " dom to possibleDominator = ", *possibleDominator, "\n");
 134 semiDomineeData.dom = possibleDominator;
 135 } else {
 136 if (verbose)
 137 dataLog(" Setting ", *semiDominee, " dom to parent of ", *block, " = ", *blockData.parent, "\n");
 138 semiDomineeData.dom = blockData.parent;
 139 }
 140 }
 141 }
 142 }
47143
48  ASSERT(graph.block(0)->predecessors.isEmpty());
 144 void computeExplicitImmediateDominators()
 145 {
 146 for (unsigned currentPreNumber = 1; currentPreNumber < m_blockByPreNumber.size(); ++currentPreNumber) {
 147 BasicBlock* block = m_blockByPreNumber[currentPreNumber];
 148 BlockData& blockData = m_data[block];
 149
 150 if (blockData.dom != m_blockByPreNumber[blockData.semiNumber]) {
 151 if (verbose)
 152 dataLog(" Because dom of ", *block, " was not ", *m_blockByPreNumber[blockData.semiNumber], ", setting to dom of ", *blockData.dom, " = ", *m_data[blockData.dom].dom, "\n");
 153 blockData.dom = m_data[blockData.dom].dom;
 154 } else {
 155 if (verbose)
 156 dataLog(" Leaving dom of ", *block, " as ", *m_blockByPreNumber[blockData.semiNumber], "\n");
 157 }
 158 }
 159 }
49160
50  unsigned numBlocks = graph.numBlocks();
 161 void link(BasicBlock* from, BasicBlock* to)
 162 {
 163 m_data[to].ancestor = from;
 164 }
51165
52  // Allocate storage for the dense dominance matrix.
53  if (numBlocks > m_results.size()) {
54  m_results.grow(numBlocks);
55  for (unsigned i = numBlocks; i--;)
56  m_results[i].resize(numBlocks);
57  m_scratch.resize(numBlocks);
 166 BasicBlock* eval(BasicBlock* block)
 167 {
 168 if (!m_data[block].ancestor)
 169 return block;
 170
 171 if (usePathCompression) {
 172 // This is the default; it allows for O(n log n) time.
 173 compress(block);
 174 return m_data[block].label;
 175 }
 176
 177 // This is a dummy implementation of EVAL. It doesn't scale, but it's useful for debugging
 178 // because it closely follows the specification of EVAL without doing anything clever.
 179 BasicBlock* candidate = block;
 180 for (; m_data[block].ancestor; block = m_data[block].ancestor) {
 181 if (m_data[block].semiNumber < m_data[candidate].semiNumber)
 182 candidate = block;
 183 }
 184 if (verbose)
 185 dataLog(" Eval returning ", *candidate, " for ", *block, "\n");
 186 return candidate;
 187 }
 188
 189 void compress(BasicBlock* initialBlock)
 190 {
 191 // This was meant to be a recursive function, but we don't like recursion because we don't
 192 // want to blow the stack. The original function will call compress() recursively on the
 193 // ancestor of anything that has an ancestor. So, we populate our worklist with the
 194 // recursive ancestors of initialBlock. Then we process the list starting from the block
 195 // that is furthest up the ancestor chain.
 196
 197 BasicBlock* ancestor = m_data[initialBlock].ancestor;
 198 ASSERT(ancestor);
 199 if (!m_data[ancestor].ancestor)
 200 return;
 201
 202 Vector<BasicBlock*, 16> stack;
 203 for (BasicBlock* block = initialBlock; block; block = m_data[block].ancestor)
 204 stack.append(block);
 205
 206 // We only care about blocks that have an ancestor that has an ancestor. The last two
 207 // elements in the stack won't satisfy this property.
 208 ASSERT(stack.size() >= 2);
 209 ASSERT(!m_data[stack[stack.size() - 1]].ancestor);
 210 ASSERT(!m_data[m_data[stack[stack.size() - 2]].ancestor].ancestor);
 211
 212 for (unsigned i = stack.size() - 2; i--;) {
 213 BasicBlock* block = stack[i];
 214 BasicBlock*& labelOfBlock = m_data[block].label;
 215 BasicBlock*& ancestorOfBlock = m_data[block].ancestor;
 216 ASSERT(ancestorOfBlock);
 217 ASSERT(m_data[ancestorOfBlock].ancestor);
 218
 219 BasicBlock* labelOfAncestorOfBlock = m_data[ancestorOfBlock].label;
 220
 221 if (m_data[labelOfAncestorOfBlock].semiNumber <
 222 m_data[labelOfBlock].semiNumber)
 223 labelOfBlock = labelOfAncestorOfBlock;
 224 ancestorOfBlock = m_data[ancestorOfBlock].ancestor;
 225 }
58226 }
59227
60  // We know that the entry block is only dominated by itself.
61  m_results[0].clearAll();
62  m_results[0].set(0);
 228 struct BlockData {
 229 BlockData()
 230 : parent(nullptr)
 231 , preNumber(UINT_MAX)
 232 , semiNumber(UINT_MAX)
 233 , ancestor(nullptr)
 234 , label(nullptr)
 235 , dom(nullptr)
 236 {
 237 }
 238
 239 BasicBlock* parent;
 240 unsigned preNumber;
 241 unsigned semiNumber;
 242 BasicBlock* ancestor;
 243 BasicBlock* label;
 244 Vector<BasicBlock*> bucket;
 245 BasicBlock* dom;
 246 };
 247
 248 Graph& m_graph;
 249 BlockMap<BlockData> m_data;
 250 Vector<BasicBlock*> m_blockByPreNumber;
 251};
 252
 253struct ValidationContext {
 254 ValidationContext(Graph& graph, Dominators& dominators)
 255 : graph(graph)
 256 , dominators(dominators)
 257 {
 258 }
 259
 260 void reportError(BasicBlock* from, BasicBlock* to, const char* message)
 261 {
 262 Error error;
 263 error.from = from;
 264 error.to = to;
 265 error.message = message;
 266 errors.append(error);
 267 }
 268
 269 void handleErrors()
 270 {
 271 if (errors.isEmpty())
 272 return;
 273
 274 startCrashing();
 275 dataLog("DFG DOMINATOR VALIDATION FAILED:\n");
 276 dataLog("\n");
 277 dataLog("For block domination relationships:\n");
 278 for (unsigned i = 0; i < errors.size(); ++i) {
 279 dataLog(
 280 " ", pointerDump(errors[i].from), " -> ", pointerDump(errors[i].to),
 281 " (", errors[i].message, ")\n");
 282 }
 283 dataLog("\n");
 284 dataLog("Control flow graph:\n");
 285 for (BlockIndex blockIndex = 0; blockIndex < graph.numBlocks(); ++blockIndex) {
 286 BasicBlock* block = graph.block(blockIndex);
 287 if (!block)
 288 continue;
 289 dataLog(" Block #", blockIndex, ": successors = [");
 290 CommaPrinter comma;
 291 for (unsigned i = 0; i < block->numSuccessors(); ++i)
 292 dataLog(comma, *block->successor(i));
 293 dataLog("], predecessors = [");
 294 comma = CommaPrinter();
 295 for (unsigned i = 0; i < block->predecessors.size(); ++i)
 296 dataLog(comma, *block->predecessors[i]);
 297 dataLog("]\n");
 298 }
 299 dataLog("\n");
 300 dataLog("Lengauer-Tarjan Dominators:\n");
 301 dataLog(dominators);
 302 dataLog("\n");
 303 dataLog("Naive Dominators:\n");
 304 naiveDominators.dump(graph, WTF::dataFile());
 305 dataLog("\n");
 306 dataLog("Graph at time of failure:\n");
 307 graph.dump();
 308 dataLog("\n");
 309 dataLog("DFG DOMINATOR VALIDATION FAILIED!\n");
 310 CRASH();
 311 }
 312
 313 Graph& graph;
 314 Dominators& dominators;
 315 NaiveDominators naiveDominators;
 316
 317 struct Error {
 318 BasicBlock* from;
 319 BasicBlock* to;
 320 const char* message;
 321 };
 322
 323 Vector<Error> errors;
 324};
 325
 326} // anonymous namespace
63327
64  // Find all of the valid blocks.
65  m_scratch.clearAll();
66  for (unsigned i = numBlocks; i--;) {
67  if (!graph.block(i))
 328void Dominators::compute(Graph& graph)
 329{
 330 LengauerTarjan lengauerTarjan(graph);
 331 lengauerTarjan.compute();
 332
 333 m_data = BlockMap<BlockData>(graph);
 334
 335 // From here we want to build a spanning tree with both upward and downward links and we want
 336 // to do a search over this tree to compute pre and post numbers that can be used for dominance
 337 // tests.
 338
 339 for (BlockIndex blockIndex = graph.numBlocks(); blockIndex--;) {
 340 BasicBlock* block = graph.block(blockIndex);
 341 if (!block)
68342 continue;
69  m_scratch.set(i);
 343
 344 BasicBlock* idomBlock = lengauerTarjan.immediateDominator(block);
 345 m_data[block].idomParent = idomBlock;
 346 if (idomBlock)
 347 m_data[idomBlock].idomKids.append(block);
70348 }
71349
72  // Mark all nodes as dominated by everything.
73  for (unsigned i = numBlocks; i-- > 1;) {
74  if (!graph.block(i) || graph.block(i)->predecessors.isEmpty())
75  m_results[i].clearAll();
76  else
77  m_results[i].set(m_scratch);
78  }
79 
80  // Iteratively eliminate nodes that are not dominator.
81  bool changed;
82  do {
83  changed = false;
84  // Prune dominators in all non entry blocks: forward scan.
85  for (unsigned i = 1; i < numBlocks; ++i)
86  changed |= pruneDominators(graph, i);
87 
88  if (!changed)
 350 unsigned nextPreNumber = 0;
 351 unsigned nextPostNumber = 0;
 352
 353 // Plain stack-based worklist because we are guaranteed to see each block exactly once anyway.
 354 Vector<BlockWithOrder> worklist;
 355 worklist.append(BlockWithOrder(graph.block(0), PreOrder));
 356 while (!worklist.isEmpty()) {
 357 BlockWithOrder item = worklist.takeLast();
 358 switch (item.order) {
 359 case PreOrder:
 360 m_data[item.block].preNumber = nextPreNumber++;
 361 worklist.append(BlockWithOrder(item.block, PostOrder));
 362 for (BasicBlock* kid : m_data[item.block].idomKids)
 363 worklist.append(BlockWithOrder(kid, PreOrder));
89364 break;
90 
91  // Prune dominators in all non entry blocks: backward scan.
92  changed = false;
93  for (unsigned i = numBlocks; i-- > 1;)
94  changed |= pruneDominators(graph, i);
95  } while (changed);
 365 case PostOrder:
 366 m_data[item.block].postNumber = nextPostNumber++;
 367 break;
 368 }
 369 }
 370
 371 if (validationEnabled()) {
 372 // Check our dominator calculation:
 373 // 1) Check that our range-based ancestry test is the same as a naive ancestry test.
 374 // 2) Check that our notion of who dominates whom is identical to a naive (not
 375 // Lengauer-Tarjan) dominator calculation.
 376
 377 ValidationContext context(graph, *this);
 378 context.naiveDominators.compute(graph);
 379
 380 for (BlockIndex fromBlockIndex = graph.numBlocks(); fromBlockIndex--;) {
 381 BasicBlock* fromBlock = graph.block(fromBlockIndex);
 382 if (!fromBlock || m_data[fromBlock].preNumber == UINT_MAX)
 383 continue;
 384 for (BlockIndex toBlockIndex = graph.numBlocks(); toBlockIndex--;) {
 385 BasicBlock* toBlock = graph.block(toBlockIndex);
 386 if (!toBlock || m_data[toBlock].preNumber == UINT_MAX)
 387 continue;
 388
 389 if (dominates(fromBlock, toBlock) != naiveDominates(fromBlock, toBlock))
 390 context.reportError(fromBlock, toBlock, "Range-based domination check is broken");
 391 if (dominates(fromBlock, toBlock) != context.naiveDominators.dominates(fromBlock, toBlock))
 392 context.reportError(fromBlock, toBlock, "Lengauer-Tarjan domination is broken");
 393 }
 394 }
 395
 396 context.handleErrors();
 397 }
96398}
97399
98 bool Dominators::pruneDominators(Graph& graph, BlockIndex idx)
 400bool Dominators::naiveDominates(BasicBlock* from, BasicBlock* to) const
99401{
100  BasicBlock* block = graph.block(idx);
101 
102  if (!block || block->predecessors.isEmpty())
103  return false;
104 
105  // Find the intersection of dom(preds).
106  m_scratch.set(m_results[block->predecessors[0]->index]);
107  for (unsigned j = block->predecessors.size(); j-- > 1;)
108  m_scratch.filter(m_results[block->predecessors[j]->index]);
109 
110  // The block is also dominated by itself.
111  m_scratch.set(idx);
112 
113  return m_results[idx].setAndCheck(m_scratch);
 402 for (BasicBlock* block = to; block; block = m_data[block].idomParent) {
 403 if (block == from)
 404 return true;
 405 }
 406 return false;
114407}
115408
116 void Dominators::dump(Graph& graph, PrintStream& out) const
 409void Dominators::dump(PrintStream& out) const
117410{
118  for (BlockIndex blockIndex = 0; blockIndex < graph.numBlocks(); ++blockIndex) {
119  BasicBlock* block = graph.block(blockIndex);
120  if (!block)
 411 if (!isValid()) {
 412 out.print(" Not Valid.\n");
 413 return;
 414 }
 415
 416 for (BlockIndex blockIndex = 0; blockIndex < m_data.size(); ++blockIndex) {
 417 if (m_data[blockIndex].preNumber == UINT_MAX)
121418 continue;
122  out.print(" Block ", *block, ":");
123  for (BlockIndex otherIndex = 0; otherIndex < graph.numBlocks(); ++otherIndex) {
124  if (!dominates(block->index, otherIndex))
125  continue;
126  out.print(" #", otherIndex);
127  }
128  out.print("\n");
 419
 420 out.print(" Block #", blockIndex, ": idom = ", pointerDump(m_data[blockIndex].idomParent), ", idomKids = [");
 421 CommaPrinter comma;
 422 for (unsigned i = 0; i < m_data[blockIndex].idomKids.size(); ++i)
 423 out.print(comma, *m_data[blockIndex].idomKids[i]);
 424 out.print("], pre/post = ", m_data[blockIndex].preNumber, "/", m_data[blockIndex].postNumber, "\n");
129425 }
130426}
131427
172947

Source/JavaScriptCore/dfg/DFGDominators.h

11/*
2  * Copyright (C) 2011 Apple Inc. All rights reserved.
 2 * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
33 *
44 * Redistribution and use in source and binary forms, with or without
55 * modification, are permitted provided that the following conditions

3030
3131#include "DFGAnalysis.h"
3232#include "DFGBasicBlock.h"
 33#include "DFGBlockMap.h"
3334#include "DFGCommon.h"
3435#include <wtf/FastBitVector.h>
3536

@@public:
4445
4546 void compute(Graph&);
4647
47  bool dominates(BlockIndex from, BlockIndex to) const
 48 bool strictlyDominates(BasicBlock* from, BasicBlock* to) const
4849 {
4950 ASSERT(isValid());
50  return m_results[to].get(from);
 51 return m_data[to].preNumber > m_data[from].preNumber
 52 && m_data[to].postNumber < m_data[from].postNumber;
5153 }
5254
5355 bool dominates(BasicBlock* from, BasicBlock* to) const
5456 {
55  return dominates(from->index, to->index);
 57 return from == to || strictlyDominates(from, to);
5658 }
5759
58  void dump(Graph&, PrintStream&) const;
 60 void dump(PrintStream&) const;
5961
6062private:
61  bool pruneDominators(Graph&, BlockIndex);
 63 bool naiveDominates(BasicBlock* from, BasicBlock* to) const;
6264
63  Vector<FastBitVector> m_results; // For each block, the bitvector of blocks that dominate it.
64  FastBitVector m_scratch; // A temporary bitvector with bit for each block. We recycle this to save new/deletes.
 65 struct BlockData {
 66 BlockData()
 67 : idomParent(nullptr)
 68 , preNumber(UINT_MAX)
 69 , postNumber(UINT_MAX)
 70 {
 71 }
 72
 73 Vector<BasicBlock*> idomKids;
 74 BasicBlock* idomParent;
 75
 76 unsigned preNumber;
 77 unsigned postNumber;
 78 };
 79
 80 BlockMap<BlockData> m_data;
6581};
6682
6783} } // namespace JSC::DFG
172947

Source/JavaScriptCore/dfg/DFGGraph.cpp

3232#include "CodeBlock.h"
3333#include "CodeBlockWithJITType.h"
3434#include "DFGClobberSet.h"
 35#include "DFGBlockWorklist.h"
3536#include "DFGJITCode.h"
3637#include "DFGVariableAccessDataDump.h"
3738#include "FullBytecodeLiveness.h"

@@void Graph::dumpBlockHeader(PrintStream&
370371 if (m_dominators.isValid()) {
371372 out.print(prefix, " Dominated by:");
372373 for (size_t i = 0; i < m_blocks.size(); ++i) {
373  if (!m_dominators.dominates(i, block->index))
 374 if (!this->block(i))
 375 continue;
 376 if (!m_dominators.dominates(this->block(i), block))
374377 continue;
375378 out.print(" #", i);
376379 }
377380 out.print("\n");
378381 out.print(prefix, " Dominates:");
379382 for (size_t i = 0; i < m_blocks.size(); ++i) {
380  if (!m_dominators.dominates(block->index, i))
 383 if (!this->block(i))
 384 continue;
 385 if (!m_dominators.dominates(block, this->block(i)))
381386 continue;
382387 out.print(" #", i);
383388 }

@@void Graph::substituteGetLocal(BasicBloc
635640 }
636641}
637642
638 // Utilities for pre- and post-order traversals.
639 namespace {
640 
641 inline void addForPreOrder(Vector<BasicBlock*>& result, Vector<BasicBlock*, 16>& worklist, BitVector& seen, BasicBlock* block)
642 {
643  if (seen.get(block->index))
644  return;
645 
646  result.append(block);
647  worklist.append(block);
648  seen.set(block->index);
649 }
650 
651 enum PostOrderTaskKind {
652  PostOrderFirstVisit,
653  PostOrderAddToResult
654 };
655 
656 struct PostOrderTask {
657  PostOrderTask(BasicBlock* block = nullptr, PostOrderTaskKind kind = PostOrderFirstVisit)
658  : m_block(block)
659  , m_kind(kind)
660  {
661  }
662 
663  BasicBlock* m_block;
664  PostOrderTaskKind m_kind;
665 };
666 
667 inline void addForPostOrder(Vector<PostOrderTask, 16>& worklist, BitVector& seen, BasicBlock* block)
668 {
669  if (seen.get(block->index))
670  return;
671 
672  worklist.append(PostOrderTask(block, PostOrderFirstVisit));
673  seen.set(block->index);
674 }
675 
676 } // anonymous namespace
677 
678643void Graph::getBlocksInPreOrder(Vector<BasicBlock*>& result)
679644{
680  Vector<BasicBlock*, 16> worklist;
681  BitVector seen;
682  addForPreOrder(result, worklist, seen, block(0));
683  while (!worklist.isEmpty()) {
684  BasicBlock* block = worklist.takeLast();
 645 BlockWorklist worklist;
 646 worklist.push(block(0));
 647 while (BasicBlock* block = worklist.pop()) {
 648 result.append(block);
685649 for (unsigned i = block->numSuccessors(); i--;)
686  addForPreOrder(result, worklist, seen, block->successor(i));
 650 worklist.push(block->successor(i));
687651 }
688652}
689653
690654void Graph::getBlocksInPostOrder(Vector<BasicBlock*>& result)
691655{
692  Vector<PostOrderTask, 16> worklist;
693  BitVector seen;
694  addForPostOrder(worklist, seen, block(0));
695  while (!worklist.isEmpty()) {
696  PostOrderTask task = worklist.takeLast();
697  switch (task.m_kind) {
698  case PostOrderFirstVisit:
699  worklist.append(PostOrderTask(task.m_block, PostOrderAddToResult));
700  for (unsigned i = task.m_block->numSuccessors(); i--;)
701  addForPostOrder(worklist, seen, task.m_block->successor(i));
 656 PostOrderBlockWorklist worklist;
 657 worklist.push(block(0));
 658 while (BlockWithOrder item = worklist.pop()) {
 659 switch (item.order) {
 660 case PreOrder:
 661 worklist.pushPost(item.block);
 662 for (unsigned i = item.block->numSuccessors(); i--;)
 663 worklist.push(item.block->successor(i));
702664 break;
703  case PostOrderAddToResult:
704  result.append(task.m_block);
 665 case PostOrder:
 666 result.append(item.block);
705667 break;
706668 }
707669 }
172947

Source/JavaScriptCore/dfg/DFGInvalidationPointInjectionPhase.cpp

2828
2929#if ENABLE(DFG_JIT)
3030
 31#include "DFGBlockSet.h"
3132#include "DFGClobberize.h"
3233#include "DFGGraph.h"
3334#include "DFGInsertionSet.h"

@@public:
5051 {
5152 ASSERT(m_graph.m_form != SSA);
5253
53  BitVector blocksThatNeedInvalidationPoints;
 54 BlockSet blocksThatNeedInvalidationPoints;
5455
5556 for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
5657 BasicBlock* block = m_graph.block(blockIndex);

@@public:
6364 // Note: this assumes that control flow occurs at bytecode instruction boundaries.
6465 if (m_originThatHadFire.isSet()) {
6566 for (unsigned i = block->numSuccessors(); i--;)
66  blocksThatNeedInvalidationPoints.set(block->successor(i)->index);
 67 blocksThatNeedInvalidationPoints.add(block->successor(i));
6768 }
6869
6970 m_insertionSet.execute(block);
7071 }
7172
7273 for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
73  if (!blocksThatNeedInvalidationPoints.get(blockIndex))
 74 BasicBlock* block = m_graph.block(blockIndex);
 75
 76 if (!blocksThatNeedInvalidationPoints.contains(block))
7477 continue;
7578
76  BasicBlock* block = m_graph.block(blockIndex);
7779 insertInvalidationCheck(0, block->at(0));
7880 m_insertionSet.execute(block);
7981 }
172947

Source/JavaScriptCore/dfg/DFGNaiveDominators.cpp

 1/*
 2 * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "DFGNaiveDominators.h"
 28
 29#if ENABLE(DFG_JIT)
 30
 31#include "DFGGraph.h"
 32#include "JSCInlines.h"
 33
 34namespace JSC { namespace DFG {
 35
 36NaiveDominators::NaiveDominators()
 37{
 38}
 39
 40NaiveDominators::~NaiveDominators()
 41{
 42}
 43
 44void NaiveDominators::compute(Graph& graph)
 45{
 46 // This implements a naive dominator solver.
 47
 48 ASSERT(graph.block(0)->predecessors.isEmpty());
 49
 50 unsigned numBlocks = graph.numBlocks();
 51
 52 // Allocate storage for the dense dominance matrix.
 53 if (numBlocks > m_results.size()) {
 54 m_results.grow(numBlocks);
 55 for (unsigned i = numBlocks; i--;)
 56 m_results[i].resize(numBlocks);
 57 m_scratch.resize(numBlocks);
 58 }
 59
 60 // We know that the entry block is only dominated by itself.
 61 m_results[0].clearAll();
 62 m_results[0].set(0);
 63
 64 // Find all of the valid blocks.
 65 m_scratch.clearAll();
 66 for (unsigned i = numBlocks; i--;) {
 67 if (!graph.block(i))
 68 continue;
 69 m_scratch.set(i);
 70 }
 71
 72 // Mark all nodes as dominated by everything.
 73 for (unsigned i = numBlocks; i-- > 1;) {
 74 if (!graph.block(i) || graph.block(i)->predecessors.isEmpty())
 75 m_results[i].clearAll();
 76 else
 77 m_results[i].set(m_scratch);
 78 }
 79
 80 // Iteratively eliminate nodes that are not dominator.
 81 bool changed;
 82 do {
 83 changed = false;
 84 // Prune dominators in all non entry blocks: forward scan.
 85 for (unsigned i = 1; i < numBlocks; ++i)
 86 changed |= pruneDominators(graph, i);
 87
 88 if (!changed)
 89 break;
 90
 91 // Prune dominators in all non entry blocks: backward scan.
 92 changed = false;
 93 for (unsigned i = numBlocks; i-- > 1;)
 94 changed |= pruneDominators(graph, i);
 95 } while (changed);
 96}
 97
 98bool NaiveDominators::pruneDominators(Graph& graph, BlockIndex idx)
 99{
 100 BasicBlock* block = graph.block(idx);
 101
 102 if (!block || block->predecessors.isEmpty())
 103 return false;
 104
 105 // Find the intersection of dom(preds).
 106 m_scratch.set(m_results[block->predecessors[0]->index]);
 107 for (unsigned j = block->predecessors.size(); j-- > 1;)
 108 m_scratch.filter(m_results[block->predecessors[j]->index]);
 109
 110 // The block is also dominated by itself.
 111 m_scratch.set(idx);
 112
 113 return m_results[idx].setAndCheck(m_scratch);
 114}
 115
 116void NaiveDominators::dump(Graph& graph, PrintStream& out) const
 117{
 118 for (BlockIndex blockIndex = 0; blockIndex < graph.numBlocks(); ++blockIndex) {
 119 BasicBlock* block = graph.block(blockIndex);
 120 if (!block)
 121 continue;
 122 out.print(" Block ", *block, ":");
 123 for (BlockIndex otherIndex = 0; otherIndex < graph.numBlocks(); ++otherIndex) {
 124 if (!dominates(block->index, otherIndex))
 125 continue;
 126 out.print(" #", otherIndex);
 127 }
 128 out.print("\n");
 129 }
 130}
 131
 132} } // namespace JSC::DFG
 133
 134#endif // ENABLE(DFG_JIT)
 135
0

Source/JavaScriptCore/dfg/DFGNaiveDominators.h

 1/*
 2 * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef DFGNaiveDominators_h
 27#define DFGNaiveDominators_h
 28
 29#if ENABLE(DFG_JIT)
 30
 31#include "DFGBasicBlock.h"
 32#include "DFGCommon.h"
 33#include <wtf/FastBitVector.h>
 34
 35namespace JSC { namespace DFG {
 36
 37class Graph;
 38
 39// This class is only used for validating the real dominators implementation.
 40
 41class NaiveDominators {
 42public:
 43 NaiveDominators();
 44 ~NaiveDominators();
 45
 46 void compute(Graph&);
 47
 48 bool dominates(BlockIndex from, BlockIndex to) const
 49 {
 50 return m_results[to].get(from);
 51 }
 52
 53 bool dominates(BasicBlock* from, BasicBlock* to) const
 54 {
 55 return dominates(from->index, to->index);
 56 }
 57
 58 void dump(Graph&, PrintStream&) const;
 59
 60private:
 61 bool pruneDominators(Graph&, BlockIndex);
 62
 63 Vector<FastBitVector> m_results; // For each block, the bitvector of blocks that dominate it.
 64 FastBitVector m_scratch; // A temporary bitvector with bit for each block. We recycle this to save new/deletes.
 65};
 66
 67} } // namespace JSC::DFG
 68
 69#endif // ENABLE(DFG_JIT)
 70
 71#endif // DFGNaiveDominators_h
0

Source/JavaScriptCore/dfg/DFGNaturalLoops.cpp

@@void NaturalLoop::dump(PrintStream& out)
4545NaturalLoops::NaturalLoops() { }
4646NaturalLoops::~NaturalLoops() { }
4747
 48void NaturalLoops::computeDependencies(Graph& graph)
 49{
 50 graph.m_dominators.computeIfNecessary(graph);
 51}
 52
4853void NaturalLoops::compute(Graph& graph)
4954{
5055 // Implement the classic dominator-based natural loop finder. The first

@@void NaturalLoops::compute(Graph& graph)
5762
5863 static const bool verbose = false;
5964
60  graph.m_dominators.computeIfNecessary(graph);
61 
6265 if (verbose) {
6366 dataLog("Dominators:\n");
64  graph.m_dominators.dump(graph, WTF::dataFile());
 67 graph.m_dominators.dump(WTF::dataFile());
6568 }
6669
6770 m_loops.resize(0);
172947

Source/JavaScriptCore/dfg/DFGNaturalLoops.h

@@public:
9393 NaturalLoops();
9494 ~NaturalLoops();
9595
 96 void computeDependencies(Graph&);
9697 void compute(Graph&);
9798
9899 unsigned numLoops() const
172947

Source/WTF/wtf/BitVector.h

@@public:
117117 return !!(bits()[bit / bitsInPointer()] & (static_cast<uintptr_t>(1) << (bit & (bitsInPointer() - 1))));
118118 }
119119
120  void quickSet(size_t bit)
 120 bool quickSet(size_t bit)
121121 {
122122 ASSERT_WITH_SECURITY_IMPLICATION(bit < size());
123  bits()[bit / bitsInPointer()] |= (static_cast<uintptr_t>(1) << (bit & (bitsInPointer() - 1)));
 123 uintptr_t& word = bits()[bit / bitsInPointer()];
 124 uintptr_t mask = static_cast<uintptr_t>(1) << (bit & (bitsInPointer() - 1));
 125 bool result = !!(word & mask);
 126 word |= mask;
 127 return result;
124128 }
125129
126  void quickClear(size_t bit)
 130 bool quickClear(size_t bit)
127131 {
128132 ASSERT_WITH_SECURITY_IMPLICATION(bit < size());
129  bits()[bit / bitsInPointer()] &= ~(static_cast<uintptr_t>(1) << (bit & (bitsInPointer() - 1)));
 133 uintptr_t& word = bits()[bit / bitsInPointer()];
 134 uintptr_t mask = static_cast<uintptr_t>(1) << (bit & (bitsInPointer() - 1));
 135 bool result = !!(word & mask);
 136 word &= ~mask;
 137 return result;
130138 }
131139
132  void quickSet(size_t bit, bool value)
 140 bool quickSet(size_t bit, bool value)
133141 {
134142 if (value)
135  quickSet(bit);
136  else
137  quickClear(bit);
 143 return quickSet(bit);
 144 return quickClear(bit);
138145 }
139146
140147 bool get(size_t bit) const

@@public:
144151 return quickGet(bit);
145152 }
146153
147  void set(size_t bit)
 154 bool set(size_t bit)
148155 {
149156 ensureSize(bit + 1);
150  quickSet(bit);
 157 return quickSet(bit);
151158 }
152159
153  void ensureSizeAndSet(size_t bit, size_t size)
 160 bool ensureSizeAndSet(size_t bit, size_t size)
154161 {
155162 ensureSize(size);
156  quickSet(bit);
 163 return quickSet(bit);
157164 }
158165
159  void clear(size_t bit)
 166 bool clear(size_t bit)
160167 {
161168 if (bit >= size())
162  return;
163  quickClear(bit);
 169 return false;
 170 return quickClear(bit);
164171 }
165172
166  void set(size_t bit, bool value)
 173 bool set(size_t bit, bool value)
167174 {
168175 if (value)
169  set(bit);
170  else
171  clear(bit);
 176 return set(bit);
 177 return clear(bit);
172178 }
173179
174180 void merge(const BitVector& other)
172947