WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
work in progress
blah.patch (text/plain), 26.45 KB, created by
Filip Pizlo
on 2013-06-27 21:30:49 PDT
(
hide
)
Description:
work in progress
Filename:
MIME Type:
Creator:
Filip Pizlo
Created:
2013-06-27 21:30:49 PDT
Size:
26.45 KB
patch
obsolete
>Index: Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >=================================================================== >--- Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (revision 152151) >+++ Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (working copy) >@@ -170,13 +170,13 @@ > 0F46E6B9176F89DB00E1F755 /* FTLSwitchCase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F46E6B7176F89D900E1F755 /* FTLSwitchCase.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F46E6C5176F8A5E00E1F755 /* DFGLazyJSValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F46E6C2176F8A5B00E1F755 /* DFGLazyJSValue.cpp */; }; > 0F46E6C6176F8A6000E1F755 /* DFGLazyJSValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F46E6C3176F8A5B00E1F755 /* DFGLazyJSValue.h */; settings = {ATTRIBUTES = (Private, ); }; }; >- 0F46E6EF177CE95A00E1F755 /* DFGAnalysis.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F46E6EE177CE95A00E1F755 /* DFGAnalysis.h */; }; >- 0F46E6F3177CF0D200E1F755 /* DFGNaturalLoops.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F46E6F1177CF0D200E1F755 /* DFGNaturalLoops.cpp */; }; >- 0F46E6F4177CF0D200E1F755 /* DFGNaturalLoops.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F46E6F2177CF0D200E1F755 /* DFGNaturalLoops.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F46E6D9177CB90000E1F755 /* LLVMDisassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F46E6D7177CB8FC00E1F755 /* LLVMDisassembler.cpp */; }; > 0F46E6E3177CC36600E1F755 /* LLVMDisassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F46E6E0177CC36600E1F755 /* LLVMDisassembler.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F46E6E4177CC36600E1F755 /* UDis86Disassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F46E6E1177CC36600E1F755 /* UDis86Disassembler.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F46E6E5177CC36600E1F755 /* X86Disassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F46E6E2177CC36600E1F755 /* X86Disassembler.cpp */; }; >+ 0F46E6EF177CE95A00E1F755 /* DFGAnalysis.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F46E6EE177CE95A00E1F755 /* DFGAnalysis.h */; }; >+ 0F46E6F3177CF0D200E1F755 /* DFGNaturalLoops.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F46E6F1177CF0D200E1F755 /* DFGNaturalLoops.cpp */; }; >+ 0F46E6F4177CF0D200E1F755 /* DFGNaturalLoops.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F46E6F2177CF0D200E1F755 /* DFGNaturalLoops.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F493AFA16D0CAD30084508B /* SourceProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F493AF816D0CAD10084508B /* SourceProvider.cpp */; }; > 0F4E1A0E173AEDDC007EE2D3 /* IntendedStructureChain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4E1A0C173AEDDC007EE2D3 /* IntendedStructureChain.cpp */; }; > 0F4E1A0F173AEDDC007EE2D3 /* IntendedStructureChain.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4E1A0D173AEDDC007EE2D3 /* IntendedStructureChain.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -353,6 +353,8 @@ > 0FDDBFB61666EEDA00C55FEF /* DFGVariableAccessDataDump.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDDBFB31666EED500C55FEF /* DFGVariableAccessDataDump.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0FE228ED1436AB2700196C48 /* Options.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE228EB1436AB2300196C48 /* Options.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0FE228EE1436AB2C00196C48 /* Options.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE228EA1436AB2300196C48 /* Options.cpp */; }; >+ 0FE42428177D40B6005E8CF2 /* DFGLoopPeelingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE42426177D40B6005E8CF2 /* DFGLoopPeelingPhase.cpp */; }; >+ 0FE42429177D40B6005E8CF2 /* DFGLoopPeelingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE42427177D40B6005E8CF2 /* DFGLoopPeelingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0FE8534B1723CDA500B618F5 /* DFGDesiredWatchpoints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE853491723CDA500B618F5 /* DFGDesiredWatchpoints.cpp */; }; > 0FE8534C1723CDA500B618F5 /* DFGDesiredWatchpoints.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE8534A1723CDA500B618F5 /* DFGDesiredWatchpoints.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0FEA0A08170513DB00BB722C /* FTLAbbreviations.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEA09FD170513DB00BB722C /* FTLAbbreviations.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -1186,13 +1188,13 @@ > 0F46E6B7176F89D900E1F755 /* FTLSwitchCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLSwitchCase.h; path = ftl/FTLSwitchCase.h; sourceTree = "<group>"; }; > 0F46E6C2176F8A5B00E1F755 /* DFGLazyJSValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGLazyJSValue.cpp; path = dfg/DFGLazyJSValue.cpp; sourceTree = "<group>"; }; > 0F46E6C3176F8A5B00E1F755 /* DFGLazyJSValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGLazyJSValue.h; path = dfg/DFGLazyJSValue.h; sourceTree = "<group>"; }; >- 0F46E6EE177CE95A00E1F755 /* DFGAnalysis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAnalysis.h; path = dfg/DFGAnalysis.h; sourceTree = "<group>"; }; >- 0F46E6F1177CF0D200E1F755 /* DFGNaturalLoops.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGNaturalLoops.cpp; path = dfg/DFGNaturalLoops.cpp; sourceTree = "<group>"; }; >- 0F46E6F2177CF0D200E1F755 /* DFGNaturalLoops.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGNaturalLoops.h; path = dfg/DFGNaturalLoops.h; sourceTree = "<group>"; }; > 0F46E6D7177CB8FC00E1F755 /* LLVMDisassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLVMDisassembler.cpp; path = disassembler/LLVMDisassembler.cpp; sourceTree = "<group>"; }; > 0F46E6E0177CC36600E1F755 /* LLVMDisassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLVMDisassembler.h; path = disassembler/LLVMDisassembler.h; sourceTree = "<group>"; }; > 0F46E6E1177CC36600E1F755 /* UDis86Disassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UDis86Disassembler.h; path = disassembler/UDis86Disassembler.h; sourceTree = "<group>"; }; > 0F46E6E2177CC36600E1F755 /* X86Disassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = X86Disassembler.cpp; path = disassembler/X86Disassembler.cpp; sourceTree = "<group>"; }; >+ 0F46E6EE177CE95A00E1F755 /* DFGAnalysis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAnalysis.h; path = dfg/DFGAnalysis.h; sourceTree = "<group>"; }; >+ 0F46E6F1177CF0D200E1F755 /* DFGNaturalLoops.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGNaturalLoops.cpp; path = dfg/DFGNaturalLoops.cpp; sourceTree = "<group>"; }; >+ 0F46E6F2177CF0D200E1F755 /* DFGNaturalLoops.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGNaturalLoops.h; path = dfg/DFGNaturalLoops.h; sourceTree = "<group>"; }; > 0F493AF816D0CAD10084508B /* SourceProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SourceProvider.cpp; sourceTree = "<group>"; }; > 0F4E1A0C173AEDDC007EE2D3 /* IntendedStructureChain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntendedStructureChain.cpp; sourceTree = "<group>"; }; > 0F4E1A0D173AEDDC007EE2D3 /* IntendedStructureChain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntendedStructureChain.h; sourceTree = "<group>"; }; >@@ -1384,6 +1386,8 @@ > 0FDDBFB31666EED500C55FEF /* DFGVariableAccessDataDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGVariableAccessDataDump.h; path = dfg/DFGVariableAccessDataDump.h; sourceTree = "<group>"; }; > 0FE228EA1436AB2300196C48 /* Options.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Options.cpp; sourceTree = "<group>"; }; > 0FE228EB1436AB2300196C48 /* Options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Options.h; sourceTree = "<group>"; }; >+ 0FE42426177D40B6005E8CF2 /* DFGLoopPeelingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGLoopPeelingPhase.cpp; path = dfg/DFGLoopPeelingPhase.cpp; sourceTree = "<group>"; }; >+ 0FE42427177D40B6005E8CF2 /* DFGLoopPeelingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGLoopPeelingPhase.h; path = dfg/DFGLoopPeelingPhase.h; sourceTree = "<group>"; }; > 0FE853491723CDA500B618F5 /* DFGDesiredWatchpoints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDesiredWatchpoints.cpp; path = dfg/DFGDesiredWatchpoints.cpp; sourceTree = "<group>"; }; > 0FE8534A1723CDA500B618F5 /* DFGDesiredWatchpoints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDesiredWatchpoints.h; path = dfg/DFGDesiredWatchpoints.h; sourceTree = "<group>"; }; > 0FEA09FD170513DB00BB722C /* FTLAbbreviations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLAbbreviations.h; path = ftl/FTLAbbreviations.h; sourceTree = "<group>"; }; >@@ -3027,6 +3031,8 @@ > 0F46E6C3176F8A5B00E1F755 /* DFGLazyJSValue.h */, > 0FB4B51C16B62772003F696B /* DFGLongLivedState.cpp */, > 0FB4B51D16B62772003F696B /* DFGLongLivedState.h */, >+ 0FE42426177D40B6005E8CF2 /* DFGLoopPeelingPhase.cpp */, >+ 0FE42427177D40B6005E8CF2 /* DFGLoopPeelingPhase.h */, > 0F2BDC3D1522801700CD8910 /* DFGMinifiedGraph.h */, > 0FB4B51016B3A964003F696B /* DFGMinifiedID.h */, > 0F2BDC4C1522818300CD8910 /* DFGMinifiedNode.cpp */, >@@ -3831,6 +3837,7 @@ > 0F46E6F4177CF0D200E1F755 /* DFGNaturalLoops.h in Headers */, > 0F46E6E3177CC36600E1F755 /* LLVMDisassembler.h in Headers */, > 0F46E6E4177CC36600E1F755 /* UDis86Disassembler.h in Headers */, >+ 0FE42429177D40B6005E8CF2 /* DFGLoopPeelingPhase.h in Headers */, > ); > runOnlyForDeploymentPostprocessing = 0; > }; >@@ -4525,6 +4532,7 @@ > 0F46E6F3177CF0D200E1F755 /* DFGNaturalLoops.cpp in Sources */, > 0F46E6D9177CB90000E1F755 /* LLVMDisassembler.cpp in Sources */, > 0F46E6E5177CC36600E1F755 /* X86Disassembler.cpp in Sources */, >+ 0FE42428177D40B6005E8CF2 /* DFGLoopPeelingPhase.cpp in Sources */, > ); > runOnlyForDeploymentPostprocessing = 0; > }; >Index: Source/JavaScriptCore/dfg/DFGBasicBlock.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGBasicBlock.h (revision 152151) >+++ Source/JavaScriptCore/dfg/DFGBasicBlock.h (working copy) >@@ -55,6 +55,7 @@ struct BasicBlock : Vector<Node*, 8> { > , isLinked(false) > #endif > , isReachable(false) >+ , didPeel(false) > , variablesAtHead(numArguments, numLocals) > , variablesAtTail(numArguments, numLocals) > , valuesAtHead(numArguments, numLocals) >@@ -120,6 +121,7 @@ struct BasicBlock : Vector<Node*, 8> { > bool isLinked; > #endif > bool isReachable; >+ bool didPeel; > > Vector<Node*> phis; > PredecessorList m_predecessors; >Index: Source/JavaScriptCore/dfg/DFGGraph.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGGraph.cpp (revision 152151) >+++ Source/JavaScriptCore/dfg/DFGGraph.cpp (working copy) >@@ -484,7 +484,189 @@ void Graph::substituteGetLocal(BasicBloc > break; > } > } >+ >+bool Graph::canBeDuplicated(Node* node) >+{ >+ // Explicitly list the things that can be duplicated since we could get it >+ // wrong for some nodes. If you add a new node, you have to decide if it's >+ // safe to duplicate it. >+ >+ switch (result->op()) { >+ case JSConstant: >+ case WeakJSConstant: >+ case Identity: >+ case ToThis: >+ case CreateThis: >+ case GetCallee: >+ case SetCallee: >+ case GetLocal: >+ case SetLocal: >+ case MovHintAndCheck: >+ case MovHint: >+ case ZombieHint: >+ case Phantom: >+ case Nop: >+ case Phi: >+ case Flush: >+ case PhantomLocal: >+ case GetLocalUnlinked: >+ case SetArgument: >+ case BitAnd: >+ case BitOr: >+ case BitXor: >+ case BitLShift: >+ case BitRShift: >+ case BitURShift: >+ case ValueToInt32: >+ case UInt32ToNumber: >+ case Int32ToDouble: >+ case ForwardInt32ToDouble: >+ case DoubleAsInt32: >+ case ArithAdd: >+ case ArithSub: >+ case ArithNegate: >+ case ArithMul: >+ case ArithDiv: >+ case ArithMod: >+ case ArithAbs: >+ case ArithMin: >+ case ArithMax: >+ case ArithSqrt: >+ case ValueAdd: >+ case GetByVal: >+ case PutByVal: >+ case PutByValAlias: >+ case GetById: >+ case GetByIdFlush: >+ case PutById: >+ case PutByIdDirect: >+ case CheckStructure: >+ case CheckExecutable: >+ case ForwardCheckStructure: >+ case StructureTransitionWatchpoint: >+ case ForwardStructureTransitionWatchpoint: >+ case PutStructure: >+ case PhantomPutStructure: >+ case AllocatePropertyStorage: >+ case ReallocatePropertyStorage: >+ case GetButterfly: >+ case CheckArray: >+ case ForwardCheckArray: >+ case Arrayify: >+ case ArrayifyToStructure: >+ case GetIndexedPropertyStorage: >+ case GetByOffset: >+ case PutByOffset: >+ case GetArrayLength: >+ case GetScope: >+ case GetMyScope: >+ case SetMyScope: >+ case SkipTopScope: >+ case SkipScope: >+ case GetClosureRegisters: >+ case GetClosureVar: >+ case PutClosureVar: >+ case GetGlobalVar: >+ case PutGlobalVar: >+ case GlobalVarWatchpoint: >+ case VarInjectionWatchpoint: >+ case CheckFunction: >+ case AllocationProfileWatchpoint: >+ case ArrayPush: >+ case ArrayPop: >+ case RegExpExec: >+ case RefExpTest: >+ case StringCharCodeAt: >+ case StringCharAt: >+ case CompareLess: >+ case CompareLessEq: >+ case CompareGreater: >+ case CompareGreaterEq: >+ case CompareEq: >+ case CompareEqConstant: >+ case CompareStrictEq: >+ case CompareStrictEqConstant: >+ case Call: >+ case Construct: >+ case NewObject: >+ case NewArray: >+ case NewArrayWithSize: >+ case NewArrayBuffer: >+ case NewRegexp: >+ case CheckHasInstance: >+ case InstanceOf: >+ case IsUndefined: >+ case IsBoolean: >+ case IsNumber: >+ case IsString: >+ case IsObject: >+ case IsFunction: >+ case TypeOf: >+ case LogicalNot: >+ case ToPrimitive: >+ case ToString: >+ case NewStringObject: >+ case MakeRope: >+ case In: >+ case CreateActivation: >+ case TearOffActivation: >+ case CreateArguments: >+ case PhantomArguments: >+ case TearOffArguments: >+ case GetMyArgumentsLength: >+ case GetMyArgumentByVal: >+ case GetMyArgumentsLengthSafe: >+ case GetMyArgumentByValSafe: >+ case CheckArgumentsNotCreated: >+ case NewFunctionNoCheck: >+ case NewFunction: >+ case NewFunctionExpression: >+ case Jump: >+ case Branch: >+ case Return: >+ case Throw: >+ case ThrowReferenceError: >+ case CountExecution: >+ case ForceOSRExit: >+ case ForwardForceOSRExit: >+ case CheckWatchdogTimer: >+ return true; >+ >+ case InlineStart: >+ // Everywhere that we inline into requires some meta-data. It's not clear >+ // that duplicating inlined code so that it's inlined from two different >+ // places is sound in the current IR. Particularly since compiling >+ // InlineStart edits an InlineCallFrame - so duplicating would mean that >+ // the same InlineCallFrame would be edited twice. Seems borked. >+ return false; >+ >+ case Switch: >+ // We would have to duplicate the SwitchData and the JumpTable. We can do >+ // it, but it doesn't work yet. >+ return false; >+ >+ case Breakpoint: >+ // I don't even want to think about what duplicating a Breakpoint means. >+ return false; >+ } >+ >+ RELEASE_ASSERT_NOT_REACHED(); >+ return false; >+} >+ >+Node* Graph::duplicateNode(Node* node) >+{ >+ Node* result = addNode(node->prediction(), *node); >+ >+ if (result->flags() & NodeHasVarArgs) { >+ result->children.setFirstChild(m_varArgChildren.size()); >+ for (unsigned i = 0; i < node->children.numChildren(); ++i) >+ m_varArgChildren.append(m_varArgChildren[node->children.firstChild() + i]); >+ } > >+ return result; >+} >+ > } } // namespace JSC::DFG > > #endif >Index: Source/JavaScriptCore/dfg/DFGGraph.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGGraph.h (revision 152151) >+++ Source/JavaScriptCore/dfg/DFGGraph.h (working copy) >@@ -644,6 +644,9 @@ public: > // introduced anywhere in the basic block. > void substituteGetLocal(BasicBlock& block, unsigned startIndexInBlock, VariableAccessData* variableAccessData, Node* newGetLocal); > >+ bool canBeDuplicated(Node*); >+ Node* duplicateNode(Node*); >+ > void invalidateCFG(); > > Profiler::Compilation* compilation() { return m_plan.compilation.get(); } >Index: Source/JavaScriptCore/dfg/DFGLoopPeelingPhase.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGLoopPeelingPhase.cpp (revision 0) >+++ Source/JavaScriptCore/dfg/DFGLoopPeelingPhase.cpp (revision 0) >@@ -0,0 +1,166 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "DFGLoopPeelingPhase.h" >+ >+#if ENABLE(DFG_JIT) >+ >+namespace JSC { namespace DFG { >+ >+class LoopPeelingPhase : public Phase { >+public: >+ LoopPeelingPhase(Graph& graph) >+ : Phase("loop peeling") >+ { >+ } >+ >+ bool run() >+ { >+ // First figure out if there are natural loops anywhere in the program. >+ // If not, give up early. If there are, set a bit for each block that >+ // belongs to any loop, since we'll have to do additional computation >+ // for those blocks. >+ >+ m_graph.m_naturalLoops.computeIfNecessary(m_graph); >+ if (!m_graph.m_naturalLoops.numLoops()) >+ return false; >+ >+ FastBitVector blocksThatMayBeDuplicated; >+ FastBitVector loopHeaders; >+ blocksThatMayBeDuplicated.resize(m_graph.m_blocks.size()); >+ loopHeaders.resize(m_graph.m_blocks.size()); >+ >+ for (unsigned i = m_graph.m_naturalLoops.numLoops(); i--;) { >+ const NaturalLoop& loop = m_graph.m_naturalLoops.loop(i); >+ loopHeaders.set(loop.header()); >+ for (unsigned j = loop.size(); j--;) >+ blocksThatMayBeDuplicated.set(loop[j]); >+ } >+ >+ FastBitVector outerLoops; >+ outerLoops.resize(m_graph.m_blocks.size()); >+ for (unsigned i = m_graph.m_naturalLoops.numLoops(); i--;) { >+ const NaturalLoop& loop = m_graph.m_naturalLoops.loop(i); >+ for (unsigned j = loop.size(); j--;) { >+ if (loop[j] == loop.header()) >+ continue; >+ if (!loopHeaders.get(loop[j])) >+ continue; >+ outerLoops.set(loop.header()); >+ break; >+ } >+ } >+ >+ Vector<double> loopCost; >+ loopCost.fill(0, m_graph.m_blocks.size()); >+ for (BlockIndex blockIndex = m_graph.m_blocks.size(); blockIndex--;) { >+ if (!blocksThatMayBeDuplicated.get(blockIndex)) >+ continue; >+ BasicBlock* block = m_graph.m_blocks[blockIndex].get(); >+ double cost = 0; >+ for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) { >+ Node* node = block->at(nodeIndex); >+ switch (node->op()) { >+ case Phantom: >+ case MovHint: >+ case MovHintAndCheck: >+ case ZombieHint: >+ case PhantomLocal: >+ break; >+ >+ case ForceOSRExit: >+ case ForwardForceOSRExit: >+ nodeIndex = block->size(); >+ break; >+ >+ default: >+ cost++; >+ } >+ } >+ loopCost[blockIndex] = cost; >+ } >+ >+ // Figure out which loops we want to peel. Don't attempt to peel loops >+ // that overlap. Select which get peeled using greedy selection. Don't >+ // peel loops that have already been peeled. Don't peel outer loops at >+ // all. >+ >+ FastBitVector blocksThatWillBeDuplicated; >+ blocksThatWillBeDuplicated.resize(m_graph.m_blocks.size()); >+ Vector<const NaturalLoop*> loopsToPeel; >+ for (unsigned i = m_graph.m_naturalLoops.numLoops(); i--;) { >+ const NaturalLoop& loop = m_graph.m_naturalLoops.loop(i); >+ >+ // Don't peel outer loops. >+ if (outerLoops.get(loop.header())) >+ continue; >+ >+ BasicBlock* headerBlock = m_graph.m_blocks[loop.header()].get(); >+ >+ // Don't peel loops that have already been peeled. >+ if (headerBlock->didPeel) >+ continue; >+ >+ double cost = 0; >+ bool overlapsOtherPeel = false; >+ for (unsigned j = loop.size(); j--;) { >+ if (blocksThatWillBeDuplicated.get(loop[j])) { >+ overlapsOtherPeel = true; >+ break; >+ } >+ cost += loopCost[loop[j]]; >+ } >+ >+ // Don't peel loops that overlap other loops that we're already >+ // peeling >+ if (overlapsOtherPeel) >+ continue; >+ >+ // Only peel small loops. >+ if (cost > Options::maximumLoopPeelCost()) >+ continue; >+ >+ loopsToPeel.append(&loop); >+ for (unsigned j = loop.size(); j--;) >+ blocksThatWillBeDuplicated.set(loop[j]); >+ } >+ >+ // Finally, create the peels. >+ // FIXME >+ >+ return false; >+ } >+}; >+ >+bool performLoopPeeling(Graph& graph) >+{ >+ SamplingRegion samplingRegion("DFG Loop Peeling Phase"); >+ return runPhase<LoopPeelingPhase>(graph); >+} >+ >+} } // namespace JSC::DFG >+ >+#endif // ENABLE(DFG_JIT) >Index: Source/JavaScriptCore/dfg/DFGLoopPeelingPhase.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGLoopPeelingPhase.h (revision 0) >+++ Source/JavaScriptCore/dfg/DFGLoopPeelingPhase.h (revision 0) >@@ -0,0 +1,49 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef DFGLoopPeelingPhase_h >+#define DFGLoopPeelingPhase_h >+ >+#include <wtf/Platform.h> >+ >+#if ENABLE(DFG_JIT) >+ >+namespace JSC { namespace DFG { >+ >+class Graph; >+ >+// Loop peeling for small natural loops. This can be called in a fixpoint >+// because it will never peel a loop twice (see BasicBlock::didPeel), it >+// only peels small loops, and it properly dethreads the graph and so >+// forth. It doesn't require the graph to be threaded to begin with. >+ >+bool performLoopPeeling(Graph&); >+ >+} } // namespace JSC::DFG >+ >+#endif // ENABLE(DFG_JIT) >+ >+#endif // DFGLoopPeelingPhase_cpp >+ >Index: Source/JavaScriptCore/runtime/Options.h >=================================================================== >--- Source/JavaScriptCore/runtime/Options.h (revision 152151) >+++ Source/JavaScriptCore/runtime/Options.h (working copy) >@@ -109,9 +109,9 @@ namespace JSC { > \ > /* Depth of inline stack, so 1 = no inlining, 2 = one level, etc. */ \ > v(unsigned, maximumInliningDepth, 5) \ >- \ > v(unsigned, maximumBinaryStringSwitchCaseLength, 50) \ > v(unsigned, maximumBinaryStringSwitchTotalLength, 2000) \ >+ v(double, maximumLoopPeelCost, 50) \ > \ > v(int32, thresholdForJITAfterWarmUp, 100) \ > v(int32, thresholdForJITSoon, 100) \
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 118151
:
205658
|
205660
|
205718