Changeset 172665 in webkit
- Timestamp:
- Aug 15, 2014 6:45:40 PM (10 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 1 added
- 28 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r172655 r172665 1 2014-08-15 Michael Saboff <msaboff@apple.com> 2 3 Change callToJavaScript and callToNativeFunction so their callFrames match the native calling conventions 4 https://bugs.webkit.org/show_bug.cgi?id=131578 5 6 Reviewed by Geoffrey Garen. 7 8 Renamed callToJavaScript and callToNativeFunction to vmEntryToJavaScript and vmEntryToNative, 9 respectively. Eliminated the sentinel frame and replaced it with the structure VMEntryRecord 10 that appears in the "locals" area of a VM entry stack frame. Changed the order that 11 vmEntryToJavaScript and vmEntryToNative creates their stack frames to be native calling 12 convention compliant. That is to save prior frame pointer, save callee save registers, then 13 allocate and populate the VMEntryRecord, and finally allocate a CallFrame for the JS function 14 that vmEntryToJavaScript will invoke. The top most vm entry frame pointer is saved in 15 VM::topVMEntryFrame. The vmEntry functions save prior contents of VM::topVMEntryFrame 16 along with the VM and VM::topCallFrame in the VMEntryRecord it places on the stack. Starting 17 at VM::topCallFrame, the stack can be walked using these VMEntryRecords. 18 19 Arbitrary stack unwinding is now handled either iteratively by loading VM::topVMEntryFrame 20 into a local variable and using CallFrame::callerFrame(VMEntryFrame*&) or by using StackVisitor. 21 Given that the stack is effectively a singly linked list, general stack unwinding needs to use 22 one of these two methods. 23 24 * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: 25 * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: 26 * JavaScriptCore.xcodeproj/project.pbxproj: 27 Addition of VMEntryRecord.h 28 29 * bytecode/BytecodeList.json: 30 Renaming of llint helper opcodes due to renaming callToJavaScript and callToNativeFunction. 31 32 * debugger/Debugger.cpp: 33 (JSC::Debugger::stepOutOfFunction): 34 (JSC::Debugger::returnEvent): 35 (JSC::Debugger::didExecuteProgram): 36 * jsc.cpp: 37 (functionDumpCallFrame): 38 * jit/JITOperations.cpp: 39 Changed unwinding to use CallFrame::callerFrame(VMEntryFrame*&). 40 41 * bytecode/CodeBlock.cpp: 42 (JSC::RecursionCheckFunctor::RecursionCheckFunctor): 43 (JSC::RecursionCheckFunctor::operator()): 44 (JSC::RecursionCheckFunctor::didRecurse): 45 (JSC::CodeBlock::noticeIncomingCall): 46 * debugger/DebuggerCallFrame.cpp: 47 (JSC::FindCallerMidStackFunctor::FindCallerMidStackFunctor): 48 (JSC::FindCallerMidStackFunctor::operator()): 49 (JSC::FindCallerMidStackFunctor::getCallerFrame): 50 (JSC::DebuggerCallFrame::callerFrame): 51 * interpreter/VMInspector.cpp: 52 (JSC::CountFramesFunctor::CountFramesFunctor): 53 (JSC::CountFramesFunctor::operator()): 54 (JSC::CountFramesFunctor::count): 55 (JSC::VMInspector::countFrames): 56 * runtime/VM.cpp: 57 (JSC::VM::VM): 58 (JSC::FindFirstCallerFrameWithCodeblockFunctor::FindFirstCallerFrameWithCodeblockFunctor): 59 (JSC::FindFirstCallerFrameWithCodeblockFunctor::operator()): 60 (JSC::FindFirstCallerFrameWithCodeblockFunctor::foundCallFrame): 61 (JSC::FindFirstCallerFrameWithCodeblockFunctor::index): 62 (JSC::VM::throwException): 63 Changed unwinding to use StackVisitor including added functor classes. 64 65 * interpreter/CallFrame.cpp: 66 (JSC::CallFrame::callerFrame): 67 Added new flavor of callerFrame() that can iteratively unwind the stack. 68 69 * interpreter/CallFrame.h: 70 (JSC::ExecState::callerFrame): Changed callerFrame() to use private common helper. 71 (JSC::ExecState::callerFrameOrVMEntryFrame): Deleted. 72 (JSC::ExecState::isVMEntrySentinel): Deleted. 73 (JSC::ExecState::vmEntrySentinelCallerFrame): Deleted. 74 (JSC::ExecState::initializeVMEntrySentinelFrame): Deleted. 75 (JSC::ExecState::callerFrameSkippingVMEntrySentinel): Deleted. 76 (JSC::ExecState::vmEntrySentinelCodeBlock): Deleted. 77 78 * interpreter/CallFrame.h: 79 (JSC::ExecState::init): 80 (JSC::ExecState::topOfFrame): 81 (JSC::ExecState::currentVPC): 82 (JSC::ExecState::setCurrentVPC): 83 Eliminated unneded checking of sentinel frame. 84 85 * interpreter/Interpreter.cpp: 86 (JSC::unwindCallFrame): 87 (JSC::Interpreter::getStackTrace): Updated for unwidning changes. 88 (JSC::Interpreter::unwind): Eliminated unneeded sentinel frame check. 89 90 * interpreter/Interpreter.cpp: 91 (JSC::Interpreter::executeCall): 92 (JSC::Interpreter::executeConstruct): 93 * jit/JITStubs.h: 94 * llint/LLIntThunks.cpp: 95 (JSC::callToJavaScript): Deleted. 96 (JSC::callToNativetion): Deleted. 97 (JSC::vmEntryToJavaScript): 98 (JSC::vmEntryToNative): 99 * llint/LLIntThunks.h: 100 Updated for vmEntryToJavaScript and vmEntryToNative name changes. 101 102 * interpreter/Interpreter.h: 103 (JSC::TopCallFrameSetter::TopCallFrameSetter): 104 (JSC::TopCallFrameSetter::~TopCallFrameSetter): 105 Eliminated unneeded sentinel frame check. 106 107 * interpreter/Interpreter.h: 108 (JSC::NativeCallFrameTracer::NativeCallFrameTracer): 109 Removed sentinel specific constructor. 110 111 * interpreter/StackVisitor.cpp: 112 (JSC::StackVisitor::StackVisitor): 113 (JSC::StackVisitor::readFrame): 114 (JSC::StackVisitor::readNonInlinedFrame): 115 (JSC::StackVisitor::readInlinedFrame): 116 (JSC::StackVisitor::Frame::print): 117 * interpreter/StackVisitor.h: 118 (JSC::StackVisitor::Frame::callerIsVMEntry): 119 Changes for unwinding using CallFrame::callerFrame(VMEntryFrame*&). Also added field that 120 indicates when about to step over a VM entry frame. 121 122 * interpreter/VMEntryRecord.h: Added. 123 (JSC::VMEntryRecord::prevTopCallFrame): 124 (JSC::VMEntryRecord::prevTopVMEntryFrame): 125 New struct to record prior state of VM's notion of VM entry and top call frames. 126 127 * jit/JITCode.cpp: 128 (JSC::JITCode::execute): 129 Use new vmEntryToJavaScript and vmEntryToNative name. 130 131 * llint/LLIntOffsetsExtractor.cpp: Added include for VMEntryRecord.h. 132 133 * llint/LowLevelInterpreter.asm: 134 * llint/LowLevelInterpreter32_64.asm: 135 * llint/LowLevelInterpreter64.asm: 136 Offline assembly implementation of creating stack frame with VMEntryRecord and well as restoring 137 relevent VM fields when exiting the VM. Added a helper that returns a VMEntryRecord given 138 a pointer to the VM entry frame. 139 140 * llint/LLIntThunks.cpp: 141 (JSC::vmEntryRecord): 142 * llint/LowLevelInterpreter.cpp: 143 (JSC::CLoop::execute): 144 C Loop changes to mirror the assembly changes. 145 146 * runtime/VM.h: 147 Added topVMEntryFrame field. 148 1 149 2014-08-15 Brian J. Burg <burg@cs.washington.edu> 2 150 -
trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
r172655 r172665 1272 1272 <ClInclude Include="..\interpreter\CallFrameInlines.h" /> 1273 1273 <ClInclude Include="..\interpreter\CallFrameClosure.h" /> 1274 <ClInclude Include="..\interpreter\VMEntryRecord.h" /> 1274 1275 <ClInclude Include="..\interpreter\Interpreter.h" /> 1275 1276 <ClInclude Include="..\interpreter\JSStack.h" /> -
trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters
r172655 r172665 2214 2214 <Filter>interpreter</Filter> 2215 2215 </ClInclude> 2216 <ClInclude Include="..\interpreter\VMEntryRecord.h"> 2217 <Filter>interpreter</Filter> 2218 </ClInclude> 2216 2219 <ClInclude Include="..\interpreter\Interpreter.h"> 2217 2220 <Filter>interpreter</Filter> -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r172655 r172665 1157 1157 6553A33217A1F1EE008CF6F3 /* CommonSlowPathsExceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 6553A33017A1F1EE008CF6F3 /* CommonSlowPathsExceptions.h */; }; 1158 1158 655EB29B10CE2581001A990E /* NodesCodegen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 655EB29A10CE2581001A990E /* NodesCodegen.cpp */; }; 1159 658D3A5619638268003C45D6 /* VMEntryRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = 658D3A5519638268003C45D6 /* VMEntryRecord.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1159 1160 65C02850171795E200351E35 /* ARMv7Disassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65C0284F171795E200351E35 /* ARMv7Disassembler.cpp */; }; 1160 1161 65C0285C1717966800351E35 /* ARMv7DOpcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65C0285A1717966800351E35 /* ARMv7DOpcode.cpp */; }; … … 2886 2887 1429D8840ED21C3D00B89619 /* SamplingTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SamplingTool.h; sourceTree = "<group>"; }; 2887 2888 1429D8DB0ED2205B00B89619 /* CallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CallFrame.cpp; sourceTree = "<group>"; }; 2888 1429D8DC0ED2205B00B89619 /* CallFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallFrame.h; sourceTree = "<group>"; };2889 1429D8DC0ED2205B00B89619 /* CallFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = CallFrame.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 2889 2890 1429D92D0ED22D7000B89619 /* JIT.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JIT.cpp; sourceTree = "<group>"; }; 2890 2891 1429D92E0ED22D7000B89619 /* JIT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JIT.h; sourceTree = "<group>"; }; … … 3072 3073 65621E6C089E859700760F35 /* PropertySlot.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = PropertySlot.h; sourceTree = "<group>"; tabWidth = 8; }; 3073 3074 65860177185A8F5E00030EEE /* MaxFrameExtentForSlowPathCall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MaxFrameExtentForSlowPathCall.h; sourceTree = "<group>"; }; 3075 658D3A5519638268003C45D6 /* VMEntryRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = VMEntryRecord.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 3074 3076 65987F2C167FE84B003C2F8D /* DFGOSRExitCompilationInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitCompilationInfo.h; path = dfg/DFGOSRExitCompilationInfo.h; sourceTree = "<group>"; }; 3075 3077 65987F2F16828A7E003C2F8D /* UnusedPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnusedPointer.h; sourceTree = "<group>"; }; … … 3114 3116 8603CEF214C7546400AE59E3 /* CodeProfiling.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeProfiling.cpp; sourceTree = "<group>"; }; 3115 3117 8603CEF314C7546400AE59E3 /* CodeProfiling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeProfiling.h; sourceTree = "<group>"; }; 3116 8604F4F2143A6C4400B295F5 /* ChangeLog */ = {isa = PBXFileReference; lastKnownFileType = text; path = ChangeLog; sourceTree = "<group>"; };3118 8604F4F2143A6C4400B295F5 /* ChangeLog */ = {isa = PBXFileReference; lastKnownFileType = text; lineEnding = 0; path = ChangeLog; sourceTree = "<group>"; }; 3117 3119 8606DDE918DA44AB00A383D0 /* IdentifierInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IdentifierInlines.h; sourceTree = "<group>"; }; 3118 3120 8612E4CB1522918400C836BE /* MatchResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MatchResult.h; sourceTree = "<group>"; }; … … 3143 3145 869EBCB60E8C6D4A008722CC /* ResultType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResultType.h; sourceTree = "<group>"; }; 3144 3146 86A054461556451B00445157 /* LowLevelInterpreter.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; name = LowLevelInterpreter.asm; path = llint/LowLevelInterpreter.asm; sourceTree = "<group>"; }; 3145 86A054471556451B00445157 /* LowLevelInterpreter32_64.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; name = LowLevelInterpreter32_64.asm; path = llint/LowLevelInterpreter32_64.asm; sourceTree = "<group>"; };3146 86A054481556451B00445157 /* LowLevelInterpreter64.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; name = LowLevelInterpreter64.asm; path = llint/LowLevelInterpreter64.asm; sourceTree = "<group>"; };3147 86A054471556451B00445157 /* LowLevelInterpreter32_64.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; lineEnding = 0; name = LowLevelInterpreter32_64.asm; path = llint/LowLevelInterpreter32_64.asm; sourceTree = "<group>"; }; 3148 86A054481556451B00445157 /* LowLevelInterpreter64.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; lineEnding = 0; name = LowLevelInterpreter64.asm; path = llint/LowLevelInterpreter64.asm; sourceTree = "<group>"; }; 3147 3149 86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITArithmetic.cpp; sourceTree = "<group>"; }; 3148 3150 86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMv7Assembler.h; sourceTree = "<group>"; }; … … 3533 3535 A7C1EAEA17987AB600299DB2 /* CallFrameInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallFrameInlines.h; sourceTree = "<group>"; }; 3534 3536 A7C1EAEB17987AB600299DB2 /* JSStackInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStackInlines.h; sourceTree = "<group>"; }; 3535 A7C1EAEC17987AB600299DB2 /* StackVisitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StackVisitor.cpp; sourceTree = "<group>"; };3537 A7C1EAEC17987AB600299DB2 /* StackVisitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = StackVisitor.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; 3536 3538 A7C1EAED17987AB600299DB2 /* StackVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StackVisitor.h; sourceTree = "<group>"; }; 3537 3539 A7C225CC139981F100FF1662 /* KeywordLookupGenerator.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = KeywordLookupGenerator.py; sourceTree = "<group>"; }; … … 3755 3757 E178633F0D9BEC0000D74E75 /* InitializeThreading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InitializeThreading.h; sourceTree = "<group>"; }; 3756 3758 E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InitializeThreading.cpp; sourceTree = "<group>"; }; 3757 E18E3A560DF9278C00D90B34 /* VM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VM.h; sourceTree = "<group>"; };3758 E18E3A570DF9278C00D90B34 /* VM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VM.cpp; sourceTree = "<group>"; };3759 E18E3A560DF9278C00D90B34 /* VM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = VM.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 3760 E18E3A570DF9278C00D90B34 /* VM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = VM.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; 3759 3761 E49DC14912EF261A00184A1F /* SourceProviderCacheItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceProviderCacheItem.h; sourceTree = "<group>"; }; 3760 3762 E49DC15112EF272200184A1F /* SourceProviderCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceProviderCache.h; sourceTree = "<group>"; }; … … 4176 4178 isa = PBXGroup; 4177 4179 children = ( 4180 658D3A5519638268003C45D6 /* VMEntryRecord.h */, 4178 4181 0F55F0F114D1063600AC7649 /* AbstractPC.cpp */, 4179 4182 0F55F0F214D1063600AC7649 /* AbstractPC.h */, … … 6018 6021 A1A009C11831A26E00CF8711 /* ARM64Assembler.h in Headers */, 6019 6022 86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */, 6023 658D3A5619638268003C45D6 /* VMEntryRecord.h in Headers */, 6020 6024 2AD2EDFB19799E38004D6478 /* EnumerationMode.h in Headers */, 6021 6025 147B83AC0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h in Headers */, -
trunk/Source/JavaScriptCore/bytecode/BytecodeList.json
r172614 r172665 140 140 { "name" : "getHostCallReturnValue" }, 141 141 { "name" : "llint_return_to_host" }, 142 { "name" : "llint_ call_to_javascript" },143 { "name" : "llint_ call_to_native_function" },142 { "name" : "llint_vm_entry_to_javascript" }, 143 { "name" : "llint_vm_entry_to_native" }, 144 144 { "name" : "llint_cloop_did_return_from_js_1" }, 145 145 { "name" : "llint_cloop_did_return_from_js_2" }, -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r172614 r172665 60 60 #include "RepatchBuffer.h" 61 61 #include "SlotVisitorInlines.h" 62 #include "StackVisitor.h" 62 63 #include "UnlinkedInstructionStream.h" 63 64 #include <wtf/BagToHashMap.h> … … 3160 3161 } 3161 3162 3163 class RecursionCheckFunctor { 3164 public: 3165 RecursionCheckFunctor(CallFrame* startCallFrame, CodeBlock* codeBlock, unsigned depthToCheck) 3166 : m_startCallFrame(startCallFrame) 3167 , m_codeBlock(codeBlock) 3168 , m_depthToCheck(depthToCheck) 3169 , m_foundStartCallFrame(false) 3170 , m_didRecurse(false) 3171 { } 3172 3173 StackVisitor::Status operator()(StackVisitor& visitor) 3174 { 3175 CallFrame* currentCallFrame = visitor->callFrame(); 3176 3177 if (currentCallFrame == m_startCallFrame) 3178 m_foundStartCallFrame = true; 3179 3180 if (m_foundStartCallFrame) { 3181 if (visitor->callFrame()->codeBlock() == m_codeBlock) { 3182 m_didRecurse = true; 3183 return StackVisitor::Done; 3184 } 3185 3186 if (!m_depthToCheck--) 3187 return StackVisitor::Done; 3188 } 3189 3190 return StackVisitor::Continue; 3191 } 3192 3193 bool didRecurse() const { return m_didRecurse; } 3194 3195 private: 3196 CallFrame* m_startCallFrame; 3197 CodeBlock* m_codeBlock; 3198 unsigned m_depthToCheck; 3199 bool m_foundStartCallFrame; 3200 bool m_didRecurse; 3201 }; 3202 3162 3203 void CodeBlock::noticeIncomingCall(ExecState* callerFrame) 3163 3204 { … … 3207 3248 return; 3208 3249 } 3209 3210 ExecState* frame = callerFrame; 3211 for (unsigned i = Options::maximumInliningDepth(); i--; frame = frame->callerFrame()) { 3212 if (frame->isVMEntrySentinel()) 3213 break; 3214 if (frame->codeBlock() == this) { 3215 // Recursive calls won't be inlined. 3216 if (Options::verboseCallLink()) 3217 dataLog(" Clearing SABI because recursion was detected.\n"); 3218 m_shouldAlwaysBeInlined = false; 3219 return; 3220 } 3221 } 3222 3250 3251 // Recursive calls won't be inlined. 3252 RecursionCheckFunctor functor(callerFrame, this, Options::maximumInliningDepth()); 3253 vm()->topCallFrame->iterate(functor); 3254 3255 if (functor.didRecurse()) { 3256 if (Options::verboseCallLink()) 3257 dataLog(" Clearing SABI because recursion was detected.\n"); 3258 m_shouldAlwaysBeInlined = false; 3259 return; 3260 } 3261 3223 3262 RELEASE_ASSERT(callerCodeBlock->m_capabilityLevelState != DFG::CapabilityLevelNotSet); 3224 3263 -
trunk/Source/JavaScriptCore/debugger/Debugger.cpp
r172324 r172665 608 608 return; 609 609 610 m_pauseOnCallFrame = m_currentCallFrame ? m_currentCallFrame->callerFrameSkippingVMEntrySentinel() : 0; 610 VMEntryFrame* topVMEntryFrame = m_vm->topVMEntryFrame; 611 m_pauseOnCallFrame = m_currentCallFrame ? m_currentCallFrame->callerFrame(topVMEntryFrame) : 0; 611 612 notifyDoneProcessingDebuggerEvents(); 612 613 } … … 724 725 725 726 // Treat stepping over a return statement like stepping out. 726 if (m_currentCallFrame == m_pauseOnCallFrame) 727 m_pauseOnCallFrame = m_currentCallFrame->callerFrameSkippingVMEntrySentinel(); 728 729 m_currentCallFrame = m_currentCallFrame->callerFrameSkippingVMEntrySentinel(); 727 if (m_currentCallFrame == m_pauseOnCallFrame) { 728 VMEntryFrame* topVMEntryFrame = m_vm->topVMEntryFrame; 729 m_pauseOnCallFrame = m_currentCallFrame->callerFrame(topVMEntryFrame); 730 } 731 732 VMEntryFrame* topVMEntryFrame = m_vm->topVMEntryFrame; 733 m_currentCallFrame = m_currentCallFrame->callerFrame(topVMEntryFrame); 730 734 } 731 735 … … 757 761 return; 758 762 if (m_currentCallFrame == m_pauseOnCallFrame) { 759 m_pauseOnCallFrame = m_currentCallFrame->callerFrameSkippingVMEntrySentinel(); 763 VMEntryFrame* topVMEntryFrame = m_vm->topVMEntryFrame; 764 m_pauseOnCallFrame = m_currentCallFrame->callerFrame(topVMEntryFrame); 760 765 if (!m_currentCallFrame) 761 766 return; 762 767 } 763 m_currentCallFrame = m_currentCallFrame->callerFrameSkippingVMEntrySentinel(); 768 VMEntryFrame* topVMEntryFrame = m_vm->topVMEntryFrame; 769 m_currentCallFrame = m_currentCallFrame->callerFrame(topVMEntryFrame); 764 770 } 765 771 -
trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp
r172372 r172665 56 56 }; 57 57 58 class FindCallerMidStackFunctor { 59 public: 60 FindCallerMidStackFunctor(CallFrame* callFrame) 61 : m_callFrame(callFrame) 62 , m_callerFrame(nullptr) 63 { } 64 65 StackVisitor::Status operator()(StackVisitor& visitor) 66 { 67 if (visitor->callFrame() == m_callFrame) { 68 m_callerFrame = visitor->callerFrame(); 69 return StackVisitor::Done; 70 } 71 return StackVisitor::Continue; 72 } 73 74 CallFrame* getCallerFrame() const { return m_callerFrame; } 75 76 private: 77 CallFrame* m_callFrame; 78 CallFrame* m_callerFrame; 79 }; 80 58 81 DebuggerCallFrame::DebuggerCallFrame(CallFrame* callFrame) 59 82 : m_callFrame(callFrame) … … 71 94 return m_caller; 72 95 73 CallFrame* callerFrame = m_callFrame->callerFrameSkippingVMEntrySentinel(); 96 FindCallerMidStackFunctor functor(m_callFrame); 97 m_callFrame->vm().topCallFrame->iterate(functor); 98 99 CallFrame* callerFrame = functor.getCallerFrame(); 74 100 if (!callerFrame) 75 101 return 0; -
trunk/Source/JavaScriptCore/interpreter/CallFrame.cpp
r170421 r172665 137 137 } 138 138 139 CallFrame* CallFrame::callerFrame(VMEntryFrame*& currVMEntryFrame) 140 { 141 if (callerFrameOrVMEntryFrame() == currVMEntryFrame) { 142 VMEntryRecord* currVMEntryRecord = vmEntryRecord(currVMEntryFrame); 143 currVMEntryFrame = currVMEntryRecord->prevTopVMEntryFrame(); 144 return currVMEntryRecord->prevTopCallFrame(); 145 } 146 return static_cast<CallFrame*>(callerFrameOrVMEntryFrame()); 147 } 148 139 149 JSActivation* CallFrame::activation() const 140 150 { -
trunk/Source/JavaScriptCore/interpreter/CallFrame.h
r171824 r172665 30 30 #include "Register.h" 31 31 #include "StackVisitor.h" 32 #include "VMEntryRecord.h" 32 33 33 34 namespace JSC { … … 95 96 CallFrame& operator=(const Register& r) { *static_cast<Register*>(this) = r; return *this; } 96 97 97 CallFrame* callerFrame() const { return callerFrameAndPC().callerFrame; } 98 CallFrame* callerFrame() const { return static_cast<CallFrame*>(callerFrameOrVMEntryFrame()); } 99 100 JS_EXPORT_PRIVATE CallFrame* callerFrame(VMEntryFrame*&); 101 98 102 static ptrdiff_t callerFrameOffset() { return OBJECT_OFFSETOF(CallerFrameAndPC, callerFrame); } 99 103 … … 162 166 Register* topOfFrame() 163 167 { 164 if ( isVMEntrySentinel() ||!codeBlock())168 if (!codeBlock()) 165 169 return registers(); 166 170 return topOfFrameInternal(); … … 170 174 Instruction* currentVPC() const 171 175 { 172 ASSERT(!isVMEntrySentinel());173 176 return bitwise_cast<Instruction*>(this[JSStack::ArgumentCount].tag()); 174 177 } 175 178 void setCurrentVPC(Instruction* vpc) 176 179 { 177 ASSERT(!isVMEntrySentinel());178 180 this[JSStack::ArgumentCount].tag() = bitwise_cast<int32_t>(vpc); 179 181 } … … 190 192 CallFrame* callerFrame, int argc, JSObject* callee) 191 193 { 192 ASSERT(callerFrame == noCaller() || callerFrame-> isVMEntrySentinel() || callerFrame->stack()->containsAddress(this));194 ASSERT(callerFrame == noCaller() || callerFrame->stack()->containsAddress(this)); 193 195 194 196 setCodeBlock(codeBlock); … … 246 248 static CallFrame* noCaller() { return 0; } 247 249 248 bool isVMEntrySentinel() const249 {250 return !!this && codeBlock() == vmEntrySentinelCodeBlock();251 }252 253 CallFrame* vmEntrySentinelCallerFrame() const254 {255 ASSERT(isVMEntrySentinel());256 return this[JSStack::ScopeChain].callFrame();257 }258 259 void initializeVMEntrySentinelFrame(CallFrame* callFrame)260 {261 setCallerFrame(noCaller());262 setReturnPC(0);263 setCodeBlock(vmEntrySentinelCodeBlock());264 static_cast<Register*>(this)[JSStack::ScopeChain] = callFrame;265 setCallee(0);266 setArgumentCountIncludingThis(0);267 }268 269 CallFrame* callerFrameSkippingVMEntrySentinel()270 {271 CallFrame* caller = callerFrame();272 if (caller->isVMEntrySentinel())273 return caller->vmEntrySentinelCallerFrame();274 return caller;275 }276 277 250 void setArgumentCountIncludingThis(int count) { static_cast<Register*>(this)[JSStack::ArgumentCount].payload() = count; } 278 251 void setCallee(JSObject* callee) { static_cast<Register*>(this)[JSStack::Callee] = Register::withCallee(callee); } … … 292 265 293 266 private: 294 static const intptr_t s_VMEntrySentinel = 1;295 267 296 268 #ifndef NDEBUG … … 331 303 } 332 304 305 void* callerFrameOrVMEntryFrame() const { return callerFrameAndPC().callerFrame; } 306 333 307 CallerFrameAndPC& callerFrameAndPC() { return *reinterpret_cast<CallerFrameAndPC*>(this); } 334 308 const CallerFrameAndPC& callerFrameAndPC() const { return *reinterpret_cast<const CallerFrameAndPC*>(this); } 335 336 static CodeBlock* vmEntrySentinelCodeBlock() { return reinterpret_cast<CodeBlock*>(s_VMEntrySentinel); }337 309 338 310 friend class JSStack; -
trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp
r172176 r172665 480 480 } 481 481 482 CallFrame* callerFrame = callFrame->callerFrame(); 483 return !callerFrame->isVMEntrySentinel(); 482 return !visitor->callerIsVMEntryFrame(); 484 483 } 485 484 … … 598 597 { 599 598 VM& vm = m_vm; 600 ASSERT(!vm.topCallFrame->isVMEntrySentinel());601 599 CallFrame* callFrame = vm.topCallFrame; 602 600 if (!callFrame) … … 684 682 NEVER_INLINE HandlerInfo* Interpreter::unwind(CallFrame*& callFrame, JSValue& exceptionValue) 685 683 { 686 if (callFrame->isVMEntrySentinel()) {687 // This happens when we throw stack overflow in a function that is called688 // directly from callToJavaScript. Stack overflow throws the exception in the689 // context of the caller. In that case the caller is the sentinel frame. The690 // right thing to do is to pretend that the exception is uncaught so that we691 // go to the uncaught exception handler, which returns through callToJavaScript.692 return 0;693 }694 695 684 CodeBlock* codeBlock = callFrame->codeBlock(); 696 685 ASSERT(codeBlock); … … 997 986 result = callData.js.functionExecutable->generatedJITCodeForCall()->execute(&vm, &protoCallFrame); 998 987 else { 999 result = JSValue::decode( callToNativeFunction(reinterpret_cast<void*>(callData.native.function), &vm, &protoCallFrame));988 result = JSValue::decode(vmEntryToNative(reinterpret_cast<void*>(callData.native.function), &vm, &protoCallFrame)); 1000 989 if (callFrame->hadException()) 1001 990 result = jsNull(); … … 1065 1054 result = constructData.js.functionExecutable->generatedJITCodeForConstruct()->execute(&vm, &protoCallFrame); 1066 1055 else { 1067 result = JSValue::decode( callToNativeFunction(reinterpret_cast<void*>(constructData.native.function), &vm, &protoCallFrame));1056 result = JSValue::decode(vmEntryToNative(reinterpret_cast<void*>(constructData.native.function), &vm, &protoCallFrame)); 1068 1057 1069 1058 if (!callFrame->hadException()) -
trunk/Source/JavaScriptCore/interpreter/Interpreter.h
r170147 r172665 158 158 , oldCallFrame(currentVM.topCallFrame) 159 159 { 160 ASSERT(!callFrame->isVMEntrySentinel());161 160 currentVM.topCallFrame = callFrame; 162 161 } … … 164 163 ~TopCallFrameSetter() 165 164 { 166 ASSERT(!oldCallFrame->isVMEntrySentinel());167 165 vm.topCallFrame = oldCallFrame; 168 166 } … … 178 176 ASSERT(vm); 179 177 ASSERT(callFrame); 180 ASSERT(!callFrame->isVMEntrySentinel());181 178 vm->topCallFrame = callFrame; 182 }183 184 enum VMEntrySentinelOKTag { VMEntrySentinelOK };185 ALWAYS_INLINE NativeCallFrameTracer(VM* vm, CallFrame* callFrame, VMEntrySentinelOKTag)186 {187 ASSERT(vm);188 ASSERT(callFrame);189 if (!callFrame->isVMEntrySentinel())190 vm->topCallFrame = callFrame;191 179 } 192 180 }; -
trunk/Source/JavaScriptCore/interpreter/StackVisitor.cpp
r171213 r172665 39 39 { 40 40 m_frame.m_index = 0; 41 if (startFrame) 42 m_frame.m_VMEntryFrame = startFrame->vm().topVMEntryFrame; 43 else 44 m_frame.m_VMEntryFrame = 0; 45 m_frame.m_callerIsVMEntryFrame = false; 41 46 readFrame(startFrame); 42 47 } … … 57 62 void StackVisitor::readFrame(CallFrame* callFrame) 58 63 { 59 ASSERT(!callFrame->isVMEntrySentinel());60 64 if (!callFrame) { 61 65 m_frame.setToEnd(); … … 105 109 m_frame.m_callFrame = callFrame; 106 110 m_frame.m_argumentCountIncludingThis = callFrame->argumentCountIncludingThis(); 107 m_frame.m_callerFrame = callFrame->callerFrameSkippingVMEntrySentinel(); 111 VMEntryFrame* currentVMEntryFrame = m_frame.m_VMEntryFrame; 112 m_frame.m_callerFrame = callFrame->callerFrame(m_frame.m_VMEntryFrame); 113 m_frame.m_callerIsVMEntryFrame = currentVMEntryFrame != m_frame.m_VMEntryFrame; 108 114 m_frame.m_callee = callFrame->callee(); 109 115 m_frame.m_scope = callFrame->scope(); … … 128 134 { 129 135 ASSERT(codeOrigin); 130 ASSERT(!callFrame->isVMEntrySentinel());131 136 132 137 int frameOffset = inlinedFrameOffset(codeOrigin); … … 381 386 printif(i, " name '%s'\n", functionName().utf8().data()); 382 387 printif(i, " sourceURL '%s'\n", sourceURL().utf8().data()); 383 printif(i, " isVMEntrySentinel %d\n", callerFrame->isVMEntrySentinel());384 388 385 389 #if ENABLE(DFG_JIT) -
trunk/Source/JavaScriptCore/interpreter/StackVisitor.h
r156984 r172665 27 27 #define StackVisitor_h 28 28 29 #include "VMEntryRecord.h" 29 30 #include <wtf/text/WTFString.h> 30 31 … … 57 58 size_t index() const { return m_index; } 58 59 size_t argumentCountIncludingThis() const { return m_argumentCountIncludingThis; } 60 bool callerIsVMEntryFrame() const { return m_callerIsVMEntryFrame; } 59 61 CallFrame* callerFrame() const { return m_callerFrame; } 60 62 JSObject* callee() const { return m_callee; } … … 95 97 size_t m_index; 96 98 size_t m_argumentCountIncludingThis; 99 VMEntryFrame* m_VMEntryFrame; 97 100 CallFrame* m_callerFrame; 98 101 JSObject* m_callee; … … 100 103 CodeBlock* m_codeBlock; 101 104 unsigned m_bytecodeOffset; 105 bool m_callerIsVMEntryFrame; 102 106 #if ENABLE(DFG_JIT) 103 107 InlineCallFrame* m_inlineCallFrame; -
trunk/Source/JavaScriptCore/interpreter/VMInspector.cpp
r163844 r172665 30 30 31 31 #include "JSCInlines.h" 32 #include "StackVisitor.h" 32 33 #include <wtf/ASCIICType.h> 33 34 #include <wtf/text/WTFString.h> … … 100 101 } 101 102 103 class CountFramesFunctor { 104 public: 105 CountFramesFunctor() 106 : m_count(-1) 107 { } 108 109 StackVisitor::Status operator()(StackVisitor& visitor) 110 { 111 m_count++; 112 return StackVisitor::Continue; 113 } 114 115 int count() const { return m_count; } 116 117 private: 118 unsigned m_count; 119 }; 120 102 121 int VMInspector::countFrames(CallFrame* frame) 103 122 { 104 int count = -1; 105 while (frame && !frame->isVMEntrySentinel()) { 106 count++; 107 frame = frame->callerFrame(); 108 } 109 return count; 123 CountFramesFunctor functor(); 124 StackVisitor::visit(frame, functor); 125 126 return functor.count(); 110 127 } 111 128 -
trunk/Source/JavaScriptCore/jit/JITCode.cpp
r163844 r172665 45 45 JSValue JITCode::execute(VM* vm, ProtoCallFrame* protoCallFrame) 46 46 { 47 JSValue result = JSValue::decode( callToJavaScript(executableAddress(), vm, protoCallFrame));47 JSValue result = JSValue::decode(vmEntryToJavaScript(executableAddress(), vm, protoCallFrame)); 48 48 return vm->exception() ? jsNull() : result; 49 49 } -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r172614 r172665 81 81 // We pass in our own code block, because the callframe hasn't been populated. 82 82 VM* vm = codeBlock->vm(); 83 CallFrame* callerFrame = exec->callerFrameSkippingVMEntrySentinel(); 83 84 VMEntryFrame* topVMEntryFrame = vm->topVMEntryFrame; 85 CallFrame* callerFrame = exec->callerFrame(topVMEntryFrame); 84 86 if (!callerFrame) 85 87 callerFrame = exec; … … 93 95 { 94 96 VM* vm = &exec->vm(); 95 CallFrame* callerFrame = exec->callerFrameSkippingVMEntrySentinel(); 97 VMEntryFrame* topVMEntryFrame = vm->topVMEntryFrame; 98 CallFrame* callerFrame = exec->callerFrame(topVMEntryFrame); 96 99 NativeCallFrameTracer tracer(vm, callerFrame); 97 100 … … 108 111 { 109 112 VM* vm = &exec->vm(); 110 CallFrame* callerFrame = exec->callerFrameSkippingVMEntrySentinel(); 113 VMEntryFrame* topVMEntryFrame = vm->topVMEntryFrame; 114 CallFrame* callerFrame = exec->callerFrame(topVMEntryFrame); 111 115 NativeCallFrameTracer tracer(vm, callerFrame); 112 116 … … 1824 1828 void JIT_OPERATION lookupExceptionHandler(VM* vm, ExecState* exec) 1825 1829 { 1826 NativeCallFrameTracer tracer(vm, exec , NativeCallFrameTracer::VMEntrySentinelOK);1830 NativeCallFrameTracer tracer(vm, exec); 1827 1831 1828 1832 JSValue exceptionValue = vm->exception(); … … 1838 1842 NativeCallFrameTracer tracer(vm, exec); 1839 1843 1840 ASSERT(!exec->isVMEntrySentinel());1841 1844 genericUnwind(vm, exec, vm->exception()); 1842 1845 } -
trunk/Source/JavaScriptCore/jit/JITStubs.h
r167094 r172665 42 42 43 43 extern "C" { 44 EncodedJSValue callToJavaScript(void*, VM*, ProtoCallFrame*);45 EncodedJSValue callToNativeFunction(void*, VM*, ProtoCallFrame*);44 EncodedJSValue vmEntryToJavaScript(void*, VM*, ProtoCallFrame*); 45 EncodedJSValue vmEntryToNative(void*, VM*, ProtoCallFrame*); 46 46 } 47 47 #endif -
trunk/Source/JavaScriptCore/jsc.cpp
r172152 r172665 688 688 EncodedJSValue JSC_HOST_CALL functionDumpCallFrame(ExecState* exec) 689 689 { 690 if (!exec->callerFrame()->isVMEntrySentinel()) 691 exec->vm().interpreter->dumpCallFrame(exec->callerFrame()); 690 VMEntryFrame* topVMEntryFrame = exec->vm().topVMEntryFrame; 691 ExecState* callerFrame = exec->callerFrame(topVMEntryFrame); 692 if (callerFrame) 693 exec->vm().interpreter->dumpCallFrame(callerFrame); 692 694 return JSValue::encode(jsUndefined()); 693 695 } -
trunk/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
r172176 r172665 50 50 #include "Structure.h" 51 51 #include "StructureChain.h" 52 #include "VMEntryRecord.h" 52 53 #include "ValueProfile.h" 53 54 #include <wtf/text/StringImpl.h> -
trunk/Source/JavaScriptCore/llint/LLIntThunks.cpp
r170876 r172665 38 38 #include "LowLevelInterpreter.h" 39 39 #include "ProtoCallFrame.h" 40 #include "StackAlignment.h" 40 41 #include "VM.h" 41 42 … … 94 95 // Non-JIT (i.e. C Loop LLINT) case: 95 96 96 EncodedJSValue callToJavaScript(void* executableAddress, VM* vm, ProtoCallFrame* protoCallFrame)97 EncodedJSValue vmEntryToJavaScript(void* executableAddress, VM* vm, ProtoCallFrame* protoCallFrame) 97 98 { 98 JSValue result = CLoop::execute(llint_ call_to_javascript, executableAddress, vm, protoCallFrame);99 JSValue result = CLoop::execute(llint_vm_entry_to_javascript, executableAddress, vm, protoCallFrame); 99 100 return JSValue::encode(result); 100 101 } 101 102 102 EncodedJSValue callToNativeFunction(void* executableAddress, VM* vm, ProtoCallFrame* protoCallFrame)103 EncodedJSValue vmEntryToNative(void* executableAddress, VM* vm, ProtoCallFrame* protoCallFrame) 103 104 { 104 JSValue result = CLoop::execute(llint_ call_to_native_function, executableAddress, vm, protoCallFrame);105 JSValue result = CLoop::execute(llint_vm_entry_to_native, executableAddress, vm, protoCallFrame); 105 106 return JSValue::encode(result); 106 107 } 108 109 extern "C" VMEntryRecord* vmEntryRecord(VMEntryFrame* entryFrame) 110 { 111 // The C Loop doesn't have any callee save registers, so the VMEntryRecord is allocated at the base of the frame. 112 intptr_t stackAlignment = stackAlignmentBytes(); 113 intptr_t VMEntryTotalFrameSize = (sizeof(VMEntryRecord) + (stackAlignment - 1)) & ~(stackAlignment - 1); 114 return reinterpret_cast<VMEntryRecord*>(static_cast<char*>(entryFrame) - VMEntryTotalFrameSize); 115 } 116 107 117 108 118 #endif // ENABLE(JIT) -
trunk/Source/JavaScriptCore/llint/LLIntThunks.h
r170147 r172665 35 35 36 36 extern "C" { 37 EncodedJSValue callToJavaScript(void*, VM*, ProtoCallFrame*);38 EncodedJSValue callToNativeFunction(void*, VM*, ProtoCallFrame*);37 EncodedJSValue vmEntryToJavaScript(void*, VM*, ProtoCallFrame*); 38 EncodedJSValue vmEntryToNative(void*, VM*, ProtoCallFrame*); 39 39 } 40 40 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r172614 r172665 43 43 const SlotSize = 8 44 44 45 const StackAlignment = 16 46 const StackAlignmentMask = StackAlignment - 1 47 45 48 const CallerFrameAndPCSize = 2 * PtrSize 46 49 … … 236 239 # ARM can't do logical ops with the sp as a source 237 240 move sp, tempReg 238 andp 0xf, tempReg241 andp StackAlignmentMask, tempReg 239 242 else 240 andp sp, 0xf, tempReg243 andp sp, StackAlignmentMask, tempReg 241 244 end 242 245 btpz tempReg, .stackPointerOkay … … 246 249 end 247 250 end 251 252 if C_LOOP 253 const CalleeSaveRegisterCount = 0 254 elsif ARM or ARMv7_TRADITIONAL or ARMv7 255 const CalleeSaveRegisterCount = 7 256 elsif ARM64 or MIPS 257 const CalleeSaveRegisterCount = 10 258 elsif SH4 or X86_64 259 const CalleeSaveRegisterCount = 5 260 elsif X86 or X86_WIN 261 const CalleeSaveRegisterCount = 3 262 elsif X86_64_WIN 263 const CalleeSaveRegisterCount = 7 264 end 265 266 const CalleeRegisterSaveSize = CalleeSaveRegisterCount * PtrSize 267 268 # VMEntryTotalFrameSize includes the space for struct VMEntryRecord and the 269 # callee save registers rounded up to keep the stack aligned 270 const VMEntryTotalFrameSize = (CalleeRegisterSaveSize + sizeof VMEntryRecord + StackAlignment - 1) & ~StackAlignmentMask 248 271 249 272 macro pushCalleeSaves() … … 418 441 end 419 442 420 macro callToJavaScriptPrologue() 421 if X86_64 or X86_64_WIN 422 push cfr 423 push t0 424 elsif X86 or X86_WIN 425 push cfr 426 elsif ARM64 427 push cfr, lr 428 elsif C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS or SH4 429 push lr 430 push cfr 431 end 432 pushCalleeSaves() 433 if X86 434 subp 12, sp 435 elsif X86_WIN 436 subp 16, sp 437 move sp, t4 438 move t4, t0 439 move t4, t2 440 andp 0xf, t2 441 andp 0xfffffff0, t0 442 move t0, sp 443 storep t4, [sp] 444 elsif ARM or ARMv7 or ARMv7_TRADITIONAL 445 subp 4, sp 446 move sp, t4 447 clrbp t4, 0xf, t5 448 move t5, sp 449 storep t4, [sp] 450 end 451 end 452 453 macro callToJavaScriptEpilogue() 454 if ARMv7 455 addp CallFrameHeaderSlots * 8, cfr, t4 456 move t4, sp 457 else 458 addp CallFrameHeaderSlots * 8, cfr, sp 459 end 460 461 loadp CallerFrame[cfr], cfr 462 463 if X86 464 addp 12, sp 465 elsif X86_WIN 466 pop t4 467 move t4, sp 468 addp 16, sp 469 elsif ARM or ARMv7 or ARMv7_TRADITIONAL 470 pop t4 471 move t4, sp 472 addp 4, sp 473 end 474 475 popCalleeSaves() 476 if X86_64 or X86_64_WIN 477 pop t2 478 pop cfr 479 elsif X86 or X86_WIN 480 pop cfr 481 elsif ARM64 482 pop lr, cfr 483 elsif C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS or SH4 484 pop cfr 485 pop lr 486 end 443 macro vmEntryRecord(entryFramePointer, resultReg) 444 subp entryFramePointer, VMEntryTotalFrameSize, resultReg 487 445 end 488 446 … … 729 687 730 688 # stub to call into JavaScript or Native functions 731 # EncodedJSValue callToJavaScript(void* code, ExecState** vmTopCallFrame, ProtoCallFrame* protoFrame)732 # EncodedJSValue callToNativeFunction(void* code, ExecState** vmTopCallFrame, ProtoCallFrame* protoFrame)689 # EncodedJSValue vmEntryToJavaScript(void* code, VM* vm, ProtoCallFrame* protoFrame) 690 # EncodedJSValue vmEntryToNativeFunction(void* code, VM* vm, ProtoCallFrame* protoFrame) 733 691 734 692 if C_LOOP 735 _llint_ call_to_javascript:693 _llint_vm_entry_to_javascript: 736 694 else 737 global _ callToJavaScript738 _ callToJavaScript:739 end 740 do CallToJavaScript(makeJavaScriptCall)695 global _vmEntryToJavaScript 696 _vmEntryToJavaScript: 697 end 698 doVMEntry(makeJavaScriptCall) 741 699 742 700 743 701 if C_LOOP 744 _llint_ call_to_native_function:702 _llint_vm_entry_to_native: 745 703 else 746 global _ callToNativeFunction747 _ callToNativeFunction:748 end 749 do CallToJavaScript(makeHostFunctionCall)704 global _vmEntryToNative 705 _vmEntryToNative: 706 end 707 doVMEntry(makeHostFunctionCall) 750 708 751 709 … … 790 748 storep address, VM::m_lastStackTop[vm] 791 749 ret 792 end 793 750 751 if C_LOOP 752 else 753 # VMEntryRecord* vmEntryRecord(const VMEntryFrame* entryFrame) 754 global _vmEntryRecord 755 _vmEntryRecord: 756 if X86_64 757 const entryFrame = t4 758 const result = t0 759 elsif X86 or X86_WIN 760 const entryFrame = t2 761 const result = t0 762 else 763 const entryFrame = a0 764 const result = t0 765 end 766 767 if X86 or X86_WIN 768 loadp 4[sp], entryFrame 769 end 770 771 vmEntryRecord(entryFrame, result) 772 ret 773 end 774 end 794 775 795 776 if C_LOOP -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp
r170147 r172665 339 339 #endif 340 340 341 // Initialize the incoming args for do CallToJavaScript:341 // Initialize the incoming args for doVMEntryToJavaScript: 342 342 t0.vp = executableAddress; 343 343 t1.vm = vm; -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
r172598 r172665 156 156 end 157 157 158 macro do CallToJavaScript(makeCall)158 macro doVMEntry(makeCall) 159 159 if X86 or X86_WIN 160 160 const entry = t4 … … 162 162 const protoCallFrame = t5 163 163 164 const previousCFR = t0 165 const previousPC = t1 166 const temp1 = t0 # Same as previousCFR 167 const temp2 = t1 # Same as previousPC 164 const temp1 = t0 165 const temp2 = t1 168 166 const temp3 = t2 169 167 const temp4 = t3 # same as vm … … 173 171 const protoCallFrame = a2 174 172 175 const previousCFR = t3 176 const previousPC = lr 177 const temp1 = t3 # Same as previousCFR 173 const temp1 = t3 178 174 const temp2 = t4 179 175 const temp3 = t5 … … 185 181 const topOfStack = a3 186 182 187 const previousCFR = t2188 const previousPC = lr189 183 const temp1 = t3 190 184 const temp2 = t5 … … 196 190 const protoCallFrame = a2 197 191 198 const previousCFR = t3 199 const previousPC = lr 200 const temp1 = t3 # Same as previousCFR 192 const temp1 = t3 201 193 const temp2 = a3 202 194 const temp3 = t8 … … 204 196 end 205 197 206 callToJavaScriptPrologue() 207 208 if X86 209 loadp 36[sp], vm 210 loadp 32[sp], entry 211 elsif X86_WIN 212 loadp 40[sp, temp3], vm 213 loadp 36[sp, temp3], entry 214 else 215 move cfr, previousCFR 198 functionPrologue() 199 pushCalleeSaves() 200 201 if X86 or X86_WIN 202 loadp 12[cfr], vm 203 loadp 8[cfr], entry 216 204 end 217 205 218 checkStackPointerAlignment(temp2, 0xbad0dc01) 219 220 # The stack reserved zone ensures that we have adequate space for the 221 # VMEntrySentinelFrame. Proceed with allocating and initializing the 222 # sentinel frame. 223 move sp, cfr 224 subp CallFrameHeaderSlots * 8, cfr 225 storep 0, ArgumentCount[cfr] 226 storep vm, Callee[cfr] 206 vmEntryRecord(cfr, sp) 207 208 storep vm, VMEntryRecord::m_vm[sp] 227 209 loadp VM::topCallFrame[vm], temp2 228 storep temp2, ScopeChain[cfr] 229 storep 1, CodeBlock[cfr] 230 if X86 231 loadp 28[sp], previousPC 232 loadp 24[sp], previousCFR 233 elsif X86_WIN 234 loadp 32[sp, temp3], previousPC 235 loadp 28[sp, temp3], previousCFR 210 storep temp2, VMEntryRecord::m_prevTopCallFrame[sp] 211 loadp VM::topVMEntryFrame[vm], temp2 212 storep temp2, VMEntryRecord::m_prevTopVMEntryFrame[sp] 213 214 # Align stack pointer 215 if X86_WIN 216 addp CallFrameAlignSlots * SlotSize, sp, temp1 217 andp ~StackAlignmentMask, temp1 218 subp temp1, CallFrameAlignSlots * SlotSize, sp 219 elsif ARM or ARMv7 or ARMv7_TRADITIONAL 220 addp CallFrameAlignSlots * SlotSize, sp, temp1 221 clrbp temp1, StackAlignmentMask, temp1 222 subp temp1, CallFrameAlignSlots * SlotSize, sp 236 223 end 237 storep previousPC, ReturnPC[cfr] 238 storep previousCFR, CallerFrame[cfr] 239 240 if X86 241 loadp 40[sp], protoCallFrame 242 elsif X86_WIN 243 loadp 44[sp, temp3], protoCallFrame 224 225 if X86 or X86_WIN 226 loadp 16[cfr], protoCallFrame 244 227 end 245 228 … … 247 230 addp CallFrameHeaderSlots, temp2, temp2 248 231 lshiftp 3, temp2 249 subp cfr, temp2, temp1232 subp sp, temp2, temp1 250 233 251 234 # Ensure that we have enough additional stack capacity for the incoming args, … … 253 236 # before we start copying the args from the protoCallFrame below. 254 237 bpaeq temp1, VM::m_jsStackLimit[vm], .stackHeightOK 255 256 if ARMv7257 subp cfr, 8, temp2258 move temp2, sp259 else260 subp cfr, 8, sp261 end262 238 263 239 if C_LOOP … … 276 252 277 253 cCall2(_llint_throw_stack_overflow_error, vm, protoCallFrame) 278 callToJavaScriptEpilogue() 254 255 vmEntryRecord(cfr, sp) 256 257 loadp VMEntryRecord::m_vm[sp], temp3 258 loadp VMEntryRecord::m_prevTopCallFrame[sp], temp4 259 storep temp4, VM::topCallFrame[temp3] 260 loadp VMEntryRecord::m_prevTopVMEntryFrame[sp], temp4 261 storep temp4, VM::topVMEntryFrame[temp3] 262 263 subp cfr, CalleeRegisterSaveSize, sp 264 265 popCalleeSaves() 266 functionEpilogue() 279 267 ret 280 268 … … 317 305 .copyArgsDone: 318 306 storep sp, VM::topCallFrame[vm] 307 storep cfr, VM::topVMEntryFrame[vm] 319 308 320 309 makeCall(entry, temp1, temp2) 321 310 322 bpeq CodeBlock[cfr], 1, .calleeFramePopped 323 loadp CallerFrame[cfr], cfr 324 325 .calleeFramePopped: 326 loadp Callee[cfr], temp3 # VM 327 loadp ScopeChain[cfr], temp4 # previous topCallFrame 311 vmEntryRecord(cfr, sp) 312 313 loadp VMEntryRecord::m_vm[sp], temp3 314 loadp VMEntryRecord::m_prevTopCallFrame[sp], temp4 328 315 storep temp4, VM::topCallFrame[temp3] 329 330 callToJavaScriptEpilogue() 316 loadp VMEntryRecord::m_prevTopVMEntryFrame[sp], temp4 317 storep temp4, VM::topVMEntryFrame[temp3] 318 319 subp cfr, CalleeRegisterSaveSize, sp 320 321 popCalleeSaves() 322 functionEpilogue() 331 323 ret 332 324 end … … 379 371 loadp VM::callFrameForThrow[t3], cfr 380 372 381 # So far, we've unwound the stack to the frame just below the sentinel frame, except382 # in the case of stack overflow in the first function called from callToJavaScript.383 # Check if we need to pop to the sentinel frame and do the necessary clean up for384 # returning to the caller C frame.385 bpeq CodeBlock[cfr], 1, .handleUncaughtExceptionAlreadyIsSentinel386 373 loadp CallerFrame + PayloadOffset[cfr], cfr 387 .handleUncaughtExceptionAlreadyIsSentinel: 388 389 loadp Callee + PayloadOffset[cfr], t3 # VM 390 loadp ScopeChain + PayloadOffset[cfr], t5 # previous topCallFrame 374 375 vmEntryRecord(cfr, sp) 376 377 loadp VMEntryRecord::m_vm[sp], t3 378 loadp VMEntryRecord::m_prevTopCallFrame[sp], t5 391 379 storep t5, VM::topCallFrame[t3] 392 393 callToJavaScriptEpilogue() 380 loadp VMEntryRecord::m_prevTopVMEntryFrame[sp], t5 381 storep t5, VM::topVMEntryFrame[t3] 382 383 subp cfr, CalleeRegisterSaveSize, sp 384 385 popCalleeSaves() 386 functionEpilogue() 394 387 ret 395 388 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r172598 r172665 139 139 end 140 140 141 macro do CallToJavaScript(makeCall)141 macro doVMEntry(makeCall) 142 142 if X86_64 143 143 const entry = t4 … … 172 172 end 173 173 174 callToJavaScriptPrologue() 175 176 if X86_64 177 loadp 7*8[sp], previousPC 178 move 6*8[sp], previousCFR 179 elsif X86_64_WIN 180 # Win64 pushes two more registers 181 loadp 9*8[sp], previousPC 182 move 8*8[sp], previousCFR 183 elsif ARM64 184 move cfr, previousCFR 185 end 174 functionPrologue() 175 pushCalleeSaves() 176 177 vmEntryRecord(cfr, sp) 186 178 187 179 checkStackPointerAlignment(temp2, 0xbad0dc01) 188 180 189 # The stack reserved zone ensures that we have adequate space for the 190 # VMEntrySentinelFrame. Proceed with allocating and initializing the 191 # sentinel frame. 192 move sp, cfr 193 subp CallFrameHeaderSlots * 8, cfr 194 storep 0, ArgumentCount[cfr] 195 storep vm, Callee[cfr] 181 storep vm, VMEntryRecord::m_vm[sp] 196 182 loadp VM::topCallFrame[vm], temp2 197 storep temp2, ScopeChain[cfr] 198 storep 1, CodeBlock[cfr] 199 200 storep previousPC, ReturnPC[cfr] 201 storep previousCFR, CallerFrame[cfr] 183 storep temp2, VMEntryRecord::m_prevTopCallFrame[sp] 184 loadp VM::topVMEntryFrame[vm], temp2 185 storep temp2, VMEntryRecord::m_prevTopVMEntryFrame[sp] 202 186 203 187 loadi ProtoCallFrame::paddedArgCount[protoCallFrame], temp2 204 188 addp CallFrameHeaderSlots, temp2, temp2 205 189 lshiftp 3, temp2 206 subp cfr, temp2, temp1190 subp sp, temp2, temp1 207 191 208 192 # Ensure that we have enough additional stack capacity for the incoming args, … … 210 194 # before we start copying the args from the protoCallFrame below. 211 195 bpaeq temp1, VM::m_jsStackLimit[vm], .stackHeightOK 212 213 move cfr, sp214 196 215 197 if C_LOOP … … 228 210 229 211 cCall2(_llint_throw_stack_overflow_error, vm, protoCallFrame) 230 callToJavaScriptEpilogue() 212 213 vmEntryRecord(cfr, temp2) 214 215 loadp VMEntryRecord::m_vm[temp2], vm 216 loadp VMEntryRecord::m_prevTopCallFrame[temp2], temp3 217 storep temp3, VM::topCallFrame[vm] 218 loadp VMEntryRecord::m_prevTopVMEntryFrame[temp2], temp3 219 storep temp3, VM::topVMEntryFrame[vm] 220 221 subp cfr, CalleeRegisterSaveSize, sp 222 223 popCalleeSaves() 224 functionEpilogue() 231 225 ret 232 226 … … 270 264 storep sp, VM::topCallFrame[vm] 271 265 end 266 storep cfr, VM::topVMEntryFrame[vm] 272 267 273 268 move 0xffff000000000000, csr1 … … 280 275 checkStackPointerAlignment(temp3, 0xbad0dc03) 281 276 282 bpeq CodeBlock[cfr], 1, .calleeFramePopped 283 loadp CallerFrame[cfr], cfr 284 285 .calleeFramePopped: 286 loadp Callee[cfr], temp2 # VM 287 loadp ScopeChain[cfr], temp3 # previous topCallFrame 288 storep temp3, VM::topCallFrame[temp2] 289 290 checkStackPointerAlignment(temp3, 0xbad0dc04) 291 292 if X86_64 or X86_64_WIN 293 pop t5 294 end 295 callToJavaScriptEpilogue() 277 vmEntryRecord(cfr, temp2) 278 279 loadp VMEntryRecord::m_vm[temp2], vm 280 loadp VMEntryRecord::m_prevTopCallFrame[temp2], temp3 281 storep temp3, VM::topCallFrame[vm] 282 loadp VMEntryRecord::m_prevTopVMEntryFrame[temp2], temp3 283 storep temp3, VM::topVMEntryFrame[vm] 284 285 subp cfr, CalleeRegisterSaveSize, sp 286 287 popCalleeSaves() 288 functionEpilogue() 296 289 297 290 ret … … 347 340 loadp VM::callFrameForThrow[t3], cfr 348 341 349 # So far, we've unwound the stack to the frame just below the sentinel frame, except350 # in the case of stack overflow in the first function called from callToJavaScript.351 # Check if we need to pop to the sentinel frame and do the necessary clean up for352 # returning to the caller C frame.353 bpeq CodeBlock[cfr], 1, .handleUncaughtExceptionAlreadyIsSentinel354 342 loadp CallerFrame[cfr], cfr 355 .handleUncaughtExceptionAlreadyIsSentinel: 356 357 loadp Callee[cfr], t3 # VM358 loadp ScopeChain[cfr], t5 # previous topCallFrame343 vmEntryRecord(cfr, t2) 344 345 loadp VMEntryRecord::m_vm[t2], t3 346 loadp VMEntryRecord::m_prevTopCallFrame[t2], t5 359 347 storep t5, VM::topCallFrame[t3] 360 361 callToJavaScriptEpilogue() 348 loadp VMEntryRecord::m_prevTopVMEntryFrame[t2], t5 349 storep t5, VM::topVMEntryFrame[t3] 350 351 subp cfr, CalleeRegisterSaveSize, sp 352 353 popCalleeSaves() 354 functionEpilogue() 362 355 ret 363 356 -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r172614 r172665 81 81 #include "SimpleTypedArrayController.h" 82 82 #include "SourceProviderCache.h" 83 #include "StackVisitor.h" 83 84 #include "StrictEvalActivation.h" 84 85 #include "StrongInlines.h" … … 150 151 , vmType(vmType) 151 152 , clientData(0) 153 , topVMEntryFrame(nullptr) 152 154 , topCallFrame(CallFrame::noCaller()) 153 155 , m_atomicStringTable(vmType == Default ? wtfThreadData().atomicStringTable() : new AtomicStringTable) … … 594 596 exception->putDirect(*vm, vm->propertyNames->message, jsString(vm, message)); 595 597 } 596 598 599 class FindFirstCallerFrameWithCodeblockFunctor { 600 public: 601 FindFirstCallerFrameWithCodeblockFunctor(CallFrame* startCallFrame) 602 : m_startCallFrame(startCallFrame) 603 , m_foundCallFrame(nullptr) 604 , m_foundStartCallFrame(false) 605 , m_index(0) 606 { } 607 608 StackVisitor::Status operator()(StackVisitor& visitor) 609 { 610 if (!m_foundStartCallFrame && (visitor->callFrame() == m_startCallFrame)) 611 m_foundStartCallFrame = true; 612 613 if (m_foundStartCallFrame) { 614 if (visitor->callFrame()->codeBlock()) { 615 m_foundCallFrame = visitor->callFrame(); 616 return StackVisitor::Done; 617 } 618 m_index++; 619 } 620 621 return StackVisitor::Continue; 622 } 623 624 CallFrame* foundCallFrame() const { return m_foundCallFrame; } 625 unsigned index() const { return m_index; } 626 627 private: 628 CallFrame* m_startCallFrame; 629 CallFrame* m_foundCallFrame; 630 bool m_foundStartCallFrame; 631 unsigned m_index; 632 }; 633 597 634 JSValue VM::throwException(ExecState* exec, JSValue error) 598 635 { … … 632 669 } 633 670 if (exception->isErrorInstance() && static_cast<ErrorInstance*>(exception)->appendSourceToMessage()) { 634 unsigned stackIndex = 0; 635 CallFrame* callFrame; 636 for (callFrame = exec; callFrame && !callFrame->codeBlock(); ) { 637 stackIndex++; 638 callFrame = callFrame->callerFrameSkippingVMEntrySentinel(); 639 } 671 FindFirstCallerFrameWithCodeblockFunctor functor(exec); 672 topCallFrame->iterate(functor); 673 CallFrame* callFrame = functor.foundCallFrame(); 674 unsigned stackIndex = functor.index(); 675 640 676 if (callFrame && callFrame->codeBlock()) { 641 677 stackFrame = stackTrace.at(stackIndex); -
trunk/Source/JavaScriptCore/runtime/VM.h
r172614 r172665 48 48 #include "TypedArrayController.h" 49 49 #include "TypeLocation.h" 50 #include "VMEntryRecord.h" 50 51 #include "Watchdog.h" 51 52 #include "Watchpoint.h" … … 236 237 VMType vmType; 237 238 ClientData* clientData; 239 VMEntryFrame* topVMEntryFrame; 238 240 ExecState* topCallFrame; 239 241 std::unique_ptr<Watchdog> watchdog;
Note: See TracChangeset
for help on using the changeset viewer.