WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
it is written
blah.patch (text/plain), 46.21 KB, created by
Filip Pizlo
on 2014-09-28 15:13:00 PDT
(
hide
)
Description:
it is written
Filename:
MIME Type:
Creator:
Filip Pizlo
Created:
2014-09-28 15:13:00 PDT
Size:
46.21 KB
patch
obsolete
>Index: Source/JavaScriptCore/ChangeLog >=================================================================== >--- Source/JavaScriptCore/ChangeLog (revision 174045) >+++ Source/JavaScriptCore/ChangeLog (working copy) >@@ -1,3 +1,55 @@ >+2014-09-28 Filip Pizlo <fpizlo@apple.com> >+ >+ FTL should sink SetLocals >+ https://bugs.webkit.org/show_bug.cgi?id=137168 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Work in progress. >+ >+ * CMakeLists.txt: >+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: >+ * JavaScriptCore.xcodeproj/project.pbxproj: >+ * bytecode/CodeBlock.h: >+ * dfg/DFGByteCodeParser.cpp: >+ (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): >+ * dfg/DFGClobberSet.h: >+ (JSC::DFG::ClobberSetAdd::operator()): >+ (JSC::DFG::ClobberSetOverlaps::operator()): >+ * dfg/DFGClobberize.h: >+ (JSC::DFG::clobberize): >+ (JSC::DFG::NoOpClobberize::operator()): >+ (JSC::DFG::CheckClobberize::operator()): >+ (JSC::DFG::AbstractHeapOverlaps::operator()): >+ (JSC::DFG::ReadMethodClobberize::operator()): >+ (JSC::DFG::WriteMethodClobberize::operator()): >+ (JSC::DFG::DefMethodClobberize::operator()): >+ * dfg/DFGFlushFormat.h: >+ (JSC::DFG::merge): >+ * dfg/DFGGraph.cpp: >+ (JSC::DFG::Graph::Graph): >+ * dfg/DFGGraph.h: >+ (JSC::DFG::Graph::capturedVarsFor): >+ * dfg/DFGPlan.cpp: >+ (JSC::DFG::Plan::compileInThreadImpl): >+ * dfg/DFGPreciseLocalClobberize.h: Added. >+ (JSC::DFG::PreciseLocalClobberizeAdaptor::PreciseLocalClobberizeAdaptor): >+ (JSC::DFG::PreciseLocalClobberizeAdaptor::read): >+ (JSC::DFG::PreciseLocalClobberizeAdaptor::write): >+ (JSC::DFG::PreciseLocalClobberizeAdaptor::def): >+ (JSC::DFG::PreciseLocalClobberizeAdaptor::readTop): >+ (JSC::DFG::PreciseLocalClobberizeAdaptor::writeTop): >+ (JSC::DFG::preciseLocalClobberize): >+ * dfg/DFGSSACalculator.h: >+ (JSC::DFG::SSACalculator::computePhis): >+ * dfg/DFGSetLocalSinkingPhase.cpp: Added. >+ (JSC::DFG::SetLocalSinkingPhase::SetLocalSinkingPhase): >+ (JSC::DFG::SetLocalSinkingPhase::run): >+ (JSC::DFG::SetLocalSinkingPhase::materialize): >+ (JSC::DFG::performSetLocalSinking): >+ * dfg/DFGSetLocalSinkingPhase.h: Added. >+ * runtime/Options.h: >+ > 2014-09-26 Filip Pizlo <fpizlo@apple.com> > > Disable function.arguments >Index: Source/JavaScriptCore/CMakeLists.txt >=================================================================== >--- Source/JavaScriptCore/CMakeLists.txt (revision 174031) >+++ Source/JavaScriptCore/CMakeLists.txt (working copy) >@@ -212,6 +212,7 @@ set(JavaScriptCore_SOURCES > dfg/DFGSSAConversionPhase.cpp > dfg/DFGSSALoweringPhase.cpp > dfg/DFGSafepoint.cpp >+ dfg/DFGSetLocalSinkingPhase.cpp > dfg/DFGSpeculativeJIT.cpp > dfg/DFGSpeculativeJIT32_64.cpp > dfg/DFGSpeculativeJIT64.cpp >Index: Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj >=================================================================== >--- Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (revision 174031) >+++ Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (working copy) >@@ -455,6 +455,7 @@ > <ClCompile Include="..\dfg\DFGPureValue.cpp" /> > <ClCompile Include="..\dfg\DFGResurrectionForValidationPhase.cpp" /> > <ClCompile Include="..\dfg\DFGSafepoint.cpp" /> >+ <ClCompile Include="..\dfg\DFGSetLocalSinkingPhase.cpp" /> > <ClCompile Include="..\dfg\DFGSpeculativeJIT.cpp" /> > <ClCompile Include="..\dfg\DFGSpeculativeJIT32_64.cpp" /> > <ClCompile Include="..\dfg\DFGSpeculativeJIT64.cpp" /> >@@ -1104,6 +1105,7 @@ > <ClInclude Include="..\dfg\DFGPhiChildren.h" /> > <ClInclude Include="..\dfg\DFGPlan.h" /> > <ClInclude Include="..\dfg\DFGPrePostNumbering.h" /> >+ <ClInclude Include="..\dfg\DFGPreciseLocalClobberize.h" /> > <ClInclude Include="..\dfg\DFGPredictionInjectionPhase.h" /> > <ClInclude Include="..\dfg\DFGPredictionPropagationPhase.h" /> > <ClInclude Include="..\dfg\DFGPromoteHeapAccess.h" /> >@@ -1118,6 +1120,7 @@ > <ClInclude Include="..\dfg\DFGScannable.h" /> > <ClInclude Include="..\dfg\DFGScoreBoard.h" /> > <ClInclude Include="..\dfg\DFGScratchRegisterAllocator.h" /> >+ <ClInclude Include="..\dfg\DFGSetLocalSinkingPhase.h" /> > <ClInclude Include="..\dfg\DFGSilentRegisterSavePlan.h" /> > <ClInclude Include="..\dfg\DFGSlowPathGenerator.h" /> > <ClInclude Include="..\dfg\DFGSpeculativeJIT.h" /> >Index: Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >=================================================================== >--- Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (revision 174031) >+++ Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (working copy) >@@ -1562,6 +1562,9 @@ > C49FE4AA19AAC83E00F40CE9 /* generate_protocol_types_implementation.py in Resources */ = {isa = PBXBuildFile; fileRef = C49FE4A819AAC83E00F40CE9 /* generate_protocol_types_implementation.py */; }; > C49FE4AB19AAC86100F40CE9 /* generate_protocol_types_header.py in Headers */ = {isa = PBXBuildFile; fileRef = C49FE4A719AAC83E00F40CE9 /* generate_protocol_types_header.py */; settings = {ATTRIBUTES = (Private, ); }; }; > C49FE4AC19AAC86100F40CE9 /* generate_protocol_types_implementation.py in Headers */ = {isa = PBXBuildFile; fileRef = C49FE4A819AAC83E00F40CE9 /* generate_protocol_types_implementation.py */; settings = {ATTRIBUTES = (Private, ); }; }; >+ DC00039319D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h in Headers */ = {isa = PBXBuildFile; fileRef = DC00039019D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ DC00039419D8BE6F00023EB0 /* DFGSetLocalSinkingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC00039119D8BE6F00023EB0 /* DFGSetLocalSinkingPhase.cpp */; }; >+ DC00039519D8BE6F00023EB0 /* DFGSetLocalSinkingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = DC00039219D8BE6F00023EB0 /* DFGSetLocalSinkingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; }; > E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */ = {isa = PBXBuildFile; fileRef = E124A8F50E555775003091F1 /* OpaqueJSString.h */; settings = {ATTRIBUTES = (Private, ); }; }; > E124A8F80E555775003091F1 /* OpaqueJSString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E124A8F60E555775003091F1 /* OpaqueJSString.cpp */; }; > E18E3A590DF9278C00D90B34 /* VM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E18E3A570DF9278C00D90B34 /* VM.cpp */; }; >@@ -3222,6 +3225,9 @@ > C49FE4A819AAC83E00F40CE9 /* generate_protocol_types_implementation.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_protocol_types_implementation.py; sourceTree = "<group>"; }; > D21202280AD4310C00ED79B6 /* DateConversion.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DateConversion.cpp; sourceTree = "<group>"; }; > D21202290AD4310C00ED79B6 /* DateConversion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DateConversion.h; sourceTree = "<group>"; }; >+ DC00039019D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPreciseLocalClobberize.h; path = dfg/DFGPreciseLocalClobberize.h; sourceTree = "<group>"; }; >+ DC00039119D8BE6F00023EB0 /* DFGSetLocalSinkingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGSetLocalSinkingPhase.cpp; path = dfg/DFGSetLocalSinkingPhase.cpp; sourceTree = "<group>"; }; >+ DC00039219D8BE6F00023EB0 /* DFGSetLocalSinkingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSetLocalSinkingPhase.h; path = dfg/DFGSetLocalSinkingPhase.h; sourceTree = "<group>"; }; > E124A8F50E555775003091F1 /* OpaqueJSString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpaqueJSString.h; sourceTree = "<group>"; }; > E124A8F60E555775003091F1 /* OpaqueJSString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpaqueJSString.cpp; sourceTree = "<group>"; }; > E178633F0D9BEC0000D74E75 /* InitializeThreading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InitializeThreading.h; sourceTree = "<group>"; }; >@@ -4755,6 +4761,7 @@ > 0F2B9CDF19D0BA7D00B1D1B5 /* DFGPhiChildren.h */, > A78A9772179738B8009DF744 /* DFGPlan.cpp */, > A78A9773179738B8009DF744 /* DFGPlan.h */, >+ DC00039019D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h */, > 0FBE0F6D16C1DB010082C5E8 /* DFGPredictionInjectionPhase.cpp */, > 0FBE0F6E16C1DB010082C5E8 /* DFGPredictionInjectionPhase.h */, > 0FFFC95114EF909500C72532 /* DFGPredictionPropagationPhase.cpp */, >@@ -4775,6 +4782,8 @@ > A741017E179DAF80002EB8BA /* DFGSaneStringGetByValSlowPathGenerator.h */, > 0F2FCCF618A60070001A27F8 /* DFGScannable.h */, > 86ECA3F9132DF25A002B2AD7 /* DFGScoreBoard.h */, >+ DC00039119D8BE6F00023EB0 /* DFGSetLocalSinkingPhase.cpp */, >+ DC00039219D8BE6F00023EB0 /* DFGSetLocalSinkingPhase.h */, > 0F1E3A65153A21DF000F9456 /* DFGSilentRegisterSavePlan.h */, > 0F1E3A501537C2CB000F9456 /* DFGSlowPathGenerator.h */, > 86EC9DC21328DF82002B2AD7 /* DFGSpeculativeJIT.cpp */, >@@ -5586,6 +5595,7 @@ > 0FEA0A08170513DB00BB722C /* FTLAbbreviations.h in Headers */, > A53CE08A18BC21C300BEDF76 /* ConsoleClient.h in Headers */, > 0FEA0A1D1708B00700BB722C /* FTLAbstractHeap.h in Headers */, >+ DC00039319D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h in Headers */, > 0FEA0A1F1708B00700BB722C /* FTLAbstractHeapRepository.h in Headers */, > 0F485328187DFDEC0083B687 /* FTLAvailableRecovery.h in Headers */, > 0FEA0A0A170513DB00BB722C /* FTLCapabilities.h in Headers */, >@@ -5907,6 +5917,7 @@ > 86ADD1460FDDEA980006EEC2 /* MacroAssemblerARMv7.h in Headers */, > 863B23E00FC6118900703AA4 /* MacroAssemblerCodeRef.h in Headers */, > 86C568E111A213EE0007F7F0 /* MacroAssemblerMIPS.h in Headers */, >+ DC00039519D8BE6F00023EB0 /* DFGSetLocalSinkingPhase.h in Headers */, > 86AE64A9135E5E1C00963012 /* MacroAssemblerSH4.h in Headers */, > 860161E40F3A83C100F84710 /* MacroAssemblerX86.h in Headers */, > 860161E50F3A83C100F84710 /* MacroAssemblerX86_64.h in Headers */, >@@ -7088,6 +7099,7 @@ > 0FF729B0166AD35C000F5BA3 /* ProfilerCompilationKind.cpp in Sources */, > 0FF729B1166AD35C000F5BA3 /* ProfilerCompiledBytecode.cpp in Sources */, > 0FF729B2166AD35C000F5BA3 /* ProfilerDatabase.cpp in Sources */, >+ DC00039419D8BE6F00023EB0 /* DFGSetLocalSinkingPhase.cpp in Sources */, > 0F190CAC189D82F6000AE5F0 /* ProfilerJettisonReason.cpp in Sources */, > 0FF729B3166AD35C000F5BA3 /* ProfilerOrigin.cpp in Sources */, > 0FF729B4166AD35C000F5BA3 /* ProfilerOriginStack.cpp in Sources */, >Index: Source/JavaScriptCore/bytecode/CodeBlock.h >=================================================================== >--- Source/JavaScriptCore/bytecode/CodeBlock.h (revision 174031) >+++ Source/JavaScriptCore/bytecode/CodeBlock.h (working copy) >@@ -384,7 +384,7 @@ public: > return 0; > return symbolTable()->captureEnd(); > } >- >+ > bool isCaptured(VirtualRegister operand, InlineCallFrame* = 0) const; > > int framePointerOffsetToGetActivationRegisters(int machineCaptureStart); >Index: Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (revision 174031) >+++ Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (working copy) >@@ -3693,12 +3693,8 @@ ByteCodeParser::InlineStackEntry::Inline > > if (m_inlineCallFrame->caller.inlineCallFrame) > m_inlineCallFrame->capturedVars = m_inlineCallFrame->caller.inlineCallFrame->capturedVars; >- else { >- for (int i = byteCodeParser->m_codeBlock->m_numVars; i--;) { >- if (byteCodeParser->m_codeBlock->isCaptured(virtualRegisterForLocal(i))) >- m_inlineCallFrame->capturedVars.set(i); >- } >- } >+ else >+ m_inlineCallFrame->capturedVars = byteCodeParser->m_graph.m_outermostCapturedVars; > > for (int i = argumentCountIncludingThis; i--;) { > VirtualRegister argument = virtualRegisterForArgument(i); >Index: Source/JavaScriptCore/dfg/DFGClobberSet.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGClobberSet.h (revision 174031) >+++ Source/JavaScriptCore/dfg/DFGClobberSet.h (working copy) >@@ -80,7 +80,7 @@ public: > { > } > >- void operator()(AbstractHeap heap) >+ void operator()(AbstractHeap heap) const > { > m_set.add(heap); > } >@@ -96,7 +96,7 @@ public: > { > } > >- void operator()(AbstractHeap heap) >+ void operator()(AbstractHeap heap) const > { > m_result |= m_set.overlaps(heap); > } >@@ -105,7 +105,7 @@ public: > > private: > const ClobberSet& m_set; >- bool m_result; >+ mutable bool m_result; > }; > > void addReads(Graph&, Node*, ClobberSet&); >Index: Source/JavaScriptCore/dfg/DFGClobberize.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGClobberize.h (revision 174031) >+++ Source/JavaScriptCore/dfg/DFGClobberize.h (working copy) >@@ -1,4 +1,4 @@ >- /* >+/* > * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without >@@ -37,7 +37,7 @@ > namespace JSC { namespace DFG { > > template<typename ReadFunctor, typename WriteFunctor, typename DefFunctor> >-void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write, DefFunctor& def) >+void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFunctor& write, const DefFunctor& def) > { > // Some notes: > // >@@ -899,7 +899,7 @@ class NoOpClobberize { > public: > NoOpClobberize() { } > template<typename... T> >- void operator()(T...) { } >+ void operator()(T...) const { } > }; > > class CheckClobberize { >@@ -910,12 +910,12 @@ public: > } > > template<typename... T> >- void operator()(T...) { m_result = true; } >+ void operator()(T...) const { m_result = true; } > > bool result() const { return m_result; } > > private: >- bool m_result; >+ mutable bool m_result; > }; > > bool doesWrites(Graph&, Node*); >@@ -928,7 +928,7 @@ public: > { > } > >- void operator()(AbstractHeap otherHeap) >+ void operator()(AbstractHeap otherHeap) const > { > if (m_result) > return; >@@ -939,7 +939,7 @@ public: > > private: > AbstractHeap m_heap; >- bool m_result; >+ mutable bool m_result; > }; > > bool accessesOverlap(Graph&, Node*, AbstractHeap); >@@ -956,7 +956,7 @@ public: > { > } > >- void operator()(AbstractHeap heap) >+ void operator()(AbstractHeap heap) const > { > m_value.read(heap); > } >@@ -972,7 +972,7 @@ public: > { > } > >- void operator()(AbstractHeap heap) >+ void operator()(AbstractHeap heap) const > { > m_value.write(heap); > } >@@ -988,12 +988,12 @@ public: > { > } > >- void operator()(PureValue value) >+ void operator()(PureValue value) const > { > m_value.def(value); > } > >- void operator()(HeapLocation location, Node* node) >+ void operator()(HeapLocation location, Node* node) const > { > m_value.def(location, node); > } >Index: Source/JavaScriptCore/dfg/DFGFlushFormat.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGFlushFormat.h (revision 174031) >+++ Source/JavaScriptCore/dfg/DFGFlushFormat.h (working copy) >@@ -118,6 +118,17 @@ inline DataFormat dataFormatFor(FlushFor > return DataFormatDead; > } > >+inline FlushFormat merge(FlushFormat a, FlushFormat b) >+{ >+ if (a == DeadFlush) >+ return b; >+ if (b == DeadFlush) >+ return a; >+ if (a == b) >+ return a; >+ return ConflictingFlush; >+} >+ > } } // namespace JSC::DFG > > namespace WTF { >Index: Source/JavaScriptCore/dfg/DFGGraph.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGGraph.cpp (revision 174031) >+++ Source/JavaScriptCore/dfg/DFGGraph.cpp (working copy) >@@ -75,6 +75,11 @@ Graph::Graph(VM& vm, Plan& plan, LongLiv > > for (unsigned i = m_mustHandleValues.size(); i--;) > m_mustHandleValues[i] = freezeFragile(plan.mustHandleValues[i]); >+ >+ for (unsigned i = m_codeBlock->m_numVars; i--;) { >+ if (m_codeBlock->isCaptured(virtualRegisterForLocal(i))) >+ m_outermostCapturedVars.set(i); >+ } > } > > Graph::~Graph() >Index: Source/JavaScriptCore/dfg/DFGGraph.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGGraph.h (revision 174031) >+++ Source/JavaScriptCore/dfg/DFGGraph.h (working copy) >@@ -367,6 +367,13 @@ public: > return baselineCodeBlockForOriginAndBaselineCodeBlock(codeOrigin, m_profiledBlock); > } > >+ const BitVector& capturedVarsFor(InlineCallFrame* inlineCallFrame) >+ { >+ if (!inlineCallFrame) >+ return m_outermostCapturedVar; >+ return inlineCallFrame->capturedVars; >+ } >+ > bool isStrictModeFor(CodeOrigin codeOrigin) > { > if (!codeOrigin.inlineCallFrame) >@@ -888,6 +895,7 @@ public: > unsigned m_parameterSlots; > int m_machineCaptureStart; > std::unique_ptr<SlowArgument[]> m_slowArguments; >+ BitVector m_outermostCapturedVars; > > #if USE(JSVALUE32_64) > std::unordered_map<int64_t, double*> m_doubleConstantsMap; >Index: Source/JavaScriptCore/dfg/DFGPlan.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGPlan.cpp (revision 174031) >+++ Source/JavaScriptCore/dfg/DFGPlan.cpp (working copy) >@@ -57,6 +57,7 @@ > #include "DFGResurrectionForValidationPhase.h" > #include "DFGSSAConversionPhase.h" > #include "DFGSSALoweringPhase.h" >+#include "DFGSetLocalSinkingPhase.h" > #include "DFGStackLayoutPhase.h" > #include "DFGStaticExecutionCountEstimationPhase.h" > #include "DFGStoreBarrierElisionPhase.h" >@@ -322,6 +323,7 @@ Plan::CompilationPath Plan::compileInThr > performCPSRethreading(dfg); > performSSAConversion(dfg); > performSSALowering(dfg); >+ performSetLocalSinking(dfg); > performGlobalCSE(dfg); > performLivenessAnalysis(dfg); > performCFA(dfg); >@@ -329,8 +331,10 @@ Plan::CompilationPath Plan::compileInThr > performPhantomCanonicalization(dfg); // Reduce the graph size a lot. > changed = false; > changed |= performStrengthReduction(dfg); >- changed |= performCriticalEdgeBreaking(dfg); >- changed |= performObjectAllocationSinking(dfg); >+ if (Options::enableObjectAllocatoinSinking()) { >+ changed |= performCriticalEdgeBreaking(dfg); >+ changed |= performObjectAllocationSinking(dfg); >+ } > if (changed) { > // State-at-tail and state-at-head will be invalid if we did strength reduction since > // it might increase live ranges. >Index: Source/JavaScriptCore/dfg/DFGPreciseLocalClobberize.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGPreciseLocalClobberize.h (revision 0) >+++ Source/JavaScriptCore/dfg/DFGPreciseLocalClobberize.h (working copy) >@@ -0,0 +1,163 @@ >+/* >+ * Copyright (C) 2014 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 DFGPreciseLocalClobberize_h >+#define DFGPreciseLocalClobberize_h >+ >+#if ENABLE(DFG_JIT) >+ >+#include "DFGClobberize.h" >+ >+namespace JSC { namespace DFG { >+ >+template<typename ReadFunctor, typename WriteFunctor, typename DefFunctor> >+class PreciseLocalClobberizeAdaptor { >+public: >+ PreciseLocalClobberizeAdaptor( >+ Graph& graph, Node* node, >+ const ReadFunctor& read, const WriteFunctor& write, const DefFunctor& def) >+ : m_graph(graph) >+ , m_node(node) >+ , m_read(read) >+ , m_write(write) >+ , m_def(def) >+ { >+ } >+ >+ void read(AbstractHeap heap) >+ { >+ if (heap.kind() == Variables) { >+ if (heap.payload().isTop()) { >+ readTop(); >+ return; >+ } >+ >+ m_read(VirtualRegister(heap.value())); >+ return; >+ } >+ >+ if (heap.overlaps(Variables)) { >+ readTop(); >+ return; >+ } >+ } >+ >+ void write(AbstractHeap heap) >+ { >+ if (heap.kind() == Variables) { >+ if (heap.payload().isTop()) { >+ writeTop(); >+ return; >+ } >+ >+ m_write(VirtualRegister(heap.value())); >+ return; >+ } >+ >+ if (heap.overlaps(Variables)) { >+ writeTop(); >+ return; >+ } >+ } >+ >+ void def(PureValue value) >+ { >+ // PureValue defs never have anything to do with locals, so ignore this. >+ } >+ >+ void def(HeapLocation location, Node* node) >+ { >+ if (location.kind() != VariableLoc) >+ return; >+ >+ RELEASE_ASSERT(location.heap().kind() == Variables); >+ >+ m_def(VirtualRegister(location.heap().payload().value()), node); >+ } >+ >+private: >+ void readTop() >+ { >+ // All of the outermost arguments, except this, are definitely read. >+ for (unsigned i = m_graph.m_codeBlock->numParameters(); i-- > 1;) >+ m_read(virtualRegisterForArgument(i)); >+ >+ // The stack header is read. >+ for (unsigned i = 0; i < JSStack::ThisArgument; ++i) >+ m_read(VirtualRegister(i)); >+ >+ // Read all of the captured variables. >+ const BitVector& capturedVars = >+ m_graph.capturedVarsFor(m_node->origin.semantic.inlineCallFrame); >+ for (unsigned i : capturedVars.setBits()) >+ m_read(virtualRegisterForLocal(i)); >+ >+ // Read all of the inline arguments and call frame headers that we didn't already capture. >+ for (InlineCallFrame* inlineCallFrame = m_node->origin.semantic.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->caller.inlineCallFrame) { >+ for (unsigned i = inlineCallFrame->arguments.size(); i-- > 1;) >+ m_read(VirtualRegister(inlineCallFrame->stackOffset + virtualRegisterForArgument(i).offset())); >+ if (inlineCallFrame->isClosureCall) { >+ m_read(VirtualRegister(inlineCallFrame->stackOffset + JSStack::ScopeChain)); >+ m_read(VirtualRegister(inlineCallFrame->stackOffset + JSStack::Callee)); >+ } >+ } >+ } >+ >+ void writeTop() >+ { >+ if (m_graph.m_codeBlock->usesArguments()) { >+ for (unsigned i = m_graph.m_codeBlock->numParameters(); i-- > 1;) >+ m_write(virtualRegisterForArgument(i)); >+ } >+ >+ const BitVector& capturedVars = >+ m_graph.capturedVarsFor(m_node->origin.semantic.inlineCallFrame); >+ for (unsigned i : capturedVars.setBits()) >+ m_write(virtualRegisterForLocal(i)); >+ } >+ >+ Graph& m_graph; >+ Node* m_node; >+ const ReadFunctor& m_read; >+ const WriteFunctor& m_write; >+ const DefFunctor& m_def; >+}; >+ >+template<typename ReadFunctor, typename WriteFunctor, typename DefFunctor> >+void preciseLocalClobberize( >+ Graph& graph, Node* node, >+ const ReadFunctor& read, const WriteFunctor& write, const DefFunctor& def) >+{ >+ PreciseLocalClobberizeAdaptor<ReadFunctor, WriteFunctor, DefFunctor> >+ adaptor(graph, node, read, write, def); >+ clobberize(graph, node, adaptor); >+} >+ >+} } // namespace JSC::DFG >+ >+#endif // ENABLE(DFG_JIT) >+ >+#endif // DFGPreciseLocalClobberize_h >+ >Index: Source/JavaScriptCore/dfg/DFGSSACalculator.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGSSACalculator.h (revision 174031) >+++ Source/JavaScriptCore/dfg/DFGSSACalculator.h (working copy) >@@ -174,7 +174,7 @@ public: > // nonLocalReachingDef() will find it later. Note that it is generally always sound to not > // prune any Phis (that is, to always have the functor insert a Phi and never return nullptr). > template<typename PhiInsertionFunctor> >- void computePhis(PhiInsertionFunctor functor) >+ void computePhis(const PhiInsertionFunctor& functor) > { > DFG_ASSERT(m_graph, nullptr, m_graph.m_dominators.isValid()); > >Index: Source/JavaScriptCore/dfg/DFGSetLocalSinkingPhase.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGSetLocalSinkingPhase.cpp (revision 0) >+++ Source/JavaScriptCore/dfg/DFGSetLocalSinkingPhase.cpp (working copy) >@@ -0,0 +1,360 @@ >+/* >+ * Copyright (C) 2014 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 "DFGSetLocalSinkingPhase.h" >+ >+#if ENABLE(DFG_JIT) >+ >+#include "DFGBlockMapInlines.h" >+#include "DFGGraph.h" >+#include "DFGInsertionSet.h" >+#include "DFGPhase.h" >+#include "DFGPreciseLocalClobberize.h" >+#include "DFGSSACalculator.h" >+#include "DFGValidate.h" >+#include "JSCInlines.h" >+ >+namespace JSC { namespace DFG { >+ >+static bool verbose = false; >+ >+class SetLocalSinkingPhase : public Phase { >+public: >+ SetLocalSinkingPhase(Graph& graph) >+ : Phase(graph, "SetLocal sinking") >+ , m_ssaCalculator(graph) >+ , m_insertionSet(graph) >+ { >+ } >+ >+ bool run() >+ { >+ // First figure out where various locals are live. >+ BlockMap<Operands<bool>> liveAtHead(m_graph); >+ BlockMap<Operands<bool>> liveAtTail(m_graph); >+ >+ for (BasicBlock* block : m_graph.blocksInNaturalOrder()) { >+ liveAtHead[block] = Operands<bool>(OperandsLike, block->variablesAtHead); >+ liveAtTail[block] = Operands<bool>(OperandsLike, block->variablesAtHead); >+ >+ liveAtHead[block].fill(false); >+ liveAtTail[block].fill(false); >+ } >+ >+ bool changed; >+ do { >+ changed = false; >+ >+ for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) { >+ BasicBlock* block = m_graph.block(blockIndex); >+ if (!block) >+ continue; >+ >+ Operands<bool> live = liveAtTail[block]; >+ for (unsigned nodeIndex = block->size(); nodeIndex--;) { >+ Node* node = block->at(nodeIndex); >+ >+ preciseLocalClobberize( >+ m_graph, node, >+ [&] (VirtualRegister operand) { >+ live.operand(operand) = true; >+ }, >+ [&] (VirtualRegister operand) { >+ live.operand(operand) = true; >+ }, >+ [&] (VirtualRegister operand, Node* source) { >+ if (source == node) { >+ // This is a load. Ignore it. >+ return; >+ } >+ >+ RELEASE_ASSERT(node->op() == SetLocal); >+ live.operand(operand) = false; >+ }); >+ } >+ >+ if (live == liveAtHead[block]) >+ continue; >+ >+ liveAtHead[block] = live; >+ changed = true; >+ >+ for (BasicBlock* predecessor : block->predecessors) { >+ for (size_t i = live.size(); i--;) >+ liveAtTail[block][i] |= live[i]; >+ } >+ } >+ >+ } while (changed); >+ >+ // All of the locals should be dead at head of root. All of the arguments should be live at >+ // head of root. >+ for (size_t i = liveAtHead[0].numberOfLocals(); i--;) >+ DFG_ASSERT(m_graph, nullptr, !liveAtHead[0].local(i)); >+ for (size_t i = liveAtHead[0].numberOfArguments(); i--;) >+ DFG_ASSERT(m_graph, nullptr, liveAtHead[0].argument(i)); >+ >+ // Next identify where we would want to sink SetLocals to. We say that there is a deferred >+ // flush if we had a SetLocal with a given VariableAccessData* but it hasn't been >+ // materialized yet. >+ BlockMap<Operands<VariableAccessData*>> deferredAtHead(m_graph); >+ BlockMap<Operands<VariableAccessData*>> deferredAtTail(m_graph); >+ >+ for (BasicBlock* block : m_graph.blocksInNaturalOrder()) { >+ deferredAtHead[block] = >+ Operands<VariableAccessData*>(OperandsLike, block->variablesAtHead); >+ deferredAtTail[block] = >+ Operands<VariableAccessData*>(OperandsLike, block->variablesAtHead); >+ >+ deferredAtHead[block].fill(nullptr); >+ deferredAtTail[block].fill(nullptr); >+ } >+ >+ bool changed; >+ do { >+ changed = false; >+ >+ for (BasicBlock* block : m_graph.blocksInNaturalOrder()) { >+ Operands<VariableAccessData*> deferred = deferredAtHead[block]; >+ >+ for (Node* node : *block) { >+ preciseLocalClobberize( >+ m_graph, node, >+ [&] (VirtualRegister operand) { >+ // We will materialize just before any reads. >+ deferred.operand(operand) = nullptr; >+ }, >+ [&] (VirtualRegister operand) { >+ // We will materialize just before any writes. >+ deferred.operand(operand) = nullptr; >+ }, >+ [&] (VirtualRegister operand, Node* source) { >+ if (source == node) { >+ // This is a load. Ignore it. >+ return; >+ } >+ >+ deferred.operand(operand) = node->variableAccessData(); >+ }); >+ } >+ >+ if (deferred == deferredAtTail[block]) >+ continue; >+ >+ deferredAtTail[block] = deferred; >+ changed = true; >+ >+ for (BasicBlock* successor : block->successors()) { >+ for (size_t i = deferred.size(); i--;) { >+ if (!liveAtHead[successor][i]) >+ continue; >+ >+ if (!deferred[i]) >+ continue; >+ >+ if (!deferredAtHead[block][i]) { >+ deferredAtHead[block][i] = deferred[i]; >+ continue; >+ } >+ >+ if (deferredAtHead[block][i] == deferred[i]) >+ continue; >+ >+ DFG_CRASH(m_graph, nullptr, "Conflicting VariableAccessData* merge"); >+ } >+ } >+ } >+ >+ } while (changed); >+ >+ // We wish to insert SetLocals at all of the materialization points, which are defined >+ // implicitly as the places where we set materialized to true even though it was previously >+ // false. To do this, we may need to build some Phi functions to handle stuff like this: >+ // >+ // Before: >+ // >+ // if (p) >+ // SetLocal(r42, @x) >+ // else >+ // SetLocal(r42, @y) >+ // >+ // After: >+ // >+ // if (p) >+ // Upsilon(@x, ^z) >+ // else >+ // Upsilon(@y, ^z) >+ // z: Phi() >+ // SetLocal(r42, @z) >+ // >+ // This means that we have an SSACalculator::Variable for each local, and a Def is any >+ // SetLocal in the original program. The original SetLocals will simply vanish. >+ >+ Operands<SSACalculator::Variable*> operandToVariable; >+ Vector<VirtualRegister> indexToOperand; >+ for (size_t i = m_graph.block(0)->variablesAtHead.size(); i--;) { >+ VirtualRegister operand(m_graph.block(0)->variablesAtHead.operandForIndex(i)); >+ >+ SSACalculator::Variable* variable = m_ssaCalculator.newVariable(); >+ operandToVariable.operand(operand) = variable; >+ ASSERT(indexToOperand.size() == variable->index()); >+ indexToOperand.append(operand); >+ } >+ >+ Vector<Node*> setLocalsToSink; >+ >+ for (BasicBlock* block : m_graph.blocksInNaturalOrder()) { >+ for (Node* node : *block) { >+ if (node->op() != SetLocal) >+ continue; >+ >+ setLocalsToSink.append(node); >+ m_ssaCalculator.newDef( >+ operandToVariable.operand(node->local()), block, node->child1().node()); >+ } >+ } >+ >+ m_ssaCalculator.computePhis( >+ [&] (SSACalculator::Variable* variable, BasicBlock* blcok) -> Node* { >+ VirtualRegister operand = indexToOperad[variable->index()]; >+ >+ if (!liveAtHead[block].operand(operand)) >+ return nullptr; >+ >+ Node* phiNode = m_graph.addNode(SpecTop, Phi, NodeOrigin()); >+ FlushFormat format = deferredAtHead[block].operand(operand)->flushFormat(); >+ DFG_ASSERT(m_graph, nullptr, format != DeadFlush && format != ConflictingFlush); >+ phiNode->mergeFlags(resultFor(format)); >+ return phiNode; >+ }); >+ >+ m_mapping = Operands<Node*>(OperandsLike, m_graph.block(0)->variablesAtHead); >+ for (BasicBlock* block : m_graph.blocksInNaturalOrder()) { >+ m_mapping.fill(nullptr); >+ >+ for (size_t i = m_mapping.size(); i--;) { >+ VirtualRegister operand(m_mapping.operandForIndex(i)); >+ >+ SSACalculator::Variable* variable = operandToVariable.operand(operand); >+ SSACalculator::Def* def = m_ssaCalculator.reachingDefAtHead(block, variable); >+ if (!def) >+ continue; >+ >+ m_mapping.operand(operand) = def->value(); >+ } >+ >+ for (SSACalculator::Def* phiDef : m_ssaCalculator.phisForBlock(block)) { >+ VirtualRegister operand = indexToOperand[phiDef->variable()->index()]; >+ >+ m_insertionSet.insert(0, phiDef->value()); >+ m_insertionSet.insertNode( >+ 0, SpecNone, MovHint, NodeOrigin(), OpInfo(operand.offset()), >+ phiDef->value()->defaultEdge()); >+ >+ m_mapping.operand(operand) = phiDef->value(); >+ } >+ >+ m_deferred = deferredAtHead[block]; >+ for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) { >+ Node* node = block->at(nodeIndex); >+ >+ preciseLocalClobberize( >+ m_graph, node, >+ [&] (VirtualRegister operand) { >+ // We will materialize just before any reads. >+ materialize(nodeIndex, node, operand); >+ }, >+ [&] (VirtualRegister operand) { >+ // We will materialize just before any writes. >+ materialize(nodeIndex, node, operand); >+ }, >+ [&] (VirtualRegister operand, Node* source) { >+ if (source == node) { >+ // This is a load. Ignore it. >+ return; >+ } >+ >+ m_deferred.operand(operand) = node->variableAccessData(); >+ }); >+ } >+ >+ size_t upsilonInsertionPoint = block->size() - 1; >+ NodeOrigin upsilonOrigin = block->last()->origin; >+ for (BasicBlock* successorBlock : block->successors()) { >+ for (SSACalculator::Def* phiDef : m_ssaCalculator.phisForBlock(successorBlock)) { >+ Node* phiNode = phiDef->value(); >+ SSACalculator::Variable* variable = phiDef->variable(); >+ VirtualRegister operand = indexToOperand[variable->index()]; >+ Node* incoming = m_mapping.operand(operand); >+ >+ Node* upsilon = m_insertionSet.insertNode( >+ upsilonInsertionPoint, SpecNone, Upsilon, upsilonOrigin, >+ OpInfo(phiNode), incoming->defaultEdge()); >+ } >+ } >+ >+ m_insertionSet.execute(block); >+ } >+ >+ // Finally eliminate the sunken SetLocals by turning them into Phantoms. This keeps whatever >+ // type check they were doing. >+ for (Node* node : setLocalsToSink) >+ node->convertToPhantom(); >+ >+ return true; >+ } >+ >+private: >+ void materialize(unsigned nodeIndex, Node* node, VirtualRegister operand) >+ { >+ if (!m_deferred.operand(operand)) >+ return; >+ >+ // Gotta insert a SetLocal. >+ VariableAccessData* variableAccessData = m_deferred.operand(operand); >+ m_insertionSet.insertNode( >+ nodeIndex, SpecNone, SetLocal, node->origin, OpInfo(variableAccessData), >+ Edge(m_mapping.operand(operand), useKindFor(variableAccessData->flushFormat()))); >+ >+ m_deferred.operand(operand) = nullptr; >+ } >+ >+ Operands<Node*> m_mapping; >+ Operands<VariableAccessData*> m_deferred; >+ SSACalculator m_ssaCalculator; >+ InsertionSet m_insertionSet; >+}; >+ >+bool performSetLocalSinking(Graph& graph) >+{ >+ SamplingRegion samplingRegion("DFG SetLocal Sinking Phase"); >+ return runPhase<SetLocalSinkingPhase>(graph); >+} >+ >+} } // namespace JSC::DFG >+ >+#endif // ENABLE(DFG_JIT) >+ >Index: Source/JavaScriptCore/dfg/DFGSetLocalSinkingPhase.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGSetLocalSinkingPhase.h (revision 0) >+++ Source/JavaScriptCore/dfg/DFGSetLocalSinkingPhase.h (working copy) >@@ -0,0 +1,46 @@ >+ /* >+ * Copyright (C) 2014 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 DFGSetLocalSinkingPhase_h >+#define DFGSetLocalSinkingPhase_h >+ >+#if ENABLE(DFG_JIT) >+ >+namespace JSC { namespace DFG { >+ >+class Graph; >+ >+// Sinks SetLocals to the absolute latest point where they can possibly happen, which is usually >+// side-effects that may observe them. This eliminates SetLocals if it sinks them past the point of >+// their deaths. >+ >+bool performSetLocalSinking(Graph&); >+ >+} } // namespace JSC::DFG >+ >+#endif // ENABLE(DFG_JIT) >+ >+#endif // DFGSetLocalSinkingPhase_h >+ >Index: Source/JavaScriptCore/runtime/Options.h >=================================================================== >--- Source/JavaScriptCore/runtime/Options.h (revision 174031) >+++ Source/JavaScriptCore/runtime/Options.h (working copy) >@@ -176,6 +176,7 @@ typedef const char* optionString; > v(bool, enableCallEdgeProfiling, true) \ > v(unsigned, frequentCallThreshold, 2) \ > v(bool, optimizeNativeCalls, false) \ >+ v(bool, enableObjectAllocationSinking, true) \ > \ > v(bool, enableConcurrentJIT, true) \ > v(unsigned, numberOfDFGCompilerThreads, computeNumberOfWorkerThreads(2, 2) - 1) \ >Index: Source/WTF/ChangeLog >=================================================================== >--- Source/WTF/ChangeLog (revision 174045) >+++ Source/WTF/ChangeLog (working copy) >@@ -1,3 +1,23 @@ >+2014-09-28 Filip Pizlo <fpizlo@apple.com> >+ >+ FTL should sink SetLocals >+ https://bugs.webkit.org/show_bug.cgi?id=137168 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Make the set bits of a BitVector iterable. >+ >+ * wtf/BitVector.h: >+ (WTF::BitVector::SetBitsIterable::SetBitsIterable): >+ (WTF::BitVector::SetBitsIterable::iterator::iterator): >+ (WTF::BitVector::SetBitsIterable::iterator::operator*): >+ (WTF::BitVector::SetBitsIterable::iterator::operator++): >+ (WTF::BitVector::SetBitsIterable::iterator::operator==): >+ (WTF::BitVector::SetBitsIterable::iterator::operator!=): >+ (WTF::BitVector::SetBitsIterable::begin): >+ (WTF::BitVector::SetBitsIterable::end): >+ (WTF::BitVector::setBits): >+ > 2014-09-26 Sam Weinig <sam@webkit.org> > > Replace OSObjectPtr with RetainPtr/adoptOS >Index: Source/WTF/wtf/BitVector.h >=================================================================== >--- Source/WTF/wtf/BitVector.h (revision 174031) >+++ Source/WTF/wtf/BitVector.h (working copy) >@@ -269,6 +269,58 @@ public: > return IntHash<uintptr_t>::hash(value); > } > >+ class SetBitsIterable { >+ public: >+ SetBitsIterable(const BitVector& bitVector) >+ : m_bitVector(bitVector) >+ { >+ } >+ >+ class iterator { >+ public: >+ iterator() >+ : m_bitVector(nullptr) >+ , m_index(0) >+ { >+ } >+ >+ iterator(const BitVector& bitVector, size_t index) >+ : m_bitVector(&bitVector) >+ , m_index(index) >+ { >+ } >+ >+ size_t operator*() const { return m_index; } >+ >+ iterator& operator++() >+ { >+ m_index = m_bitVector->findBit(m_index + 1, true); >+ return *this; >+ } >+ >+ bool operator==(const iterator& other) const >+ { >+ return m_index == other.m_index; >+ } >+ >+ bool operator!=(const iterator& other) const >+ { >+ return !(*this == other); >+ } >+ private: >+ const BitVector* m_bitVector; >+ size_t m_index; >+ }; >+ >+ iterator begin() const { return iterator(m_bitVector, 0); } >+ iterator end() const { return iterator(m_bitVector, m_bitVector.size()); } >+ >+ private: >+ const BitVector& m_bitVector; >+ }; >+ >+ SetBitsIterable setBits() const { return SetBitsIterable(*this); } >+ > private: > static unsigned bitsInPointer() > {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 137168
:
238816
|
238823
|
238826
|
238829
|
238903
|
238928
|
238983
|
238991
|
239169