WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
the patch
blah.patch (text/plain), 48.07 KB, created by
Filip Pizlo
on 2013-09-30 11:48:50 PDT
(
hide
)
Description:
the patch
Filename:
MIME Type:
Creator:
Filip Pizlo
Created:
2013-09-30 11:48:50 PDT
Size:
48.07 KB
patch
obsolete
>Index: Source/JavaScriptCore/ChangeLog >=================================================================== >--- Source/JavaScriptCore/ChangeLog (revision 156667) >+++ Source/JavaScriptCore/ChangeLog (working copy) >@@ -1,3 +1,77 @@ >+2013-09-30 Filip Pizlo <fpizlo@apple.com> >+ >+ Get rid of the AlreadyInJSStack recoveries since they are totally redundant with the DisplacedInJSStack recoveries >+ https://bugs.webkit.org/show_bug.cgi?id=122065 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This mostly just kills a bunch of code. >+ >+ But incidentaly while killing that code, I uncovered a bug in our FTL OSR entrypoint >+ creation phase. The phase inserts a sequence of SetLocal(ExtractOSREntryLocal) nodes. >+ If we hoist some type check into the local, then we might inject a conversion node >+ between the ExtractOSREntryLocal and the SetLocal - for example we might put in a >+ Int32ToDouble node. But currently the FixupPhase will make all conversion nodes placed >+ on an edge of a SetLocal use forward exit. This then confuses the OSR exit machinery. >+ When OSR exit sees a forward exit, it tries to "roll forward" execution from the exiting >+ node to the first node that has a different CodeOrigin. This only works if the nodes >+ after the forward exit are MovHints or other tnings that the OSR exit compiler can >+ forward-execute. But here, it will see a bunch of SetLocal and ExtractOSREntryLocal >+ nodes for the same bytecode index. Two possible solutions exist. We could teach the >+ forward-execution logic how to deal with multiple SetLocals and ExtractOSREntryLocals. >+ This would be a lot of complexity; right now it just needs to deal with exactly one >+ SetLocal-like operation. The alternative is to make sure that the conversion node that >+ we inject ends up exiting *backward* rather than forward. >+ >+ But making the conversion nodes exit backward is somewhat tricky. Before this patch, >+ conversion nodes always exit forward for SetLocals and backwards otherwise. It turns out >+ that the solution is to rationalize how we choose the speculation direciton for a >+ conversion node. The conversion node's speculation direction should be the same as the >+ speculation direction of the node for which it is doing a conversion. Since SetLocal's >+ already exit forward by default, this policy preserves our previous behavior. But it >+ also allows the OSR entrypoint creation phase to make its SetLocals exit backward >+ instead. >+ >+ * CMakeLists.txt: >+ * GNUmakefile.list.am: >+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: >+ * JavaScriptCore.xcodeproj/project.pbxproj: >+ * Target.pri: >+ * bytecode/CodeOrigin.h: >+ * bytecode/ValueRecovery.cpp: Added. >+ (JSC::ValueRecovery::recover): >+ (JSC::ValueRecovery::dumpInContext): >+ (JSC::ValueRecovery::dump): >+ * bytecode/ValueRecovery.h: >+ * dfg/DFGFixupPhase.cpp: >+ (JSC::DFG::FixupPhase::fixupSetLocalsInBlock): >+ (JSC::DFG::FixupPhase::fixEdge): >+ * dfg/DFGJITCode.cpp: >+ (JSC::DFG::JITCode::reconstruct): >+ * dfg/DFGNode.h: >+ (JSC::DFG::Node::speculationDirection): >+ (JSC::DFG::Node::setSpeculationDirection): >+ * dfg/DFGOSREntrypointCreationPhase.cpp: >+ (JSC::DFG::OSREntrypointCreationPhase::run): >+ * dfg/DFGOSRExitCompiler32_64.cpp: >+ (JSC::DFG::OSRExitCompiler::compileExit): >+ * dfg/DFGOSRExitCompiler64.cpp: >+ (JSC::DFG::OSRExitCompiler::compileExit): >+ * dfg/DFGSpeculativeJIT.cpp: >+ (JSC::DFG::SpeculativeJIT::compileInlineStart): >+ (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): >+ * dfg/DFGSpeculativeJIT.h: >+ (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): >+ * dfg/DFGValueSource.h: >+ (JSC::DFG::ValueSource::valueRecovery): >+ * dfg/DFGVariableEventStream.cpp: >+ (JSC::DFG::VariableEventStream::reconstruct): >+ * interpreter/Register.h: >+ (JSC::Register::unboxedStrictInt52): >+ * runtime/Arguments.cpp: >+ (JSC::Arguments::tearOff): >+ * runtime/Arguments.h: >+ > 2013-09-30 Patrick Gansterer <paroga@webkit.org> > > Fix compilation for COMPILER(MSVC) && !CPU(X86) after r156490. >Index: Source/JavaScriptCore/CMakeLists.txt >=================================================================== >--- Source/JavaScriptCore/CMakeLists.txt (revision 156667) >+++ Source/JavaScriptCore/CMakeLists.txt (working copy) >@@ -72,6 +72,7 @@ set(JavaScriptCore_SOURCES > bytecode/StructureStubClearingWatchpoint.cpp > bytecode/StructureStubInfo.cpp > bytecode/UnlinkedCodeBlock.cpp >+ bytecode/ValueRecovery.cpp > bytecode/Watchpoint.cpp > > bytecompiler/BytecodeGenerator.cpp >Index: Source/JavaScriptCore/GNUmakefile.list.am >=================================================================== >--- Source/JavaScriptCore/GNUmakefile.list.am (revision 156667) >+++ Source/JavaScriptCore/GNUmakefile.list.am (working copy) >@@ -167,6 +167,7 @@ javascriptcore_sources += \ > Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp \ > Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h \ > Source/JavaScriptCore/bytecode/ValueProfile.h \ >+ Source/JavaScriptCore/bytecode/ValueRecovery.cpp \ > Source/JavaScriptCore/bytecode/ValueRecovery.h \ > Source/JavaScriptCore/bytecode/VirtualRegister.h \ > Source/JavaScriptCore/bytecode/Watchpoint.cpp \ >Index: Source/JavaScriptCore/Target.pri >=================================================================== >--- Source/JavaScriptCore/Target.pri (revision 156667) >+++ Source/JavaScriptCore/Target.pri (working copy) >@@ -80,6 +80,7 @@ SOURCES += \ > bytecode/StructureStubClearingWatchpoint.cpp \ > bytecode/StructureStubInfo.cpp \ > bytecode/UnlinkedCodeBlock.cpp \ >+ bytecode/ValueRecovery.cpp \ > bytecode/Watchpoint.cpp \ > bytecompiler/BytecodeGenerator.cpp \ > bytecompiler/NodesCodegen.cpp \ >Index: Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj >=================================================================== >--- Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (revision 156667) >+++ Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (working copy) >@@ -320,6 +320,7 @@ > <ClCompile Include="..\bytecode\StructureStubClearingWatchpoint.cpp" /> > <ClCompile Include="..\bytecode\StructureStubInfo.cpp" /> > <ClCompile Include="..\bytecode\UnlinkedCodeBlock.cpp" /> >+ <ClCompile Include="..\bytecode\ValueRecovery.cpp" /> > <ClCompile Include="..\bytecode\Watchpoint.cpp" /> > <ClCompile Include="..\bytecompiler\BytecodeGenerator.cpp" /> > <ClCompile Include="..\bytecompiler\NodesCodegen.cpp" /> >Index: Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >=================================================================== >--- Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (revision 156667) >+++ Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (working copy) >@@ -118,8 +118,6 @@ > 0F24E54217EA9F5900ABB217 /* CCallHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E53D17EA9F5900ABB217 /* CCallHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F24E54317EA9F5900ABB217 /* FPRInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E53E17EA9F5900ABB217 /* FPRInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F24E54417EA9F5900ABB217 /* GPRInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E53F17EA9F5900ABB217 /* GPRInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; >- 0F24E55517F0B71C00ABB217 /* InlineCallFrameSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F24E55317F0B71C00ABB217 /* InlineCallFrameSet.cpp */; }; >- 0F24E55617F0B71C00ABB217 /* InlineCallFrameSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E55417F0B71C00ABB217 /* InlineCallFrameSet.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F24E54C17EE274900ABB217 /* JITOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F24E54517EE274900ABB217 /* JITOperations.cpp */; }; > 0F24E54D17EE274900ABB217 /* JITOperations.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54617EE274900ABB217 /* JITOperations.h */; }; > 0F24E54E17EE274900ABB217 /* JITOperationWrappers.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54717EE274900ABB217 /* JITOperationWrappers.h */; }; >@@ -127,6 +125,9 @@ > 0F24E55017EE274900ABB217 /* Repatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F24E54917EE274900ABB217 /* Repatch.cpp */; }; > 0F24E55117EE274900ABB217 /* Repatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54A17EE274900ABB217 /* Repatch.h */; }; > 0F24E55217EE274900ABB217 /* ScratchRegisterAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54B17EE274900ABB217 /* ScratchRegisterAllocator.h */; }; >+ 0F24E55517F0B71C00ABB217 /* InlineCallFrameSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F24E55317F0B71C00ABB217 /* InlineCallFrameSet.cpp */; }; >+ 0F24E55617F0B71C00ABB217 /* InlineCallFrameSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E55417F0B71C00ABB217 /* InlineCallFrameSet.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 0F24E55817F74EDB00ABB217 /* ValueRecovery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F24E55717F74EDB00ABB217 /* ValueRecovery.cpp */; }; > 0F256C361627B0AD007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F256C341627B0AA007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F2B66AC17B6B53F00A7AE3F /* GCIncomingRefCounted.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66A817B6B53D00A7AE3F /* GCIncomingRefCounted.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 0F2B66AD17B6B54500A7AE3F /* GCIncomingRefCountedInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2B66A917B6B53D00A7AE3F /* GCIncomingRefCountedInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -1322,8 +1323,6 @@ > 0F24E53D17EA9F5900ABB217 /* CCallHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCallHelpers.h; sourceTree = "<group>"; }; > 0F24E53E17EA9F5900ABB217 /* FPRInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FPRInfo.h; sourceTree = "<group>"; }; > 0F24E53F17EA9F5900ABB217 /* GPRInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPRInfo.h; sourceTree = "<group>"; }; >- 0F24E55317F0B71C00ABB217 /* InlineCallFrameSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InlineCallFrameSet.cpp; sourceTree = "<group>"; }; >- 0F24E55417F0B71C00ABB217 /* InlineCallFrameSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineCallFrameSet.h; sourceTree = "<group>"; }; > 0F24E54517EE274900ABB217 /* JITOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITOperations.cpp; sourceTree = "<group>"; }; > 0F24E54617EE274900ABB217 /* JITOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITOperations.h; sourceTree = "<group>"; }; > 0F24E54717EE274900ABB217 /* JITOperationWrappers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITOperationWrappers.h; sourceTree = "<group>"; }; >@@ -1331,6 +1330,9 @@ > 0F24E54917EE274900ABB217 /* Repatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Repatch.cpp; sourceTree = "<group>"; }; > 0F24E54A17EE274900ABB217 /* Repatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Repatch.h; sourceTree = "<group>"; }; > 0F24E54B17EE274900ABB217 /* ScratchRegisterAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScratchRegisterAllocator.h; sourceTree = "<group>"; }; >+ 0F24E55317F0B71C00ABB217 /* InlineCallFrameSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InlineCallFrameSet.cpp; sourceTree = "<group>"; }; >+ 0F24E55417F0B71C00ABB217 /* InlineCallFrameSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineCallFrameSet.h; sourceTree = "<group>"; }; >+ 0F24E55717F74EDB00ABB217 /* ValueRecovery.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ValueRecovery.cpp; sourceTree = "<group>"; }; > 0F256C341627B0AA007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCallArrayAllocatorSlowPathGenerator.h; path = dfg/DFGCallArrayAllocatorSlowPathGenerator.h; sourceTree = "<group>"; }; > 0F2B66A817B6B53D00A7AE3F /* GCIncomingRefCounted.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GCIncomingRefCounted.h; sourceTree = "<group>"; }; > 0F2B66A917B6B53D00A7AE3F /* GCIncomingRefCountedInlines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GCIncomingRefCountedInlines.h; sourceTree = "<group>"; }; >@@ -3764,8 +3766,6 @@ > 969A078F0ED1D3AE00F1F681 /* bytecode */ = { > isa = PBXGroup; > children = ( >- 0F24E55317F0B71C00ABB217 /* InlineCallFrameSet.cpp */, >- 0F24E55417F0B71C00ABB217 /* InlineCallFrameSet.h */, > 0F8335B41639C1E3001443B5 /* ArrayAllocationProfile.cpp */, > 0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */, > 0F63945115D07051006A597C /* ArrayProfile.cpp */, >@@ -3800,6 +3800,8 @@ > 0F93329514CA7DC10085F3C6 /* GetByIdStatus.cpp */, > 0F93329614CA7DC10085F3C6 /* GetByIdStatus.h */, > 0F0B83A814BCF55E00885B4F /* HandlerInfo.h */, >+ 0F24E55317F0B71C00ABB217 /* InlineCallFrameSet.cpp */, >+ 0F24E55417F0B71C00ABB217 /* InlineCallFrameSet.h */, > 969A07930ED1D3AE00F1F681 /* Instruction.h */, > BCFD8C900EEB2EE700283848 /* JumpTable.cpp */, > BCFD8C910EEB2EE700283848 /* JumpTable.h */, >@@ -3838,6 +3840,7 @@ > A79E781E15EECBA80047C855 /* UnlinkedCodeBlock.cpp */, > A79E781F15EECBA80047C855 /* UnlinkedCodeBlock.h */, > 0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */, >+ 0F24E55717F74EDB00ABB217 /* ValueRecovery.cpp */, > 0F426A451460CBAB00131F8F /* ValueRecovery.h */, > 0F426A461460CBAB00131F8F /* VirtualRegister.h */, > 0F919D2215853CDE004A4E7D /* Watchpoint.cpp */, >@@ -5276,6 +5279,7 @@ > 14E84FA014EE1ACC00D6D5D4 /* WeakSet.cpp in Sources */, > 0F6E5C191724AF3D005C574F /* WebKitLLVMLibraryAnchor.cpp in Sources */, > 0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */, >+ 0F24E55817F74EDB00ABB217 /* ValueRecovery.cpp in Sources */, > A7E5AB3A1799E4B200D2833D /* X86Disassembler.cpp in Sources */, > 863C6D9C1521111A00585E4E /* YarrCanonicalizeUCS2.cpp in Sources */, > 86704B8412DBA33700A9FE7B /* YarrInterpreter.cpp in Sources */, >Index: Source/JavaScriptCore/bytecode/CodeOrigin.h >=================================================================== >--- Source/JavaScriptCore/bytecode/CodeOrigin.h (revision 156667) >+++ Source/JavaScriptCore/bytecode/CodeOrigin.h (working copy) >@@ -97,7 +97,7 @@ struct InlineCallFrame { > WriteBarrier<JSFunction> callee; // This may be null, indicating that this is a closure call and that the JSFunction and JSScope are already on the stack. > CodeOrigin caller; > BitVector capturedVars; // Indexed by the machine call frame's variable numbering. >- signed stackOffset : 31; >+ int stackOffset : 31; > bool isCall : 1; > > // There is really no good notion of a "default" set of values for >Index: Source/JavaScriptCore/bytecode/ValueRecovery.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/ValueRecovery.cpp (revision 0) >+++ Source/JavaScriptCore/bytecode/ValueRecovery.cpp (working copy) >@@ -0,0 +1,132 @@ >+/* >+ * Copyright (C) 2011, 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 "ValueRecovery.h" >+ >+namespace JSC { >+ >+JSValue ValueRecovery::recover(ExecState* exec) const >+{ >+ switch (technique()) { >+ case DisplacedInJSStack: >+ return exec->r(virtualRegister().offset()).jsValue(); >+ case Int32DisplacedInJSStack: >+ return jsNumber(exec->r(virtualRegister().offset()).unboxedInt32()); >+ case Int52DisplacedInJSStack: >+ return jsNumber(exec->r(virtualRegister().offset()).unboxedInt52()); >+ case StrictInt52DisplacedInJSStack: >+ return jsNumber(exec->r(virtualRegister().offset()).unboxedStrictInt52()); >+ case DoubleDisplacedInJSStack: >+ return jsNumber(exec->r(virtualRegister().offset()).unboxedDouble()); >+ case CellDisplacedInJSStack: >+ return exec->r(virtualRegister().offset()).unboxedCell(); >+ case BooleanDisplacedInJSStack: >+#if USE(JSVALUE64) >+ return exec->r(virtualRegister().offset()).jsValue(); >+#else >+ return jsBoolean(exec->r(virtualRegister().offset()).unboxedBoolean()); >+#endif >+ case Constant: >+ return constant(); >+ default: >+ RELEASE_ASSERT_NOT_REACHED(); >+ return JSValue(); >+ } >+} >+ >+void ValueRecovery::dumpInContext(PrintStream& out, DumpContext* context) const >+{ >+ switch (technique()) { >+ case InGPR: >+ out.print(gpr()); >+ return; >+ case UnboxedInt32InGPR: >+ out.print("int32(", gpr(), ")"); >+ return; >+ case UnboxedInt52InGPR: >+ out.print("int52(", gpr(), ")"); >+ return; >+ case UnboxedStrictInt52InGPR: >+ out.print("strictInt52(", gpr(), ")"); >+ return; >+ case UnboxedBooleanInGPR: >+ out.print("bool(", gpr(), ")"); >+ return; >+ case UnboxedCellInGPR: >+ out.print("cell(", gpr(), ")"); >+ return; >+ case UInt32InGPR: >+ out.print("uint32(", gpr(), ")"); >+ return; >+ case InFPR: >+ out.print(fpr()); >+ return; >+#if USE(JSVALUE32_64) >+ case InPair: >+ out.print("pair(", tagGPR(), ", ", payloadGPR(), ")"); >+ return; >+#endif >+ case DisplacedInJSStack: >+ out.printf("*%d", virtualRegister().offset()); >+ return; >+ case Int32DisplacedInJSStack: >+ out.printf("*int32(%d)", virtualRegister().offset()); >+ return; >+ case Int52DisplacedInJSStack: >+ out.printf("*int52(%d)", virtualRegister().offset()); >+ return; >+ case StrictInt52DisplacedInJSStack: >+ out.printf("*strictInt52(%d)", virtualRegister().offset()); >+ return; >+ case DoubleDisplacedInJSStack: >+ out.printf("*double(%d)", virtualRegister().offset()); >+ return; >+ case CellDisplacedInJSStack: >+ out.printf("*cell(%d)", virtualRegister().offset()); >+ return; >+ case BooleanDisplacedInJSStack: >+ out.printf("*bool(%d)", virtualRegister().offset()); >+ return; >+ case ArgumentsThatWereNotCreated: >+ out.printf("arguments"); >+ return; >+ case Constant: >+ out.print("[", inContext(constant(), context), "]"); >+ return; >+ case DontKnow: >+ out.printf("!"); >+ return; >+ } >+ RELEASE_ASSERT_NOT_REACHED(); >+} >+ >+void ValueRecovery::dump(PrintStream& out) const >+{ >+ dumpInContext(out, 0); >+} >+ >+} // namespace JSC >+ >Index: Source/JavaScriptCore/bytecode/ValueRecovery.h >=================================================================== >--- Source/JavaScriptCore/bytecode/ValueRecovery.h (revision 156667) >+++ Source/JavaScriptCore/bytecode/ValueRecovery.h (working copy) >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2011 Apple Inc. All rights reserved. >+ * Copyright (C) 2011, 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 >@@ -42,14 +42,6 @@ struct DumpContext; > // Describes how to recover a given bytecode virtual register at a given > // code point. > enum ValueRecoveryTechnique { >- // It's already in the stack at the right location. >- AlreadyInJSStack, >- // It's already in the stack but unboxed. >- AlreadyInJSStackAsUnboxedInt32, >- AlreadyInJSStackAsUnboxedInt52, >- AlreadyInJSStackAsUnboxedCell, >- AlreadyInJSStackAsUnboxedBoolean, >- AlreadyInJSStackAsUnboxedDouble, > // It's in a register. > InGPR, > UnboxedInt32InGPR, >@@ -89,48 +81,6 @@ public: > bool isSet() const { return m_technique != DontKnow; } > bool operator!() const { return !isSet(); } > >- static ValueRecovery alreadyInJSStack() >- { >- ValueRecovery result; >- result.m_technique = AlreadyInJSStack; >- return result; >- } >- >- static ValueRecovery alreadyInJSStackAsUnboxedInt32() >- { >- ValueRecovery result; >- result.m_technique = AlreadyInJSStackAsUnboxedInt32; >- return result; >- } >- >- static ValueRecovery alreadyInJSStackAsUnboxedInt52() >- { >- ValueRecovery result; >- result.m_technique = AlreadyInJSStackAsUnboxedInt52; >- return result; >- } >- >- static ValueRecovery alreadyInJSStackAsUnboxedCell() >- { >- ValueRecovery result; >- result.m_technique = AlreadyInJSStackAsUnboxedCell; >- return result; >- } >- >- static ValueRecovery alreadyInJSStackAsUnboxedBoolean() >- { >- ValueRecovery result; >- result.m_technique = AlreadyInJSStackAsUnboxedBoolean; >- return result; >- } >- >- static ValueRecovery alreadyInJSStackAsUnboxedDouble() >- { >- ValueRecovery result; >- result.m_technique = AlreadyInJSStackAsUnboxedDouble; >- return result; >- } >- > static ValueRecovery inGPR(MacroAssembler::RegisterID gpr, DataFormat dataFormat) > { > ASSERT(dataFormat != DataFormatNone); >@@ -256,21 +206,6 @@ public: > } > } > >- bool isAlreadyInJSStack() const >- { >- switch (technique()) { >- case AlreadyInJSStack: >- case AlreadyInJSStackAsUnboxedInt32: >- case AlreadyInJSStackAsUnboxedInt52: >- case AlreadyInJSStackAsUnboxedCell: >- case AlreadyInJSStackAsUnboxedBoolean: >- case AlreadyInJSStackAsUnboxedDouble: >- return true; >- default: >- return false; >- } >- } >- > MacroAssembler::RegisterID gpr() const > { > ASSERT(m_technique == InGPR || m_technique == UnboxedInt32InGPR || m_technique == UnboxedBooleanInGPR || m_technique == UInt32InGPR || m_technique == UnboxedInt52InGPR || m_technique == UnboxedStrictInt52InGPR || m_technique == UnboxedCellInGPR); >@@ -309,95 +244,11 @@ public: > return JSValue::decode(m_source.constant); > } > >- void dumpInContext(PrintStream& out, DumpContext* context) const >- { >- switch (technique()) { >- case AlreadyInJSStack: >- out.printf("-"); >- return; >- case AlreadyInJSStackAsUnboxedInt32: >- out.printf("(int32)"); >- return; >- case AlreadyInJSStackAsUnboxedInt52: >- out.printf("(int52)"); >- return; >- case AlreadyInJSStackAsUnboxedCell: >- out.printf("(cell)"); >- return; >- case AlreadyInJSStackAsUnboxedBoolean: >- out.printf("(bool)"); >- return; >- case AlreadyInJSStackAsUnboxedDouble: >- out.printf("(double)"); >- return; >- case InGPR: >- out.print(gpr()); >- return; >- case UnboxedInt32InGPR: >- out.print("int32(", gpr(), ")"); >- return; >- case UnboxedInt52InGPR: >- out.print("int52(", gpr(), ")"); >- return; >- case UnboxedStrictInt52InGPR: >- out.print("strictInt52(", gpr(), ")"); >- return; >- case UnboxedBooleanInGPR: >- out.print("bool(", gpr(), ")"); >- return; >- case UnboxedCellInGPR: >- out.print("cell(", gpr(), ")"); >- return; >- case UInt32InGPR: >- out.print("uint32(", gpr(), ")"); >- return; >- case InFPR: >- out.print(fpr()); >- return; >-#if USE(JSVALUE32_64) >- case InPair: >- out.print("pair(", tagGPR(), ", ", payloadGPR(), ")"); >- return; >-#endif >- case DisplacedInJSStack: >- out.printf("*%d", virtualRegister().offset()); >- return; >- case Int32DisplacedInJSStack: >- out.printf("*int32(%d)", virtualRegister().offset()); >- return; >- case Int52DisplacedInJSStack: >- out.printf("*int52(%d)", virtualRegister().offset()); >- return; >- case StrictInt52DisplacedInJSStack: >- out.printf("*strictInt52(%d)", virtualRegister().offset()); >- return; >- case DoubleDisplacedInJSStack: >- out.printf("*double(%d)", virtualRegister().offset()); >- return; >- case CellDisplacedInJSStack: >- out.printf("*cell(%d)", virtualRegister().offset()); >- return; >- case BooleanDisplacedInJSStack: >- out.printf("*bool(%d)", virtualRegister().offset()); >- return; >- case ArgumentsThatWereNotCreated: >- out.printf("arguments"); >- return; >- case Constant: >- out.print("[", inContext(constant(), context), "]"); >- return; >- case DontKnow: >- out.printf("!"); >- return; >- } >- RELEASE_ASSERT_NOT_REACHED(); >- } >- >- void dump(PrintStream& out) const >- { >- dumpInContext(out, 0); >- } >+ JSValue recover(ExecState*) const; > >+ void dumpInContext(PrintStream& out, DumpContext* context) const; >+ void dump(PrintStream& out) const; >+ > private: > ValueRecoveryTechnique m_technique; > union { >Index: Source/JavaScriptCore/dfg/DFGFixupPhase.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (revision 156667) >+++ Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (working copy) >@@ -1219,7 +1219,7 @@ private: > case FlushedJSValue: > break; > case FlushedDouble: >- fixEdge<NumberUse>(node->child1(), ForwardSpeculation); >+ fixEdge<NumberUse>(node->child1()); > break; > case FlushedInt32: > fixEdge<Int32Use>(node->child1()); >@@ -1407,11 +1407,11 @@ private: > // edge, you either call fixEdge() or perform the equivalent functionality > // yourself. Obviously, you should have a really good reason if you do the latter. > template<UseKind useKind> >- void fixEdge(Edge& edge, SpeculationDirection direction = BackwardSpeculation) >+ void fixEdge(Edge& edge) > { > if (isDouble(useKind)) { > if (edge->shouldSpeculateInt32ForArithmetic()) { >- injectInt32ToDoubleNode(edge, useKind, direction); >+ injectInt32ToDoubleNode(edge, useKind, m_currentNode->speculationDirection()); > return; > } > >@@ -1424,6 +1424,7 @@ private: > Node* result = m_insertionSet.insertNode( > m_indexInBlock, SpecInt52AsDouble, Int52ToDouble, > m_currentNode->codeOrigin, Edge(edge.node(), NumberUse)); >+ result->setSpeculationDirection(m_currentNode->speculationDirection()); > edge = Edge(result, useKind); > return; > } >@@ -1477,6 +1478,7 @@ private: > Node* result = m_insertionSet.insertNode( > m_indexInBlock, SpecInt52, Int52ToValue, > m_currentNode->codeOrigin, Edge(edge.node(), UntypedUse)); >+ result->setSpeculationDirection(m_currentNode->speculationDirection()); > edge = Edge(result, useKind); > return; > } >Index: Source/JavaScriptCore/dfg/DFGJITCode.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGJITCode.cpp (revision 156667) >+++ Source/JavaScriptCore/dfg/DFGJITCode.cpp (working copy) >@@ -92,31 +92,7 @@ void JITCode::reconstruct( > continue; > } > >- ValueRecovery recovery = recoveries[i]; >- JSValue value; >- switch (recovery.technique()) { >- case AlreadyInJSStack: >- case AlreadyInJSStackAsUnboxedCell: >- case AlreadyInJSStackAsUnboxedBoolean: >- value = exec->r(operand).jsValue(); >- break; >- case AlreadyInJSStackAsUnboxedInt32: >- value = jsNumber(exec->r(operand).unboxedInt32()); >- break; >- case AlreadyInJSStackAsUnboxedInt52: >- value = jsNumber(exec->r(operand).unboxedInt52()); >- break; >- case AlreadyInJSStackAsUnboxedDouble: >- value = jsDoubleNumber(exec->r(operand).unboxedDouble()); >- break; >- case Constant: >- value = recovery.constant(); >- break; >- default: >- RELEASE_ASSERT_NOT_REACHED(); >- break; >- } >- result[i] = value; >+ result[i] = recoveries[i].recover(exec); > } > } > >Index: Source/JavaScriptCore/dfg/DFGNode.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGNode.h (revision 156667) >+++ Source/JavaScriptCore/dfg/DFGNode.h (working copy) >@@ -274,6 +274,26 @@ struct Node { > return filterFlags(~flags); > } > >+ SpeculationDirection speculationDirection() >+ { >+ if (flags() & NodeExitsForward) >+ return ForwardSpeculation; >+ return BackwardSpeculation; >+ } >+ >+ void setSpeculationDirection(SpeculationDirection direction) >+ { >+ switch (direction) { >+ case ForwardSpeculation: >+ mergeFlags(NodeExitsForward); >+ return; >+ case BackwardSpeculation: >+ clearFlags(NodeExitsForward); >+ return; >+ } >+ RELEASE_ASSERT_NOT_REACHED(); >+ } >+ > void setOpAndDefaultFlags(NodeType op) > { > m_op = op; >Index: Source/JavaScriptCore/dfg/DFGOSREntrypointCreationPhase.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGOSREntrypointCreationPhase.cpp (revision 156667) >+++ Source/JavaScriptCore/dfg/DFGOSREntrypointCreationPhase.cpp (working copy) >@@ -102,8 +102,9 @@ public: > Node* node = newRoot->appendNode( > m_graph, variable->prediction(), ExtractOSREntryLocal, codeOrigin, > OpInfo(variable->local().offset())); >- newRoot->appendNode( >+ Node* setLocal = newRoot->appendNode( > m_graph, SpecNone, SetLocal, codeOrigin, OpInfo(variable), Edge(node)); >+ setLocal->setSpeculationDirection(BackwardSpeculation); > } > > newRoot->appendNode( >Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp (revision 156667) >+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp (working copy) >@@ -228,7 +228,6 @@ void OSRExitCompiler::compileExit(const > > for (size_t index = 0; index < operands.size(); ++index) { > const ValueRecovery& recovery = operands[index]; >- int operand = operands.operandForIndex(index); > > switch (recovery.technique()) { > case DisplacedInJSStack: >@@ -250,23 +249,6 @@ void OSRExitCompiler::compileExit(const > &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload); > break; > >- case AlreadyInJSStackAsUnboxedInt32: >- case AlreadyInJSStackAsUnboxedCell: >- case AlreadyInJSStackAsUnboxedBoolean: >- m_jit.load32( >- AssemblyHelpers::tagFor(operand), >- GPRInfo::regT0); >- m_jit.load32( >- AssemblyHelpers::payloadFor(operand), >- GPRInfo::regT1); >- m_jit.store32( >- GPRInfo::regT0, >- &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.tag); >- m_jit.store32( >- GPRInfo::regT1, >- &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload); >- break; >- > default: > break; > } >@@ -299,7 +281,6 @@ void OSRExitCompiler::compileExit(const > AssemblyHelpers::payloadFor(operand)); > break; > >- case AlreadyInJSStackAsUnboxedInt32: > case UnboxedInt32InGPR: > case Int32DisplacedInJSStack: > m_jit.load32( >@@ -313,7 +294,6 @@ void OSRExitCompiler::compileExit(const > AssemblyHelpers::payloadFor(operand)); > break; > >- case AlreadyInJSStackAsUnboxedCell: > case UnboxedCellInGPR: > case CellDisplacedInJSStack: > m_jit.load32( >@@ -327,7 +307,6 @@ void OSRExitCompiler::compileExit(const > AssemblyHelpers::payloadFor(operand)); > break; > >- case AlreadyInJSStackAsUnboxedBoolean: > case UnboxedBooleanInGPR: > case BooleanDisplacedInJSStack: > m_jit.load32( >Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp (revision 156667) >+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp (working copy) >@@ -156,11 +156,11 @@ void OSRExitCompiler::compileExit(const > // definitely in a well-known spot in the scratch buffer regardless of whether it had > // originally been in a register or spilled. This allows us to decouple "where was > // the variable" from "how was it represented". Consider that the >- // AlreadyInJSStackAsUnboxedInt32 recovery: it tells us that the value is in a >- // particular place and that that place holds an unboxed int32. We have three different >- // places that a value could be (stack, displaced, register) and a bunch of different >- // ways of representing a value. The number of recoveries is three * a bunch. The code >- // below means that we have to have three + a bunch cases rather than three * a bunch. >+ // Int32DisplacedInJSStack recovery: it tells us that the value is in a >+ // particular place and that that place holds an unboxed int32. We have two different >+ // places that a value could be (displaced, register) and a bunch of different >+ // ways of representing a value. The number of recoveries is two * a bunch. The code >+ // below means that we have to have two + a bunch cases rather than two * a bunch. > // Once we have loaded the value from wherever it was, the reboxing is the same > // regardless of its location. Likewise, before we do the reboxing, the way we get to > // the value (i.e. where we load it from) is the same regardless of its type. Because >@@ -234,7 +234,6 @@ void OSRExitCompiler::compileExit(const > > for (size_t index = 0; index < operands.size(); ++index) { > const ValueRecovery& recovery = operands[index]; >- int operand = operands.operandForIndex(index); > > switch (recovery.technique()) { > case DisplacedInJSStack: >@@ -246,13 +245,6 @@ void OSRExitCompiler::compileExit(const > m_jit.store64(GPRInfo::regT0, scratch + index); > break; > >- case AlreadyInJSStackAsUnboxedInt32: >- case AlreadyInJSStackAsUnboxedDouble: >- case AlreadyInJSStackAsUnboxedInt52: >- m_jit.load64(AssemblyHelpers::addressFor(operand), GPRInfo::regT0); >- m_jit.store64(GPRInfo::regT0, scratch + index); >- break; >- > default: > break; > } >@@ -274,7 +266,6 @@ void OSRExitCompiler::compileExit(const > m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand)); > break; > >- case AlreadyInJSStackAsUnboxedInt32: > case UnboxedInt32InGPR: > case Int32DisplacedInJSStack: > m_jit.load64(scratch + index, GPRInfo::regT0); >@@ -283,7 +274,6 @@ void OSRExitCompiler::compileExit(const > m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand)); > break; > >- case AlreadyInJSStackAsUnboxedInt52: > case UnboxedInt52InGPR: > case Int52DisplacedInJSStack: > m_jit.load64(scratch + index, GPRInfo::regT0); >@@ -307,7 +297,6 @@ void OSRExitCompiler::compileExit(const > m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand)); > break; > >- case AlreadyInJSStackAsUnboxedDouble: > case InFPR: > case DoubleDisplacedInJSStack: > m_jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0); >Index: Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (revision 156667) >+++ Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (working copy) >@@ -1539,13 +1539,12 @@ void SpeculativeJIT::compileInlineStart( > unsigned argumentPositionStart = node->argumentPositionStart(); > CodeBlock* codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame); > for (int i = 0; i < argumentCountIncludingThis; ++i) { >- ValueRecovery recovery; >+ ValueSource valueSource; > if (codeBlock->isCaptured(virtualRegisterForArgument(i))) >- recovery = ValueRecovery::alreadyInJSStack(); >+ valueSource = ValueSource(ValueInJSStack); > else { > ArgumentPosition& argumentPosition = > m_jit.graph().m_argumentPositions[argumentPositionStart + i]; >- ValueSource valueSource; > switch (argumentPosition.flushFormat()) { > case DeadFlush: > case FlushedJSValue: >@@ -1567,8 +1566,9 @@ void SpeculativeJIT::compileInlineStart( > valueSource = ValueSource(BooleanInJSStack); > break; > } >- recovery = computeValueRecoveryFor(valueSource); > } >+ ValueRecovery recovery = computeValueRecoveryFor( >+ inlineCallFrame->stackOffset + virtualRegisterForArgument(i).offset(), valueSource); > // The recovery should refer either to something that has already been > // stored into the stack at the right place, or to a constant, > // since the Arguments code isn't smart enough to handle anything else. >@@ -1898,10 +1898,10 @@ void SpeculativeJIT::linkOSREntries(Link > ASSERT(osrEntryIndex == m_osrEntryHeads.size()); > } > >-ValueRecovery SpeculativeJIT::computeValueRecoveryFor(const ValueSource& valueSource) >+ValueRecovery SpeculativeJIT::computeValueRecoveryFor(int operand, const ValueSource& valueSource) > { > if (valueSource.isInJSStack()) >- return valueSource.valueRecovery(); >+ return valueSource.valueRecovery(operand); > > ASSERT(valueSource.kind() == HaveNode); > Node* node = valueSource.id().node(m_jit.graph()); >Index: Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (revision 156667) >+++ Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (working copy) >@@ -2282,11 +2282,11 @@ public: > Vector<OwnPtr<SlowPathGenerator>, 8> m_slowPathGenerators; > Vector<SilentRegisterSavePlan> m_plans; > >- ValueRecovery computeValueRecoveryFor(const ValueSource&); >+ ValueRecovery computeValueRecoveryFor(int operand, const ValueSource&); > > ValueRecovery computeValueRecoveryFor(int operand) > { >- return computeValueRecoveryFor(valueSourceForOperand(VirtualRegister(operand))); >+ return computeValueRecoveryFor(operand, valueSourceForOperand(VirtualRegister(operand))); > } > }; > >Index: Source/JavaScriptCore/dfg/DFGValueSource.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGValueSource.h (revision 156667) >+++ Source/JavaScriptCore/dfg/DFGValueSource.h (working copy) >@@ -178,28 +178,10 @@ public: > return valueSourceKindToDataFormat(kind()); > } > >- ValueRecovery valueRecovery() const >+ ValueRecovery valueRecovery(int operand) const > { > ASSERT(isTriviallyRecoverable()); > switch (kind()) { >- case ValueInJSStack: >- return ValueRecovery::alreadyInJSStack(); >- >- case Int32InJSStack: >- return ValueRecovery::alreadyInJSStackAsUnboxedInt32(); >- >- case Int52InJSStack: >- return ValueRecovery::alreadyInJSStackAsUnboxedInt52(); >- >- case CellInJSStack: >- return ValueRecovery::alreadyInJSStackAsUnboxedCell(); >- >- case BooleanInJSStack: >- return ValueRecovery::alreadyInJSStackAsUnboxedBoolean(); >- >- case DoubleInJSStack: >- return ValueRecovery::alreadyInJSStackAsUnboxedDouble(); >- > case SourceIsDead: > return ValueRecovery::constant(jsUndefined()); > >@@ -207,8 +189,7 @@ public: > return ValueRecovery::argumentsThatWereNotCreated(); > > default: >- RELEASE_ASSERT_NOT_REACHED(); >- return ValueRecovery(); >+ return ValueRecovery::displacedInJSStack(VirtualRegister(operand), dataFormat()); > } > } > >Index: Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp (revision 156667) >+++ Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp (working copy) >@@ -124,8 +124,10 @@ void VariableEventStream::reconstruct( > // reflect this. > if (!index) { > valueRecoveries = Operands<ValueRecovery>(codeBlock->numParameters(), numVariables); >- for (size_t i = 0; i < valueRecoveries.size(); ++i) >- valueRecoveries[i] = ValueRecovery::alreadyInJSStack(); >+ for (size_t i = 0; i < valueRecoveries.size(); ++i) { >+ valueRecoveries[i] = ValueRecovery::displacedInJSStack( >+ VirtualRegister(valueRecoveries.operandForIndex(i)), DataFormatJS); >+ } > return; > } > >@@ -181,7 +183,7 @@ void VariableEventStream::reconstruct( > for (unsigned i = 0; i < operandSources.size(); ++i) { > ValueSource& source = operandSources[i]; > if (source.isTriviallyRecoverable()) { >- valueRecoveries[i] = source.valueRecovery(); >+ valueRecoveries[i] = source.valueRecovery(operandSources.operandForIndex(i)); > continue; > } > >@@ -278,13 +280,6 @@ void VariableEventStream::reconstruct( > valueRecoveries[i] = > ValueRecovery::displacedInJSStack(static_cast<VirtualRegister>(info.u.virtualReg), info.format); > } >- >- // Step 4: Make sure that for locals that coincide with true call frame headers, the exit compiler knows >- // that those values don't have to be recovered. Signal this by using ValueRecovery::alreadyInJSStack() >- for (InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->caller.inlineCallFrame) { >- for (unsigned i = JSStack::CallFrameHeaderSize; i--;) >- valueRecoveries.setLocal(VirtualRegister(inlineCallFrame->stackOffset).toLocal() - i - 1, ValueRecovery::alreadyInJSStack()); >- } > } > > } } // namespace JSC::DFG >Index: Source/JavaScriptCore/interpreter/Register.h >=================================================================== >--- Source/JavaScriptCore/interpreter/Register.h (revision 156667) >+++ Source/JavaScriptCore/interpreter/Register.h (working copy) >@@ -71,6 +71,7 @@ namespace JSC { > Instruction* vPC() const; > int32_t unboxedInt32() const; > int64_t unboxedInt52() const; >+ int64_t unboxedStrictInt52() const; > bool unboxedBoolean() const; > double unboxedDouble() const; > JSCell* unboxedCell() const; >@@ -177,6 +178,11 @@ namespace JSC { > return u.integer >> JSValue::int52ShiftAmount; > } > >+ ALWAYS_INLINE int64_t Register::unboxedStrictInt52() const >+ { >+ return u.integer; >+ } >+ > ALWAYS_INLINE bool Register::unboxedBoolean() const > { > return !!payload(); >Index: Source/JavaScriptCore/runtime/Arguments.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/Arguments.cpp (revision 156667) >+++ Source/JavaScriptCore/runtime/Arguments.cpp (working copy) >@@ -356,53 +356,9 @@ void Arguments::tearOff(CallFrame* callF > m_registerArray = std::make_unique<WriteBarrier<Unknown>[]>(m_numArguments); > m_registers = m_registerArray.get() - CallFrame::offsetFor(1) - 1; > >- tearOffForInlineCallFrame( >- callFrame->vm(), callFrame->registers() + inlineCallFrame->stackOffset, >- inlineCallFrame); >-} >- >-void Arguments::tearOffForInlineCallFrame(VM& vm, Register* registers, InlineCallFrame* inlineCallFrame) >-{ > for (size_t i = 0; i < m_numArguments; ++i) { > ValueRecovery& recovery = inlineCallFrame->arguments[i + 1]; >- // In the future we'll support displaced recoveries (indicating that the >- // argument was flushed to a different location), but for now we don't do >- // that so this code will fail if that were to happen. On the other hand, >- // it's much less likely that we'll support in-register recoveries since >- // this code does not (easily) have access to registers. >- JSValue value; >- Register* location = ®isters[CallFrame::argumentOffset(i)]; >- switch (recovery.technique()) { >- case AlreadyInJSStack: >- value = location->jsValue(); >- break; >- case AlreadyInJSStackAsUnboxedInt32: >- value = jsNumber(location->unboxedInt32()); >- break; >- case AlreadyInJSStackAsUnboxedInt52: >- value = jsNumber(location->unboxedInt52()); >- break; >- case AlreadyInJSStackAsUnboxedCell: >- value = location->unboxedCell(); >- break; >- case AlreadyInJSStackAsUnboxedBoolean: >- value = jsBoolean(location->unboxedBoolean()); >- break; >- case AlreadyInJSStackAsUnboxedDouble: >-#if USE(JSVALUE64) >- value = jsNumber(*bitwise_cast<double*>(location)); >-#else >- value = location->jsValue(); >-#endif >- break; >- case Constant: >- value = recovery.constant(); >- break; >- default: >- RELEASE_ASSERT_NOT_REACHED(); >- break; >- } >- trySetArgument(vm, i, value); >+ trySetArgument(callFrame->vm(), i, recovery.recover(callFrame)); > } > } > >Index: Source/JavaScriptCore/runtime/Arguments.h >=================================================================== >--- Source/JavaScriptCore/runtime/Arguments.h (revision 156667) >+++ Source/JavaScriptCore/runtime/Arguments.h (working copy) >@@ -63,8 +63,6 @@ private: > Arguments(CallFrame*); > Arguments(CallFrame*, NoParametersType); > >- void tearOffForInlineCallFrame(VM& vm, Register*, InlineCallFrame*); >- > public: > DECLARE_INFO; >
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
Flags:
oliver
:
review+
webkit-ews
:
commit-queue-
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 122065
:
213018
|
213022
|
213028
|
213031