Changeset 173279 in webkit
- Timestamp:
- Sep 4, 2014, 2:08:38 PM (11 years ago)
- Location:
- trunk/Source
- Files:
-
- 2 added
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/CMakeLists.txt
r173251 r173279 127 127 dfg/DFGBinarySwitch.cpp 128 128 dfg/DFGBlockInsertionSet.cpp 129 dfg/DFGBlockSet.cpp 129 130 dfg/DFGBlockWorklist.cpp 130 131 dfg/DFGByteCodeParser.cpp -
trunk/Source/JavaScriptCore/ChangeLog
r173269 r173279 1 2014-09-03 Filip Pizlo <fpizlo@apple.com> 2 3 Beef up the DFG's CFG analyses to include iterated dominance frontiers and more user-friendly BlockSets 4 https://bugs.webkit.org/show_bug.cgi?id=136520 5 6 Reviewed by Geoffrey Garen. 7 8 Add code to compute iterated dominance frontiers. This involves using BlockSet a lot, so 9 this patch also makes BlockSet a lot more user-friendly. 10 11 * CMakeLists.txt: 12 * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: 13 * JavaScriptCore.xcodeproj/project.pbxproj: 14 * dfg/DFGBasicBlock.h: 15 * dfg/DFGBlockSet.cpp: Added. 16 (JSC::DFG::BlockSet::dump): 17 * dfg/DFGBlockSet.h: 18 (JSC::DFG::BlockSet::iterator::iterator): 19 (JSC::DFG::BlockSet::iterator::operator++): 20 (JSC::DFG::BlockSet::iterator::operator==): 21 (JSC::DFG::BlockSet::iterator::operator!=): 22 (JSC::DFG::BlockSet::Iterable::Iterable): 23 (JSC::DFG::BlockSet::Iterable::begin): 24 (JSC::DFG::BlockSet::Iterable::end): 25 (JSC::DFG::BlockSet::iterable): 26 (JSC::DFG::BlockAdder::BlockAdder): 27 (JSC::DFG::BlockAdder::operator()): 28 * dfg/DFGBlockSetInlines.h: Added. 29 (JSC::DFG::BlockSet::iterator::operator*): 30 * dfg/DFGDominators.cpp: 31 (JSC::DFG::Dominators::strictDominatorsOf): 32 (JSC::DFG::Dominators::dominatorsOf): 33 (JSC::DFG::Dominators::blocksStrictlyDominatedBy): 34 (JSC::DFG::Dominators::blocksDominatedBy): 35 (JSC::DFG::Dominators::dominanceFrontierOf): 36 (JSC::DFG::Dominators::iteratedDominanceFrontierOf): 37 * dfg/DFGDominators.h: 38 (JSC::DFG::Dominators::forAllStrictDominatorsOf): 39 (JSC::DFG::Dominators::forAllDominatorsOf): 40 (JSC::DFG::Dominators::forAllBlocksStrictlyDominatedBy): 41 (JSC::DFG::Dominators::forAllBlocksDominatedBy): 42 (JSC::DFG::Dominators::forAllBlocksInDominanceFrontierOf): 43 (JSC::DFG::Dominators::forAllBlocksInIteratedDominanceFrontierOf): 44 (JSC::DFG::Dominators::forAllBlocksInDominanceFrontierOfImpl): 45 (JSC::DFG::Dominators::forAllBlocksInIteratedDominanceFrontierOfImpl): 46 * dfg/DFGGraph.cpp: 47 (JSC::DFG::Graph::dumpBlockHeader): 48 * dfg/DFGInvalidationPointInjectionPhase.cpp: 49 (JSC::DFG::InvalidationPointInjectionPhase::run): 50 1 51 2014-09-04 Mark Lam <mark.lam@apple.com> 2 52 -
trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
r173198 r173279 373 373 <ClCompile Include="..\dfg\DFGBinarySwitch.cpp" /> 374 374 <ClCompile Include="..\dfg\DFGBlockInsertionSet.cpp" /> 375 <ClCompile Include="..\dfg\DFGBlockSet.cpp" /> 375 376 <ClCompile Include="..\dfg\DFGBlockWorklist.cpp" /> 376 377 <ClCompile Include="..\dfg\DFGByteCodeParser.cpp" /> … … 999 1000 <ClInclude Include="..\dfg\DFGBlockWorklist.h" /> 1000 1001 <ClInclude Include="..\dfg\DFGBlockSet.h" /> 1002 <ClInclude Include="..\dfg\DFGBlockSetInlines.h" /> 1001 1003 <ClInclude Include="..\dfg\DFGBranchDirection.h" /> 1002 1004 <ClInclude Include="..\dfg\DFGByteCodeParser.h" /> -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r173251 r173279 482 482 0FBE0F7616C1DB0F0082C5E8 /* DFGUnificationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBE0F6F16C1DB010082C5E8 /* DFGUnificationPhase.cpp */; }; 483 483 0FBE0F7716C1DB120082C5E8 /* DFGUnificationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBE0F7016C1DB010082C5E8 /* DFGUnificationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; }; 484 0FBF158C19B7A53100695DD0 /* DFGBlockSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBF158A19B7A53100695DD0 /* DFGBlockSet.cpp */; }; 485 0FBF158D19B7A53100695DD0 /* DFGBlockSetInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBF158B19B7A53100695DD0 /* DFGBlockSetInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; 484 486 0FBFDD04196C92BF007A5BFA /* DFGPhantomRemovalPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBFDD02196C92BF007A5BFA /* DFGPhantomRemovalPhase.cpp */; }; 485 487 0FBFDD05196C92BF007A5BFA /* DFGPhantomRemovalPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBFDD03196C92BF007A5BFA /* DFGPhantomRemovalPhase.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 2406 2408 0FBE0F6F16C1DB010082C5E8 /* DFGUnificationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGUnificationPhase.cpp; path = dfg/DFGUnificationPhase.cpp; sourceTree = "<group>"; }; 2407 2409 0FBE0F7016C1DB010082C5E8 /* DFGUnificationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGUnificationPhase.h; path = dfg/DFGUnificationPhase.h; sourceTree = "<group>"; }; 2410 0FBF158A19B7A53100695DD0 /* DFGBlockSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGBlockSet.cpp; path = dfg/DFGBlockSet.cpp; sourceTree = "<group>"; }; 2411 0FBF158B19B7A53100695DD0 /* DFGBlockSetInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBlockSetInlines.h; path = dfg/DFGBlockSetInlines.h; sourceTree = "<group>"; }; 2408 2412 0FBFDD02196C92BF007A5BFA /* DFGPhantomRemovalPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPhantomRemovalPhase.cpp; path = dfg/DFGPhantomRemovalPhase.cpp; sourceTree = "<group>"; }; 2409 2413 0FBFDD03196C92BF007A5BFA /* DFGPhantomRemovalPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPhantomRemovalPhase.h; path = dfg/DFGPhantomRemovalPhase.h; sourceTree = "<group>"; }; … … 4827 4831 0FC3CCF519ADA410006AC72A /* DFGBlockMap.h */, 4828 4832 0FC3CCF619ADA410006AC72A /* DFGBlockMapInlines.h */, 4833 0FBF158A19B7A53100695DD0 /* DFGBlockSet.cpp */, 4829 4834 0FC3CCF719ADA410006AC72A /* DFGBlockSet.h */, 4835 0FBF158B19B7A53100695DD0 /* DFGBlockSetInlines.h */, 4830 4836 0FC3CCF819ADA410006AC72A /* DFGBlockWorklist.cpp */, 4831 4837 0FC3CCF919ADA410006AC72A /* DFGBlockWorklist.h */, … … 5920 5926 0F66E16C14DF3F1600B7B2E4 /* DFGEdge.h in Headers */, 5921 5927 A7D9A29617A0BC7400EE2618 /* DFGEdgeDominates.h in Headers */, 5928 0FBF158D19B7A53100695DD0 /* DFGBlockSetInlines.h in Headers */, 5922 5929 A7986D5717A0BB1E00A95DD0 /* DFGEdgeUsesStructure.h in Headers */, 5923 5930 0FBC0AE81496C7C700D4FBDD /* DFGExitProfile.h in Headers */, … … 7415 7422 0FCEFACA1805E75500472CE4 /* InitializeLLVM.cpp in Sources */, 7416 7423 A513E5B7185B8BD3007E95AD /* InjectedScript.cpp in Sources */, 7424 0FBF158C19B7A53100695DD0 /* DFGBlockSet.cpp in Sources */, 7417 7425 A514B2C2185A684400F3C7CB /* InjectedScriptBase.cpp in Sources */, 7418 7426 A58E35911860DECF001F24FE /* InjectedScriptHost.cpp in Sources */, -
trunk/Source/JavaScriptCore/dfg/DFGBasicBlock.h
r173069 r173279 187 187 }; 188 188 189 typedef Vector<BasicBlock*, 5> BlockList; 190 189 191 struct UnlinkedBlock { 190 192 BasicBlock* m_block; -
trunk/Source/JavaScriptCore/dfg/DFGBlockSet.h
r173072 r173279 33 33 namespace JSC { namespace DFG { 34 34 35 class Graph; 36 35 37 class BlockSet { 36 38 public: … … 50 52 } 51 53 54 class iterator { 55 public: 56 iterator() 57 : m_graph(nullptr) 58 , m_set(nullptr) 59 , m_index(0) 60 { 61 } 62 63 iterator& operator++() 64 { 65 m_index = m_set->m_set.findBit(m_index + 1, true); 66 return *this; 67 } 68 69 BasicBlock* operator*() const; 70 71 bool operator==(const iterator& other) const 72 { 73 return m_index == other.m_index; 74 } 75 76 bool operator!=(const iterator& other) const 77 { 78 return !(*this == other); 79 } 80 81 private: 82 friend class BlockSet; 83 84 Graph* m_graph; 85 const BlockSet* m_set; 86 size_t m_index; 87 }; 88 89 class Iterable { 90 public: 91 Iterable(Graph& graph, const BlockSet& set) 92 : m_graph(graph) 93 , m_set(set) 94 { 95 } 96 97 iterator begin() const 98 { 99 iterator result; 100 result.m_graph = &m_graph; 101 result.m_set = &m_set; 102 result.m_index = m_set.m_set.findBit(0, true); 103 return result; 104 } 105 106 iterator end() const 107 { 108 iterator result; 109 result.m_graph = &m_graph; 110 result.m_set = &m_set; 111 result.m_index = m_set.m_set.size(); 112 return result; 113 } 114 115 private: 116 Graph& m_graph; 117 const BlockSet& m_set; 118 }; 119 120 Iterable iterable(Graph& graph) const 121 { 122 return Iterable(graph, *this); 123 } 124 125 void dump(PrintStream&) const; 126 52 127 private: 53 128 BitVector m_set; 129 }; 130 131 class BlockAdder { 132 public: 133 BlockAdder(BlockSet& set) 134 : m_set(set) 135 { 136 } 137 138 bool operator()(BasicBlock* block) const 139 { 140 return m_set.add(block); 141 } 142 private: 143 BlockSet& m_set; 54 144 }; 55 145 -
trunk/Source/JavaScriptCore/dfg/DFGDominators.cpp
r173072 r173279 401 401 } 402 402 403 BlockSet Dominators::strictDominatorsOf(BasicBlock* to) const 404 { 405 BlockSet result; 406 forAllStrictDominatorsOf(to, BlockAdder(result)); 407 return result; 408 } 409 410 BlockSet Dominators::dominatorsOf(BasicBlock* to) const 411 { 412 BlockSet result; 413 forAllDominatorsOf(to, BlockAdder(result)); 414 return result; 415 } 416 417 BlockSet Dominators::blocksStrictlyDominatedBy(BasicBlock* from) const 418 { 419 BlockSet result; 420 forAllBlocksStrictlyDominatedBy(from, BlockAdder(result)); 421 return result; 422 } 423 424 BlockSet Dominators::blocksDominatedBy(BasicBlock* from) const 425 { 426 BlockSet result; 427 forAllBlocksDominatedBy(from, BlockAdder(result)); 428 return result; 429 } 430 431 BlockSet Dominators::dominanceFrontierOf(BasicBlock* from) const 432 { 433 BlockSet result; 434 forAllBlocksInDominanceFrontierOfImpl(from, BlockAdder(result)); 435 return result; 436 } 437 438 BlockSet Dominators::iteratedDominanceFrontierOf(const BlockList& from) const 439 { 440 BlockSet result; 441 forAllBlocksInIteratedDominanceFrontierOfImpl(from, BlockAdder(result)); 442 return result; 443 } 444 403 445 bool Dominators::naiveDominates(BasicBlock* from, BasicBlock* to) const 404 446 { -
trunk/Source/JavaScriptCore/dfg/DFGDominators.h
r173072 r173279 32 32 #include "DFGBasicBlock.h" 33 33 #include "DFGBlockMap.h" 34 #include "DFGBlockSet.h" 34 35 #include "DFGCommon.h" 35 #include <wtf/FastBitVector.h>36 36 37 37 namespace JSC { namespace DFG { … … 58 58 } 59 59 60 template<typename Functor> 61 void forAllStrictDominatorsOf(BasicBlock* to, const Functor& functor) const 62 { 63 for (BasicBlock* block = m_data[to].idomParent; block; block = m_data[block].idomParent) 64 functor(block); 65 } 66 67 template<typename Functor> 68 void forAllDominatorsOf(BasicBlock* to, const Functor& functor) const 69 { 70 for (BasicBlock* block = to; block; block = m_data[block].idomParent) 71 functor(block); 72 } 73 74 template<typename Functor> 75 void forAllBlocksStrictlyDominatedBy(BasicBlock* from, const Functor& functor) const 76 { 77 Vector<BasicBlock*, 16> worklist; 78 worklist.appendVector(m_data[from].idomKids); 79 while (!worklist.isEmpty()) { 80 BasicBlock* block = worklist.takeLast(); 81 functor(block); 82 worklist.appendVector(m_data[block].idomKids); 83 } 84 } 85 86 template<typename Functor> 87 void forAllBlocksDominatedBy(BasicBlock* from, const Functor& functor) const 88 { 89 Vector<BasicBlock*, 16> worklist; 90 worklist.append(from); 91 while (!worklist.isEmpty()) { 92 BasicBlock* block = worklist.takeLast(); 93 functor(block); 94 worklist.appendVector(m_data[block].idomKids); 95 } 96 } 97 98 BlockSet strictDominatorsOf(BasicBlock* to) const; 99 BlockSet dominatorsOf(BasicBlock* to) const; 100 BlockSet blocksStrictlyDominatedBy(BasicBlock* from) const; 101 BlockSet blocksDominatedBy(BasicBlock* from) const; 102 103 template<typename Functor> 104 void forAllBlocksInDominanceFrontierOf( 105 BasicBlock* from, const Functor& functor) const 106 { 107 BlockSet set; 108 forAllBlocksInDominanceFrontierOfImpl( 109 from, 110 [&] (BasicBlock* block) { 111 if (set.add(block)) 112 functor(block); 113 }); 114 } 115 116 BlockSet dominanceFrontierOf(BasicBlock* from) const; 117 118 template<typename Functor> 119 void forAllBlocksInIteratedDominanceFrontierOf( 120 const BlockList& from, const Functor& functor) 121 { 122 BlockSet set; 123 forAllBlocksInIteratedDominanceFrontierOfImpl( 124 from, 125 [&] (BasicBlock* block) -> bool { 126 if (!set.add(block)) 127 return false; 128 functor(block); 129 return true; 130 }); 131 } 132 133 BlockSet iteratedDominanceFrontierOf(const BlockList& from) const; 134 60 135 void dump(PrintStream&) const; 61 136 62 137 private: 63 138 bool naiveDominates(BasicBlock* from, BasicBlock* to) const; 139 140 template<typename Functor> 141 void forAllBlocksInDominanceFrontierOfImpl( 142 BasicBlock* from, const Functor& functor) const 143 { 144 // Paraphrasing from http://en.wikipedia.org/wiki/Dominator_(graph_theory): 145 // "The dominance frontier of a block 'from' is the set of all blocks 'to' such that 146 // 'from' dominates an immediate predecessor of 'to', but 'from' does not strictly 147 // dominate 'to'." 148 // 149 // A useful corner case to remember: a block may be in its own dominance frontier if it has 150 // a loop edge to itself, since it dominates itself and so it dominates its own immediate 151 // predecessor, and a block never strictly dominates itself. 152 153 forAllBlocksDominatedBy( 154 from, 155 [&] (BasicBlock* block) { 156 for (unsigned successorIndex = block->numSuccessors(); successorIndex--;) { 157 BasicBlock* to = block->successor(successorIndex); 158 if (!strictlyDominates(from, to)) 159 functor(to); 160 } 161 }); 162 } 163 164 template<typename Functor> 165 void forAllBlocksInIteratedDominanceFrontierOfImpl( 166 const BlockList& from, const Functor& functor) const 167 { 168 BlockList worklist = from; 169 while (!worklist.isEmpty()) { 170 BasicBlock* block = worklist.takeLast(); 171 forAllBlocksInDominanceFrontierOfImpl( 172 block, 173 [&] (BasicBlock* otherBlock) { 174 if (functor(otherBlock)) 175 worklist.append(otherBlock); 176 }); 177 } 178 } 64 179 65 180 struct BlockData { -
trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp
r173072 r173279 370 370 out.print("\n"); 371 371 if (m_dominators.isValid()) { 372 out.print(prefix, " Dominated by:"); 373 for (size_t i = 0; i < m_blocks.size(); ++i) { 374 if (!this->block(i)) 375 continue; 376 if (!m_dominators.dominates(this->block(i), block)) 377 continue; 378 out.print(" #", i); 379 } 380 out.print("\n"); 381 out.print(prefix, " Dominates:"); 382 for (size_t i = 0; i < m_blocks.size(); ++i) { 383 if (!this->block(i)) 384 continue; 385 if (!m_dominators.dominates(block, this->block(i))) 386 continue; 387 out.print(" #", i); 388 } 389 out.print("\n"); 372 out.print(prefix, " Dominated by: ", m_dominators.dominatorsOf(block), "\n"); 373 out.print(prefix, " Dominates: ", m_dominators.blocksDominatedBy(block), "\n"); 374 out.print(prefix, " Dominance Frontier: ", m_dominators.dominanceFrontierOf(block), "\n"); 375 out.print(prefix, " Iterated Dominance Frontier: ", m_dominators.iteratedDominanceFrontierOf(BlockList(1, block)), "\n"); 390 376 } 391 377 if (m_naturalLoops.isValid()) { -
trunk/Source/JavaScriptCore/dfg/DFGInvalidationPointInjectionPhase.cpp
r173072 r173279 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 #if ENABLE(DFG_JIT) 30 30 31 #include "DFGBlockSet .h"31 #include "DFGBlockSetInlines.h" 32 32 #include "DFGClobberize.h" 33 33 #include "DFGGraph.h" … … 70 70 m_insertionSet.execute(block); 71 71 } 72 73 for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {74 BasicBlock* block = m_graph.block(blockIndex);75 72 76 if (!blocksThatNeedInvalidationPoints.contains(block)) 77 continue; 78 73 for (BasicBlock* block : blocksThatNeedInvalidationPoints.iterable(m_graph)) { 79 74 insertInvalidationCheck(0, block->at(0)); 80 75 m_insertionSet.execute(block); -
trunk/Source/WTF/ChangeLog
r173271 r173279 1 2014-09-03 Filip Pizlo <fpizlo@apple.com> 2 3 Beef up the DFG's CFG analyses to include iterated dominance frontiers and more user-friendly BlockSets 4 https://bugs.webkit.org/show_bug.cgi?id=136520 5 6 Reviewed by Geoffrey Garen. 7 8 Give BitVector a way to quickly find the next set (or unset) bit. Make BitVector equality 9 faster. Fix a minor closure goof in Spectrum. 10 11 * wtf/BitVector.cpp: 12 (WTF::BitVector::equalsSlowCase): 13 (WTF::BitVector::equalsSlowCaseFast): 14 (WTF::BitVector::equalsSlowCaseSimple): 15 * wtf/BitVector.h: 16 (WTF::BitVector::findBit): 17 (WTF::BitVector::findBitFast): 18 (WTF::BitVector::findBitSimple): 19 (WTF::BitVector::findBitInWord): 20 * wtf/Spectrum.h: 21 (WTF::Spectrum::removeIf): 22 1 23 2014-09-04 Anders Carlsson <andersca@apple.com> 2 24 -
trunk/Source/WTF/wtf/BitVector.cpp
r159039 r173279 184 184 bool BitVector::equalsSlowCase(const BitVector& other) const 185 185 { 186 bool result = equalsSlowCaseFast(other); 187 ASSERT(result == equalsSlowCaseSimple(other)); 188 return result; 189 } 190 191 bool BitVector::equalsSlowCaseFast(const BitVector& other) const 192 { 193 if (isInline() != other.isInline()) 194 return equalsSlowCaseSimple(other); 195 196 const OutOfLineBits* myBits = outOfLineBits(); 197 const OutOfLineBits* otherBits = other.outOfLineBits(); 198 199 size_t myNumWords = myBits->numWords(); 200 size_t otherNumWords = otherBits->numWords(); 201 size_t minNumWords; 202 size_t maxNumWords; 203 204 const OutOfLineBits* longerBits; 205 if (myNumWords < otherNumWords) { 206 minNumWords = myNumWords; 207 maxNumWords = otherNumWords; 208 longerBits = otherBits; 209 } else { 210 minNumWords = otherNumWords; 211 maxNumWords = myNumWords; 212 longerBits = myBits; 213 } 214 215 for (size_t i = minNumWords; i < maxNumWords; ++i) { 216 if (longerBits->bits()[i]) 217 return false; 218 } 219 220 for (size_t i = minNumWords; i--;) { 221 if (myBits->bits()[i] != otherBits->bits()[i]) 222 return false; 223 } 224 225 return false; 226 } 227 228 bool BitVector::equalsSlowCaseSimple(const BitVector& other) const 229 { 186 230 // This is really cheesy, but probably good enough for now. 187 231 for (unsigned i = std::max(size(), other.size()); i--;) { -
trunk/Source/WTF/wtf/BitVector.h
r173072 r173279 1 1 /* 2 * Copyright (C) 2011 Apple Inc. All rights reserved.2 * Copyright (C) 2011, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 #include <stdio.h> 30 30 #include <wtf/Assertions.h> 31 #include <wtf/DataLog.h> 31 32 #include <wtf/HashFunctions.h> 32 33 #include <wtf/HashTraits.h> … … 216 217 } 217 218 219 size_t findBit(size_t index, bool value) const 220 { 221 size_t result = findBitFast(index, value); 222 if (!ASSERT_DISABLED) { 223 size_t expectedResult = findBitSimple(index, value); 224 if (result != expectedResult) { 225 dataLog("findBit(", index, ", ", value, ") on ", *this, " should have gotten ", expectedResult, " but got ", result, "\n"); 226 ASSERT_NOT_REACHED(); 227 } 228 } 229 return result; 230 } 231 218 232 WTF_EXPORT_PRIVATE void dump(PrintStream& out) const; 219 233 … … 288 302 return WTF::bitCount(static_cast<unsigned>(bits)); 289 303 return WTF::bitCount(static_cast<uint64_t>(bits)); 304 } 305 306 size_t findBitFast(size_t startIndex, bool value) const 307 { 308 if (isInline()) { 309 size_t index = startIndex; 310 findBitInWord(m_bitsOrPointer, index, maxInlineBits(), value); 311 return index; 312 } 313 314 const OutOfLineBits* bits = outOfLineBits(); 315 316 // value = true: casts to 1, then xors to 0, then negates to 0. 317 // value = false: casts to 0, then xors to 1, then negates to -1 (i.e. all one bits). 318 uintptr_t skipValue = -(static_cast<uintptr_t>(value) ^ 1); 319 size_t numWords = bits->numWords(); 320 321 size_t wordIndex = startIndex / bitsInPointer(); 322 size_t startIndexInWord = startIndex - wordIndex * bitsInPointer(); 323 324 while (wordIndex < numWords) { 325 uintptr_t word = bits->bits()[wordIndex]; 326 if (word != skipValue) { 327 size_t index = startIndexInWord; 328 if (findBitInWord(word, index, bitsInPointer(), value)) 329 return wordIndex * bitsInPointer() + index; 330 } 331 332 wordIndex++; 333 startIndexInWord = 0; 334 } 335 336 return bits->numBits(); 337 } 338 339 size_t findBitSimple(size_t index, bool value) const 340 { 341 while (index < size()) { 342 if (get(index) == value) 343 return index; 344 index++; 345 } 346 return size(); 347 } 348 349 static bool findBitInWord(uintptr_t word, size_t& index, size_t endIndex, bool value) 350 { 351 word >>= index; 352 353 while (index < endIndex) { 354 if ((word & 1) == static_cast<uintptr_t>(value)) 355 return true; 356 index++; 357 word >>= 1; 358 } 359 360 index = endIndex; 361 return false; 290 362 } 291 363 … … 325 397 326 398 WTF_EXPORT_PRIVATE bool equalsSlowCase(const BitVector& other) const; 399 bool equalsSlowCaseFast(const BitVector& other) const; 400 bool equalsSlowCaseSimple(const BitVector& other) const; 327 401 WTF_EXPORT_PRIVATE uintptr_t hashSlowCase() const; 328 402 -
trunk/Source/WTF/wtf/Spectrum.h
r173069 r173279 111 111 void removeIf(const Functor& functor) 112 112 { 113 m_map.removeIf([ functor] (typename HashMap<T, CounterType>::KeyValuePairType& pair) {113 m_map.removeIf([&functor] (typename HashMap<T, CounterType>::KeyValuePairType& pair) { 114 114 return functor(KeyAndCount(pair.key, pair.value)); 115 115 });
Note:
See TracChangeset
for help on using the changeset viewer.